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
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

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:
    4,455
    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:
    466
    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:
    4,455
    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)