How to make tone/lightmapped materials affected by light in BL
by Marcus L · in Torque 3D Professional · 07/05/2010 (10:15 am) · 19 replies
Hello Torquers,
I am currently trying out pureLIGHTs awesome features using the pureLIGHT trial. Now the problem I've came across is that tone/lightmapped materials are not affected by dynamic lights in BL. Could anyone plz help me with this one, I'm trying to make dynamic lights affect lightmapped materials in BL.
Thanks,
Marcus L.
I am currently trying out pureLIGHTs awesome features using the pureLIGHT trial. Now the problem I've came across is that tone/lightmapped materials are not affected by dynamic lights in BL. Could anyone plz help me with this one, I'm trying to make dynamic lights affect lightmapped materials in BL.
Thanks,
Marcus L.
#2
EDIT: Figured the shadows, but AL even without shadows causes 60% framerate drop (200fps-30fps), plus it for some reasons looks worse in AL. So i need alternative solutions =/.
07/05/2010 (10:56 am)
Might sound noobish, but how do i disable shadows. I tried to press the check box in the editor "Disable Shadows" but they're still there.Quote:... and seeing what the performance difference between BL and AL is then?Umm, I'm not having issues with preformance btw.
EDIT: Figured the shadows, but AL even without shadows causes 60% framerate drop (200fps-30fps), plus it for some reasons looks worse in AL. So i need alternative solutions =/.
#3
Advanced Lighting will (optionally) pre-populate the contents of the light-buffer with the contents of the lightmap, using multiple render targets. It is bandwidth intensive both because it is drawing to multiple, full-screen buffers, but because it is sampling from many sources. It's a solution, but it is a high-end solution.
Here is how to enable basic lighting + lightmaps (though I have not tested it it should work):
shaderFeatureHLSL.cpp, line 1670 (ish), RTLightingFeatHLSL::processVert():
Remove the feature tests so it looks like:
Next remove these lines from RTLightingFeatHLSL::processPix()
Then at the end of RTLightingFeatHLSL::processPix() change this:
To this...
That should work, but you may need to mess around with it a bit.
07/05/2010 (3:40 pm)
Relevant Background information:Advanced Lighting will (optionally) pre-populate the contents of the light-buffer with the contents of the lightmap, using multiple render targets. It is bandwidth intensive both because it is drawing to multiple, full-screen buffers, but because it is sampling from many sources. It's a solution, but it is a high-end solution.
Here is how to enable basic lighting + lightmaps (though I have not tested it it should work):
shaderFeatureHLSL.cpp, line 1670 (ish), RTLightingFeatHLSL::processVert():
// Skip out on realtime lighting if we don't have a normal
// or we're doing some sort of baked lighting.
if ( !inNormal ||
fd.features[MFT_LightMap] ||
fd.features[MFT_ToneMap] ||
fd.features[MFT_VertLit] )
return;Remove the feature tests so it looks like:
// Skip out on realtime lighting if we don't have a normal
if ( !inNormal )
return;Next remove these lines from RTLightingFeatHLSL::processPix()
// Skip out on realtime lighting if we don't have a normal
// or we're doing some sort of baked lighting.
//
// TODO: We can totally detect for this in the material
// feature setup... we should move it out of here!
//
if ( fd.features[MFT_LightMap] || fd.features[MFT_ToneMap] || fd.features[MFT_VertLit] )
return;Then at the end of RTLightingFeatHLSL::processPix() change this:
// Apply the lighting to the diffuse color. LangElement *lighting = new GenOp( "float4( @.rgb + ambient.rgb, 1 )", rtShading ); meta->addStatement( new GenOp( " @;\r\n", assignColor( lighting, Material::Mul ) ) ); output = meta;
To this...
// Apply the lighting to the diffuse color.
LangElement *lighting = new GenOp( "float4( @.rgb + ambient.rgb, 1 )", rtShading );
if(fd.features[MFT_LightMap] || fd.features[MFT_ToneMap] || fd.features[MFT_VertLit])
{
Var *d_lightcolor = new Var( "d_lightcolor", "float4" );
meta->addStatement( new GenOp( " @ = @;\r\n", new DecOp(d_lightcolor), lighting ) );
}
else
meta->addStatement( new GenOp( " @;\r\n", assignColor( lighting, Material::Mul ) ) );
output = meta;That should work, but you may need to mess around with it a bit.
#4
Thanks again :D
oh, and Steve, btw. appreciate the help, but AL seems to refuse to run smoothly on my GeForce 8600m gt =/
07/05/2010 (4:26 pm)
Thanks man, you really helped me out there. Worked perfectly, and it barely touched the fps. I wish i would have skilz like you there Pat, seen you all over the forums helping people with shader related problems. Unfortunately words like light-buffer and full screen-buffers don't say much to me yet, but hey, I've only been torquing about 2 years without any knowledge or education from before, plus I'm still learning.Thanks again :D
oh, and Steve, btw. appreciate the help, but AL seems to refuse to run smoothly on my GeForce 8600m gt =/
#6
In the ToneMap, LightMap, and VertLit features, the comment:
Advanced Lighting is choking on your 8600m because of memory bandwidth. A full-screen buffer is the size of the resolution you are running * the bit depth, so lets say you are running at 1280x720 (720p on HDTV) with 32-bit render targets. 1280 * 720 * 32 / 8 (bits->bytes) / 1024 (bytes->kb) / 1024 (kb->mb) is a 3.5mb chunk of memory. Now if you are running at 60fps, you are moving that chunk of memory 60 times a second...210 mb/s just to move the contents of a 32-bit back-buffer across the bus.
This is why deferred rendering is so memory-bandwidth heavy; and why pre-pass lighting (Advanced Lighting) is cheaper, but still very expensive.
07/06/2010 (9:49 am)
It worked without any modifications? Hot damn. I can fix ShaderGen without even trying the code in a compiler (I wrote the post on my mac, on the couch just kind of eye-balling it). With this kind of success under my belt, I am going to attempt to walk across the river on my way home today. ;)In the ToneMap, LightMap, and VertLit features, the comment:
// Right now, only Advanced Lighting is supportedis incorrect, now I guess!
Advanced Lighting is choking on your 8600m because of memory bandwidth. A full-screen buffer is the size of the resolution you are running * the bit depth, so lets say you are running at 1280x720 (720p on HDTV) with 32-bit render targets. 1280 * 720 * 32 / 8 (bits->bytes) / 1024 (bytes->kb) / 1024 (kb->mb) is a 3.5mb chunk of memory. Now if you are running at 60fps, you are moving that chunk of memory 60 times a second...210 mb/s just to move the contents of a 32-bit back-buffer across the bus.
This is why deferred rendering is so memory-bandwidth heavy; and why pre-pass lighting (Advanced Lighting) is cheaper, but still very expensive.
#7
Thanks for the explanation, but still wondering why AL requires more memory than BL. I mean, I've heard that AL needs to render the scene twice, but why?
getting one step closer to knowing all :D
07/06/2010 (10:01 am)
These are noobish questions, so for the people who knows this stuff, don't read, you may choke of laugher even tho its doubt fullThanks for the explanation, but still wondering why AL requires more memory than BL. I mean, I've heard that AL needs to render the scene twice, but why?
getting one step closer to knowing all :D
#8
First all geometry in the scene is drawn to the pre-pass buffer, storing linear view-space depth and view-space normals (these words may make little sense). Then lighting is applied to the scene, by sampling from the pre-pass buffer, and drawing to the light buffer. Then the forward pass is finally drawn, which samples from the light buffer to get lighting values.
Traditional deferred rendering will use 3-4 full-screen buffers, and draw to all of them at the same time, then re-combine the scene later.
Pre-pass trades drawing the geometry twice, for less memory usage.
07/06/2010 (10:17 am)
Well for AL, you need two full-screen buffers to store the depth and normal for each pixel, and the lighting values of each pixel (advanced readers: ignore tiling/binning). First all geometry in the scene is drawn to the pre-pass buffer, storing linear view-space depth and view-space normals (these words may make little sense). Then lighting is applied to the scene, by sampling from the pre-pass buffer, and drawing to the light buffer. Then the forward pass is finally drawn, which samples from the light buffer to get lighting values.
Traditional deferred rendering will use 3-4 full-screen buffers, and draw to all of them at the same time, then re-combine the scene later.
Pre-pass trades drawing the geometry twice, for less memory usage.
#9
Could you shine a brighter light on this part?
EDIT: for the sorrow of my spelling skills.
07/06/2010 (12:40 pm)
Wow, thanks Pat! Great detailed, but not overly technical description. Could you shine a brighter light on this part?
Quote:. What are the multiple render targets, objects in game scene with the final lightmap, or is that stage yet unlighted? (Argh, i tried multiple way to word that question, but they all seemed just as vague.)
Advanced Lighting will (optionally) pre-populate the contents of the light-buffer with the contents of the lightmap, using multiple render targets
EDIT: for the sorrow of my spelling skills.
#10
Multiple render targets, you output multiple pixels, to different targets. So, you draw a cube, and the cube gets drawn to both target A and target B.
In the case of the Advanced Lighting functionality, when a lightmapped object is drawn, it draws its normal/depth to the pre-pass buffer (like all opaque objects) and then it draws the information from its lightmap into the lighting buffer, during the same draw call.
In this way, by the time the renderer needs the lighting information, all of it (lightmaps and dynamic lighting) are now contained within the light buffer.
Does that make more sense?
07/06/2010 (1:43 pm)
When drawing, normally, you are rendering to a single target. You output one pixel color, and it gets stored in one target. Multiple render targets, you output multiple pixels, to different targets. So, you draw a cube, and the cube gets drawn to both target A and target B.
In the case of the Advanced Lighting functionality, when a lightmapped object is drawn, it draws its normal/depth to the pre-pass buffer (like all opaque objects) and then it draws the information from its lightmap into the lighting buffer, during the same draw call.
In this way, by the time the renderer needs the lighting information, all of it (lightmaps and dynamic lighting) are now contained within the light buffer.
Does that make more sense?
#11
My fictitious and magical theory about HOW T3D Deferred Rendering actually worked was not quite as simple and eloquent. And my ability to ask Google the right questions(and lack of), were rewarded with contradicting Deferred Rendering definitions (normally a query self discovered with a bottle of Scotch and studying the Source like a classical novel; T3D = thick plot).
07/06/2010 (2:40 pm)
Perfect. This is real good information, thanks for explaining the process so well.My fictitious and magical theory about HOW T3D Deferred Rendering actually worked was not quite as simple and eloquent. And my ability to ask Google the right questions(and lack of), were rewarded with contradicting Deferred Rendering definitions (normally a query self discovered with a bottle of Scotch and studying the Source like a classical novel; T3D = thick plot).
#12
This evolved into what T3D has now. A full write-up is in ShaderX7, but with pre-pass dominating much of the current/next gen, there are lots of references on it now. We just previously called it 'deferred' because nobody had heard of 'light pre-pass'.
07/06/2010 (2:57 pm)
The T3D deferred rendering technique is actually "Pre-pass lighting." The renderer was written based on this blog post: diaryofagraphicsprogrammer.blogspot.com/2008/03/light-pre-pass-renderer.htmlThis evolved into what T3D has now. A full write-up is in ShaderX7, but with pre-pass dominating much of the current/next gen, there are lots of references on it now. We just previously called it 'deferred' because nobody had heard of 'light pre-pass'.
#13
07/06/2010 (3:26 pm)
Wow, thats exactly the type of information i have been missing on this subject! Time to put on reading glasses and fetch more Scotch (Yup im gonna drink and read technical documentation until the next T3D version release, my liver is in TorquePowered hands- hmm that doesn't sound quite right).
#14
Need a little more help. Using your code works perfectly except from this one thing. Lighting seems to go through stuff. Of course i can live with this, but I'm sure you know the answer to this one. And will this be more resource demanding or less?
07/09/2010 (8:00 am)
@Pat WilsonNeed a little more help. Using your code works perfectly except from this one thing. Lighting seems to go through stuff. Of course i can live with this, but I'm sure you know the answer to this one. And will this be more resource demanding or less?
#15
You could move the shadow maps from advanced lighting into basic lighting, but that would be much more resource demanding, and probably a pain in the ass.
07/09/2010 (10:07 am)
Yep that will happen. There are only projected shadows, in Basic Lighting, and doing a projected shadow for every object is a very bad idea.You could move the shadow maps from advanced lighting into basic lighting, but that would be much more resource demanding, and probably a pain in the ass.
#16
07/09/2010 (10:09 am)
Ok, thanks, didn't think it was shadows that avoided light from getting casted through meshes, but thanks anyways Pat.
#17
Kudos to Pat for the blindly written code that works. Excellent explanations also :)
07/09/2010 (10:47 am)
Whoa, cool thread! Kudos to Pat for the blindly written code that works. Excellent explanations also :)
#18
08/31/2010 (7:27 am)
Working fine and good.Great Work. Congrats...
#19
01/24/2011 (1:43 pm)
This is A+ material.
Associate Steve Acaster
[YorkshireRifles.com]
Just for the sake of it, have you tried disabling ALL shadows in AL and seeing what the performance difference between BL and AL is then?