Find spec/reflect angle

Become a member of the CGSociety

Connect, Share, and Learn with our Large Growing CG Art Community. It's Free!

THREAD CLOSED
 
Thread Tools Search this Thread Display Modes
  02 February 2013
Find spec/reflect angle

I spend way too much time moving lights into the correct spot to get good spec/reflect for product shots. I want to be able to use a line from the camera to the object to represent the camera angle. Then a second line is created depending on the bounce angle from the surface, showing me where the light/object should be placed.

How would I calculate that bounce angle? It wouldn't have to totally accurate, just a good approximation.


Any thoughts?
pixlmoonky
 
  02 February 2013
It's just the reflection of the camera ray by the surface normal.
Place a point on the surface (get closest location to your spec control).
Get the normal at that point, say N
Get the camera ray at that point, say R (subtract the camera filmback position from the world space point position)
Get the cross product between N and R, that's your rotation axis, call it T.
Get the angle between N and R, call it "a"
Rotate N by a, that's the direction your light will need to face.
__________________
Come, Join the Cult http://www.cultofrig.com - Rigging from First Principles
 
  02 February 2013
That gets me in the right direction to start, thanks.

This won't work for the times I need to reflect a specific object or lightObject. I would need to ray to shoot out to a place in space.

Or am I thinking wrong on this?

pixlmonky
 
  02 February 2013
The principle is the same, reflection is always based on the relationship between normal and POV.
For a specific object you could place that object along that same line if its centre is also its centre of geometry, or if you want a specific point of such object to be reflect work with a second location and then apply to that object's transform the transform of your "reflector" and its transform delta from such "reflector" control.

For more complex things like defining where the edges of the object would be reflected (approximately) you would need to step it up an order of magnitude to at least consider a plane, a bounding box and would need to work off multiple vectors to establish distance as well as direction, but that might be well beyond the scope.

Also worth noting:
do a dot product between the normal and the ray first, if it's 0 it's a glancing hit, and if negative that face is facing away from the camera and therefore the reflection won't be seen.
After that test, if the cross product between normal and ray isn't valid (a 0 vector) it means the normal is fully facing the camera and for a spec in that place your light would be a headlight placed alongside the ray itself.
__________________
Come, Join the Cult http://www.cultofrig.com - Rigging from First Principles
 
  02 February 2013
Here is a mel script i made a while ago to tweak the lighting of my still images. It basically does what you asked for, or more precise, it creates a curve either from mesh faces or a points on a nurbs surface that is the reflection ray of the current cameras view to these points using their normal. Call the procedure with cShowReflectionRay().


global proc cShowReflectionRay(){
	if(`window -exists "cShowReflectionRay"`) deleteUI "cShowReflectionRay";
	if(`windowPref -exists "cShowReflectionRay"`) windowPref -remove "cShowReflectionRay";
	window -title "show reflection ray" -width 300 -resizeToFitChildren 1 "cShowReflectionRay";
	string $mainLayout = `rowColumnLayout -numberOfColumns 1 -cw 1 300`;
		separator -style "none" -height 10;
		rowColumnLayout -numberOfColumns 3 -cw 1 10 -cw 2 260 -cw 3 10;
			text -l "";
			string $radioGrp = `radioButtonGrp
				-numberOfRadioButtons 2
				-labelArray2 "average values" "per component"
				-cw 1 129
				-select 1`;			
			text -l "";

	setParent $mainLayout;
		separator -style "none" -height 7;
		rowColumnLayout -numberOfColumns 5 -cw 1 5 -cw 2 97 -cw 3 96 -cw 4 97 -cw 5 5;
			text -l "";
			button -l "show rays" -command ("cShowReflectionRay_doIt (`radioButtonGrp -q -select \"" + $radioGrp + "\"` - 1);");
			button -l "ok" -command ("cShowReflectionRay_doIt (`radioButtonGrp -q -select \"" + $radioGrp + "\"` - 1)");
			button -l "cancel" -command ("deleteUI \"cShowReflectionRay\"");
	setParent $mainLayout;
		separator -style "none" -height 5;
	showWindow "cShowReflectionRay";
};

global proc cShowReflectionRay_doIt(int $showRayPerComponent)
{
	string $sel[] = `ls -fl -sl`;
	string $activePanel = `getPanel -withFocus`;
	string $currentCam = `modelPanel -q -camera $activePanel`;
	string $camTransform[] = {};
	if(`nodeType $currentCam` == "camera")
	{
		$camTransform = `listRelatives -parent -f $currentCam`;
	}
	else $camTransform = {$currentCam};
	vector $camPos = `xform -q -ws -t $camTransform[0]`;

	vector $pList[] = {};
	vector $nList[] = {};
	for($i=0;$i<`size $sel`;$i++)
	{
		string $shape[] = `ls -long -o $sel[0]`;
		string $component[] = {$sel[$i]};

		vector $p, $n;
		if(`nodeType $shape[0]` == "nurbsSurface")
		{
			tokenize $component[0] "[]" $component;
			float $uv[] = {(float($component[1])),(float($component[2]))};
			$p = `pointOnSurface -u $uv[0] -v $uv[1] -p $shape[0]`;
			$n = `pointOnSurface -u $uv[0] -v $uv[1] -nn $shape[0]`;
		}
		else if(`nodeType $shape[0]` == "mesh")
		{
			string $fv[] = `polyListComponentConversion -ff -tvf $component[0]`;
			$fv = `filterExpand -sm 70 -ex true $fv`;
			if(`size $fv` < 3){
				print($component[0] + ": invalid face, skipped\n");
				continue;
			};
			float $tmp[] = {};
			float $averagePos[] = {};
			for($k=0;$k<`size $fv`;$k++){
				string $vertex[] = `polyListComponentConversion -fvf -tv $fv[$k]`;
				float $pos[] = `xform -q -ws -t $vertex[0]`;
				$tmp[`size $tmp`] = $pos[0];
				$tmp[`size $tmp`] = $pos[1];
				$tmp[`size $tmp`] = $pos[2];

			};
			vector $v1 = <<($tmp[3] - $tmp[0]),($tmp[4] - $tmp[1]),($tmp[5] - $tmp[2])>>;
			vector $v2 = <<($tmp[6] - $tmp[0]),($tmp[7] - $tmp[1]),($tmp[8] - $tmp[2])>>;

			float $averagePos[] = {};
			for($k=0;$k<`size $fv`;$k++){
				$averagePos[0] = $averagePos[0] + $tmp[$k * 3];
				$averagePos[1] = $averagePos[1] + $tmp[$k * 3 + 1];
				$averagePos[2] = $averagePos[2] + $tmp[$k * 3 + 2];
			};
			$averagePos = {($averagePos[0] / `size $fv`),($averagePos[1] / `size $fv`),($averagePos[2] / `size $fv`)};
			$p = <<$averagePos[0],$averagePos[1],$averagePos[2]>>;
			$n = unit(`cross $v1 $v2`);
		}
		else
			return;

		if($showRayPerComponent == 1){
			vector $camToPOS = $camPos - $p;
			float $length_1 = mag($camToPOS);
			float $length_2 = sind(90 - `rad_to_deg (angle($n, $camToPOS))`) * $length_1;
			vector $mPoint = $p + $n * $length_2;
			vector $camToMPoint = $mPoint - $camPos;
			vector $finalPoint = $mPoint + $camToMPoint;
			string $curve = `curve -d 1 -p ($p.x) ($p.y) ($p.z) -p ($finalPoint.x) ($finalPoint.y) ($finalPoint.z)`;
			xform -piv ($p.x) ($p.y) ($p.z) $curve;
		}else{
			$pList[`size $pList`] = $p;
			$nList[`size $nList`] = $n;
		};
	};
	if($showRayPerComponent == 0){
		float $p[], $n[];
		int $numComponents = `size $pList`;
		for($i=0;$i<`size $pList`;$i++){
			vector $tmp = $pList[$i];
			$p[0] = $p[0] + ($tmp.x) / $numComponents; 
			$p[1] = $p[1] + ($tmp.y) / $numComponents; 
			$p[2] = $p[2] + ($tmp.z) / $numComponents; 
			$tmp = $nList[$i];
			$n[0] = $n[0] + ($tmp.x) / $numComponents; 
			$n[1] = $n[1] + ($tmp.y) / $numComponents; 
			$n[2] = $n[2] + ($tmp.z) / $numComponents; 
		};
		vector $camToPOS = $camPos - <<$p[0],$p[1],$p[2]>>;
		float $length_1 = mag($camToPOS);
		float $length_2 = sind(90 - `rad_to_deg (angle(<<$n[0],$n[1],$n[2]>>, $camToPOS))`) * $length_1;
		vector $mPoint = <<$p[0],$p[1],$p[2]>> + <<$n[0],$n[1],$n[2]>> * $length_2;
		vector $camToMPoint = $mPoint - $camPos;
		vector $finalPoint = $mPoint + $camToMPoint;
		string $curve = `curve -d 1 -p $p[0] $p[1] $p[2] -p ($finalPoint.x) ($finalPoint.y) ($finalPoint.z)`;
		xform -piv $p[0] $p[1] $p[2] $curve;
	};
};

Last edited by zaskar : 02 February 2013 at 09:22 AM.
 
  02 February 2013
Originally Posted by zaskar: Here is a mel script i made a while ago to tweak the lighting of my still images. It basically does what you asked for, or more precise, it creates a curve either from mesh faces or a points on a nurbs surface that is the reflection ray of the current cameras view to these points using their normal. Call the procedure with cShowReflectionRay().


neat! I'm saving it.
__________________
maya@reddit r/maya
 
  02 February 2013
very interesting thread, unfortunately zaskars script doesn't do anything in maya 2012?
 
  02 February 2013
Originally Posted by Sorath: very interesting thread, unfortunately zaskars script doesn't do anything in maya 2012?


it does! you just need to have it in your shelf (or somehow manage to launch the script with your persp view in focus) and select faces
__________________
maya@reddit r/maya
 
  02 February 2013
I am using 2012, works perfect for me.
Make sure you have a face selected when you hit "show rays".


Pixlmonky
 
  02 February 2013
well, not really useful.

I thought more about coding something which gives you a vector on every object showing the reflection angle regarding to the selected light viewn always from the current camera.
The reflection vector should update when moving the light.
This can be extended with showing reflection falloffvectors like normals in different size and color depending on reflection values and brdf/fresnel values in shaders and so forth.
It's a neat idea for lighting tools dev.

If I have time I'll look into it.
 
  02 February 2013
Thread automatically closed

This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.
__________________
CGTalk Policy/Legalities
Note that as CGTalk Members, you agree to the terms and conditions of using this website.
 
Thread Closed share thread



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
CGSociety
Society of Digital Artists
www.cgsociety.org

Powered by vBulletin
Copyright 2000 - 2006,
Jelsoft Enterprises Ltd.
Minimize Ads
Forum Jump
Miscellaneous

All times are GMT. The time now is 03:15 PM.


Powered by vBulletin
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.