I have troubles understanding how unity’s screen space coordinates work.
Let me illustrate my confusion. I have created basic scene with one cube and Unlit shader attached to it, which I modified to return the result of o.vertex = mul(UNITY_MATRIX_MVP, float4(v.vertex));
And this is the result I get:
Why UNITY_MATRIX_MVP returns coordinates in screen pixel space? These are not homogeneous coordinates that I would expect from the same operation in OpenGL or Direct3D.
The SV_POSITION semantic isn’t something you would normally access in the fragment shader directly. In DX9 (and OpenGL) this will result in a shader error. However in DX11 the SV_POSITION semantic when accessed in the fragment shader is the clip position post transformation by rastorization, which is equivalent to VPOS, which is the pixel position.
If you pass the clip space position via an additional semantic, like TEXCOORD#, it’ll be as @jvo3dc described.
I have tried fixed4 col = fixed4(i.vertex.xy / i.vertex.w, 0.0, 1.0) ;
However, it results in the same yellow box as in the first image.
@bgolus I am sorry I may not understand your reply. What is special about SV_POSITION? I thought it is similar to gl_FragCoord in OpenGL which gives you the current shader coordinate on the screen. Could you please help me clarify this confusion ?
UPDATE:
I have tried passing another variable of type TEXCOORD1. Now everything works as expected! Thank you! (see the shader below).
Is there any good resource to figure out how Unity Semantics work?
SV_POSITION is the DX11 equivalent to GLSL’s gl_Position, and in most shader languages can only be accessed in the vertex shader, hence why it’ll give you an error if you try to access it in the fragment shader when using DX9 or OpenGL. However a quirk of DX11 is SV_POSITION is also accessible in the pixel (aka fragment) shader, at which point it is the equivalent of GLSL’s gl_FragCoord.
If you really do want gl_FragCood, and want it to work across multiple platforms, you have to output the vertex position as a separate variable from the v2f struct, and then add UNITY_VPOS_TYPE vpos : VPOS to your fragment shader function definition, as VPOS is the equivalent to gl_FragCoord and which Unity will properly translate for all platforms.
Btw, Unity semantics aren’t really Unity specific, they should be equivalent to DX11’s semantics. Unity will then translate them to the semantics needed by each platform. If you’re familiar with OpenGL then looking at Unity’s HLSL2GLSL might be of use to you: https://github.com/aras-p/hlsl2glslfork