Game Development Community

Getting the albedo before the diffuse pass.

by Lukas Joergensen · in Torque 3D Professional · 06/10/2014 (3:21 am) · 8 replies

Hey guys, I've been hitting an issue with my SSGI.

I need to do some calculations based on the colors of the scene before lighting is applied.

I thought "PFXAfterDiffuse" would solve this, but I was wrong unfortunately.

imageshack.com/a/img843/4403/lm39.png


My examinations indicate that the issue lies in that PFXAfterDiffuse is applied after the scene has been lit.

Using:
renderTime = "PFXBeforeBin";
   renderBin = "AL_LightBinMgr";

Does not work either because the $backBuffer is empty at that point.
Is there another way to access the albedo before the diffuse render pass? It's my understanding from deferred rendering that at some point it should be possible to access the albedo before the lighting is applied.

Is it because the albedo is rendered after the lighting and then lighting is applied? Or am I so unfortunate that the albedo is rendered at simultaneously with lighting being applied?

#1
06/10/2014 (9:47 am)
This is a vague remembrance from an experiment with the outline shader, and re-ordering it so it was drawn earlier to prevent it hitting the translucent textures, so take it with a grain of salt, but:

what we ended up doing was going into /game/core/scripts/client/renderManager.cs and taking on a name to:
DiffuseRenderPassManager.addManager( new RenderObjectMgr(ShadowBin)     { bintype = "Shadow"; renderOrder = 0.7; processAddOrder = 0.7; } );
then triggering the renderTime off that name.

github.com/GarageGames/Torque3D/blob/development/Engine/source/lighting/advanced... points to an AL_PrePassBin that at first glance at least appears to function as a before-bin, though haven't really traced it fully. That give you any ideas?
#2
06/10/2014 (11:42 am)
From my examinations, it seems the engine first calculates light and bakes that to the lightInfo, and then uses that when it renders the albedo, such that the albedo is never actually to be found anywhere. :(

If I'm right it's not possible to get the albedo before light is applied.

So I tried working with the diffuse map after i has been lit, but it's just too flat because it doesn't get applied as if it was light.

Can anyone help me on the math for applying the a color as if it were light?

I got the following:
imageshack.com/a/img855/9199/gr5b.jpg

Using the following code:

#include "shadergen:/autogenConditioners.h"

uniform sampler2D indirectMap : register(S0);
uniform sampler2D diffuseMap : register(S1);

float4 main(float2 tex : TEXCOORD0, float2 uv0 : TEXCOORD1) : COLOR0
{
	float4 color = tex2D(diffuseMap, uv0);
	float4 indirect = tex2D(indirectMap, uv0);
	
	float colorLength = length(color);
	
	return normalize(color + (color*indirect)*1)*colorLength;
}

It works, but it doesn't work very well.. It just gives color bleed it doesn't actually "light".

So I've got the indirect color, and I've got the diffuse, I just need to calculate the resulting color properly.
#3
06/10/2014 (5:04 pm)
Quote:From my examinations, it seems the engine first calculates light and bakes that to the lightInfo, and then uses that when it renders the albedo, such that the albedo is never actually to be found anywhere. :(
Got some research done on that, but since you seem more interested in

Quote:It works, but it doesn't work very well.. It just gives color bleed it doesn't actually "light".
So I've got the indirect color, and I've got the diffuse, I just need to calculate the resulting color properly.

We'll cut to the chase and toss over: a nice cheat-sheet I jut ran across: tech-artists.org/wiki/Blending_functions that seems to have 5 light ones listed to try. (6 if you count overlay)
#4
06/11/2014 (12:02 am)
Still unable to produce the results I get from applying it directly to the lighting.

There are a lot of artefacts caused by black and grainy areas in the indirect light map, that aren't issues when applied to the lightinfomap.

I guess I'd really prefer being able to access the albedo before lighting is applied.
#5
06/11/2014 (12:10 am)
Quote:From my examinations, it seems the engine first calculates light and bakes that to the lightInfo, and then uses that when it renders the albedo, such that the albedo is never actually to be found anywhere. :(

Well, research thusfar: going over a screencap with nSight, seeing a greyscale lighted image that that's tagging as either the or right after the AdvancedLightBinManager_Render_Sunlight phase as a render-target, at which point it takes a second pass filling in color along the way.

Not quite certain yet whether we'd be looking at a tie-in to curEntry.shadowMap->postLightRender(); getRenderSignal().trigger(state, this); or _onPostRender(); when it comes to tying it back into an injection-point for a RenderPassManager if such is needed.

Far as I've been able to squeeze in thus-far around the personal and community work. Hope that gives some places to dig for folks at least.
#6
06/12/2014 (10:55 am)
Okay so I just had an idea, I'll see if I can make it work.

From what I can make out (and from what Azaezel said) it goes like this:
imageshack.com/a/img841/3963/0vth.png
So what I'm trying is not possible in the current flow, however what I thought of doing was to try and split the global illumination into two parts: illumination and color bleeding.. Perhaps it will work then, as I'm able to calculate illumination without having access to the albedo, the albedo is just for calculation the color bleed.

Edit:
This was what I expected T3D to be doing:
https://cdn.tutsplus.com/gamedev/uploads/2013/11/deferred-v2.png

But it seems that it skips the "color" rendertarget.
#7
06/12/2014 (2:57 pm)
So this is the flow I ended up using:

imageshack.com/a/img849/72/s4tr.png

It doesn't use the albedo, but approximates the color bleeding from the final render.
#8
06/12/2014 (5:45 pm)
That sound good! I really hope it works :D