Search Unity

Combining JMO's TextureAdd Bumped Shader with Unity's Standard Shader

Discussion in 'Shaders' started by kenaochreous, Jul 1, 2016.

  1. kenaochreous

    kenaochreous

    Joined:
    Sep 7, 2012
    Posts:
    395
    So I've been trying to combine JMO's TextureAdd Bumped shader with Unity's Standard shader. I have a pretty solid grasp of how Shaderlab's and Cg's syntax is written but what I don't understand is how the individual elements interact with eachother. I thought that combine both shaders would be as simple as past one shader's code into another's. But while it did compile one the code that I pasted was not being displayed.

    So here is Unity's Standard Shader's code.
    Code (csharp):
    1. Shader "Standard"
    2. {
    3.     Properties
    4.     {
    5.         _Color("Color", Color) = (1,1,1,1)
    6.         _MainTex("Albedo", 2D) = "white" {}
    7.    
    8.         _Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
    9.  
    10.         _Glossiness("Smoothness", Range(0.0, 1.0)) = 0.5
    11.         [Gamma] _Metallic("Metallic", Range(0.0, 1.0)) = 0.0
    12.         _MetallicGlossMap("Metallic", 2D) = "white" {}
    13.  
    14.         _BumpScale("Scale", Float) = 1.0
    15.         _BumpMap("Normal Map", 2D) = "bump" {}
    16.  
    17.         _Parallax ("Height Scale", Range (0.005, 0.08)) = 0.02
    18.         _ParallaxMap ("Height Map", 2D) = "black" {}
    19.  
    20.         _OcclusionStrength("Strength", Range(0.0, 1.0)) = 1.0
    21.         _OcclusionMap("Occlusion", 2D) = "white" {}
    22.  
    23.         _EmissionColor("Color", Color) = (0,0,0)
    24.         _EmissionMap("Emission", 2D) = "white" {}
    25.    
    26.         _DetailMask("Detail Mask", 2D) = "white" {}
    27.  
    28.         _DetailAlbedoMap("Detail Albedo x2", 2D) = "grey" {}
    29.         _DetailNormalMapScale("Scale", Float) = 1.0
    30.         _DetailNormalMap("Normal Map", 2D) = "bump" {}
    31.  
    32.         [Enum(UV0,0,UV1,1)] _UVSec ("UV Set for secondary textures", Float) = 0
    33.  
    34.  
    35.         // Blending state
    36.         [HideInInspector] _Mode ("__mode", Float) = 0.0
    37.         [HideInInspector] _SrcBlend ("__src", Float) = 1.0
    38.         [HideInInspector] _DstBlend ("__dst", Float) = 0.0
    39.         [HideInInspector] _ZWrite ("__zw", Float) = 1.0
    40.     }
    41.  
    42.     CGINCLUDE
    43.         #define UNITY_SETUP_BRDF_INPUT MetallicSetup
    44.     ENDCG
    45.  
    46.     SubShader
    47.     {
    48.         Tags { "RenderType"="Opaque" "PerformanceChecks"="False" }
    49.         LOD 300
    50.  
    51.  
    52.         // ------------------------------------------------------------------
    53.         //  Base forward pass (directional light, emission, lightmaps, ...)
    54.         Pass
    55.         {
    56.             Name "FORWARD"
    57.             Tags { "LightMode" = "ForwardBase" }
    58.  
    59.             Blend [_SrcBlend] [_DstBlend]
    60.             ZWrite [_ZWrite]
    61.  
    62.             CGPROGRAM
    63.             #pragma target 3.0
    64.             // TEMPORARY: GLES2.0 temporarily disabled to prevent errors spam on devices without textureCubeLodEXT
    65.             #pragma exclude_renderers gles
    66.        
    67.             // -------------------------------------
    68.                
    69.             #pragma shader_feature _NORMALMAP
    70.             #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
    71.             #pragma shader_feature _EMISSION
    72.             #pragma shader_feature _METALLICGLOSSMAP
    73.             #pragma shader_feature ___ _DETAIL_MULX2
    74.             #pragma shader_feature _PARALLAXMAP
    75.        
    76.             #pragma multi_compile_fwdbase
    77.             #pragma multi_compile_fog
    78.  
    79.             #pragma vertex vertBase
    80.             #pragma fragment fragBase
    81.             #include "UnityStandardCoreForward.cginc"
    82.  
    83.             ENDCG
    84.         }
    85.         // ------------------------------------------------------------------
    86.         //  Additive forward pass (one light per pass)
    87.         Pass
    88.         {
    89.             Name "FORWARD_DELTA"
    90.             Tags { "LightMode" = "ForwardAdd" }
    91.             Blend [_SrcBlend] One
    92.             Fog { Color (0,0,0,0) } // in additive pass fog should be black
    93.             ZWrite Off
    94.             ZTest LEqual
    95.  
    96.             CGPROGRAM
    97.             #pragma target 3.0
    98.             // GLES2.0 temporarily disabled to prevent errors spam on devices without textureCubeLodEXT
    99.             #pragma exclude_renderers gles
    100.  
    101.             // -------------------------------------
    102.  
    103.        
    104.             #pragma shader_feature _NORMALMAP
    105.             #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
    106.             #pragma shader_feature _METALLICGLOSSMAP
    107.             #pragma shader_feature ___ _DETAIL_MULX2
    108.             #pragma shader_feature _PARALLAXMAP
    109.        
    110.             #pragma multi_compile_fwdadd_fullshadows
    111.             #pragma multi_compile_fog
    112.  
    113.             #pragma vertex vertAdd
    114.             #pragma fragment fragAdd
    115.             #include "UnityStandardCoreForward.cginc"
    116.  
    117.             ENDCG
    118.         }
    119.         // ------------------------------------------------------------------
    120.         //  Shadow rendering pass
    121.         Pass {
    122.             Name "ShadowCaster"
    123.             Tags { "LightMode" = "ShadowCaster" }
    124.        
    125.             ZWrite On ZTest LEqual
    126.  
    127.             CGPROGRAM
    128.             #pragma target 3.0
    129.             // TEMPORARY: GLES2.0 temporarily disabled to prevent errors spam on devices without textureCubeLodEXT
    130.             #pragma exclude_renderers gles
    131.        
    132.             // -------------------------------------
    133.  
    134.  
    135.             #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
    136.             #pragma multi_compile_shadowcaster
    137.  
    138.             #pragma vertex vertShadowCaster
    139.             #pragma fragment fragShadowCaster
    140.  
    141.             #include "UnityStandardShadow.cginc"
    142.  
    143.             ENDCG
    144.         }
    145.         // ------------------------------------------------------------------
    146.         //  Deferred pass
    147.         Pass
    148.         {
    149.             Name "DEFERRED"
    150.             Tags { "LightMode" = "Deferred" }
    151.  
    152.             CGPROGRAM
    153.             #pragma target 3.0
    154.             // TEMPORARY: GLES2.0 temporarily disabled to prevent errors spam on devices without textureCubeLodEXT
    155.             #pragma exclude_renderers nomrt gles
    156.        
    157.  
    158.             // -------------------------------------
    159.  
    160.             #pragma shader_feature _NORMALMAP
    161.             #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
    162.             #pragma shader_feature _EMISSION
    163.             #pragma shader_feature _METALLICGLOSSMAP
    164.             #pragma shader_feature ___ _DETAIL_MULX2
    165.             #pragma shader_feature _PARALLAXMAP
    166.  
    167.             #pragma multi_compile ___ UNITY_HDR_ON
    168.             #pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
    169.             #pragma multi_compile DIRLIGHTMAP_OFF DIRLIGHTMAP_COMBINED DIRLIGHTMAP_SEPARATE
    170.             #pragma multi_compile DYNAMICLIGHTMAP_OFF DYNAMICLIGHTMAP_ON
    171.        
    172.             #pragma vertex vertDeferred
    173.             #pragma fragment fragDeferred
    174.  
    175.             #include "UnityStandardCore.cginc"
    176.  
    177.             ENDCG
    178.         }
    179.  
    180.         // ------------------------------------------------------------------
    181.         // Extracts information for lightmapping, GI (emission, albedo, ...)
    182.         // This pass it not used during regular rendering.
    183.         Pass
    184.         {
    185.             Name "META"
    186.             Tags { "LightMode"="Meta" }
    187.  
    188.             Cull Off
    189.  
    190.             CGPROGRAM
    191.             #pragma vertex vert_meta
    192.             #pragma fragment frag_meta
    193.  
    194.             #pragma shader_feature _EMISSION
    195.             #pragma shader_feature _METALLICGLOSSMAP
    196.             #pragma shader_feature ___ _DETAIL_MULX2
    197.  
    198.             #include "UnityStandardMeta.cginc"
    199.             ENDCG
    200.         }
    201.     }
    202.  
    203.     SubShader
    204.     {
    205.         Tags { "RenderType"="Opaque" "PerformanceChecks"="False" }
    206.         LOD 150
    207.  
    208.         // ------------------------------------------------------------------
    209.         //  Base forward pass (directional light, emission, lightmaps, ...)
    210.         Pass
    211.         {
    212.             Name "FORWARD"
    213.             Tags { "LightMode" = "ForwardBase" }
    214.  
    215.             Blend [_SrcBlend] [_DstBlend]
    216.             ZWrite [_ZWrite]
    217.  
    218.             CGPROGRAM
    219.             #pragma target 2.0
    220.        
    221.             #pragma shader_feature _NORMALMAP
    222.             #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
    223.             #pragma shader_feature _EMISSION
    224.             #pragma shader_feature _METALLICGLOSSMAP
    225.             #pragma shader_feature ___ _DETAIL_MULX2
    226.             // SM2.0: NOT SUPPORTED shader_feature _PARALLAXMAP
    227.  
    228.             #pragma skip_variants SHADOWS_SOFT DIRLIGHTMAP_COMBINED DIRLIGHTMAP_SEPARATE
    229.  
    230.             #pragma multi_compile_fwdbase
    231.             #pragma multi_compile_fog
    232.  
    233.             #pragma vertex vertBase
    234.             #pragma fragment fragBase
    235.             #include "UnityStandardCoreForward.cginc"
    236.  
    237.             ENDCG
    238.         }
    239.         // ------------------------------------------------------------------
    240.         //  Additive forward pass (one light per pass)
    241.         Pass
    242.         {
    243.             Name "FORWARD_DELTA"
    244.             Tags { "LightMode" = "ForwardAdd" }
    245.             Blend [_SrcBlend] One
    246.             Fog { Color (0,0,0,0) } // in additive pass fog should be black
    247.             ZWrite Off
    248.             ZTest LEqual
    249.        
    250.             CGPROGRAM
    251.             #pragma target 2.0
    252.  
    253.             #pragma shader_feature _NORMALMAP
    254.             #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
    255.             #pragma shader_feature _METALLICGLOSSMAP
    256.             #pragma shader_feature ___ _DETAIL_MULX2
    257.             // SM2.0: NOT SUPPORTED shader_feature _PARALLAXMAP
    258.             #pragma skip_variants SHADOWS_SOFT
    259.        
    260.             #pragma multi_compile_fwdadd_fullshadows
    261.             #pragma multi_compile_fog
    262.        
    263.             #pragma vertex vertAdd
    264.             #pragma fragment fragAdd
    265.             #include "UnityStandardCoreForward.cginc"
    266.  
    267.             ENDCG
    268.         }
    269.         // ------------------------------------------------------------------
    270.         //  Shadow rendering pass
    271.         Pass {
    272.             Name "ShadowCaster"
    273.             Tags { "LightMode" = "ShadowCaster" }
    274.        
    275.             ZWrite On ZTest LEqual
    276.  
    277.             CGPROGRAM
    278.             #pragma target 2.0
    279.  
    280.             #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
    281.             #pragma skip_variants SHADOWS_SOFT
    282.             #pragma multi_compile_shadowcaster
    283.  
    284.             #pragma vertex vertShadowCaster
    285.             #pragma fragment fragShadowCaster
    286.  
    287.             #include "UnityStandardShadow.cginc"
    288.  
    289.             ENDCG
    290.         }
    291.  
    292.         // ------------------------------------------------------------------
    293.         // Extracts information for lightmapping, GI (emission, albedo, ...)
    294.         // This pass it not used during regular rendering.
    295.         Pass
    296.         {
    297.             Name "META"
    298.             Tags { "LightMode"="Meta" }
    299.  
    300.             Cull Off
    301.  
    302.             CGPROGRAM
    303.             #pragma vertex vert_meta
    304.             #pragma fragment frag_meta
    305.  
    306.             #pragma shader_feature _EMISSION
    307.             #pragma shader_feature _METALLICGLOSSMAP
    308.             #pragma shader_feature ___ _DETAIL_MULX2
    309.  
    310.             #include "UnityStandardMeta.cginc"
    311.             ENDCG
    312.         }
    313.     }
    314.  
    315.  
    316.     FallBack "VertexLit"
    317.     CustomEditor "StandardShaderGUI"
    318. }
    319.  

    Here is JMO's TextureAdd Bumped shader's code.
    Code (csharp):
    1. // MatCap Shader, (c) 2015 Jean Moreno
    2.  
    3. Shader "MatCap/Bumped/Textured Add"
    4. {
    5.     Properties
    6.     {
    7.         _MainTex ("Base (RGB)", 2D) = "white" {}
    8.         _BumpMap ("Normal Map", 2D) = "bump" {}
    9.         _MatCap ("MatCap (RGB)", 2D) = "white" {}
    10.         [Toggle(MATCAP_ACCURATE)] _MatCapAccurate ("Accurate Calculation", Int) = 0
    11.     }
    12.  
    13.     Subshader
    14.     {
    15.         Tags { "RenderType"="Opaque" }
    16.    
    17.         Pass
    18.         {
    19.             Tags { "LightMode" = "Always" }
    20.        
    21.             CGPROGRAM
    22.                 #pragma vertex vert
    23.                 #pragma fragment frag
    24.                 #pragma fragmentoption ARB_precision_hint_fastest
    25.                 #pragma shader_feature MATCAP_ACCURATE
    26.                 #include "UnityCG.cginc"
    27.            
    28.                 struct v2f
    29.                 {
    30.                     float4 pos    : SV_POSITION;
    31.                     float2 uv     : TEXCOORD0;
    32.                     float2 uv_bump : TEXCOORD1;
    33.                
    34.             #if MATCAP_ACCURATE
    35.                     fixed3 tSpace0 : TEXCOORD2;
    36.                     fixed3 tSpace1 : TEXCOORD3;
    37.                     fixed3 tSpace2 : TEXCOORD4;
    38.             #else
    39.                     float3 c0 : TEXCOORD2;
    40.                     float3 c1 : TEXCOORD3;
    41.             #endif
    42.                 };
    43.            
    44.                 uniform float4 _MainTex_ST;
    45.                 uniform float4 _BumpMap_ST;
    46.            
    47.                 v2f vert (appdata_tan v)
    48.                 {
    49.                     v2f o;
    50.                     o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    51.                     o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
    52.                     o.uv_bump = TRANSFORM_TEX(v.texcoord,_BumpMap);
    53.                
    54.             #if MATCAP_ACCURATE
    55.                     //Accurate bump calculation: calculate tangent space matrix and pass it to fragment shader
    56.                     fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
    57.                     fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
    58.                     fixed3 worldBinormal = cross(worldNormal, worldTangent) * v.tangent.w;
    59.                     o.tSpace0 = fixed3(worldTangent.x, worldBinormal.x, worldNormal.x);
    60.                     o.tSpace1 = fixed3(worldTangent.y, worldBinormal.y, worldNormal.y);
    61.                     o.tSpace2 = fixed3(worldTangent.z, worldBinormal.z, worldNormal.z);
    62.             #else
    63.                     //Faster but less accurate method (especially on non-uniform scaling)
    64.                     v.normal = normalize(v.normal);
    65.                     v.tangent = normalize(v.tangent);
    66.                     TANGENT_SPACE_ROTATION;
    67.                     o.c0 = mul(rotation, normalize(UNITY_MATRIX_IT_MV[0].xyz));
    68.                     o.c1 = mul(rotation, normalize(UNITY_MATRIX_IT_MV[1].xyz));
    69.             #endif        
    70.                     return o;
    71.                 }
    72.            
    73.                 uniform sampler2D _MainTex;
    74.                 uniform sampler2D _BumpMap;
    75.                 uniform sampler2D _MatCap;
    76.            
    77.                 fixed4 frag (v2f i) : COLOR
    78.                 {
    79.                     fixed4 tex = tex2D(_MainTex, i.uv);
    80.                     fixed3 normals = UnpackNormal(tex2D(_BumpMap, i.uv_bump));
    81.                
    82.             #if MATCAP_ACCURATE
    83.                     //Rotate normals from tangent space to world space
    84.                     float3 worldNorm;
    85.                     worldNorm.x = dot(i.tSpace0.xyz, normals);
    86.                     worldNorm.y = dot(i.tSpace1.xyz, normals);
    87.                     worldNorm.z = dot(i.tSpace2.xyz, normals);
    88.                     worldNorm = mul((float3x3)UNITY_MATRIX_V, worldNorm);
    89.                     float4 mc = tex2D(_MatCap, worldNorm.xy * 0.5 + 0.5);
    90.             #else
    91.                     half2 capCoord = half2(dot(i.c0, normals), dot(i.c1, normals));
    92.                     float4 mc = tex2D(_MatCap, capCoord*0.5+0.5);
    93.             #endif
    94.                
    95.                     return (tex + (mc*2.0)-1.0);
    96.                 }
    97.             ENDCG
    98.         }
    99.     }
    100.  
    101.     Fallback "VertexLit"
    102. }

    Lastly here's my attempt to merge the two. What exactly am I doing wrong here?
    Code (csharp):
    1.  
    2. Shader "MyStandard"
    3. {
    4.    Properties
    5.    {
    6.      _Color("Color", Color) = (1,1,1,1)
    7.      _MainTex("Albedo", 2D) = "white" {}
    8.  
    9.      _Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
    10.  
    11.      _Glossiness("Smoothness", Range(0.0, 1.0)) = 0.5
    12.      [Gamma] _Metallic("Metallic", Range(0.0, 1.0)) = 0.0
    13.      _MetallicGlossMap("Metallic", 2D) = "white" {}
    14.  
    15.      _BumpScale("Scale", Float) = 1.0
    16.      _BumpMap("Normal Map", 2D) = "bump" {}
    17.  
    18.      _MatCap ("MatCap (RGB)", 2D) = "white" {}
    19.      [Toggle(MATCAP_ACCURATE)] _MatCapAccurate ("Accurate Calculation", Int) = 0
    20.  
    21.      _Parallax ("Height Scale", Range (0.005, 0.08)) = 0.02
    22.      _ParallaxMap ("Height Map", 2D) = "black" {}
    23.  
    24.      _OcclusionStrength("Strength", Range(0.0, 1.0)) = 1.0
    25.      _OcclusionMap("Occlusion", 2D) = "white" {}
    26.  
    27.      _EmissionColor("Color", Color) = (0,0,0)
    28.      _EmissionMap("Emission", 2D) = "white" {}
    29.  
    30.      _DetailMask("Detail Mask", 2D) = "white" {}
    31.  
    32.      _DetailAlbedoMap("Detail Albedo x2", 2D) = "grey" {}
    33.      _DetailNormalMapScale("Scale", Float) = 1.0
    34.      _DetailNormalMap("Normal Map", 2D) = "bump" {}
    35.  
    36.      [Enum(UV0,0,UV1,1)] _UVSec ("UV Set for secondary textures", Float) = 0
    37.  
    38.  
    39.      // Blending state
    40.      [HideInInspector] _Mode ("__mode", Float) = 0.0
    41.      [HideInInspector] _SrcBlend ("__src", Float) = 1.0
    42.      [HideInInspector] _DstBlend ("__dst", Float) = 0.0
    43.      [HideInInspector] _ZWrite ("__zw", Float) = 1.0
    44.    }
    45.  
    46.    CGINCLUDE
    47.      #define UNITY_SETUP_BRDF_INPUT MetallicSetup
    48.    ENDCG
    49.  
    50.    SubShader
    51.    {
    52.      Tags { "RenderType"="Opaque" "PerformanceChecks"="False" }
    53.      LOD 300
    54.  
    55.      Pass
    56.      {
    57.        Tags { "LightMode" = "Always" }
    58.    
    59.        CGPROGRAM
    60.          #pragma vertex vert
    61.          #pragma fragment frag
    62.          #pragma fragmentoption ARB_precision_hint_fastest
    63.          #pragma shader_feature MATCAP_ACCURATE
    64.          #include "UnityCG.cginc"
    65.      
    66.          struct v2f
    67.          {
    68.            float4 pos   : SV_POSITION;
    69.            float2 uv    : TEXCOORD0;
    70.            float2 uv_bump : TEXCOORD1;
    71.        
    72.        #if MATCAP_ACCURATE
    73.            fixed3 tSpace0 : TEXCOORD2;
    74.            fixed3 tSpace1 : TEXCOORD3;
    75.            fixed3 tSpace2 : TEXCOORD4;
    76.        #else
    77.            float3 c0 : TEXCOORD2;
    78.            float3 c1 : TEXCOORD3;
    79.        #endif
    80.          };
    81.      
    82.          uniform float4 _MainTex_ST;
    83.          uniform float4 _BumpMap_ST;
    84.      
    85.          v2f vert (appdata_tan v)
    86.          {
    87.            v2f o;
    88.            o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    89.            o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
    90.            o.uv_bump = TRANSFORM_TEX(v.texcoord,_BumpMap);
    91.        
    92.        #if MATCAP_ACCURATE
    93.            //Accurate bump calculation: calculate tangent space matrix and pass it to fragment shader
    94.            fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
    95.            fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
    96.            fixed3 worldBinormal = cross(worldNormal, worldTangent) * v.tangent.w;
    97.            o.tSpace0 = fixed3(worldTangent.x, worldBinormal.x, worldNormal.x);
    98.            o.tSpace1 = fixed3(worldTangent.y, worldBinormal.y, worldNormal.y);
    99.            o.tSpace2 = fixed3(worldTangent.z, worldBinormal.z, worldNormal.z);
    100.        #else
    101.            //Faster but less accurate method (especially on non-uniform scaling)
    102.            v.normal = normalize(v.normal);
    103.            v.tangent = normalize(v.tangent);
    104.            TANGENT_SPACE_ROTATION;
    105.            o.c0 = mul(rotation, normalize(UNITY_MATRIX_IT_MV[0].xyz));
    106.            o.c1 = mul(rotation, normalize(UNITY_MATRIX_IT_MV[1].xyz));
    107.        #endif    
    108.            return o;
    109.          }
    110.      
    111.          uniform sampler2D _MainTex;
    112.          uniform sampler2D _BumpMap;
    113.          uniform sampler2D _MatCap;
    114.      
    115.          fixed4 frag (v2f i) : COLOR
    116.          {
    117.            fixed4 tex = tex2D(_MainTex, i.uv);
    118.            fixed3 normals = UnpackNormal(tex2D(_BumpMap, i.uv_bump));
    119.        
    120.        #if MATCAP_ACCURATE
    121.            //Rotate normals from tangent space to world space
    122.            float3 worldNorm;
    123.            worldNorm.x = dot(i.tSpace0.xyz, normals);
    124.            worldNorm.y = dot(i.tSpace1.xyz, normals);
    125.            worldNorm.z = dot(i.tSpace2.xyz, normals);
    126.            worldNorm = mul((float3x3)UNITY_MATRIX_V, worldNorm);
    127.            float4 mc = tex2D(_MatCap, worldNorm.xy * 0.5 + 0.5);
    128.        #else
    129.            half2 capCoord = half2(dot(i.c0, normals), dot(i.c1, normals));
    130.            float4 mc = tex2D(_MatCap, capCoord*0.5+0.5);
    131.        #endif
    132.        
    133.            return (tex + (mc*2.0)-1.0);
    134.          }
    135.        ENDCG
    136.      }
    137.  
    138.      // ------------------------------------------------------------------
    139.      //  Base forward pass (directional light, emission, lightmaps, ...)
    140.      Pass
    141.      {
    142.        Name "FORWARD"
    143.        Tags { "LightMode" = "ForwardBase" }
    144.  
    145.        Blend [_SrcBlend] [_DstBlend]
    146.        ZWrite [_ZWrite]
    147.  
    148.        CGPROGRAM
    149.        #pragma target 3.0
    150.        // TEMPORARY: GLES2.0 temporarily disabled to prevent errors spam on devices without textureCubeLodEXT
    151.        #pragma exclude_renderers gles
    152.    
    153.        // -------------------------------------
    154.        
    155.        #pragma shader_feature _NORMALMAP
    156.        #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
    157.        #pragma shader_feature _EMISSION
    158.        #pragma shader_feature _METALLICGLOSSMAP
    159.        #pragma shader_feature ___ _DETAIL_MULX2
    160.        #pragma shader_feature _PARALLAXMAP
    161.    
    162.        #pragma multi_compile_fwdbase
    163.        #pragma multi_compile_fog
    164.  
    165.        #pragma vertex vertBase
    166.        #pragma fragment fragBase
    167.        #include "UnityStandardCoreForward.cginc"
    168.  
    169.        ENDCG
    170.      }
    171.      // ------------------------------------------------------------------
    172.      //  Additive forward pass (one light per pass)
    173.      Pass
    174.      {
    175.        Name "FORWARD_DELTA"
    176.        Tags { "LightMode" = "ForwardAdd" }
    177.        Blend [_SrcBlend] One
    178.        Fog { Color (0,0,0,0) } // in additive pass fog should be black
    179.        ZWrite Off
    180.        ZTest LEqual
    181.  
    182.        CGPROGRAM
    183.        #pragma target 3.0
    184.        // GLES2.0 temporarily disabled to prevent errors spam on devices without textureCubeLodEXT
    185.        #pragma exclude_renderers gles
    186.  
    187.        // -------------------------------------
    188.  
    189.    
    190.        #pragma shader_feature _NORMALMAP
    191.        #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
    192.        #pragma shader_feature _METALLICGLOSSMAP
    193.        #pragma shader_feature ___ _DETAIL_MULX2
    194.        #pragma shader_feature _PARALLAXMAP
    195.    
    196.        #pragma multi_compile_fwdadd_fullshadows
    197.        #pragma multi_compile_fog
    198.  
    199.        #pragma vertex vertAdd
    200.        #pragma fragment fragAdd
    201.        #include "UnityStandardCoreForward.cginc"
    202.  
    203.        ENDCG
    204.      }
    205.      // ------------------------------------------------------------------
    206.      //  Shadow rendering pass
    207.      Pass {
    208.        Name "ShadowCaster"
    209.        Tags { "LightMode" = "ShadowCaster" }
    210.    
    211.        ZWrite On ZTest LEqual
    212.  
    213.        CGPROGRAM
    214.        #pragma target 3.0
    215.        // TEMPORARY: GLES2.0 temporarily disabled to prevent errors spam on devices without textureCubeLodEXT
    216.        #pragma exclude_renderers gles
    217.    
    218.        // -------------------------------------
    219.  
    220.  
    221.        #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
    222.        #pragma multi_compile_shadowcaster
    223.  
    224.        #pragma vertex vertShadowCaster
    225.        #pragma fragment fragShadowCaster
    226.  
    227.        #include "UnityStandardShadow.cginc"
    228.  
    229.        ENDCG
    230.      }
    231.      // ------------------------------------------------------------------
    232.      //  Deferred pass
    233.      Pass
    234.      {
    235.        Name "DEFERRED"
    236.        Tags { "LightMode" = "Deferred" }
    237.  
    238.        CGPROGRAM
    239.        #pragma target 3.0
    240.        // TEMPORARY: GLES2.0 temporarily disabled to prevent errors spam on devices without textureCubeLodEXT
    241.        #pragma exclude_renderers nomrt gles
    242.    
    243.  
    244.        // -------------------------------------
    245.  
    246.        #pragma shader_feature _NORMALMAP
    247.        #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
    248.        #pragma shader_feature _EMISSION
    249.        #pragma shader_feature _METALLICGLOSSMAP
    250.        #pragma shader_feature ___ _DETAIL_MULX2
    251.        #pragma shader_feature _PARALLAXMAP
    252.  
    253.        #pragma multi_compile ___ UNITY_HDR_ON
    254.        #pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
    255.        #pragma multi_compile DIRLIGHTMAP_OFF DIRLIGHTMAP_COMBINED DIRLIGHTMAP_SEPARATE
    256.        #pragma multi_compile DYNAMICLIGHTMAP_OFF DYNAMICLIGHTMAP_ON
    257.    
    258.        #pragma vertex vertDeferred
    259.        #pragma fragment fragDeferred
    260.  
    261.        #include "UnityStandardCore.cginc"
    262.  
    263.        ENDCG
    264.      }
    265.  
    266.      // ------------------------------------------------------------------
    267.      // Extracts information for lightmapping, GI (emission, albedo, ...)
    268.      // This pass it not used during regular rendering.
    269.      Pass
    270.      {
    271.        Name "META"
    272.        Tags { "LightMode"="Meta" }
    273.  
    274.        Cull Off
    275.  
    276.        CGPROGRAM
    277.        #pragma vertex vert_meta
    278.        #pragma fragment frag_meta
    279.  
    280.        #pragma shader_feature _EMISSION
    281.        #pragma shader_feature _METALLICGLOSSMAP
    282.        #pragma shader_feature ___ _DETAIL_MULX2
    283.  
    284.        #include "UnityStandardMeta.cginc"
    285.        ENDCG
    286.      }
    287.    }
    288.  
    289.    SubShader
    290.    {
    291.      Tags { "RenderType"="Opaque" "PerformanceChecks"="False" }
    292.      LOD 150
    293.  
    294.      // ------------------------------------------------------------------
    295.      //  Base forward pass (directional light, emission, lightmaps, ...)
    296.      Pass
    297.      {
    298.        Name "FORWARD"
    299.        Tags { "LightMode" = "ForwardBase" }
    300.  
    301.        Blend [_SrcBlend] [_DstBlend]
    302.        ZWrite [_ZWrite]
    303.  
    304.        CGPROGRAM
    305.        #pragma target 2.0
    306.    
    307.        #pragma shader_feature _NORMALMAP
    308.        #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
    309.        #pragma shader_feature _EMISSION
    310.        #pragma shader_feature _METALLICGLOSSMAP
    311.        #pragma shader_feature ___ _DETAIL_MULX2
    312.        // SM2.0: NOT SUPPORTED shader_feature _PARALLAXMAP
    313.  
    314.        #pragma skip_variants SHADOWS_SOFT DIRLIGHTMAP_COMBINED DIRLIGHTMAP_SEPARATE
    315.  
    316.        #pragma multi_compile_fwdbase
    317.        #pragma multi_compile_fog
    318.  
    319.        #pragma vertex vertBase
    320.        #pragma fragment fragBase
    321.        #include "UnityStandardCoreForward.cginc"
    322.  
    323.        ENDCG
    324.      }
    325.      // ------------------------------------------------------------------
    326.      //  Additive forward pass (one light per pass)
    327.      Pass
    328.      {
    329.        Name "FORWARD_DELTA"
    330.        Tags { "LightMode" = "ForwardAdd" }
    331.        Blend [_SrcBlend] One
    332.        Fog { Color (0,0,0,0) } // in additive pass fog should be black
    333.        ZWrite Off
    334.        ZTest LEqual
    335.    
    336.        CGPROGRAM
    337.        #pragma target 2.0
    338.  
    339.        #pragma shader_feature _NORMALMAP
    340.        #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
    341.        #pragma shader_feature _METALLICGLOSSMAP
    342.        #pragma shader_feature ___ _DETAIL_MULX2
    343.        // SM2.0: NOT SUPPORTED shader_feature _PARALLAXMAP
    344.        #pragma skip_variants SHADOWS_SOFT
    345.    
    346.        #pragma multi_compile_fwdadd_fullshadows
    347.        #pragma multi_compile_fog
    348.    
    349.        #pragma vertex vertAdd
    350.        #pragma fragment fragAdd
    351.        #include "UnityStandardCoreForward.cginc"
    352.  
    353.        ENDCG
    354.      }
    355.      // ------------------------------------------------------------------
    356.      //  Shadow rendering pass
    357.      Pass {
    358.        Name "ShadowCaster"
    359.        Tags { "LightMode" = "ShadowCaster" }
    360.    
    361.        ZWrite On ZTest LEqual
    362.  
    363.        CGPROGRAM
    364.        #pragma target 2.0
    365.  
    366.        #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
    367.        #pragma skip_variants SHADOWS_SOFT
    368.        #pragma multi_compile_shadowcaster
    369.  
    370.        #pragma vertex vertShadowCaster
    371.        #pragma fragment fragShadowCaster
    372.  
    373.        #include "UnityStandardShadow.cginc"
    374.  
    375.        ENDCG
    376.      }
    377.  
    378.      // ------------------------------------------------------------------
    379.      // Extracts information for lightmapping, GI (emission, albedo, ...)
    380.      // This pass it not used during regular rendering.
    381.      Pass
    382.      {
    383.        Name "META"
    384.        Tags { "LightMode"="Meta" }
    385.  
    386.        Cull Off
    387.  
    388.        CGPROGRAM
    389.        #pragma vertex vert_meta
    390.        #pragma fragment frag_meta
    391.  
    392.        #pragma shader_feature _EMISSION
    393.        #pragma shader_feature _METALLICGLOSSMAP
    394.        #pragma shader_feature ___ _DETAIL_MULX2
    395.  
    396.        #include "UnityStandardMeta.cginc"
    397.        ENDCG
    398.      }
    399.    }
    400.  
    401.  
    402.    FallBack "VertexLit"
    403. }
    404.  
     
  2. Namey5

    Namey5

    Joined:
    Jul 5, 2013
    Posts:
    188
    Well, adding the first shader as a new pass at the beginning will just draw underneath the rest of the passes. I'm not entirely sure what you are trying to accomplish though, seeing as JMO's shaders are supposed to 'fake' lighting using a LUT, whilst the standard shader actually calculates lighting.
     
  3. kenaochreous

    kenaochreous

    Joined:
    Sep 7, 2012
    Posts:
    395
    Well my goal was to use Unity 3d's Edge Detection image effect in conjunction with JMO's TextureAdd Bumped shader. However when I tried to do that the Edge Detection image effect didn't detect the shader properly and I could only get it to properly detect Unity 3d's standard shader. So the idea was to merge both JMO's TextureAdd Bumped shader and Unity 3d's standard shader into one shader in order to get the edge detection to detect the shader properly.

    Now that I'm thinking about it I'm not sure if merging those two shaders would achieve the effect I want. I'm looking to create a Cartoony shader with proper edge detection. Do you have any suggestions for what I could do?
     
  4. Namey5

    Namey5

    Joined:
    Jul 5, 2013
    Posts:
    188
    They seem to work just fine for me, in both forward and deferred.

    Just keep in mind that edge detection uses the depth texture, and so objects that are moderately close together will not have an outline. You could redraw the object as black slightly larger with inverted faces for per object outline, but this has its own artifacts. Not knowing the style you are going for, I can't help too much.
     
  5. kenaochreous

    kenaochreous

    Joined:
    Sep 7, 2012
    Posts:
    395
    Alright here are some screenshots to illustrate the style that I'm trying to achieve. Also if you need to recreate my scene make sure to set the rendering path of your camera to Deferred.

    So here is a screenshot of a model using Unity's Standard shader and Edge Detection script. For the Edge Detection script I've set mode to Roberts Cross Depth Normals and cranked the Normals Sensitivity to 1.25
    Ethan with Standard Shader.png

    Now here is the same model except I've swapped out Unity's standard shader for JMO's Matcap_TextureAdd_Bumped Shader.
    Ethan with Matcap_TextureAdd_Bumped Shader.png

    As you can see most of the edges are no longer being detected. I want to create a shader that uses JMO's Matcap_TextureAdd_Bumped Shader and has proper edge detection. Something like this.
    Ethan with Standard Shader + Matcap_TextureAdd_Bumped Shader.png

    Do you know how could I accomplish this effect? I apologize if I was not being clear earlier.
     
    Last edited: Jul 2, 2016
  6. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    It is much more difficult to do what you want using deferred with that shader. It however will "just work" if you use forward.

    Unless you're planning on using the standard shader for most things there's no reason to use deferred as the deferred rendering path only works with materials using the standard shading model. everything else either had to be approximated (which unity does with many of the legacy shaders when in deferred).

    And, like you're seeing with this shader, done stuff gets broken when you use deferred. This is 100% a Unity issue they haven't bothered to fix.
     
  7. kenaochreous

    kenaochreous

    Joined:
    Sep 7, 2012
    Posts:
    395
    It doesn't seem any different from when I set my rendering path to deferred. Is there something wrong with my camera's settings?
    Ethan with Matcap_TextureAdd_Bumped Shader + Rendering Path Forward .png
     
  8. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Ah, so this is a difference between deferred and forward I had not realized existed.

    Some image effects use scene normals and some do not. Many of the edge detection options do not use the normals for instance, but the robert's cross you want to use does. These scene normals come from a texture Unity generates called the camera depth normal texture because it combines both the scene normals and the depth into a single texture for optimization purposes.

    In the deferred rendering path the image effects that use the scene normals use a copy of the deferred normals gbuffer which includes the normal map as part of the normals. It makes a copy since the gbuffer normals are in world space and the camera depth normal texture is expected to be in view space.

    However for the forward rendering path the camera depth normal texture gets rendered using replacement shaders. Basically the camera view is re-rendered with a different shader on everything in the scene. The built in replacement shader for generating the camera depth normals texture does not take into account the normal map!

    There's some good reasons as to why this would be setup like this ... mainly because replacement shaders end up not really working very well in more complex setups and Unity has been moving away from using them for new features with 5.0, but it does look like the only way to get the effect you're looking for is to do this using the deferred path, or using a custom replacement shader pass and modified image effect.

    So, here's that shader modified to work with deferred.

    Code (CSharp):
    1. // MatCap Shader, (c) 2015 Jean Moreno
    2. Shader "MatCap/Bumped/Textured Add Deferred Capable"
    3. {
    4.     Properties
    5.     {
    6.         _MainTex ("Base (RGB)", 2D) = "white" {}
    7.         _BumpMap ("Normal Map", 2D) = "bump" {}
    8.         _MatCap ("MatCap (RGB)", 2D) = "white" {}
    9.     }
    10.     Subshader
    11.     {
    12.         Tags { "RenderType"="Opaque" }
    13.  
    14.         Pass
    15.         {
    16.             Tags { "LightMode" = "ForwardBase" }
    17.      
    18.             CGPROGRAM
    19.                 #pragma vertex vert
    20.                 #pragma fragment frag
    21.                 #pragma fragmentoption ARB_precision_hint_fastest
    22.                 #include "UnityCG.cginc"
    23.          
    24.                 struct v2f
    25.                 {
    26.                     float4 pos    : SV_POSITION;
    27.                     float2 uv     : TEXCOORD0;
    28.                     float2 uv_bump : TEXCOORD1;
    29.              
    30.                     fixed3 tSpace0 : TEXCOORD2;
    31.                     fixed3 tSpace1 : TEXCOORD3;
    32.                     fixed3 tSpace2 : TEXCOORD4;
    33.                 };
    34.          
    35.                 uniform float4 _MainTex_ST;
    36.                 uniform float4 _BumpMap_ST;
    37.          
    38.                 v2f vert (appdata_tan v)
    39.                 {
    40.                     v2f o;
    41.                     o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    42.                     o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
    43.                     o.uv_bump = TRANSFORM_TEX(v.texcoord,_BumpMap);
    44.              
    45.                     //Accurate bump calculation: calculate tangent space matrix and pass it to fragment shader
    46.                     fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
    47.                     fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
    48.                     fixed3 worldBinormal = cross(worldNormal, worldTangent) * v.tangent.w;
    49.                     o.tSpace0 = fixed3(worldTangent.x, worldBinormal.x, worldNormal.x);
    50.                     o.tSpace1 = fixed3(worldTangent.y, worldBinormal.y, worldNormal.y);
    51.                     o.tSpace2 = fixed3(worldTangent.z, worldBinormal.z, worldNormal.z);
    52.                     return o;
    53.                 }
    54.          
    55.                 uniform sampler2D _MainTex;
    56.                 uniform sampler2D _BumpMap;
    57.                 uniform sampler2D _MatCap;
    58.          
    59.                 fixed4 frag (v2f i) : COLOR
    60.                 {
    61.                     fixed4 tex = tex2D(_MainTex, i.uv);
    62.                     fixed3 normals = UnpackNormal(tex2D(_BumpMap, i.uv_bump));
    63.              
    64.                     //Rotate normals from tangent space to world space
    65.                     float3 worldNorm;
    66.                     worldNorm.x = dot(i.tSpace0.xyz, normals);
    67.                     worldNorm.y = dot(i.tSpace1.xyz, normals);
    68.                     worldNorm.z = dot(i.tSpace2.xyz, normals);
    69.                     worldNorm = mul((float3x3)UNITY_MATRIX_V, worldNorm);
    70.                     float4 mc = tex2D(_MatCap, worldNorm.xy * 0.5 + 0.5);
    71.              
    72.                     return (tex + (mc*2.0)-1.0);
    73.                 }
    74.             ENDCG
    75.         }
    76.  
    77.         Pass
    78.         {
    79.             Tags { "LightMode" = "Deferred" }
    80.      
    81.             CGPROGRAM
    82.                 #pragma vertex vert
    83.                 #pragma fragment frag
    84.                 #pragma fragmentoption ARB_precision_hint_fastest
    85.                 #include "UnityCG.cginc"
    86.                 #pragma multi_compile _ UNITY_HDR_ON
    87.          
    88.                 struct v2f
    89.                 {
    90.                     float4 pos    : SV_POSITION;
    91.                     float2 uv     : TEXCOORD0;
    92.                     float2 uv_bump : TEXCOORD1;
    93.              
    94.                     fixed3 tSpace0 : TEXCOORD2;
    95.                     fixed3 tSpace1 : TEXCOORD3;
    96.                     fixed3 tSpace2 : TEXCOORD4;
    97.                 };
    98.          
    99.                 uniform float4 _MainTex_ST;
    100.                 uniform float4 _BumpMap_ST;
    101.          
    102.                 v2f vert (appdata_tan v)
    103.                 {
    104.                     v2f o;
    105.                     o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    106.                     o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
    107.                     o.uv_bump = TRANSFORM_TEX(v.texcoord,_BumpMap);
    108.              
    109.                     //Accurate bump calculation: calculate tangent space matrix and pass it to fragment shader
    110.                     fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
    111.                     fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
    112.                     fixed3 worldBinormal = cross(worldNormal, worldTangent) * v.tangent.w;
    113.                     o.tSpace0 = fixed3(worldTangent.x, worldBinormal.x, worldNormal.x);
    114.                     o.tSpace1 = fixed3(worldTangent.y, worldBinormal.y, worldNormal.y);
    115.                     o.tSpace2 = fixed3(worldTangent.z, worldBinormal.z, worldNormal.z);
    116.  
    117.                     return o;
    118.                 }
    119.          
    120.                 uniform sampler2D _MainTex;
    121.                 uniform sampler2D _BumpMap;
    122.                 uniform sampler2D _MatCap;
    123.          
    124.                 void frag (v2f i,
    125.                     out half4 outDiffuse : SV_Target0,          // RT0: diffuse color (rgb), occlusion (a)
    126.                     out half4 outSpecSmoothness : SV_Target1,   // RT1: spec color (rgb), smoothness (a)
    127.                     out half4 outNormal : SV_Target2,           // RT2: normal (rgb), --unused, very low precision-- (a)
    128.                     out half4 outEmission : SV_Target3          // RT3: emission (rgb), --unused-- (a)) : COLOR
    129.                     )
    130.                 {
    131.                     fixed4 tex = tex2D(_MainTex, i.uv);
    132.                     fixed3 normals = UnpackNormal(tex2D(_BumpMap, i.uv_bump));
    133.  
    134.                     //Rotate normals from tangent space to world space
    135.                     float3 worldNorm;
    136.                     worldNorm.x = dot(i.tSpace0.xyz, normals);
    137.                     worldNorm.y = dot(i.tSpace1.xyz, normals);
    138.                     worldNorm.z = dot(i.tSpace2.xyz, normals);
    139.              
    140.                     float3 viewNorm = mul((float3x3)UNITY_MATRIX_V, worldNorm);
    141.                     float4 mc = tex2D(_MatCap, viewNorm.xy * 0.5 + 0.5);
    142.  
    143.                     half3 color = saturate(tex.rgb + (mc.rgb*2.0)-1.0);
    144.  
    145.                     #ifndef UNITY_HDR_ON
    146.                         color.rgb = exp2(-color.rgb);
    147.                     #endif
    148.  
    149.                     outDiffuse = half4(0.0, 0.0, 0.0, 1.0);
    150.                     outSpecSmoothness = half4(0.0, 0.0, 0.0, 0.0);
    151.                     outNormal = half4(worldNorm, 1.0);
    152.                     outEmission = half4(color, 1.0);
    153.                 }
    154.             ENDCG
    155.         }
    156.     }
    157.     Fallback "VertexLit"
    158. }
     
    Namey5 likes this.
  9. Namey5

    Namey5

    Joined:
    Jul 5, 2013
    Posts:
    188
    This is a useful note for me, as I am self taught and so not too aware as to how to write a fragment shader in Deferred. Cheers.