Search Unity

How do i implement decals into a shader in hlsl

Discussion in 'Universal Render Pipeline' started by benritchie, May 17, 2022.

  1. benritchie

    benritchie

    Joined:
    Feb 5, 2021
    Posts:
    8
    I have asked this question before but i wrote it in CGPROGRAM and was informed that i should use hlsl or shader Graph. I re-wrote it in HLSL and tried to use a suggested function (from "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl") but was unable to get it to work.

    in the code i tried temporarily only returning the colour from the decal but im not sure if ive done it right.

    Code (CSharp):
    1. Shader "Custom/Affine Lit hlsl"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Texture", 2D) = "white" {}
    6.         _Albeado("Albeado", color) = (1,1,1,1)
    7.         _Accuracy("Vertex Accuracy",Range(0,1000)) = 100
    8.         _AmbientColour("Ambient colour", color) = (0,0,0,0)
    9.         [MaterialToggle]_GlossUse("Use Gloss", Float) = 1
    10.         _Gloss("Gloss", Float) = 1
    11.     }
    12.     SubShader
    13.     {
    14.         Tags { "RenderType" = "Opaque" }
    15.  
    16.         HLSLINCLUDE
    17.         #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    18.  
    19.         CBUFFER_START(UnityPerMaterial)
    20.             float4 _Albeado;
    21.             float _Accuracy;
    22.             float4 _AmbientColour;
    23.             float _LightColourUse;
    24.             float _Gloss;
    25.             float _GlossUse;
    26.         CBUFFER_END
    27.  
    28.         TEXTURE2D(_MainTex);
    29.         SAMPLER(sampler_MainTex);
    30.  
    31.         float Posterize(float steps, float value)
    32.         {
    33.             value = floor(value * steps) / steps;
    34.             return value;
    35.         }
    36.  
    37.         float4 VertexSnap(float4 position)
    38.         {
    39.             float4 vertexPos = position;
    40.             vertexPos.xyz = position.xyz / position.w;
    41.             vertexPos.x = Posterize(_Accuracy, vertexPos.x);
    42.             vertexPos.y = Posterize(_Accuracy, vertexPos.y);
    43.             vertexPos.xyz *= position.w;
    44.             return vertexPos;
    45.         }
    46.  
    47.         ENDHLSL
    48.  
    49.         Pass
    50.         {
    51.             Name "MainPass"
    52.             Tags {"LightMode" = "UniversalForward" "Queue" = "Geometry"}
    53.  
    54.             Zwrite On
    55.             Cull Back
    56.  
    57.             HLSLPROGRAM
    58.             #pragma vertex vert
    59.             #pragma fragment frag
    60.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
    61.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl"
    62.  
    63.             struct VertexIn
    64.             {
    65.                 float4 position : POSITION;
    66.                 float2 uv : TEXCOORD0;
    67.                 float3 normal : NORMAL;
    68.                 float4 Vcolour : COLOR0;
    69.             };
    70.  
    71.             struct VertexOut
    72.             {
    73.                 float4 position : SV_POSITION;
    74.                 noperspective float2 uv : TEXCOORD0;
    75.                 float3 normal : TEXCOORD1;
    76.                 float4 vertColour : COLOR0;
    77.                 float3 worldPosition : TEXCOORD2;
    78.             };
    79.  
    80.             VertexOut vert(VertexIn i)
    81.             {
    82.                 VertexOut o;
    83.                 o.position = TransformObjectToHClip(i.position.xyz);
    84.                 o.position = VertexSnap(o.position);
    85.                 o.worldPosition = TransformObjectToWorld(i.position.xyz);
    86.  
    87.                 o.normal = i.normal;
    88.                 o.uv = i.uv;
    89.                 o.vertColour = i.Vcolour;
    90.                 return o;
    91.             }
    92.            
    93.             float4 frag(VertexOut i) : SV_Target
    94.             {
    95.                 //in frag decleration of variables and normal to world-space normal
    96.                 float3 worldPos = i.worldPosition.xyz;
    97.                 float2 uv = i.uv;
    98.                 float3 worldSpaceNormal = TransformObjectToWorldNormal(i.normal.xyz);
    99.                 worldSpaceNormal = normalize(worldSpaceNormal);
    100.  
    101.                 //LightLevel
    102.                 float3 lightDir = normalize(GetMainLight().direction);
    103.                 float lightFalloff = max(0, dot(lightDir, worldSpaceNormal));
    104.  
    105.                 //Light Colour
    106.                 float3 lightColour = lerp(float3(1, 1, 1), GetMainLight().color, _LightColourUse);
    107.                 float3 directDiffuse = lightFalloff * lightColour;
    108.                 float3 diffuse = _AmbientColour.rgb + directDiffuse;
    109.  
    110.                 //Specular
    111.                 float3 fragToCam = _WorldSpaceCameraPos - worldPos;
    112.                 float3 viewDir = normalize(fragToCam);
    113.                 float3 reflectNormal = reflect(-viewDir, worldSpaceNormal);
    114.                 float specularFalloff = max(0, dot(lightDir, reflectNormal));
    115.                 specularFalloff = pow(specularFalloff, _Gloss);
    116.                 float3 specular = specularFalloff * lightColour;
    117.                 specular = specular * _GlossUse;
    118.  
    119.                 //finalise and output
    120.                 float3 UnderColour = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv).rgb * _Albeado.rgb * i.vertColour.rgb;
    121.                 float3 FinalColour = diffuse * UnderColour + specular;
    122.  
    123.                 half3 colDec = (0.5, 0.5, 0.5);
    124.                 half3 norDec = normalize(float3(1, 1, 1));
    125.  
    126.                 //return float4(FinalColour, 0);
    127.  
    128.  
    129.                 ApplyDecalToBaseColor(i.position, colDec);
    130.                 return float4(colDec, 0);
    131.             }
    132.             ENDHLSL
    133.         }
    134.     }
    135. }
    136.  
     
  2. DevDunk

    DevDunk

    Joined:
    Feb 13, 2020
    Posts:
    5,063
    Sadly the only way I currently can get a decal shader to work is to make a decal shader graph (and if you want you can use the generated shaderlab code in a text editor).
    Or since the shader is not that long you can just make the shader in shader graph
     
  3. benritchie

    benritchie

    Joined:
    Feb 5, 2021
    Posts:
    8
    Thats a shame.:(
     
  4. kripto289

    kripto289

    Joined:
    Feb 21, 2013
    Posts:
    505
    I wrote simple URP decal shader, it must work everywhere (and in VR too)

    Code (CSharp):
    1.  
    2. Shader "Unlit/SimpleDecalURP"
    3. {
    4.     Properties
    5.     {
    6.         _MainTex ("Texture", 2D) = "white" {}
    7.     }
    8.     SubShader
    9.     {
    10.         Tags { "RenderType"="Transparent" "Queue"="Transparent"}
    11.         Blend SrcAlpha OneMinusSrcAlpha
    12.         Pass
    13.         {
    14.             HLSLPROGRAM
    15.             #pragma vertex vert
    16.             #pragma fragment frag
    17.          
    18.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    19.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
    20.             struct v2f
    21.             {
    22.                 float4 vertex : SV_POSITION;
    23.             };
    24.             sampler2D _MainTex;
    25.             float4 _MainTex_ST;
    26.             v2f vert (float4 vertex : POSITION)
    27.             {
    28.                 v2f o;
    29.                 o.vertex = TransformObjectToHClip(vertex.xyz);
    30.              
    31.                 return o;
    32.             }
    33.             float4 frag (v2f i) : SV_Target
    34.             {
    35.                 float2 UV = i.vertex.xy / _ScaledScreenParams.xy;
    36. #if UNITY_REVERSED_Z
    37.                 float depth = SampleSceneDepth(UV);
    38. #else
    39.                 // Adjust Z to match NDC for OpenGL ([-1, 1])
    40.                 float depth = lerp(UNITY_NEAR_CLIP_VALUE, 1, SampleSceneDepth(UV));
    41. #endif
    42.                 float3 worldPos = ComputeWorldSpacePosition(UV, depth, UNITY_MATRIX_I_VP);
    43.                 float3 localPos = mul(unity_WorldToObject, float4(worldPos, 1));
    44.                 const float3 fade = float3(10, 3, 10);
    45.                 float3 decalClipFade = saturate((0.5 - abs(localPos.xyz)) * fade);
    46.                 float clipFade = decalClipFade.x * decalClipFade.y * decalClipFade.z;
    47.                 float2 textureUV = (localPos.xz + 0.5) * _MainTex_ST.xy + _MainTex_ST.zw;
    48.                 float4 mainColor = tex2D(_MainTex, textureUV);
    49.                 mainColor.a *= clipFade;
    50.                 return  mainColor;
    51.             }
    52.             ENDHLSL
    53.         }
    54.     }
    55. }
    56.  
    57.  
     
    Beauque likes this.
  5. DevDunk

    DevDunk

    Joined:
    Feb 13, 2020
    Posts:
    5,063
    That's great!
    Do you have any idea on how to implement a shader that just turns zwrite off in the pass and that's it? (I use that to make portals in my game and would love to use decals)