Home Unity

Wind Waker Style Firefly Lights

polycounter lvl 9
Offline / Send Message
Dickie polycounter lvl 9

Ok here's what I've got so far ^
I'm currently attempting Wind Waker style lighting and aided with @SimonT 's very helpful Hyrule Travel Guide I think I've come relatively close.
In the article it's proposed that you render a sphere 3 times:
Pass 1: only the back faces into a stencil
Pass 2: front faces increment the stencil
Pass 3: all faces decrement the stencil
Finally a full screen quad is rendered over the camera with the light colour added into the scene

I'm pretty sure that's not exactly correct as then you wouldn't be able to have different colours/intensities/overlapping lights without rendering the full screen quad again for every increment. And WW definitely has multiple light levels as seen in:


I might be wrong and it may well work as described but I'm looking for a solution which would work with multiple light colours and scalability.

I've tried a few different combinations but currently my shader works as per:
Pass 1: only the back faces into a stencil
Pass 2: front faces increment the stencil if a match
Pass 3: if a match to the incremented stencil then renders the sphere's geometry

current shader:
[spoiler]
[code]
Shader "StencLight" {
    Properties {
        _Color ("Main Color", Color) = (1,1,1,0)
        _StencilLayer("Stencil layer", int) = 1
        _StencilLayerPlusOne("Stencil Layer + 1", int ) = 2
    }
    SubShader {
        Tags { "RenderType"="Opaque" "Queue"="Geometry+1"}

         ZWrite off
       
        CGINCLUDE
        #include "UnityCG.cginc"
            struct appdata {
                float4 vertex : POSITION;
            };
            struct v2f {
                float4 pos : SV_POSITION;
            };
            v2f vert(appdata v) {
                v2f o;
                o.pos =  UnityObjectToClipPos(v.vertex);
                return o;
            }
        ENDCG



        Pass {

            Stencil {
                   // writes back faces to a stencil buffer
                Ref [_StencilLayer]
                Comp always
                Pass replace
            }
            colormask 0
            Cull Front
            ZTest greater
        
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            half4 frag(v2f i) : SV_Target {
                return half4(0.2,0.2,0,1);
            }
            ENDCG
        }
        Pass {
            Stencil {
                // where front faces match back faces incriment the stencil buffer
                Ref [_StencilLayer]
                Comp Equal
                Pass IncrSat
            }
            colormask 0
            Cull Back
            ZTest less
        
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

               half4 frag(v2f i) : SV_Target {
                return half4(0,0.2,0.2,1);
            }
            ENDCG
        }

           Pass
        {
        ColorMask RGB
        Cull Front
        ZTest Always
        Stencil {
            // only renders pixels that made it past the second phase
            Ref [_StencilLayerPlusOne]
            // should really work out how to do ^ programatically
            // can't seem to do any math in the ref line
            Comp equal 
        }

        // max blending
        // personally I don't want doubling up of differnt light bands
        BlendOP Max
        Blend One One
        
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag


            float4 _Color;
            
            fixed4 frag (v2f i) : SV_Target
            {

                return _Color;
            }
            ENDCG
        }
    } 
}  
[/code]
code is public domain, do with it what you will
[/spoiler]

But it has some issues, namely there's bits where it gets confused when rotating the camera:

(check the bottom of one of the sphere's popping in in the far right)
and each the materials have to have separate stencil values + specifically assigned render que values. All of which isn't all that much of a downside because of the fixed almost topdown camera angle of my game but

does anyone have any ideas get getting it to work 'properly' without said issues?

Replies

Sign In or Register to comment.