Camera forward vector in shader
Asked Answered
A

3

0

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.

Abrasion answered 9/8, 2023 at 17:1 Comment(5)

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.

Wilfredwilfreda

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.

Abrasion

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_ModelViewMatrixInverseTranspose, and it may be UNITY_MATRIX_IT_MV in a surface shader.

Wilfredwilfreda

UNITY_MATRIX_IT_MV[2].xyz works great, thx.

Abrasion

@Abrasion @Wilfredwilfreda Thanks guys, UNITY_MATRIX_IT_MV[2].xyz worked for me too. Maybe turn it into an answer for other users?

Historicism
O
0

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;
Objectify answered 9/8, 2023 at 2:33 Comment(0)
P
0

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.

Pesky answered 6/6, 2023 at 2:35 Comment(3)

Same here, or equivalently: float3 viewForward = unity_CameraToWorld._m02_m12_m22;

Languishing

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?)

Perception

Is it the same as unity_CameraWorldClipPlanes[5].xyz? or - unity_CameraWorldClipPlanes[4].xyz?

Flammable
B
0

If you want to get an analogue of IsFacing in the vertex shader use:

half3 normal    = UnityObjectToWorldNormal(v.normal);
half3 worldVert = mul(unity_ObjectToWorld, v.vertex);
half3 viewDir   = _WorldSpaceCameraPos - worldVert;
normal *= lerp(-1, 1, dot(normal, viewDir) > 0);
Betimes answered 9/8, 2023 at 16:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.