Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

HELP: Black Mesh from Surf Shader + ForwardBase Lighting

Discussion in 'Shaders' started by azyre, Feb 27, 2020.

  1. azyre

    azyre

    Joined:
    May 25, 2017
    Posts:
    4
    Using ForwardBase Lighting on a Surf shader generates these black meshes at the origin, without transform applied.
    Anyone have any ideas as to what causes this?
    Will post code if it helps.
    upload_2020-2-27_8-11-19.png
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,256
  3. azyre

    azyre

    Joined:
    May 25, 2017
    Posts:
    4
    upload_2020-2-29_17-48-5.png
    upload_2020-2-29_17-50-38.png
    The initial seemed to be solved by adding a Blend SrcAlpha OneMinusSrcAlpha but there seems to be an additional, similar issue of ghost objects.

    Shader Code here:
    It's supposed to be a lighting based shader that reads from textures, adjusting uvs based on light information.
    Much thanks for the help.

    Code (CSharp):
    1. Shader "Watercolour/Main"
    2. {
    3.     Properties {
    4.         _Color ("Tint Color 1", Color) = (1,1,1,1)
    5.         _Color2 ("Tint Color 2", Color) = (1,1,1,1)
    6.         _InkCol ("Ink Color", Color) = (1,1,1,1)
    7.      
    8.         _BlotchTex ("Blotches (RGB)", 2D) = "white" {}
    9.         _DetailTex ("Detail (RGB)", 2D) = "white" {}
    10.         _PaperTex ("Paper (RGB)", 2D) = "white" {}
    11.         _RampTex ("Ramp (RGB)", 2D) = "white" {}
    12.      
    13.         _TintScale ("Tint Scale", Range(2,8)) = 4
    14.         _PaperStrength ("Paper Strength", Range(0,1)) = 1
    15.         _BlotchMulti ("Blotch Multiply", Range(0,16)) = 4
    16.         _BlotchSub ("Blotch Subtract", Range(0,8)) = 2
    17.  
    18.         [PowerSlider(8)] _FresnelExponent ("Fresnel Exponent", Range(0, 4)) = 1
    19.     }
    20.     SubShader {
    21.         Tags { "RenderType"="Opaque" "LightMode"="ForwardBase"}
    22.         LOD 200
    23.  
    24.         Blend SrcAlpha OneMinusSrcAlpha
    25.  
    26.         CGPROGRAM
    27.         #pragma surface surf Standard fullforwardshadows vertex:vert
    28.         #pragma target 3.5
    29.         #pragma debug
    30.  
    31.         sampler2D _BlotchTex;
    32.         sampler2D _DetailTex;
    33.         sampler2D _PaperTex;
    34.         sampler2D _RampTex;
    35.         float4 _RampTex_TexelSize;
    36.         half _BlotchMulti;
    37.         half _BlotchSub;
    38.         half _TintScale;
    39.         half _PaperStrength;
    40.         fixed4 _Color;
    41.         fixed4 _Color2;
    42.         fixed4 _InkCol;
    43.         half _FresnelExponent;
    44.  
    45.         struct Input {
    46.             float2 uv_BlotchTex;
    47.             float2 uv_DetailTex;
    48.             float2 uv_PaperTex;
    49.             float2 uv_RampTex;
    50.             float3 worldNormal;
    51.             float3 viewDir;
    52.             float3 lightDir;
    53.             float lightAtten;
    54.         };
    55.  
    56.         UNITY_INSTANCING_BUFFER_START(Props)
    57.         // put more per-instance properties here
    58.         UNITY_INSTANCING_BUFFER_END(Props)
    59.  
    60.         void vert (inout appdata_base v, out Input o) {
    61.             UNITY_INITIALIZE_OUTPUT(Input, o);
    62.             float4 worldPos = mul(unity_ObjectToWorld, v.vertex);
    63.  
    64.             float3 lightDir = float3(0, 0, 0);
    65.             float lightAtten = 0;
    66.             int lights = 4;
    67.          
    68.             for(int i = 0; i < 4; i++) {
    69.                 float3 lightPos = float3(unity_4LightPosX0[i], unity_4LightPosY0[i], unity_4LightPosZ0[i]);
    70.                 if(lightPos[0] == 0 && lightPos[1] == 0 && lightPos[2] == 0) {
    71.                     lights--;
    72.                     continue;
    73.                 }
    74.                 lightDir += normalize(lightPos - worldPos);
    75.                 lightAtten += (1 - unity_4LightAtten0[i]) * length(unity_LightColor[0]);
    76.                 // lightAtten += length(unity_LightColor[0]);
    77.             }
    78.             o.lightDir = lightDir / lights;
    79.             o.lightAtten = lightAtten / lights;
    80.             // o.lightDir = normalize(lightDir);
    81.  
    82.             // bgolus god's light atten fix
    83.             // float range = (0.005 * sqrt(1000000 - unity_4LightAtten0[0]])) / sqrt(unity_4LightAtten0[0]]);
    84.             // float attenUV = distance(lightPos, worldPos) / range;
    85.             // float atten = saturate(1.0 / (1.0 + 25.0 * attenUV*attenUV) * saturate((1 - attenUV) * 5.0));
    86.             // float atten = tex2D(_LightTextureB0, (attenUV * attenUV).xx).UNITY_ATTEN_CHANNEL;
    87.         }
    88.  
    89.         fixed4 screen (fixed4 colA, fixed4 colB) {
    90.             fixed4 white = fixed4(1, 1, 1, 1);
    91.             return white - (white - colA) * (white - colB);
    92.         }
    93.  
    94.         fixed4 softlight (fixed4 colA, fixed4 colB) {
    95.             fixed4 white = fixed4(1, 1, 1, 1);
    96.             return (white - 2 * colB) * pow(colA, 2) + 2 * colB * colA;
    97.         }
    98.  
    99.         void surf (Input IN, inout SurfaceOutputStandard o) {
    100.             fixed c = tex2D (_BlotchTex, IN.uv_BlotchTex).r;
    101.             c *= _BlotchMulti;
    102.             c -= _BlotchSub;          
    103.             c *= tex2D (_DetailTex, IN.uv_DetailTex).r;          
    104.  
    105.             float f = dot(IN.worldNormal, IN.lightDir) * IN.lightAtten;
    106.             f = pow(f, _FresnelExponent);
    107.  
    108.             c = saturate(c * .3 + f);
    109.             c = tex2D (_RampTex, half2(1 - c, 0)).r;
    110.             c = saturate(c);
    111.  
    112.             fixed4 tint = tex2D (_BlotchTex, IN.uv_BlotchTex / _TintScale);  
    113.             tint = lerp(_Color, _Color2, tint.r);
    114.          
    115.             fixed4 ink = screen(_InkCol, fixed4(c, c, c, 1));
    116.  
    117.             o.Albedo = lerp(ink * tint, softlight(tex2D (_PaperTex, IN.uv_PaperTex), ink * tint), _PaperStrength);
    118.             // o.Albedo = IN.lightDir * IN.lightAtten;
    119.             // o.Albedo = dot(IN.worldNormal, IN.lightDir);
    120.         }
    121.         ENDCG
    122.     }
    123.     FallBack "Diffuse"
    124. }
    125.  
     
    Last edited: Mar 1, 2020
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,256
    Surface shaders are vertex fragment shader generators that generate multiple passes, one of which will be using
    “LightMode” = “ForwardBase”
    . If you set that tag on the
    SubShader
    it’ll override all of the individual passes and break the shader.

    Remove that line and the shader should work, or at least the black mesh should disappear. I’m not exactly sure what your intended goal is though.
     
  5. azyre

    azyre

    Joined:
    May 25, 2017
    Posts:
    4
    I realised early on that removing the ForwardBase Lighting tag would solve my issue but I can only access the lighting values I need such as unity_4LightAtten, unity_4LightPos0, etc. in the ForwardBase pass.

    Is there a way to access those values another way?
    or
    Is there a way to specify the vert shader to activate for that ForwardBase pass and then pass the data to the other passes?
     
  6. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,256
    Nope.

    If you want data that's accessible by all passes, you need to set it yourself from script as a material property or global uniform.

    Also, unless you specifically need support for additional per pixel lights and shadows, which if you're using per-vertex light data you're probably not, there's not really a need for any of the other passes. Change the
    fullforwardshadows
    (which enables shadows on the forward add passes) to
    noforwardadd
    so it doesn't even generate that pass to begin with.

    You probably also want to remove the
    Blend SrcAlpha OneMinusSrcAlpha
    as it's not currently doing anything really useful but making your shader more expensive to render.