OSL Object Space to "UV" Space Transform - This may be a simple vector math question

I’m still troubleshooting my Parallax Vector Transform script, which up until last night I had assumed was airquote production ready enough to list in the Scripts Thread. I found an error that is really blatant, in a simple test case that I should have run already. Up until last night, I had simply been testing planes… in those cases, the incoming UV Vector always matches the object space.

Case 1:


Pretty spiffy. Unfortunately, when packing UVs you really want to be able to rotate the UV however fits best. There’s no reason you should have to have X and Y in the “UV Space” to align perfect with the Object Space. See what happens at 45 degrees of uv only rotation (about the Z axis). Obviously both the checker and displacement should shift…

Case 2:


I know exactly what needs to be done, but my math skills are lacking. See the 15 //comment section of the simple osl code below.

How do I rotate one vector to match the direction of another vector?

Relevant Section:



//below, the normalized IR is based on the Incident Ray transformed to object space... 
//relevant code states "vector normalizedIR = normalize( Ito );"
//all well and good, works splendidly, assuming UV's X and Y directions match the Object's X and Y.
//to do it right, I would want
//
//vector ITuv = transform( "uv space" , I );
//then
//vector normalizedIR = normalize( ITuv );
//
//unfortunately, uv space is not an existent space in OSL's eight available contexts.
//
//but fortunately, I have both the UV Vector (UVVectorIn), as well as the Object space vector (OSVectorIn)
//It should simply be a matter of rotating or transforming Ito to match the direction of a rotated/transformed UV Vector.
//for instance, in the image, it would be rotated <0 , 0 , 45>
//this should be fixed
vector normalizedIR = normalize( Ito ); 

Full Code:


#include "stdosl.h"

shader node_texture_parallax(


float HeightValueIn = 0.5
[[ string UIlabel = "Height Map" ]],
vector UVVectorIn = vector(0 , 0 , 0)
[[ string UIlabel = "Tex Coord Vector" ]],
float Strength = 0.6
[[ string UIlabel = "Strength" ]],
float MinClampValue = 0.0
[[ string UIlabel = "Minimum Clamp Value" ]],
float Bias = -3
[[ string UIlabel = "Bias Value" ]],
vector OSVectorIn = vector(0, 0, 0)
[[ string UIlabel = "Object Space Vector" ]],
output vector TextureCoords = vector(1.0 , 1.0 , 1.0) 
[[ string UIlabel = "Texture Coordinates" ]])
{


float Val = clamp( HeightValueIn , MinClampValue , 1 );


//incident ray I is the viewing ray to the shader position P
//these are 5 of the 8 available spaces...


//vector Itc = transform("camera" , I );
vector Ito = transform("object" , I );
//vector Itw = transform("world" , I);
//vector Its = transform("shader" , I );
//vector Itco = transform( "common" , I );
//the other 3 are "screen", "raster", and "NDC"...




//below, the normalized IR is based on the Incident Ray transformed to object space... 
//relevant code states "vector normalizedIR = normalize( Ito );"
//all well and good, works splendidly, assuming UV's X and Y directions match the Object's X and Y.
//to do it right, I would want
//
//vector ITuv = transform( "uv space" , I );
//then
//vector normalizedIR = normalize( ITuv );
//
//unfortunately, uv space is not an existent space in OSL's eight available contexts.
//
//but fortunately, I have both the UV Vector (UVVectorIn), as well as the Object space vector (OSVectorIn)
//It should simply be a matter of rotating or transforming Ito to match the direction of a rotated/transformed UV Vector.
//for instance, in the image, it would be rotated <0 , 0 , 45>
//this should be fixed
vector normalizedIR = normalize( Ito ); 




float adjustedStrength = Strength/10;
float adjustedBias = Bias/100;


vector finalStrength = vector( adjustedStrength * Val + adjustedBias , adjustedStrength * Val + adjustedBias , 0 );


finalStrength[0] = finalStrength[0] * normalizedIR[0];
finalStrength[1] = finalStrength[1] * normalizedIR[1];


//rather than be UVVectorIn... it needs to be OffsetUVVectorIn...
TextureCoords[0] = UVVectorIn[0] + finalStrength[0];
TextureCoords[1] = UVVectorIn[1] + finalStrength[1];
TextureCoords[2] = UVVectorIn[2];


}