Home Unity

Deferred shader with double-sided translucency, how?

polycounter lvl 9
Offline / Send Message
CarlCraft polycounter lvl 9
I am working in Unity.

I have been working on a foliage shader but am stuck on its lighting. What I'm looking for is double-sided translucency in deferred path. If a quads frontface is lit, its backface should also be lit and vice versa. I have had some success with custom lighting but that means forward rendering which I unfortunately cannot use in this case. 

 I have some pictures and examples of what my shader is doing and where its going wrong:
Shader "TwosidedNoFlip"
{
    Properties
    {
        _ColorFront ("Front Color", Color) = (1,0,0,1)
	_ColorBack ("Back Back", Color) = (0,1,0,1)
    }
   
    SubShader
    {
        Tags { "Queue" = "Geometry" "RenderType" = "Opaque" }
		
	Cull Off

        CGPROGRAM
        #pragma surface surf Standard
 	#pragma target 3.0
      
        float4 _ColorFront;
        float4 _ColorBack;
        
        struct Input
        {
		fixed facing : VFACE;        
	};
       
        void surf (Input IN, inout SurfaceOutputStandard o)
        {
			
            if (IN.facing < 0.5) //If it is backface
	    {
                o.Albedo = _ColorBack;
	    }
	    else //If it is frontface
	    {
                o.Albedo = _ColorFront; 
	    }
        }
        ENDCG
    }
}
The results is:


The top part is what I want; both sides to be lit when one of the sides is hit with a light. The problem with this shader is that if the backface is lit, none of the faces receives the lighting.
The alternative I have come up with is:
Shader "TwosidedYesFlip"
{
    Properties
    {
        _ColorFront ("Front Color", Color) = (1,0,0,1)
	_ColorBack ("Back Back", Color) = (0,1,0,1)
    }
   
    SubShader
    {
        Tags { "Queue" = "Geometry" "RenderType" = "Opaque" }
		
	Cull Off

        CGPROGRAM
        #pragma surface surf Standard
 	#pragma target 3.0
      
        float4 _ColorFront;
        float4 _ColorBack;
         
        struct Input
        {
		fixed facing : VFACE;        
	};
       
        void surf (Input IN, inout SurfaceOutputStandard o)
        {
			
            if (IN.facing < 0.5) //If it is backface
	    {
                o.Albedo = _ColorBack;
                o.Normal *= -1.0; //Flip backfaces normals
	    }
	    else //If it is frontface
	    {
                o.Albedo = _ColorFront; 
	    }
        }
        ENDCG
    }
}
The only part that changed is an added line "o.Normal *= -1.0;" in the surf function. This flips the normals of the backface so they point outward from the backfaces perspective. This results in:

Now the quad can get lit from both sides, but the light doesn't shine through. It needs to shine through!

I know wherein the problem lies: The normals of each face point either outward or they both point in just one direction, when a solution for me would be if both faces pointed in both directions simultaneously. To my understanding this isn't possible.

Is there any other solution to this problem? Can you somehow gather the "negative" light and use that to OneMinus it and use it in the emission? What I mean with negative light:
 

Pic from https://youtu.be/6_-NNKc4lrk?t=253

Can I make a custom lighting pass but still somehow keep it deferred? 

Ant suggestions on where to look is appreciated, thanks

Replies

  • Prot
    Offline / Send Message
    Prot polycounter lvl 6
    Hi,

    If you want to keep it deferred with " Standard " lighting in shader, it's not an easy way. You don't have access to any kind of lighting information before the lighting pass in surface shader in deferred.
    You can try to modify the built in shader from unity named " Internal-DeferredShading ". You can download them from unity dowload archive website. To use the new you created, unity explains it at the bottom of this page : https://docs.unity3d.com/560/Documentation/Manual/RenderTech-DeferredShading.html
    And modify the " UnityStandardInput.cginc " to have translucents parameters.

    I don't know if it's the best solution but it could be a way.

    Regards,
  • CarlCraft
    Offline / Send Message
    CarlCraft polycounter lvl 9
    Hope everyone had nice holidays :) Thanks for the reply @Prot

    Is it possible to access/use lighting information at all in deferred, or are you only talking about unitys "standard" having no access to it? Do you think using "negative light" pictured in OP is viable in this case, or even possible?

    Thank you
  • Prot
    Offline / Send Message
    Prot polycounter lvl 6
    Hi,

    If you don't want to rewrite the lighting function in your surface shader, you don't have lights informations in " surf ".
    Edit : You can try with negative light but I think you will have strange result with bushes (for example) or foliages in shadows.
    It's look like UE4 do it this way and works fine. But for unity, negative light is still a light so you don't have any informations if you don't make your own lighting.
  • CarlCraft
    Offline / Send Message
    CarlCraft polycounter lvl 9
    Double post, my bad
  • CarlCraft
    Offline / Send Message
    CarlCraft polycounter lvl 9
    I understand. Do you know if it is possible to access this "negative light" without fiddling with the standard deferred rendering model? Or is there no light information available at all? 
Sign In or Register to comment.