- Home /
Camera forward vector in shader
Is there an easy way to get the camera's forward vector in a surface shader (the near clip plane's normal)? Perhaps a built-in shader constant or input struct variable? I want something like the "viewDir" variable from here, but just the forward vector, not a ray per-pixel.
I'm trying to do some calculations off pixel distances projected onto the near clipping plane's normal instead of the distance from the camera position.
The near clip plane doesn't have a single normal in world space unless you're using an orthographic projection. You're dealing with a frustum, and not necessarily even an isosceles one.
Hmm, well then forget that near clipping plane's normal stuff. I would still like the camera's forward vector in the surface shader though - if it's possible to do it without sending it as a uniform.
Unity provides the matrix that transforms from view to object space, so you can get the vector you want, without calculations (you'll need to rotate again if you need it in world space). I don't know surface shaders, so can't tell you what the uniform is called, in them, or if you can just grab the [2].xyz of it, though I suspect so. In GLSL, it's called gl_$$anonymous$$odelView$$anonymous$$atrixInverseTranspose, and it may be UNITY_$$anonymous$$ATRIX_IT_$$anonymous$$V in a surface shader.
UNITY_$$anonymous$$ATRIX_IT_$$anonymous$$V[2].xyz works great, thx.
Answer by moosefetcher · Sep 22, 2016 at 10:07 AM
I know it's 5 years later on from the original question, but the solution mentioned in the comments above worked for me too. I put this in my frag function and it works perfectly:
float3 viewDir = UNITY_MATRIX_IT_MV[2].xyz;
Answer by rcabot · May 18, 2018 at 02:21 PM
For those of you still attempting to use moosefetcher's answer, I tried this in my vertex shader and it messed with my lighting for some reason.
In the end I used float3 forward = mul((float3x3)unity_CameraToWorld, float3(0,0,1));
which worked fine.
Same here, or equivalently: float3 viewForward = unity_CameraToWorld._m02_m12_m22;
Note: In a vertex shader, using VR and Single Pass Instanced, using unity_CameraToWorld seem to fail on Unity 2021.3.0f1.
unity_StereoCameraToWorld[1] (right eye matrix) dont seem to be set up correctly (rotation matrix values are all zero?)
Your answer
Follow this Question
Related Questions
Adding Spheremap reflection and Gloss/Shininess controls to a Sruface Shader 0 Answers
Get local position in surface shader 2 Answers
Splat Map shader no longer working in Unity 5 1 Answer
Vertex Offset not written to depth buffer in Surface Shader 0 Answers
How to add Bump/Normal Map to surface shader? (CG) 0 Answers