Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

How to get worldPos in fragment shader

Discussion in 'Shaders' started by ivkoni, Mar 14, 2011.

  1. ivkoni

    ivkoni

    Joined:
    Jan 26, 2009
    Posts:
    978
    How can we get worldPos in a fragment shader?
    I know that it is available in surface shaders, but I need it in a fragment shader.

    thanks
     
  2. ivkoni

    ivkoni

    Joined:
    Jan 26, 2009
    Posts:
    978
    This looks correct. Copy-paste from the Internal-PrePassLighting Shader.
    Code (csharp):
    1.  
    2. Shader "WorldPos" {
    3. Properties {
    4.     _MainTex ("Base (RGB)", 2D) = "white" {}
    5. }
    6.  
    7. SubShader {
    8.     Pass {
    9.  
    10.    
    11. CGPROGRAM
    12. #pragma vertex vert
    13. #pragma fragment frag
    14. #include "UnityCG.cginc"
    15.  
    16. uniform sampler2D _MainTex;
    17.  
    18. struct appdata {
    19.     float4 vertex : POSITION;
    20.     float3 texcoord : TEXCOORD0;
    21. };
    22.  
    23. struct v2f {
    24.     float4 pos : SV_POSITION;
    25.     float4 uv : TEXCOORD0;
    26.     float3 ray : TEXCOORD1;
    27. };
    28.  
    29.  
    30.  
    31. v2f vert (appdata v)
    32. {
    33.     v2f o;
    34.     o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    35.     o.uv = ComputeScreenPos (o.pos);
    36.     o.ray = mul (UNITY_MATRIX_MV, v.vertex).xyz * float3(-1,-1,1);
    37.    
    38.     // v.texcoord is equal to 0 when we are drawing 3D light shapes and
    39.     // contains a ray pointing from the camera to one of near plane's
    40.     // corners in camera space when we are drawing a full screen quad.
    41.     o.ray = lerp(o.ray, v.texcoord, v.texcoord.z != 0);
    42.    
    43.     return o;
    44. }
    45.  
    46. sampler2D _CameraDepthTexture;
    47. float4x4 _CameraToWorld;
    48. float3 _clipPoint;
    49. float3 _clipNormal;
    50.  
    51. half4 frag (v2f i) : COLOR
    52. {
    53.     i.ray = i.ray * (_ProjectionParams.z / i.ray.z);
    54.     float2 uv = i.uv.xy / i.uv.w;
    55.    
    56.     float depth = UNITY_SAMPLE_DEPTH(tex2D (_CameraDepthTexture, uv));
    57.     depth = Linear01Depth (depth);
    58.     float4 vpos = float4(i.ray * depth,1);
    59.     float3 wpos = mul (_CameraToWorld, vpos).xyz;
    60.    
    61.     return half4(wpos,1.0f);
    62.    
    63. }
    64.  
    65. ENDCG
    66. }
    67.  
    68. }
    69. Fallback Off
    70. }
    71.  
    don't forget to set your camera to render the depth texture

    Code (csharp):
    1.  
    2. camera.depthTextureMode = DepthTextureMode.Depth;
    3.  
    I still want to know if there are other ways to do it. How is worldPos calculated in surface shaders.
     
  3. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,865
    worldpos = mul(_ObjectToWorld, vertex)
     
    forestrf likes this.
  4. ivkoni

    ivkoni

    Joined:
    Jan 26, 2009
    Posts:
    978
    :)
    I want the world position associated with the fragment.

    I still want to know if there are other ways to do it. How is worldPos calculated in surface shaders?
     
  5. ivkoni

    ivkoni

    Joined:
    Jan 26, 2009
    Posts:
    978
    Aubergine, would you know how to pass the
    Code (csharp):
    1.  
    2. worldpos = mul(_ObjectToWorld, vertex);
    3.  
    to the fragment shader?
    I understand that this is the vertex position in world space, however I really don't know how shaders actually work.
    If I pass somehow (TEXCOORD?) the vertices world positions, would the fragments world positions be automatically computed for me?
    Looks like it should: The easiest way is to pass the world-position down from the vertex shader via a varying variable
    But how exactly would I do this?
     
  6. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,865
    You just pass it through the input structure, but the above "worldpos" can not compute anything automatically for you. Its up to you to use it however you want. Unless you bind it to POSITION or somethin.
     
  7. ivkoni

    ivkoni

    Joined:
    Jan 26, 2009
    Posts:
    978
    Thank you sir. I believe I got it. I will bind it to something like COLOR or TEXCOORD, and then it would be linearly interpolated for me by the rasterizer. I will try this when I get a chance.
     
  8. ivkoni

    ivkoni

    Joined:
    Jan 26, 2009
    Posts:
    978
    It does work. But more importantly, the process through which fragments are computed is not a black box any more. Just a gray box. Dark gray box.

    thanks again Aubergine
     
  9. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,865
    Welcome to my grey box :p
     
  10. MHDante

    MHDante

    Joined:
    Aug 20, 2013
    Posts:
    10
    To anyone stumbling onto this old post: Ivkoni above posted the following line:
    Code (CSharp):
    1. worldpos = mul(_ObjectToWorld, vertex);
    This contains an error, it should be written as:
    Code (CSharp):
    1. worldpos = mul(_Object2World, vertex);
    Thanks for helping me out.

     
  11. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,878
    ...and since then Unity has changed it again (saw this page from google hits trying to check something else, it's a top hit, so worth necroing). 2019 version is:

    mul( unity_ObjectToWorld, vertex ) // see Unity docs top of this page for latest: https://docs.unity3d.com/Manual/SL-UnityShaderVariables.html

    (where "vertex" is usually in.vertex / IN.vertex etc, whatever you named your appdata_full parameter to your vertex-shader method).

    PS: I prefer the new name. It's clear (it tells you it's data supplied specifically by Unity), and it gets rid of the ugly, incorrect, use of "2" (digits in GL/HLSL/GLSL functions and vars have specific meaning, it's a bad idea to use them to mean something else too).
     
    Kaldrin and sarahnorthway like this.
  12. Kaldrin

    Kaldrin

    Joined:
    Jul 10, 2018
    Posts:
    42
    Thank you!