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

Raytracing shader pass: Material properties?

Discussion in 'Shaders' started by AlanRStagner, Dec 14, 2019.

  1. AlanRStagner

    AlanRStagner

    Joined:
    Jan 9, 2018
    Posts:
    11
    So I've been messing around with Unity's new DXR support in 2019.3 as a bit of a learning experiment. I see that I can give object shaders a custom named raytracing-specific pass that I can use in the dispatch call for the raytracing shader using SetShaderPass, which looks something like

    Code (CSharp):
    1. Shader "Unlit/TestDummyShader"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Texture", 2D) = "white" {}
    6.     }
    7.    
    8.     // regular vertex/fragment shader passes here
    9.     SubShader
    10.     {
    11.         Tags { "RenderType"="Opaque" }
    12.         LOD 100
    13.  
    14.         Pass
    15.         {
    16.             CGPROGRAM
    17.             #pragma vertex vert
    18.             #pragma fragment frag
    19.             // make fog work
    20.             #pragma multi_compile_fog
    21.  
    22.             #include "UnityCG.cginc"
    23.  
    24.             struct appdata
    25.             {
    26.                 float4 vertex : POSITION;
    27.                 float2 uv : TEXCOORD0;
    28.             };
    29.  
    30.             struct v2f
    31.             {
    32.                 float2 uv : TEXCOORD0;
    33.                 UNITY_FOG_COORDS(1)
    34.                 float4 vertex : SV_POSITION;
    35.             };
    36.  
    37.             sampler2D _MainTex;
    38.             float4 _MainTex_ST;
    39.  
    40.             v2f vert (appdata v)
    41.             {
    42.                 v2f o;
    43.                 o.vertex = UnityObjectToClipPos(v.vertex);
    44.                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    45.                 UNITY_TRANSFER_FOG(o,o.vertex);
    46.                 return o;
    47.             }
    48.  
    49.             fixed4 frag (v2f i) : SV_Target
    50.             {
    51.                 // sample the texture
    52.                 fixed4 col = tex2D(_MainTex, i.uv);
    53.                 // apply fog
    54.                 UNITY_APPLY_FOG(i.fogCoord, col);
    55.                 return col;
    56.             }
    57.             ENDCG
    58.         }
    59.     }
    60.  
    61.     // raytracing passes I can use from a raytracing shader dispatch via RaytracingShader.SetShaderPass
    62.     SubShader
    63.     {
    64.         Pass {
    65.             Name "RTPass"
    66.  
    67.             HLSLPROGRAM
    68.             #pragma raytracing HitShader
    69.            
    70.             [shader("closesthit")]
    71.             void HitShader(inout RayPayload rayPayload : SV_RayPayload, BuiltInTriangleIntersectionAttributes hitInfo : SV_IntersectionAttributes) {
    72.                 // ray hit stuff here
    73.             }
    74.             ENDHLSL
    75.         }
    76.     }
    77. }
    However, there's one thing I'm missing, and that's how to handle material properties from such a raytracing pass. For example, how do I sample from _MainTex in that pass? (I already know how to use the intersection attributes to interpolate vertex data so I can get at the UVs mind you, figured that out by crawling the HDRP source code).

    The regular old
    sampler2D _MainTex;
    declaration doesn't seem to work in that HLSL block so I'm not sure what I should be using instead.

    Code (CSharp):
    1.  
    2. SubShader
    3. {
    4.    Pass {
    5.        Name "RTPass"
    6.  
    7.        HLSLPROGRAM
    8.        #pragma raytracing HitShader
    9.        
    10.        // ==== what goes here to reference _MainTex / _MainTex_ST, along with other parameters ?? ====
    11.        
    12.        [shader("closesthit")]
    13.        void HitShader(inout RayPayload rayPayload : SV_RayPayload, BuiltInTriangleIntersectionAttributes hitInfo : SV_IntersectionAttributes) {
    14.            // how to sample from _MainTex here, given coordinates?
    15.        }
    16.        ENDHLSL
    17.    }
    18. }
    19.  
     
  2. AlanRStagner

    AlanRStagner

    Joined:
    Jan 9, 2018
    Posts:
    11
    OK so I managed to finally crawl enough of the HDRP source to figure out how this is supposed to work. Looks like I can include the Common.hlsl file from the Core RP library and then just do this:

    Code (csharp):
    1.  
    2. TEXTURE2D(_MainTex);
    3. SAMPLER(sampler_MainTex);
    4.  
    5. // ...
    6.  
    7. float4 col = _MainTex.SampleLevel( sampler_MainTex, texCoord, 0 );
    8.