For those that don’t know, here’s what a World Normal is:
And here’s how you retrieve it:
float3 worldN = WorldNormalVector(IN, o.Normal);
(can be useful for all sorts of things)
What I would really like to do is have the ability to rotate it. Any Suggestions?
I’m unfamiliar with that WorldNormalVector function, but the world normal can be constructed by multiplying the InverseViewMatrix with the tangent normal values.
It’s simple to add a second camera into the scene, by which you want your world normals to be “rotated” by and get the InverseViewMatrix from that camera and parse it to the shader.
Thou honestly… I have no idea what any of this can be useful for. Lighting will not match up with the shadows as a major concern (deferred, non baked lighting).
The world normal is useful for manipulating the shader relative to the world. As a simple example, the following code will add blue emission from left of x, no matter the model’s rotation:
o.Emission = WorldNormalVector(IN, o.Normal).x *float3 (0,0,1);
Anyways I think I have a solution. I’ll post the process when I’m done. Of course by all means if someone has an easy solution feel free to share.
Yes… But your original question made it sound like you are adjusting the output normals, not using it for coloring…
Also an alternative, and more frequently used method for that Emission code is with a dot product with worldnormals and a direction vector . That way you can have any direction you want…
As example: emission = dot(WorldNormal, float3(1,0,0)) * Color; //Will have a “light” coming from X+
note that this direction vector needs to be normalized for accurate results. Otherwise you’ll get over brightening.
Actually I am indeed looking to rotating the World Normal. I have a custom spherical harmonics ambient term that is driven by the world normal. Want to rotate those results. Sorry for the confusion.
Thanks leocov at polycount. For some reason I wasn’t able to declare a float3x3, so I wrote out the Matrix multiplication by hand:
// World Normal
float3 worldN = WorldNormalVector(IN, o.Normal);
// Matrix Adjustment
float Xangle = _RotateX;
float Yangle = _RotateY;
float Zangle = _RotateZ;
float3 MatrixMultX = (0,0,0);
MatrixMultX.x = (worldN.x);
MatrixMultX.y = (worldN.y*cos(Xangle)+worldN.y*-sin(Xangle));
MatrixMultX.z = (+worldN.z*sin(Xangle)+worldN.z*cos(Xangle));
worldN = MatrixMultX;
float3 MatrixMultY = (0,0,0);
MatrixMultY.x = (worldN.x*cos(Yangle)+worldN.x*sin(Yangle));
MatrixMultY.y = (worldN.y);
MatrixMultY.z = (worldN.z*-sin(Yangle)+worldN.z*cos(Yangle));
worldN = MatrixMultY;
float3 MatrixMultZ = (0,0,0);
MatrixMultZ.x = (worldN.x*cos(Zangle)+worldN.x*-sin(Zangle));
MatrixMultZ.y = (worldN.y*sin(Zangle)+worldN.y*cos(Zangle));
MatrixMultZ.z = (worldN.z);
worldN = MatrixMultZ;
3 Likes