Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Any chance we can get a minimal example of a shader for the LD SRP?

Discussion in '2018.1 Beta' started by jbooth, Jan 10, 2018.

  1. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    I've been trying to write a minimal LIT shader for the LD pathway so I can understand how to write shaders for the new pipeline and support it's lighting pathways. However, there are no examples, and as usual, no documentation on any of the shader code included in the LD SRP, nor are there any examples which aren't either based on a shader graph or giant shader frameworks.

    The first thing I tried was to take the LightweightStandard shader, strip it down, and get it to compile under a project with the LD pipeline installed, with the contents of each pass included into the code.

    However, it cannot find any of the required include files from the Lightweight Pipeline, even though I am running the lightweight pipeline included with the Shader Graph project.

    So I downloaded the Lightweight pipeline from BitBucket and copied it's folders into my project, but this produces a conflict since the LD pipeline is already installed into the project. So I removed the pipeline and copied the include files it needs into the appropriate folders.

    It managed to find the includes for:

    Code (CSharp):
    1. #include "LightweightShaderLibrary/InputSurface.hlsl"
    2. #include "LightweightShaderLibrary/Lighting.hlsl"
    But the includes they depend on in Core are not found, even when copied into the project and included in the correct folders.

    Can we PLEASE get an example of a single lit shader, which supports all of the lighting pathways this pipeline provides properly? And another with tessellation enabled? Will we have to include this entire shader framework with our distributions, or is there some way to properly access the #includes when the render pipeline is installed?
     
  2. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    Bump!

    In the shipped beta, the include paths to the shaders cannot be found. But if you install SRP from the BitBucket into a fresh 2018.1 project, it doesn't compile. Can we please get ANY WORKING EXAMPLE of a lit shader which is not built in a shader graph? I will change engines before I'm forced to write shaders in a shader graph.
     
    MadeFromPolygons and Josh_OAS like this.
  3. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,618
    I guess you already extracted the shader code of a ShaderGraph generated file and this is not working for you? I just did that and saved the file as .shader, which seems to work for me in the "Lightweight Example Project". No compile errors:
    Code (CSharp):
    1. Shader "Unlit/NewShader"
    2. {
    3.     Properties
    4.     {
    5.         _Color ("Color", Color) = (1,1,1,1)
    6.     }
    7.  
    8.     SubShader
    9.     {
    10.         Tags { "RenderType" = "Opaque" }
    11.         LOD 100
    12.  
    13.         Pass
    14.         {
    15.             CGPROGRAM
    16.  
    17. #include "HLSLSupport.cginc"
    18. #define UNITY_INSTANCED_LOD_FADE
    19. #define UNITY_INSTANCED_SH
    20. #define UNITY_INSTANCED_LIGHTMAPSTS
    21. #include "UnityShaderVariables.cginc"
    22. #include "UnityShaderUtilities.cginc"
    23.  
    24. #pragma target 3.0
    25.  
    26. #pragma multi_compile _ _MAIN_LIGHT_COOKIE
    27. #pragma multi_compile _MAIN_DIRECTIONAL_LIGHT _MAIN_SPOT_LIGHT
    28. #pragma multi_compile _ _ADDITIONAL_LIGHTS
    29. #pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE
    30. #pragma multi_compile _ UNITY_SINGLE_PASS_STEREO STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON
    31. #pragma multi_compile _ LIGHTMAP_ON
    32. #pragma multi_compile _ DIRLIGHTMAP_COMBINED
    33. #pragma multi_compile _ _HARD_SHADOWS _SOFT_SHADOWS _HARD_SHADOWS_CASCADES _SOFT_SHADOWS_CASCADES
    34. #pragma multi_compile _ _VERTEX_LIGHTS
    35. #pragma multi_compile_fog
    36. #pragma multi_compile_instancing
    37. #pragma vertex vert
    38. #pragma fragment frag
    39. #pragma glsl
    40. #pragma debug
    41.  
    42.  
    43. #include "LightweightLighting.cginc"
    44. struct VertexInput
    45. {
    46.     float4 vertex : POSITION;
    47.     float3 normal : NORMAL;
    48.     float4 tangent : TANGENT;
    49.     float4 texcoord1 : TEXCOORD1;
    50.     UNITY_VERTEX_INPUT_INSTANCE_ID
    51. };
    52.  
    53. struct SurfaceInputs
    54. {
    55. };
    56.  
    57. struct SurfaceDescription
    58. {
    59.     float3 Albedo;
    60.     float3 Normal;
    61.     float3 Emission;
    62.     float Metallic;
    63.     float Smoothness;
    64.     float Occlusion;
    65.     float Alpha;
    66. };
    67.  
    68. float4 _Color;
    69.  
    70. VertexInput PopulateVertexData(VertexInput v)
    71. {
    72.     return v;
    73. }
    74.  
    75. SurfaceDescription PopulateSurfaceData(SurfaceInputs IN)
    76. {
    77.     SurfaceDescription surface = (SurfaceDescription)0;
    78.  
    79.     surface.Albedo = _Color;
    80.     surface.Normal = float3 (0,0,1);
    81.     surface.Emission = IsGammaSpace() ? float3(0, 0, 0) : GammaToLinearSpace(float3(0, 0, 0));
    82.     surface.Metallic = 0;
    83.     surface.Smoothness = 0.5;
    84.     surface.Occlusion = 1;
    85.     surface.Alpha = 1;
    86.  
    87.     return surface;
    88. }
    89.  
    90. struct VertexOutput
    91. {
    92.     float4 position : SV_POSITION;
    93. #ifdef LIGHTMAP_ON
    94.     float4 lightmapUV : TEXCOORD0;
    95. #else
    96.     float4 vertexSH : TEXCOORD0;
    97. #endif
    98.     half4 fogFactorAndVertexLight : TEXCOORD1; // x: fogFactor, yzw: vertex light
    99.     float3 WorldSpaceNormal : TEXCOORD3;
    100.     float3 WorldSpaceTangent : TEXCOORD4;
    101.     float3 WorldSpaceBiTangent : TEXCOORD5;
    102.     float3 WorldSpaceViewDirection : TEXCOORD6;
    103.     float3 WorldSpacePosition : TEXCOORD7;
    104.     half4 uv1 : TEXCOORD8;
    105.     UNITY_VERTEX_OUTPUT_STEREO
    106. };
    107.  
    108. VertexOutput vert(VertexInput v)
    109. {
    110.     v = PopulateVertexData(v);
    111.  
    112.     UNITY_SETUP_INSTANCE_ID(v);
    113.     VertexOutput o = (VertexOutput)0;
    114.     UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
    115.  
    116.     o.WorldSpaceNormal = mul(v.normal,(float3x3)unity_WorldToObject);
    117.     o.WorldSpaceTangent = mul((float3x3)unity_ObjectToWorld,v.tangent);
    118.     o.WorldSpaceBiTangent = normalize(cross(o.WorldSpaceNormal, o.WorldSpaceTangent.xyz) * v.tangent.w);
    119.     o.WorldSpaceViewDirection = mul((float3x3)unity_ObjectToWorld,ObjSpaceViewDir(v.vertex));
    120.     o.WorldSpacePosition = mul(unity_ObjectToWorld,v.vertex);
    121.     o.uv1 = v.texcoord1;
    122.  
    123.     float3 lwWNormal = normalize(UnityObjectToWorldNormal(v.normal));
    124.     float4 lwWorldPos = mul(unity_ObjectToWorld, v.vertex);
    125.     float4 clipPos = mul(UNITY_MATRIX_VP, lwWorldPos);
    126.  
    127. #ifdef LIGHTMAP_ON
    128.     o.lightmapUV.zw = v.texcoord1 * unity_LightmapST.xy + unity_LightmapST.zw;
    129. #else
    130.     o.vertexSH = half4(EvaluateSHPerVertex(lwWNormal), 0.0);
    131. #endif
    132.  
    133.     o.fogFactorAndVertexLight.yzw = VertexLighting(lwWorldPos.xyz, lwWNormal);
    134.     o.fogFactorAndVertexLight.x = ComputeFogFactor(clipPos.z);
    135.     o.position = clipPos;
    136.     return o;
    137. }
    138.  
    139. fixed4 frag(VertexOutput IN) : SV_Target
    140. {
    141.     float3 WorldSpaceNormal = normalize(IN.WorldSpaceNormal);
    142.     float3 WorldSpaceTangent = IN.WorldSpaceTangent;
    143.     float3 WorldSpaceBiTangent = IN.WorldSpaceBiTangent;
    144.     float3 WorldSpaceViewDirection = normalize(IN.WorldSpaceViewDirection);
    145.     float3 WorldSpacePosition = IN.WorldSpacePosition;
    146.     float4 uv1 = IN.uv1;
    147.     SurfaceInputs surfaceInput = (SurfaceInputs)0;
    148.  
    149.     SurfaceDescription surf = PopulateSurfaceData(surfaceInput);
    150.     float3 Albedo = float3(0.5, 0.5, 0.5);
    151.     float3 Specular = float3(0, 0, 0);
    152.     float Metallic = 0;
    153.     float3 Normal = float3(0, 0, 1);
    154.     float3 Emission = 0;
    155.     float Smoothness = 0.5;
    156.     float Occlusion = 1;
    157.     float Alpha = 1;
    158.  
    159.     Albedo = surf.Albedo;
    160.     Normal = surf.Normal;
    161.     Emission = surf.Emission;
    162.     Metallic = surf.Metallic;
    163.     Smoothness = surf.Smoothness;
    164.     Occlusion = surf.Occlusion;
    165.     Alpha = surf.Alpha;
    166.  
    167. #if defined(UNITY_COLORSPACE_GAMMA)
    168.     Albedo = Albedo * Albedo;
    169.     Emission = Emission * Emission;
    170. #endif
    171.  
    172. #if _NORMALMAP
    173.     half3 normalWS = TangentToWorldNormal(Normal, WorldSpaceTangent, WorldSpaceBiTangent, WorldSpaceNormal);
    174. #else
    175.     half3 normalWS = normalize(WorldSpaceNormal);
    176. #endif
    177.  
    178. #if LIGHTMAP_ON
    179.     half3 indirectDiffuse = SampleLightmap(IN.lightmapUV.zw, normalWS);
    180. #else
    181.     half3 indirectDiffuse = EvaluateSHPerPixel(normalWS, IN.vertexSH);
    182. #endif
    183.  
    184.     half4 color = LightweightFragmentPBR(
    185.             WorldSpacePosition,
    186.             normalWS,
    187.             WorldSpaceViewDirection,
    188.             indirectDiffuse,
    189.             IN.fogFactorAndVertexLight.yzw,
    190.             Albedo,
    191.             Metallic,
    192.             Specular,
    193.             Smoothness,
    194.             Occlusion,
    195.             Emission,
    196.             Alpha);
    197.     // Computes fog factor per-vertex
    198.     ApplyFog(color.rgb, IN.fogFactorAndVertexLight.x);
    199.  
    200. #if _AlphaOut
    201.     color.a = Alpha;
    202. #else
    203.     color.a = 1;
    204. #endif
    205.  
    206. #if _AlphaClip
    207.     clip(Alpha - 0.01);
    208. #endif
    209.  
    210.     return color;
    211. }
    212.  
    213.  
    214.             ENDCG
    215.         }
    216.     }
    217. }
    218.  
    I left out the shadow pass and renamed a few variables.
     
    Reanimate_L, OCASM and jbooth like this.
  4. MadeFromPolygons

    MadeFromPolygons

    Joined:
    Oct 5, 2013
    Posts:
    3,981
    You can actually turn shader graphs into shaders by changing the extension, and the code is pretty readable, might not be the best start but at least its a start :)
     
  5. 00christian00

    00christian00

    Joined:
    Jul 22, 2012
    Posts:
    1,035
    Do shaders need to be rewritten for the new pipeline? The quoted shader seem identical to the current shader format.
     
  6. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    What's interesting is that the code in the depot for the LD standard shader differs in some significant ways that what's output from the shader graph. It would be nice to know which is the correct pattern to follow. For instance:

    Shader graph uses CGPROGRAM, while the new LD standard shader uses HLSLPROGRAM. Further, many of the lighting functions used by each are different. So which pathways are the correct pathways moving forward? Is using the compiled output of the shader graph going to be a dead end once that gets updated?

    Format is similar, but the lighting pathways are totally different, and surface shaders are no more, so every shader now has to deal with the 'ever changing, every version of Unity breaks your shader or adds new stuff you are expected to reverse engineer and support with no documentation' lighting pathways in vertex/fragment shaders.
     
    Reahreic, noio and MadeFromPolygons like this.
  7. phil_lira

    phil_lira

    Unity Technologies

    Joined:
    Dec 17, 2014
    Posts:
    584
    Hi @jbooth the version of the Lightweight Pipeline and SRP core package you have had an issue with shader include paths from package manager. I can provide you a new version but it won't work with shader graph as the lightweight pipeline needs master node template needs to be updated.

    In order to update to latest lightweight pipeline package, open the manifest.json file in your project's UnityPackageManager folder. Replace it with this one: https://goo.gl/ZoG5ts

    SRP and the pipelines that we are shipping with it use a new shader library. Also each pipeline is responsible for settings the shader constants. Unity will only set the perobject constants. Therefore you have to create shaders specific to each pipeline as they handle lighting fundamentally different.

    We are still working on the documentation of this new shader library, but we strongly encourage people to start using ShaderGraph whenever possible.

    I've created a shader example here that works with LightweightPipeline. The forward pass itself has many simplification from the LW standard one for simplicity sake. I've added some comments to describe some bits I think it's important to mention: https://goo.gl/YyaXoa

    Some highlights:
    • Subshader must have a "RenderPipeline" = "LightweightPipeline" tag. You can create a single shader file that supports multiple pipelines this way. If no "RenderPipeline" tag is used in the Subshader it will match buitin Unity pipelines.
    • Your lit Pass must have "LightMode" = "LightweightForward". LW does not support deferred path.
    • "ShadowCaster" and "Meta" lightmodes work the same.
    • UNITY_MATRIX_* work for all pipelines.
    • LW sets the same Time, Fog , and _WorldSpaceCameraPos, _ProjectionParams, _ScreenParams, _ZBufferParams constants described here (https://docs.unity3d.com/Manual/SL-UnityShaderVariables.html)
    • LW sets per-object lightmap and lightprobe constants. unity_SpecCube0 is used for reflection. Box projection is not supported.
    • Light constants are different. Lightweight abstracts them with a Light struct that contains direction, color and attenuation regardless of the light type. You can use GetMainLight and GetLight to get a Light struct. Main light is the brighest directional light in the scene or a shadow casting spot light closest to the camera if no directional light is present.
    • LW does not support realtime GI and LPPV.
    • Shader path include wise you just need to include
      "LWRP/ShaderLibrary/Core.hlsl"
      "LWRP/ShaderLibrary/Lighting.hlsl"
     
    Last edited: Jan 17, 2018
    MadeFromPolygons and recursive like this.
  8. phil_lira

    phil_lira

    Unity Technologies

    Joined:
    Dec 17, 2014
    Posts:
    584
    @00christian00 You have to write lit shaders for each pipeline since the way light is handled in each pipeline is fundamentally different. You can actually have multiple Subshaders in the same file for each pipeline. For unlit shaders they might work without any changes, depends on if the constants they use are set by the pipeline or not.
     
  9. 00christian00

    00christian00

    Joined:
    Jul 22, 2012
    Posts:
    1,035
    Thanks!
    Can we have a higher precision vertex colors with the new lightweight pipeline?
    The current vertex color format is too low resolution and often introduce banding that isn't visible in the modeling software.
    I doubt there is any performance gain in keeping the current format.
     
  10. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    Hi,
    I want to thank @phil_lira for posting this example and @LeonhardP for pointing me to this thread.
    The lack of proper documentation with detailed examples is very discouraging, hope it changes soon.
     
    LeonhardP likes this.
  11. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    So, gave this another try. Installed 2018.1b8 from the Unity Hub and selected the lightweight pipeline. The included shaders throw errors on install, and don't even work right in the shader graph or in the scene.

    Also noticed there are now like 5 different pipelines- Lightweight VR, Lightweight, HD, and 3D ultra, and the old pipeline. Does that mean we now need to supply 5 different versions of our shaders?
     
    Flurgle likes this.
  12. elbows

    elbows

    Joined:
    Nov 28, 2009
    Posts:
    2,502
    I was under the impression that 3D ultra is just the old pipeline with post-processing and certain default project settings, but I havent double-checked my facts.
     
  13. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    Given that some of these pipelines are going to break every shader in existence, it would seem wise if they were more clear about these things.
     
  14. IsaiahKelly

    IsaiahKelly

    Joined:
    Nov 11, 2012
    Posts:
    418
    No. There are only 3 pipelines: built-in renderer (old), lightweight and high definition. Those are simply templates with preconfigured settings for certain use cases. It can be a bit confusing though. They do show descriptions under each template, but the actual names could probably be improved. Maybe they should prefix 2D, 3D and 3D ultra templates with "Built-in" to make it clearer.

    Templates - Overview, Details, and Request for Feedback
     
    Last edited: Feb 24, 2018
    Peter77 likes this.
  15. elbows

    elbows

    Joined:
    Nov 28, 2009
    Posts:
    2,502
    I note that the template formerly known as 3D Ultra, which caused a little confusion in this thread, is now called 3D With Extras (Preview).
     
  16. MadeFromPolygons

    MadeFromPolygons

    Joined:
    Oct 5, 2013
    Posts:
    3,981
    Anybody find anything else of use to a novice shader author?

    Trying to get my head around writing a LW shader but there seem some big undocumented differences between this and old pipeline that I cant seem to bash through on my own!

    What I am really looking for is do's and dont's