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
But! You should take a renderDoc capture of the glitch and you might be able to identify where its going wrong.
https://agilethief.artstation.com/projects/OBBXy?album_id=70137
It worked out pretty great as we could have literally hundreds of these "fake lights" with practically no perf hit.
Our solution treated the spheres as additive blends on top of whatever else was there.
@radiancef0rge yeah it's a pretty interesting problem. I know what the problem is with the current shader setup is (it writes the first sphere's mesh into the stencil and then the second stencil increments regardless of if it's the overlap of the original sphere or a different sphere) I just can't think of a better solution haha
@Agiletheif oooh looks perfect, would you consider sharing shadercode or atleast point out which bit I'm doing wrong?
Going to try looking at the command buffer examples and injecting the lights in the deferred lighting chain now as I've run out of ideas