- Home /
Shader: actual view direction/normal?
Hiho.
I only have basic knowledge about shaders, ShaderLab, and CG, and I didn't find my answer in any docs, examples, or by trial&error, so my hope is one of you could help me out.
I am looking for the actual view direction, i.e. the vector from the camera position through the currently rendered pixel, as I am trying to find the angle between that and the normal of the object at that point/along that ray. Or to put it differently, I am looking for the actual orientation of an object/vertex/pixel with respect to an arbitrary screen location, not with respect to the camera plane (see the following example).
I can use this which gives me some view-dependent object space(?) normal:
float3 viewN = mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal);
but this vector remains constant, no matter where on the screen the object is (i.e., it uses the constant normal of the camera plane (=the equivalent of transform.forward) for all pixels). And there is something called "viewDir" in surface shaders, if I understand it correctly, but I am not sure what it does precisely.
I don't care if I need to use a fragment shader or a surface shader for that, I am happy with any solution that works.
Thanks! Wolfram
Did you ever solve this? I am also looking to for the view direction for use in a v2f program
Answer by equalsequals · Jan 31, 2012 at 07:28 PM
I was able to figure it out here:
struct v2f {
float4 pos : SV_POSITION;
float3 normal : TEXCOORD0; //you don't need these semantics except for XBox360
float3 viewT : TEXCOORD1; //you don't need these semantics except for XBox360
};
v2f vert (appdata_base v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.normal = normalize(v.normal);
o.viewT = normalize(WorldSpaceViewDir(v.vertex));//ObjSpaceViewDir is similar, but localspace.
return o;
}
Just make sure you have #include "UnityCG.cginc"
in there as well.
Cheers
==
Answer by Julien-Lynge · Jan 31, 2012 at 05:22 PM
I believe that you can get the view direction vector within the surface shader function like so:
struct Input { float3 viewDir; //whatever else you need to define for Input }
void surf (Input IN, inout EditorSurfaceOutput o) { float3 temp = IN.viewDir; //gives the view direction as a float3, so you can access e.g. IN.viewDir.x }
Note that you may have to use a lighting model that takes into account view direction - that's beyond my expertise.
half4 LightingName (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten);
getting the view direction in a surface shader is straight-forward like that, yes. But we, or at least I am talking about vertex-to-fragment programs and NOT surface shaders. Surface Shaders do unnecessary calculations for a lot of effects and is often more effective and more economical to write the v2f functions yourself ins$$anonymous$$d of letting the surface shader generate it for you.
I certainly understand that you don't want a surface shader, but that's what the initial question asked for, so that's what I gave. I don't appreciate you giving me -1 karma for answering the question as asked - you may want to start your own post if your question is markedly different.