1
\$\begingroup\$

I'm applying a "burning" dissolve shader to an object which uses the Standard shader already. Because I need the Standard shader for better lighting, etc, I looked into how to use them "both" or how to extend the standard shader.

According to the Unity docs I can define which lighting mode I want to use in the pragma so I used Standard. That must not work the way I thought, because I see none of the lighting I do when using the standard shader directly.

I'm using the burning dissolve shader from Harry Alisavakis

Shader "Custom/BurnDissolve" {
    Properties {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _SliceGuide("Slice Guide (RGB)", 2D) = "white" {}
        _SliceAmount("Slice Amount", Range(0.0, 1.0)) = 0

        _BurnSize("Burn Size", Range(0.0, 1.0)) = 0.15
        _BurnRamp("Burn Ramp (RGB)", 2D) = "white" {}
        _BurnColor("Burn Color", Color) = (1,1,1,1)

        _EmissionAmount("Emission amount", float) = 2.0
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200
        Cull Off
        CGPROGRAM
        #pragma surface surf Standard

        fixed4 _Color;
        sampler2D _MainTex;
        sampler2D _SliceGuide;
        sampler2D _BumpMap;
        sampler2D _BurnRamp;
        fixed4 _BurnColor;
        float _BurnSize;
        float _SliceAmount;
        float _EmissionAmount;

        struct Input {
            float2 uv_MainTex;
        };

        void surf (Input IN, inout SurfaceOutputStandard o) {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            half test = tex2D(_SliceGuide, IN.uv_MainTex).rgb - _SliceAmount;
            clip(test);

            if (test < _BurnSize && _SliceAmount > 0) {
                o.Emission = tex2D(_BurnRamp, float2(test * (1 / _BurnSize), 0)) * _BurnColor * _EmissionAmount;
            }

            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Standard"
}

I also tried adding this as another subshader to a copy of the Standard shader source, but I wasn't able to get it working there. If I put it before the others, it works as if it was alone, if I put it after, the standard shader works like if it was alone.

I'm still new to shaders so I'm sure I'm misunderstanding this. How can I get the dissolve shader to apply as well the standard shader, without hopefully having to manually rewrite stuff.

\$\endgroup\$
2
  • \$\begingroup\$ I think you actually want lightModel Standard not just Standard \$\endgroup\$ Dec 17 '17 at 1:41
  • 1
    \$\begingroup\$ Trying that, I get Shader error in 'Custom/BurnDissolve': Unexpected identifier "SurfaceOutputStandard". Expected one of: sampler sampler1D sampler2D sampler3D samplerCUBE sampler_state SamplerState SamplerComparisonState bool int uint half float double or a user-defined type at line 34 - because the Standard value changes the arguments passed to surf. With just Standard it properly recognizes SurfaceOutputStandard \$\endgroup\$
    – BotskoNet
    Dec 17 '17 at 1:47
2
+50
\$\begingroup\$

Here's a version of your shader where I've added normal mapping and pulled the smoothness map from the albedo texture's alpha.

You can see it gives consistent lighting behaviour on my test model below. The Ethan in the middle is using the Standard shader, and the ones on either side are using the Dissolve shader below.

Three Ethans, demonstrating lighting consistency with & without dissolve.

If there are other particular lighting features you need, reply and we can figure out how to add them.

Shader "Custom/Dissolve" {
    Properties {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _BumpMap ("Normal Map", 2D) = "white" {}

        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0

        _SliceGuide ("Slice Guide", 2D) = "white" {}
        _SliceAmount ("Slice Amount", Range(0, 1)) = 0.0
        _BurnRamp ("Burn Ramp", 2D) = "white" {}
        _BurnSize ("Burn Size", Range(0, 1)) = 0.15
        _EmissionAmount ("Emission Amount", float) = 2.0
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        #pragma surface surf Standard addshadow
        #pragma target 3.0

        sampler2D _MainTex;
        sampler2D _BumpMap;
        sampler2D _SliceGuide;
        sampler2D _BurnRamp;

        struct Input {
            float2 uv_MainTex;
            float2 uv_BumpMap;
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;

        half _SliceAmount;
        half _BurnSize;
        half _EmissionAmount;

        void surf (Input IN, inout SurfaceOutputStandard o) {
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);

            half test = tex2D(_SliceGuide, IN.uv_MainTex).rgb - _SliceAmount;
            clip(test);

            // I skipped the _BurnColor here 'cause I was getting enough 
            // colour from the BurnRamp texture already.
            if (test < _BurnSize && _SliceAmount > 0) {
                o.Emission = tex2D(_BurnRamp, float2(test * (1 / _BurnSize), 0)) * _EmissionAmount;
            }

            o.Albedo = c.rgb * _Color.rgb;
            // Apply normal mapping.
            o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));

            o.Metallic = _Metallic;

            // My Albedo map has smoothness in its Alpha channel.
            o.Smoothness = _Glossiness * c.a;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}
\$\endgroup\$
1
  • \$\begingroup\$ Thanks, I'll try this out. I had gotten some outside help that got me closer (like 95%), mainly by adding #pragma target 3.0 and setting o.Normal and o.Smoothness but this touches a few things I haven't tried, like addshadow and toying with Metallic. Since this does exactly what I needed to solve the issue (everything else is tweaking) I'll mark it accepted already. \$\endgroup\$
    – BotskoNet
    Dec 20 '17 at 23:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.