0
\$\begingroup\$

I found a unity shader with custom lighting method that approximates subsurface scattering effect. I tried using it in deferred rendering mode and unfortunately it doesn't work. From what I have read on the internet, I guess I need to replace internal-deferred shader with my own and write my own brdf and lighting function and modify gbuffer contents and so on. Is this the right approach? or is there a better way?

Here's the shader code just in case.

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


        _MetallicGlossMap ("Metallic gloss (R, A)", 2D) = "white" {}
        _Metallic ("Metallic", Range(0,1)) = 0.0
        _Smoothness ("Smoothness", Range(0,1)) = 0.5
        
        _BumpMap ("Normal map", 2D) = "bump" {}
        _BumpScale ("Bump Scale", Float) = 1.0


        _LocalThickness ("Local Thickness", 2D) = "gray" {}
        _Distortion ("Material Light Distortion", Range(0, 1)) = 0.1
        _Power ("Power", Float) = 1.0
        _Scale ("Scale", Range(1.0, 100.0)) = 1.0
        _Attenuation ("Attenuation", Range(0.0, 1.0)) = 1.0
        _Ambient ("Ambient Light", Range(0.0, 100.0)) = 0.5
    }
    SubShader
    {
        Tags { "Queue"="Geometry" "RenderType"="Opaque" }
        LOD 200
        ZWrite On

        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf StandardTranslucent fullforwardshadows deferred

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        sampler2D _MainTex;
        sampler2D _MetallicGlossMap;
        sampler2D _BumpMap;

        sampler2D _LocalThickness;

        struct Input
        {
            float2 uv_MainTex;
        };

        fixed4 _Color;
        
        half _Metallic;
        half _Smoothness;
        
        fixed _BumpScale;

        float _Distortion;

        float _Power;
        float _Scale;

        float thickness;

        float _Attenuation;
        float _Ambient;

        #include "UnityPBSLighting.cginc"

        inline half4 LightingStandardTranslucent(SurfaceOutputStandard s, fixed3 viewDirection, UnityGI gi) {
            half4 standardPBR = LightingStandard(s, viewDirection, gi);

            /**************************TRANSLUCENT LIGHTING PART*******************************/
            //

            // Light Direction
            float3 L = gi.light.dir;
            // View Direction
            float3 V = viewDirection;
            // Normal of the current Vertex
            float3 N = s.Normal;

            // Half way vector
            float3 H = normalize(L + N * _Distortion);
            // Intensity of the backlight
            float I = pow(saturate(dot(V, -H)), _Power) * _Scale;

            I = _Attenuation * (I + _Ambient) * thickness;
            standardPBR.rgb = standardPBR.rgb + gi.light.color * I;
            standardPBR.a = 1.0f;

            return standardPBR;
        }

        void LightingStandardTranslucent_GI(SurfaceOutputStandard s, UnityGIInput data, inout UnityGI gi)
        {
            LightingStandard_GI(s, data, gi);        
        }

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            fixed4 mg = tex2D(_MetallicGlossMap, IN.uv_MainTex);
            fixed3 nml = UnpackScaleNormal(tex2D(_BumpMap, IN.uv_MainTex), _BumpScale);

            o.Albedo = c.rgb;
            // Metallic and smoothness come from slider variables
            o.Metallic = mg.r * _Metallic;
            o.Smoothness = mg.a * _Smoothness;
            o.Normal = nml;
            o.Alpha = 1.0f;
            float thick = tex2D(_LocalThickness, IN.uv_MainTex).r;

            thickness = thick;
        }
        ENDCG
    }
    FallBack "Diffuse"
}
\$\endgroup\$
2
  • \$\begingroup\$ Deferred rendering doesn't shade each object one by one, where you can use a custom shader on just one object. Instead it records all the surface properties into the GBuffer, then shades that combined buffer by splatting lights into it, all using the same shader. You might be able to smuggle your subsurface effect into the emissive channel of the G-buffer, or render it in forward mode as a transparent object layered on top of the deferred pass. But if you're using this custom effect on most of the screen, and it reacts to each light, it might be worth building into the deferred shading step. \$\endgroup\$
    – DMGregory
    Commented Apr 22 at 11:02
  • \$\begingroup\$ Thank you for the detailed answer Gregory. Could you be a little bit more kind to give me hints about first two methods? Do you mean using finalgbuffer:Colorfunction? \$\endgroup\$
    – V.R.S
    Commented Apr 22 at 15:42

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.