Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Can anyone give me a quick rundown of the basics of a handwritten URP shader vs In-built?

Discussion in 'Shaders' started by MadeFromPolygons, Oct 9, 2019.

  1. MadeFromPolygons

    MadeFromPolygons

    Joined:
    Oct 5, 2013
    Posts:
    3,967
    Hi guys I am trying to learn how to write shaders by hand for URP but lack of documentation and varying info all over the place is confusing me.

    As an exercise to learn this I am trying to convert this shader from minionsart:

    Code (CSharp):
    1. Shader "Unlit/SimpleWater"
    2. {
    3.     Properties
    4.     {
    5.         _Tint("Tint", Color) = (1, 1, 1, .5)
    6.         _MainTex ("Main Texture", 2D) = "white" {}
    7.         _NoiseTex("Extra Wave Noise", 2D) = "white" {}
    8.         _Speed("Wave Speed", Range(0,1)) = 0.5
    9.         _Amount("Wave Amount", Range(0,1)) = 0.5
    10.         _Height("Wave Height", Range(0,1)) = 0.5
    11.         _Foam("Foamline Thickness", Range(0,3)) = 0.5
    12.      
    13.     }
    14.     SubShader
    15.     {
    16.         Tags { "RenderType"="Opaque"  "Queue" = "Transparent" }
    17.         LOD 100
    18.         Blend SrcAlpha OneMinusSrcAlpha
    19.         Pass
    20.         {
    21.             CGPROGRAM
    22.             #pragma vertex vert
    23.             #pragma fragment frag
    24.             // make fog work
    25.             #pragma multi_compile_fog
    26.          
    27.             #include "UnityCG.cginc"
    28.             struct appdata
    29.             {
    30.                 float4 vertex : POSITION;
    31.                 float2 uv : TEXCOORD0;
    32.             };
    33.             struct v2f
    34.             {
    35.                 float2 uv : TEXCOORD0;
    36.                 UNITY_FOG_COORDS(1)
    37.                 float4 vertex : SV_POSITION;
    38.                 float4 scrPos : TEXCOORD1;//
    39.             };
    40.             float4 _Tint;
    41.             uniform sampler2D _CameraDepthTexture; //Depth Texture
    42.             sampler2D _MainTex, _NoiseTex;//
    43.             float4 _MainTex_ST;
    44.             float _Speed, _Amount, _Height, _Foam;//
    45.          
    46.             v2f vert (appdata v)
    47.             {
    48.                 v2f o;
    49.                 float4 tex = tex2Dlod(_NoiseTex, float4(v.uv.xy, 0, 0));//extra noise tex
    50.                 v.vertex.y += sin(_Time.z * _Speed + (v.vertex.x * v.vertex.z * _Amount * tex)) * _Height;//movement
    51.                 o.vertex = UnityObjectToClipPos(v.vertex);
    52.                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    53.                 o.scrPos = ComputeScreenPos(o.vertex); // grab position on screen
    54.                 UNITY_TRANSFER_FOG(o,o.vertex);
    55.              
    56.                 return o;
    57.             }
    58.          
    59.             fixed4 frag (v2f i) : SV_Target
    60.             {
    61.                 // sample the texture
    62.          
    63.                 half4 col = tex2D(_MainTex, i.uv) * _Tint;// texture times tint;
    64.                 half depth = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.scrPos))); // depth
    65.                 half4 foamLine =1 - saturate(_Foam * (depth - i.scrPos.w));// foam line by comparing depth and screenposition
    66.                 col += foamLine * _Tint; // add the foam line and tint to the texture
    67.                 return col ;
    68.             }
    69.             ENDCG
    70.         }
    71.     }
    72. }
    However I am struggling to find decent info on what is required to get this to work for URP. In another thread here someone explained how I can get an alternative to SAMPLE_DEPTH_TEXTURE_PROJ and UNITY_PROJ_COORD

    But right now I am having trouble working out what includes, pragma etc statements I need, where in general everything is located (as in which hlsl files contain the useful stuff) as well as how to set up the appdata and v2f structs properly as none of that compiles.

    Right now I am trial and erroring it so if anyone has any bits of knowledge I would appreciate it and I am certain this will also be useful to other users too!

    TLDR

    Whats the minimum I need to get this working (or at very least compiling) with URP?

    What parts of this cannot be converted at all, and what alternatives do I have other than ripping those bits out (I am sure the fog bits wont work for example)?

    I am happy to work some stuff out on my own, but I definately need to be pointed in the right direction as all the varying info flying around has me super confused

    Thanks for any help you can provide!
     
    Last edited: Oct 9, 2019
    olli_vrcoaster likes this.
  2. Namey5

    Namey5

    Joined:
    Jul 5, 2013
    Posts:
    188
    Unfortunately, its not exactly trivial to upgrade shaders to the new pipelines. Not only is a different shading language used, but most of the common macros and functions that were previously commonplace in shaders no longer exist. Thankfully, your shader doesn't interact with lighting - so we don't actually need to change much;

    Code (CSharp):
    1. Shader "Unlit/SimpleWater"
    2. {
    3.     Properties
    4.     {
    5.         _Tint("Tint", Color) = (1, 1, 1, .5)
    6.         _MainTex ("Main Texture", 2D) = "white" {}
    7.         _NoiseTex("Extra Wave Noise", 2D) = "white" {}
    8.         _Speed("Wave Speed", Range(0,1)) = 0.5
    9.         _Amount("Wave Amount", Range(0,1)) = 0.5
    10.         _Height("Wave Height", Range(0,1)) = 0.5
    11.         _Foam("Foamline Thickness", Range(0,3)) = 0.5
    12.        
    13.     }
    14.     SubShader
    15.     {
    16.         Tags { "RenderType"="Opaque"  "Queue" = "Transparent" }
    17.         LOD 100
    18.         Blend SrcAlpha OneMinusSrcAlpha
    19.         Pass
    20.         {
    21.             Name "Unlit"
    22.  
    23.             HLSLPROGRAM
    24.             #pragma vertex vert
    25.             #pragma fragment frag
    26.             // make fog work
    27.             #pragma multi_compile_fog
    28.            
    29.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    30.  
    31.             struct appdata
    32.             {
    33.                 float4 vertex : POSITION;
    34.                 float2 uv : TEXCOORD0;
    35.             };
    36.             struct v2f
    37.             {
    38.                 float4 vertex : SV_POSITION;
    39.                 float2 uv : TEXCOORD0;
    40.                 float fogCoords : TEXCOORD1;
    41.                 float4 scrPos : TEXCOORD2;//
    42.             };
    43.  
    44.             float4 _Tint;
    45.             Texture2D _CameraDepthTexture; SamplerState sampler_CameraDepthTexture; //Depth Texture
    46.             Texture2D _MainTex, _NoiseTex; SamplerState sampler_MainTex;//
    47.             float4 _MainTex_ST;
    48.             float _Speed, _Amount, _Height, _Foam;//
    49.            
    50.             //This is a replacement for the old 'UnityObjectToClipPos()'
    51.             float4 ObjectToClipPos (float3 pos)
    52.             {
    53.                 return mul (UNITY_MATRIX_VP, mul (UNITY_MATRIX_M, float4 (pos,1)));
    54.             }
    55.  
    56.             v2f vert (appdata v)
    57.             {
    58.                 v2f o;
    59.                 float4 tex = _NoiseTex.SampleLevel (sampler_MainTex, v.uv.xy, 0);//extra noise tex
    60.                 v.vertex.y += sin (_Time.z * _Speed + (v.vertex.x * v.vertex.z * _Amount * tex)) * _Height;//movement
    61.  
    62.                 VertexPositionInputs vertInputs = GetVertexPositionInputs (v.vertex.xyz);    //This function calculates all the relative spaces of the objects vertices
    63.                 o.vertex = vertInputs.positionCS;
    64.                 //o.vertex = ObjectToClipPos (v.vertex);
    65.                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    66.                 o.scrPos = vertInputs.positionNDC; // grab position on screen
    67.                 o.fogCoords = ComputeFogFactor (o.vertex.z);
    68.                
    69.                 return o;
    70.             }
    71.            
    72.             fixed4 frag (v2f i) : SV_Target
    73.             {
    74.                 // sample the texture
    75.            
    76.                 half4 col = _MainTex.Sample (sampler_MainTex, i.uv) * _Tint;// texture times tint;
    77.                 half depth = LinearEyeDepth (_CameraDepthTexture.Sample (sampler_CameraDepthTexture, i.scrPos.xy / i.scrPos.w).r); // depth
    78.                 half4 foamLine = 1 - saturate (_Foam * (depth - i.scrPos.w));// foam line by comparing depth and screenposition
    79.                 col += foamLine * _Tint; // add the foam line and tint to the texture
    80.                 return MixFog (col, i.fogCoords);
    81.             }
    82.             ENDHLSL
    83.         }
    84.     }
    85. }
    A few things to note - aside from some of the internal functions and practices changing, there are two key things to getting a shader to work with the new pipelines. Number 1 (and probably the most important) is naming your pass. SRPs no longer render by whole materials; instead they only render specific passes, and to make sure unsupported shaders aren't rendered, the pipeline will only render passes with specific names - one of which is "Unlit". The other key thing is the switch from CG to HLSL. It won't look like much has changed (because both languages have the same syntax), but they aren't identical. As you can see, the old include files no longer work, so you'll need to use the HLSL includes from the SRP package. Probably the main thing you'll notice though is that textures now work differently. Textures come in two parts - the texture and the sampler that stores information about how to draw that texture. In CG, texture objects came with these two forcibly combined, so you didn't need to worry about it. However, in HLSL, you have to declare sampler states separately and sample the textures using them. This does mean that you can reuse sampler states, as I have between _MainTex and _NoiseTex.

    There might be some errors here; I don't use the new pipelines, so I wrote this entirely off the github shaders, but it should work.
     
  3. mouurusai

    mouurusai

    Joined:
    Dec 2, 2011
    Posts:
    350
    Who says so? My CGish shaders works perfectly fine with LWRP.
     
    Last edited: Oct 10, 2019
  4. Namey5

    Namey5

    Joined:
    Jul 5, 2013
    Posts:
    188
    CG is still supported, but the new frameworks are based entirely around HLSL and that is what Unity is pushing everyone to switch over to, not to mention that the core libraries and shaders are all written in HLSL and often rely on HLSL functionality that isn't part of CG (like separate sampler-states).
     
    MadeFromPolygons likes this.
  5. mouurusai

    mouurusai

    Joined:
    Dec 2, 2011
    Posts:
    350
    As far I know, Unity don't use CG nor HLSL, just CG/HLSL ish syntax, so forcing to other "ish" sounds kinda nonsensical.
    Did Unity Technologies make recommendations about migrating to HLSL ish mode?
     
  6. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,539
    Separate sampler states is present in CGPROGRAM as well, the key is that you need to be handling the platform differences in definition and thus would have to wrap the declaration in the appropriate platform defines that use that syntax. There were several macros for handling platform differences in separate sampler states, like
    UNITY_DECLARE_TEX2D(_Name);
    which on most platforms would define a
    Texture2D
    and
    SamplerState
    property in your CG shader, this syntax works fine in CG. Or
    UNITY_DECLARE_TEX2D_NOSAMPLER(_Name);
    for just a texture and no sampler.
    UNITY_SAMPLE_TEX2D_SAMPLER(_tex, _sampler, uv)
    to sample using separate texture and sampler.

    Unity has simply changed the naming of these macros for the render pipelines. It's now just
    TEXTURE2D(_Name)
    for just a texture and
    SAMPLER(_name) 
    for just a sampler, or define both at once with
    TEXTURE2D_PARAM(_texName, _sampleName)
    , among many other macros.
    You can find the main Macros in
    com.unity.render-pipelines.core\ShaderLibrary\API\D3D11.hlsl
    , there's a different .hlsl file in that directory for each platform that has different results needed for the macros.
     
    Last edited: Oct 10, 2019
    forestrf, Flubzies, andywatts and 3 others like this.
  7. Namey5

    Namey5

    Joined:
    Jul 5, 2013
    Posts:
    188
    Ah right. I'm not formally trained on this stuff, but I remember Unity used to always push for using DX9 style 'sampler2D' declarations over the separated methods, so I misinterpreted that as a language difference between CG and HLSL.
     
  8. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    Cg is not supported, and hasn’t been for several years. I believe Unity 4.7 was the last version of Unity to support Cg, and then only when compiling to desktop OpenGL. GLES and DirectX platforms stopped supporting Cg long before that.

    The confusion is Cg and Direct3D 9 HLSL have nearly identical syntax and built in functions, and the letters “cg” show up so often in Unity’s shaders. I say nearly identical because there are a handful of functions that they do not share. For example, Cg does not have
    tex2Dgrad
    , but instead has an overload of
    tex2D
    that has the same functionality. However
    CGPROGRAM
    and
    HLSLPROGRAM
    are identical, as are .cginc and .hlsl files, and are compiled as Direct3D 11 or 12 HLSL (which also happily accepts Direct3D 9 HLSL). They just never had a chance to make a clean break with past versions of Unity, where all those occurrences of “cg” were common, until the SRPs.

    Some other confusion comes from Unity’s heavy reliance on macros to bridge the gap between different APIs where the cross compiling tools they use couldn’t quite keep up. The SRPs continue this, with things like texture uniforms and sample functions being wrapped in macros that write out forms supported by the current API. Aiming for Direct3D11? Texture2D, SamplerState, and tex.Sample(sampleState, uv). GLES? sampler2D and tex2D(tex, uv).

    Humorously though, they still use the term “fragment shader”, which dates back to Unity’s original OpenGL only origins. Both Cg and HLSL refer to it as a “pixel shader”.
     
  9. MadeFromPolygons

    MadeFromPolygons

    Joined:
    Oct 5, 2013
    Posts:
    3,967
    Guys thanks so much for all the informative replies, not only do I feel I have a much better handle on how to start translating my existing shaders, but I also have a better handle on where to look to find existing macros for the new pipeline etc!

    Thanks a bunch!
     
  10. Tartiflette

    Tartiflette

    Joined:
    Apr 10, 2015
    Posts:
    84
    I'd like to add that you can right click on the master nodes of the shader graph to get the generated code, which can be quite useful if you want to get all the boiler plate code, or want to figure out how to access some of the vertex data etc. The problem is that it generates a ridiculously large file that you'll have to decipher.
     
    bgolus likes this.
  11. ROBYER1

    ROBYER1

    Joined:
    Oct 9, 2015
    Posts:
    1,450
    I really wish there was a converter or even a Unity backed guide for this! That or I just learn more of Shader Graph to recreate my effects.. yeah probably that!
     
  12. ROBYER1

    ROBYER1

    Joined:
    Oct 9, 2015
    Posts:
    1,450
    Quick update, so far any old school built-in or custom shader *that is unlit* I had seems to work with Universal RP on Scriptable Render Pipeline when I follow the guide here to enable GPU instancing support. Maybe I just found an unexpected way of converting old shaders but they all work!

    Just follow the steps here: https://docs.unity3d.com/Manual/SinglePassInstancing.html

    Let me know if this works for any of you!
     
  13. Pnvanol

    Pnvanol

    Joined:
    Jan 11, 2016
    Posts:
    114
    Thank you , how do I remove lighting from custom shaders...
     
  14. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,539
    What kind of custom shader? You've written your own? Did you copy code from a URP shader? Or just trying to make an existing shader you have not receive lighting? If it's an old shader that's still working in URP it shouldn't really be receiving lighting since it would be a basic vert/frag forward shader and the old lighting macros shouldn't be compatible...
    My main advice would be to simply look at the code the URP's Unlit shader uses and adapt your code to it.

    Post the shader you're trying to modify and we may be able to help you.
     
    yc_ and Pnvanol like this.
  15. Pnvanol

    Pnvanol

    Joined:
    Jan 11, 2016
    Posts:
    114
    Code (CSharp):
    1. Shader "Custom/TilemapShader" {
    2.     Properties {      
    3.         _MainTex ("Map", 2D) = "white" {}
    4.         _Tileset("Tileset", 2D) = "white" {}
    5.         _Size("Map & Tileset Size", Vector) = (16, 16, 20, 13)
    6.     }
    7.     SubShader {
    8.         Tags { "RenderType"="Opaque" }
    9.         LOD 200
    10.  
    11.         CGPROGRAM
    12.         // Physically based Standard lighting model, and enable shadows on all light types
    13.         #pragma surface surf Standard fullforwardshadows
    14.  
    15.         // Use shader model 3.0 target, to get nicer looking lighting
    16.         #pragma target 3.0
    17.  
    18.         sampler2D _MainTex;
    19.         sampler2D _Tileset;
    20.  
    21.         struct Input {
    22.             float2 uv_MainTex;
    23.         };
    24.  
    25.         float4 _Size;
    26.         // _Size.xy is the size of the map in tiles.
    27.         // _Size.zw is the size of the tileset in tiles.
    28.  
    29.         void surf (Input IN, inout SurfaceOutputStandard o) {
    30.  
    31.             // Scale up the uvs into tile space.
    32.             float2 mapLocation = IN.uv_MainTex * _Size.xy;
    33.  
    34.             // Get this pixel's position within the tile we're drawing.
    35.             float2 inTileUV = frac(mapLocation);
    36.  
    37.             // Clamp the texel we read from.
    38.             // ("Point" filtering does this too, but its math is slightly
    39.             // different, which can show up as a shimmer between tiles)
    40.             mapLocation = (mapLocation - inTileUV) / _Size.xy;
    41.  
    42.             // Slightly inset tiles so they don't bleed at the edges.
    43.             inTileUV = inTileUV * 126.0f / 128.0f + 1.0f / 128.0f;
    44.  
    45.             // Calculate texture sampling gradients using original UV.
    46.             // Otherwise jumps at tile borders make the hardware apply filtering
    47.             // that lets adjactent tiles bleed in at the edges.
    48.             float4 grad = float4(ddx(IN.uv_MainTex), ddy(IN.uv_MainTex));
    49.  
    50.             // Read our map texture to determine what tiles go here.
    51.             float4 tileIndex = tex2D(_MainTex, mapLocation);
    52.  
    53.             // Generate UV offsets into our tileset texture.
    54.             tileIndex = (tileIndex * 255.0f + inTileUV.xyxy )/_Size.zwzw ;
    55.  
    56.             // Sample two tiles from our tileset: one base tile and one overlay.
    57.             // (Hey, we have room for two indices, might as well use it!)
    58.             fixed4 base = tex2Dgrad(_Tileset, tileIndex.xy, grad.xy, grad.zw);
    59.             fixed4 over = tex2Dgrad(_Tileset, tileIndex.zw, grad.xy, grad.zw);
    60.  
    61.             // Combine overlaid tile with base using standard alpha blending.
    62.             fixed4 c = lerp(base, over, over.a);
    63.  
    64.             // Put all this into terms the Unity lighting model understands.
    65.             o.Albedo = c.rgb;        
    66.             o.Metallic = 0.0f;
    67.             o.Smoothness = 0.0f;
    68.             o.Alpha = c.a;
    69.         }
    70.         ENDCG
    71.     }
    72.     FallBack "Diffuse"
    73. }
    Here it is, thank you for your help

    This shader was made in 2017, and it doesn't work with the URP, I think it must be because it uses lighting. So if I can remove the lighting from it out should be ok.
    What it does is turns a colour map into a Tileset
     
  16. Pnvanol

    Pnvanol

    Joined:
    Jan 11, 2016
    Posts:
    114
    Replied you above
     
  17. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,539
    Here it is converted to URP, adapted from URP Unlit shader. Let me know if there's an issue with it.


    Code (CSharp):
    1. Shader "Custom/TilemapShader"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex("Map", 2D) = "white" {}
    6.         [NoScaleOffset]_Tileset("Tileset", 2D) = "white" {}
    7.         _Size("Map & Tileset Size", Vector) = (16, 16, 20, 13)
    8.        
    9.         // BlendMode
    10.         [HideInInspector] _Surface("__surface", Float) = 0.0
    11.         [HideInInspector] _Blend("__blend", Float) = 0.0
    12.         [HideInInspector] _AlphaClip("__clip", Float) = 0.0
    13.         [HideInInspector] _SrcBlend("Src", Float) = 1.0
    14.         [HideInInspector] _DstBlend("Dst", Float) = 0.0
    15.         [HideInInspector] _ZWrite("ZWrite", Float) = 1.0
    16.         [HideInInspector] _Cull("__cull", Float) = 2.0
    17.  
    18.         // Editmode props
    19.         [HideInInspector] _QueueOffset("Queue offset", Float) = 0.0
    20.     }
    21.     SubShader
    22.     {
    23.         Tags { "RenderType" = "Opaque" "IgnoreProjector" = "True" "RenderPipeline" = "UniversalPipeline" }
    24.         LOD 100
    25.  
    26.         Blend [_SrcBlend][_DstBlend]
    27.         ZWrite [_ZWrite]
    28.         Cull [_Cull]
    29.  
    30.         Pass
    31.         {
    32.             Name "Unlit"
    33.             HLSLPROGRAM
    34.             // Required to compile gles 2.0 with standard srp library
    35.             #pragma prefer_hlslcc gles
    36.             #pragma exclude_renderers d3d11_9x
    37.  
    38.             #pragma vertex vert
    39.             #pragma fragment frag
    40.  
    41.             // -------------------------------------
    42.             // Unity defined keywords
    43.             #pragma multi_compile_instancing
    44.  
    45.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
    46.  
    47.             TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
    48.             TEXTURE2D(_Tileset); SAMPLER(sampler_Tileset);
    49.            
    50.             CBUFFER_START(UnityPerMaterial)
    51.                 float4 _MainTex_ST;
    52.                 float4 _Size;
    53.             CBUFFER_END
    54.  
    55.             struct Attributes
    56.             {
    57.                 float4 positionOS       : POSITION;
    58.                 float2 uv               : TEXCOORD0;
    59.                 UNITY_VERTEX_INPUT_INSTANCE_ID
    60.             };
    61.  
    62.             struct Varyings
    63.             {
    64.                 float2 uv        : TEXCOORD0;
    65.                 float4 vertex : SV_POSITION;
    66.  
    67.                 UNITY_VERTEX_INPUT_INSTANCE_ID
    68.                 UNITY_VERTEX_OUTPUT_STEREO
    69.             };
    70.  
    71.             Varyings vert(Attributes input)
    72.             {
    73.                 Varyings output = (Varyings)0;
    74.  
    75.                 UNITY_SETUP_INSTANCE_ID(input);
    76.                 UNITY_TRANSFER_INSTANCE_ID(input, output);
    77.                 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
    78.  
    79.                 VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
    80.                 output.vertex = vertexInput.positionCS;
    81.                 output.uv = TRANSFORM_TEX(input.uv, _MainTex);
    82.  
    83.                 return output;
    84.             }
    85.  
    86.             half4 frag(Varyings input) : SV_Target
    87.             {
    88.                 UNITY_SETUP_INSTANCE_ID(input);
    89.                 UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
    90.  
    91.                 // Scale up the uvs into tile space.
    92.                 float2 mapLocation = input.uv * _Size.xy;
    93.                 // Get this pixel's position within the tile we're drawing.
    94.                 float2 inTileUV = frac(mapLocation);
    95.  
    96.                 // Clamp the texel we read from.
    97.                 // ("Point" filtering does this too, but its math is slightly
    98.                 // different, which can show up as a shimmer between tiles)
    99.                 mapLocation = (mapLocation - inTileUV) / _Size.xy;
    100.    
    101.                 // Slightly inset tiles so they don't bleed at the edges.
    102.                 inTileUV = inTileUV * 126.0f / 128.0f + 1.0f / 128.0f;
    103.    
    104.                 // Calculate texture sampling gradients using original UV.
    105.                 // Otherwise jumps at tile borders make the hardware apply filtering
    106.                 // that lets adjactent tiles bleed in at the edges.
    107.                 float4 grad = float4(ddx(input.uv), ddy(input.uv));
    108.    
    109.                 // Read our map texture to determine what tiles go here.
    110.                 float4 tileIndex = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, mapLocation);
    111.    
    112.                 // Generate UV offsets into our tileset texture.
    113.                 tileIndex = (tileIndex * 255.0f + inTileUV.xyxy )/_Size.zwzw ;
    114.    
    115.                 // Sample two tiles from our tileset: one base tile and one overlay.
    116.                 // (Hey, we have room for two indices, might as well use it!)
    117.                 half4 base = SAMPLE_TEXTURE2D_GRAD(_Tileset, sampler_Tileset, tileIndex.xy, grad.xy, grad.zw);
    118.                 half4 over = SAMPLE_TEXTURE2D_GRAD(_Tileset, sampler_Tileset, tileIndex.zw, grad.xy, grad.zw);
    119.    
    120.                 // Combine overlaid tile with base using standard alpha blending.
    121.                 return lerp(base, over, over.a);
    122.             }
    123.             ENDHLSL
    124.         }
    125.         Pass
    126.         {
    127.             Tags{"LightMode" = "DepthOnly"}
    128.  
    129.             ZWrite On
    130.             ColorMask 0
    131.  
    132.             HLSLPROGRAM
    133.             // Required to compile gles 2.0 with standard srp library
    134.             #pragma prefer_hlslcc gles
    135.             #pragma exclude_renderers d3d11_9x
    136.             #pragma target 2.0
    137.  
    138.             #pragma vertex DepthOnlyVertex
    139.             #pragma fragment DepthOnlyFragment
    140.  
    141.             // -------------------------------------
    142.             // Material Keywords
    143.             #pragma shader_feature _ALPHATEST_ON
    144.  
    145.             //--------------------------------------
    146.             // GPU Instancing
    147.             #pragma multi_compile_instancing
    148.  
    149.             #include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl"
    150.             #include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"
    151.             ENDHLSL
    152.         }
    153.     }
    154.     FallBack "Hidden/Universal Render Pipeline/FallbackError"
    155. }
     
  18. Pnvanol

    Pnvanol

    Joined:
    Jan 11, 2016
    Posts:
    114
    Thank you so much, I am on 2019.2.21 on lightweight render pipeline I thought it is the same as the UDP I get this two errors

    upload_2020-3-7_11-24-41.png
     

    Attached Files:

  19. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,539
    Yeah, lightweight was renamed universal in 2019.3, so some of the references are different, could you upgrade?
     
    Pnvanol likes this.
  20. Pnvanol

    Pnvanol

    Joined:
    Jan 11, 2016
    Posts:
    114
    I'd love to upgrade to enjoy the new unity Ui, but when I do I have such an annoying bug on the editor that makes unity editor useless. So I want to stay in 2019.2. 20 for a while if possible as I wasted crazy time trying to solve that bug...
    This is the bug https://forum.unity.com/threads/i-c...n-search-boxes-in-unity-editor-2019-3.818832/
     
  21. Pnvanol

    Pnvanol

    Joined:
    Jan 11, 2016
    Posts:
    114
  22. Finijumper

    Finijumper

    Joined:
    Jul 12, 2016
    Posts:
    78
    @Invertex can you help me convert a fast mobile bloom shader into URP? It doesn't throw any error but the bloom isn't working in URP but it in Built-in is working.
     
  23. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    Fixing post processing is a totally different ball game than translating a shader. For the most part the original shaders will work perfectly fine, however you have to completely rewrite all of the c# code for post process effects to work with the version of the Post Processing Stack v2 that the URP uses. You can't use the older
    OnRenderImage
    function anymore.

    https://docs.unity3d.com/Packages/com.unity.postprocessing@2.1/manual/Writing-Custom-Effects.html

    Alternatively you could use the built in bloom which is already highly optimized.
     
  24. Finijumper

    Finijumper

    Joined:
    Jul 12, 2016
    Posts:
    78
    So you're saying that this can't be translated?
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. [ExecuteInEditMode]
    4. [RequireComponent(typeof(Camera))]
    5. [AddComponentMenu("Image Effects/FastMobileBloom")]
    6. public class FastMobileBloom : MonoBehaviour
    7. {
    8.     [Range(0.0f, 1.5f)] public float threshold = 0.25f;
    9.  
    10.     [Range(0.00f, 4.0f)] public float intensity = 1.0f;
    11.     [Range(0.25f, 5.5f)] public float blurSize = 1.0f;
    12.     [Range(1, 4)] public int blurIterations = 2;
    13.  
    14.     public Material fastBloomMaterial = null;
    15.  
    16.     void OnRenderImage(RenderTexture source, RenderTexture destination)
    17.     {
    18.         int rtW = source.width / 4;
    19.         int rtH = source.height / 4;
    20.        
    21.         //initial downsample
    22.         RenderTexture rt = RenderTexture.GetTemporary(rtW, rtH, 0, source.format);
    23.         rt.DiscardContents();
    24.  
    25.         fastBloomMaterial.SetFloat("_Spread", blurSize);
    26.         fastBloomMaterial.SetVector("_ThresholdParams", new Vector2(1.0f, -threshold));
    27.         Graphics.Blit(source, rt, fastBloomMaterial, 0);
    28.  
    29.  
    30.         //downscale
    31.         for(int i = 0; i < blurIterations - 1; i++)
    32.         {
    33.             RenderTexture rt2 = RenderTexture.GetTemporary(rt.width / 2, rt.height / 2, 0, source.format);
    34.             rt2.DiscardContents();
    35.  
    36.             fastBloomMaterial.SetFloat("_Spread", blurSize);
    37.             Graphics.Blit(rt, rt2, fastBloomMaterial, 1);
    38.             RenderTexture.ReleaseTemporary(rt);
    39.             rt = rt2;
    40.         }
    41.         //upscale
    42.         for(int i = 0; i < blurIterations - 1; i++)
    43.         {
    44.             RenderTexture rt2 = RenderTexture.GetTemporary(rt.width * 2, rt.height * 2, 0, source.format);
    45.             rt2.DiscardContents();
    46.  
    47.             fastBloomMaterial.SetFloat("_Spread", blurSize);
    48.             Graphics.Blit(rt, rt2, fastBloomMaterial, 2);
    49.             RenderTexture.ReleaseTemporary(rt);
    50.             rt = rt2;
    51.         }
    52.  
    53.         fastBloomMaterial.SetFloat("_BloomIntensity", intensity);
    54.         fastBloomMaterial.SetTexture("_BloomTex", rt);
    55.         Graphics.Blit(source, destination, fastBloomMaterial, 3);
    56.  
    57.         RenderTexture.ReleaseTemporary(rt);
    58.     }
    59. }
    60.  
     
  25. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    I'm saying the page I linked to describes the basics of how to, and that there's not really a point since the built in Bloom is probably just as fast.
     
  26. noshabacheema

    noshabacheema

    Joined:
    Apr 21, 2021
    Posts:
    1
    Here a working example of @Namey5 's code including SRB batcher compatibility:


    Code (CSharp):
    1. Shader "Unlit/SimpleWater"
    2. {
    3.     Properties
    4.     {
    5.         _Tint("Tint", Color) = (1, 1, 1, .5)
    6.         _MainTex("Main Texture", 2D) = "white" {}
    7.         _NoiseTex("Extra Wave Noise", 2D) = "white" {}
    8.         _Speed("Wave Speed", Range(0,1)) = 0.5
    9.         _Amount("Wave Amount", Range(0,1)) = 0.5
    10.         _Height("Wave Height", Range(0,1)) = 0.5
    11.         _Foam("Foamline Thickness", Range(0,3)) = 0.5
    12.     }
    13.     SubShader
    14.     {
    15.         Tags { "RenderType" = "Opaque"  "Queue" = "Transparent" "RenderPipeline" = "UniversalPipeline"}
    16.         LOD 100
    17.         Blend SrcAlpha OneMinusSrcAlpha
    18.         Pass
    19.         {
    20.             Name "Unlit"
    21.             HLSLPROGRAM
    22.             #pragma vertex vert
    23.             #pragma fragment frag
    24.             // make fog work
    25.             #pragma multi_compile_fog
    26.             //#include "UnityCG.cginc"
    27.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    28.             struct appdata
    29.             {
    30.                 float4 vertex : POSITION;
    31.                 float2 uv : TEXCOORD0;
    32.             };
    33.             struct v2f
    34.             {
    35.                 float2 uv : TEXCOORD0;
    36.                 float fogCoords : TEXCOORD1;
    37.                 float4 vertex : SV_POSITION;
    38.                 float4 scrPos : TEXCOORD2;//
    39.             };
    40.             CBUFFER_START(UnityPerMaterial)
    41.             float4 _Tint;
    42.             Texture2D _CameraDepthTexture; SamplerState sampler_CameraDepthTexture; //Depth Texture
    43.             sampler2D _MainTex, _NoiseTex;//
    44.             float4 _MainTex_ST;
    45.             float _Speed, _Amount, _Height, _Foam;//
    46.             CBUFFER_END
    47.             v2f vert(appdata v)
    48.             {
    49.                 v2f o;
    50.                 float4 tex = tex2Dlod(_NoiseTex, float4(v.uv.xy, 0, 0));//extra noise tex
    51.                 v.vertex.y += sin(_Time.z * _Speed + (v.vertex.x * v.vertex.z * _Amount * tex)) * _Height;//movement
    52.                 //o.vertex = UnityObjectToClipPos(v.vertex);
    53.                 VertexPositionInputs vertInputs = GetVertexPositionInputs(v.vertex.xyz);    //This function calculates all the relative spaces of the objects vertices
    54.                 o.vertex = vertInputs.positionCS;
    55.            
    56.                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    57.                 o.scrPos = ComputeScreenPos(o.vertex); // grab position on screen
    58.                 //UNITY_TRANSFER_FOG(o,o.vertex);
    59.                 o.fogCoords = ComputeFogFactor(o.vertex.z);
    60.                 return o;
    61.             }
    62.             half4 frag(v2f i) : SV_Target
    63.             {
    64.                 // sample the texture
    65.                 half4 col = tex2D(_MainTex, i.uv) * _Tint;// texture times tint;
    66.                 half depth = LinearEyeDepth(_CameraDepthTexture.Sample(sampler_CameraDepthTexture, i.scrPos.xy / i.scrPos.w).r, _ZBufferParams);
    67.                 half4 foamLine = 1 - saturate(_Foam * (depth - i.scrPos.w));// foam line by comparing depth and screenposition
    68.                 col += foamLine * _Tint; // add the foam line and tint to the texture
    69.                 return half4(MixFog(col, i.fogCoords), col.a);
    70.             }
    71.             ENDHLSL
    72.         }
    73.     }
    74. }