I’ve written a simple surface shader (copied below) that i’ve been using to add edge textures (small floating planes slightly extruded) onto solid geometry. This generally works great.
One problem is, naturally this transparent shader always gets rendered forward, which doees actually bring some problems with the amount of lights I want to use.
As you can see below, it’s entirely excluded from the albedo deferred pass.
Now, given the limitation that these are never going to be rendered transparent, and always resting on top of solid geomeetry - is it possible to push these into the deferred pass? It’s my understanding that this is possible, but might require a fragment shader, rather than a surface shader?
Writing a basic fragment shader, I’m a little bit stuck on how to actually achieve this, and very new with writing to the GBuffer / deferred in general:
Not making much progress here, so here’s what I understand so far, if anyone is able to help:
To do this, I’d need to write the results of my transparent texture over what’s in the existing gBuffer.
and a fragment shader is required for this, is that right?
You can’t reference the value of the existing gBuffer while writing an output, and not everything is finalised yet.
The way around this is to use something called the “finalgbuffer”.
Unfortunately that’s where the trail runs cold, I can’t find much of any documentation on finalgbuffer outside of a few Unity forum threads, but not any real code examples:
Currently when trying to use this, it doesn’t seem to do anything (I would expect this to be all black?).
Yes thanks I’ve come across that, though unfortunately couldn’t quite piece together how they were doing it, but it’s very close to what I want to achieve (though what I’m looking for is way simpler, just a diffuse overlay).
I was really interested in implementing this myself, but I suppose this is a fallback option.
are there grab passes in your version of unity? since you can reuse a single grabpass for as many models as you like by sharing a name, you could conceivably have all decals be able to blend by just reading the grabpass and blending the decal color with it however you like.
i use the grabpass in forward to render planar reflections (and share a grabpass with water!), and blend just like this, but i don’t know the intricacies of writing for deffered.
yeah, in that case i think your only option for that method would be to do it in forward with another camera, but that probably won’t be amazing for your performance.
Not making any great progress on this. I can’t seem to find any information on the finalgbuffer at all.
It definitely exists, and I’m imagining I can blend it by the existing buffer multiplied by (1 - the alpha of the texture) to blend these decals in the deferred pass, but the documentation is elusive.
This might actually work, and funnily enough it doesn’t use finalgbuffer at all.
The one problem with this is that it outputs using VertexOutputDeferred as the fragment input, which doesn’t carry any vertex colour information. If there’s a way you can access vertex colour information with that input, perfect.
Just want to amend, I only want to output to the first gBuffer, 0 (albedo only) to blend in semi transparent textures (and solid textures being multiplied by the vertex colour alpha). Everything else is not required.
void fragDeferredDull(
VertexOutputDeferred i,
out half4 outGBuffer0 : SV_Target0,
out half4 outGBuffer1 : SV_Target1,
out half4 outGBuffer2 : SV_Target2,
out half4 outEmission : SV_Target3 // RT3: emission (rgb), --unused-- (a)
#if defined(SHADOWS_SHADOWMASK) && (UNITY_ALLOWED_MRT_COUNT > 4)
, out half4 outShadowMask : SV_Target4 // RT4: shadowmask (rgba)
#endif
)
i.e. therer’s no equivalent of color :COLOR0 as far as I can tell?
Ah, as far as I understand, no - unfortunately that VertexOutputDeferred is a built in struct and can not be easily edited to the best of my knowledge?
Still not making any great progress on this unfortunately.
I’ve been going through this thread for more information on using the finalgbuffer, but unfortunately didn’t come across any real code examples of how to properly use the finalgbuffer: