Shader Lights + Complex Materials

Started by
17 comments, last by SimmerD 18 years, 10 months ago
I don't know if i am the right person to help since i havent even started using shaders, but i guess ive been reading up enough about it that i could try. Note: I'll be using GLSL as example, im not sure if Cg, HLSL are capable of this but i presume they should.

Since we are allowed to link multiple shader objects(VS/PS), we could link the required light shader(Spot/Directional/Omni) into your program object.You could come up with a standard interface like this:

"MyShader.glsl"
void MyShader
{
doLightFunction();
doShadowFunction();


}

"SpotLight.glsl"
void doLightFunction()
{
}

"OmniLight.glsl"
void doLightFunction()
{
}

During linktime, you could link the required shader into your program object and your MyShader will call the correct LighFunction for you.
Advertisement
You can use light caches to make the engine render again only the polygons in the light influence sphere
Quote:Original post by 999999999
You can use light caches to make the engine render again only the polygons in the light influence sphere


That would be very similar to deferred lighting/shading.

About the Shader thing above, I'm not too sure, you don't want to build/rebuild the programs often, and combining all possibilities can be heavy.
A good cache mechanism could help though, but there's also the problem of data format.
You could render your omni light to a cubemap, but the mesh rendering shader better be expecting a cubemap and not a texture2D...
-* So many things to do, so little time to spend. *-
This topic is covered quite well in '3D Game Engine Programming' by Stefan Zerbst
Ive Actualy got that book, my only problem right now is Dealing with combining "materials" with multiple different types of lights.
Quote:Original post by HippieHunter
Ive Actualy got that book, my only problem right now is Dealing with combining "materials" with multiple different types of lights.


Same here, if anyone have a working solution I'm interested.

-* So many things to do, so little time to spend. *-
There is an OpenGL demo in the Cg Toolkit that iterates over an array of Light interfaces. The interface consists of the method CalcLight(..). There are different light types or classes like PointLight Spotlight that implement this interface, but the main material shader is the same all the time. The demo only changes the uniform parameters and Cg updates and recompiles the shader automatically. To bad there are no interfaces in GLSL, because they make Cg programs very flexible.

Is a GLSL target profile for Cg planned, to make Cg usable with the next PS30 ATI hw?
Well then you could just use an if statement,

uniformLightType
void LightFunction()
{
if(uniformLightType == 0)
{
do spotlight
}
else if(uniformLightType == 0)
{
do directional
}

}

Yes i know conditionals are bad, but i remember reading on nvidias page that while constants are prefered for if/for statements, uniforms can be compiled JIT by the driver. Why dont you just try using if's and see the results, im sure drivers are pretty good at optimising such things.
This is increasingly an issue with games, how to properly combine materials, possibly multiple blended materials, with various lights.

I like to use compositing. Compositing is often used as a part of deferred shading. There are really three aspects of standard deferred shading.

1) Compositing material properties before lighting to a 2d buffer.

2) Compositing geometric information to a 2d buffer ( like depth, viewspace position, etc. ).

3) Using light proxy geometry to light the scene.

I do #1, without doing #2 and #3.

The idea is to blend together just the unlit diffuse terms for all of your objects to the back buffer, then stretchrect offscreen to a texture. You can have any # of terrain layers, blood decals, scorch marks, etc. Render Z at this time.

Then do the same with the normal maps. You can store something else like gloss or low-precision depth in dest alpha.

Optionally do a 3rd buffer for specular material color, but you can often just get away with a mono gloss term.

Then draw your ambient lighting, global reflections, and emissive terms to the back buffer.

Now you can render your shadow term to dest alpha or stencil.

Now start blending in your lights, using any shader you like. With my scheme, you don't draw full-screen quads for your lighting, although you could do that if you have view space depth stored in a buffer.

You draw the geometry in the range of the light, but instead of using the texture coordinates of the geometry, you use the 2d screen coordinates to fetch the diffuse, normal & gloss from the 2d buffers you stored earlier.

This particular variation on deferred shading has some advantages over standard deferred shading.

1) does not require MRT.
2) works fine with AA, even when forced from the control panel.
3) does not require writing depth to a buffer
4) no issues with capping light proxy geometry

Some disadvantages

1) more batches are required than with DS, although still far less than standard rendering in many scenarios.

2) don't have view-space depth in a buffer, which is useful for several effects.

This topic is closed to new replies.

Advertisement