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];
}