# questions, Multipass lighting, Projection, Linear Colors, ....

This topic is 3622 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

____I decided to put all my questions together here, to avoid an excessive number of posts. Just need comments on whether my understandings are (in)correct, correction and clarification for my incorrect info, answers to my questions, and some tips on how I might improve. Projected Textures
1. I looked into the demo at Ultimate Game Programming, and the projected texture on the torus wraps around to the opposite side of the torus(facing away from the projector). Is there an easy way to eliminate this?
2. Are decals just projected textures that don't move, or is there more to them?
Glow Effect
1. Do I render only specular and emissive contributions to the buffer that will be blurred?
Linearized colors
1. To see if I understand the basic idea: convert colors (constants, texture samples, vertex colors) to linear, perform light calculations with linear colors, convert result to system gamma format.
2. I've heard blending occurs in gamma space. Is this only true for the back-buffer, or does it affect RenderTargets/FBOs?
Multipass Lighting
1. To see if I understand the idea: render by object, render the object multiple times (once per light) adding to frame buffer, move to next object and repeat ?
2. I have heard that this approach presents problems for transparency. Is it because the alpha-blending makes it look like multiple objects stacked in front of each other? Can someone clarify the issue?
3. Because of blending, my lights will be accumulated in gamma space, right? So I need to use either a float buffer, or a different color-space (ex. NAO32, RGBE, etc)?
1. To help limit the number of combinations, could I use an fx shader where each pass is a type of lighting? ex.
• Pass0 - depth only pass, supports alpha-test
• Pass1 - albedo and ambient
• Pass2 - Spot light
• Pass3 - Point light
Float Buffer Alternatives
1. To check if my understanding is correct, with something like NAO32, you don't have hardware blending, since the results would be wrong?
2. Is there any way to support blending here, that doesn't involve an excess of decoding and ping-ponging between buffers?
Premultiplied Alpha
1. Heard it's good for compositing, but causes precision issues for non-floating point values. Can anyone whose played around with it comment on it's real-world (dis)advantages?
2. I've heard that, with some trade-offs, this can be used to solve the multipass lighting transparency issue. Can anyone elaborate?
Multipass performance steps: ____After a lot of reading, these are the general steps I've gathered for optimizing a multipass lighting pipeline. Comments, critiques, and suggestions for improvement are needed. So please blast away at it.
1. Early-Z
• Perform frustum culling on all objects bounding shapes
• Make list of objects in frustum
• Update depth for objects in frustum
2. Sort Object list
• Sort by material
• In material groups, by distance to camera (near to far for opaque, far to near for translucent)
3. Lights
• Perform frustum culling on all lights' bounding volumes
• Build list of lights that affect frustum
4. Ambient/Directional Light pass
• Draw object albedo with ambient lighting
• Depth test to eliminate obscured fragments
• Occlusion query to eliminate following light passes for mostly obscured objects
5. Lighting passes
• Depth-test and stencil write to determine which object fragments are in light volume
• Render object with that light, adding contribution to frame-buffer via blending
• rinse, repeat
Questions
• Does Early-Z eliminate need to sort opaque objects by distance to camera (since the fragments will be rejected regardless of order)?
• In ambient pass, do I draw only that object's ambient, and then start handling lights that influence it?
• When restricting light influence with the stencil buffer, do I just mark the fragments it influences in stencil, then render that light, then clear stencil and do it again for next light?
• Any suggestions on speedy sort algorithms that work well for material sorting?
____Lastly, thanks to everyone who answers my questions in full, or in part. I desperately need clarification on these for my own project. Rest assured, all your advice will be put to good use. Cheers. ;) [EDIT] By PolyVox's request, adding links to some of the materials I've read, as I track them down. Gamma correct rendering HDR the Bungie Way" simon brown - Gamma-Correct Rendering Adventures with Gamma-Correct Rendering Premultiplied alpha Premultiplied alpha Alpha Premultiplication The Dirty Secrets of Premultiplied Alpha General Shading Offset Dev Blog - Illumination vs. Illuminance, Bump Mapping Offset Dev Blog - entries "12/16/2004" & "12/20/2004" Offset Dev Blog - Lighting Pipeline Deferred Rendering in Killzone 2 (PDF) Finding Next Gen - CryEngine 2 (PDF) NAO32 Converting RGB to LogLuv in a fragment shader more to come... [Edited by - n00body on July 24, 2008 1:42:49 PM]

##### Share on other sites
Quote:
 Original post by n00bodyGlow Effect Do I render only specular and emissive contributions to the buffer that will be blurred?

That's the way it was done in Nvidia's old implementation. But you could do it however you want...there's no real right or wrong way to do it.

Quote:
 Original post by n00bodyLinearized colors To see if I understand the basic idea: convert colors (constants, texture samples, vertex colors) to linear, perform light calculations with linear colors, convert result to system gamma format. I've heard blending occurs in gamma space. Is this only true for the back-buffer, or does it affect RenderTargets/FBOs?

Blending is done in linear space. Unless you're doing something fancy with how you store your colors in the render target, there's no need to convert to gamma or anything like that.

Quote:
 Original post by n00bodyMultipass Lighting To see if I understand the idea: render by object, render the object multiple times (once per light) adding to frame buffer, move to next object and repeat ? I have heard that this approach presents problems for transparency. Is it because the alpha-blending makes it look like multiple objects stacked in front of each other? Can someone clarify the issue? Because of blending, my lights will be accumulated in gamma space, right? So I need to use either a float buffer, or a different color-space (ex. NAO32, RGBE, etc)?

1. Yes, that's the basic premise. Also note that the first time you render the object you'll want to do so with blending off and z-writes enabled, while subsequent passes will have blending enabled and z-writes disabled.

2. It's a problem because multi-pass lighting requires that additive blending is used, while alpha-blended objects require alpha-blending (duh). You can't do both at once, so alpha-blended objects have to be done all in one pass.

3. Like I said earlier, it's done in linear space. You can use a regular R8G8B8A8 surface is you don't need HDR, or fp16 otherwise. You can't do multi-pass with something like NAO32 or RGBE, because those are non-linear and therefore you can't use hardware blending with them.

Quote:
 Original post by n00bodyShader CombinationsTo help limit the number of combinations, could I use an fx shader where each pass is a type of lighting? ex.Pass0 - depth only pass, supports alpha-testPass1 - albedo and ambientPass2 - Spot lightPass3 - Point light

Instead of passes, I would probably do them as techniques. That way they're easier to reference.

Quote:
 Original post by n00bodyFloat Buffer Alternatives To check if my understanding is correct, with something like NAO32, you don't have hardware blending, since the results would be wrong? Is there any way to support blending here, that doesn't involve an excess of decoding and ping-ponging between buffers?

Right, you can't use hardware blending. For my engine where I use NAO32, I render opaque objects in one pass and output NAO32. Then later I render in transparent objects after tone-mapping, and do the tone-mapping in the shader. I'm not sure, but I believe they did something similar to this in Heavenly Sword.

Quote:
 Original post by n00bodyQuestionsDoes Early-Z eliminate need to sort opaque objects by distance to camera (since the fragments will be rejected regardless of order)?In ambient pass, do I draw only that object's ambient, and then start handling lights that influence it?When restricting light influence with the stencil buffer, do I just mark the fragments it influences in stencil, then render that light, then clear stencil and do it again for next light?

1. Yes, with a z-prepass you'll be never render any invisible pixels so there's no need to sort by depth.

2. You could do that, but if you have a global light source (like the sun) it would probably be smart to group that in with the ambient pass. The less passes, the better.

3. It would probably be smarter to use a unique value for each light, and test for equivalency with that value when rendering that lighting pass. The 255 values an 8-bit stencil gives you should be enough, I'd think.

##### Share on other sites
It seems like you've been doing a lot of interesting reading and have covered a wide variety of topics. Do you mind sharing some of the resources you have been using?

##### Share on other sites
Quote:

Quote:
 2. I have heard that this approach presents problems for transparency. Is it because the alpha-blending makes it look like multiple objects stacked in front of each other? Can someone clarify the issue?

2. It's a problem because multi-pass lighting requires that additive blending is used, while alpha-blended objects require alpha-blending (duh). You can't do both at once, so alpha-blended objects have to be done all in one pass.

This is very easy to solve. In the first pass you apply alpha blending, in the later passes, you add the next pass, but multiplied by its own alpha value. In Direct X, it would look something like:

// first passdxDevice->SetRenderState( D3DRS_SRCBLEND , D3DBLEND_SRCALPHA );dxDevice->SetRenderState( D3DRS_DESTBLEND , D3DBLEND_INVSRCALPHA  );// render object// later lighting passesfor( each light ){  dxDevice->SetRenderState( D3DRS_SRCBLEND , D3DBLEND_SRCALPHA );  dxDevice->SetRenderState( D3DRS_DESTBLEND , D3DBLEND_ONE  );  // render object}

Quote:
 # Sort Object list * Sort by material * In material groups, by distance to camera (near to far for opaque, far to near for translucent)# Ambient/Directional Light pass * Occlusion query to eliminate following light passes for mostly obscured objects

I think combining these techniques has some potential problems.

First, if you sort by material and than only sort translucent within each material group, your alpha-order might fail when translucent objects of different materials lay behind each other. You should sort all translucent objects together and forget about materials for these. For solid objects, material sorting is fine.

Second, If you have many materials, sorting solid objects from near to far only within their material groups, your scene will not be rendered from front to back at all. Therefore, your occlusion queries will have much less effect then when the whole scene is rendered front to back, as many far away objects will be rendered earlier than near objects because they are in different material groups.

##### Share on other sites
Just a comment about multipass-lighting...I'm my opinion this is not the way to do things anymore on modern hardware, instead do lighting in world-space in the pixel shader.

old way:

vertex shader calculates a set number of tangent-space vectors to send to pixel shader. Pixel shader does the lighting in tangent-space. Saves pixel shader instructions, but eats up VS output slots (a max of 8 in ps3.0) at most you could do 4 lights per-pass...multiple passes sucks.

new way:

transform normal to world-space in the vertex shader, the normal map to world- space in the pixel shader and *bang*, do as many world-space lighting calcs as you have math instructions (for ps3.0 this means many lights on one pass)..in 2.0 you have a much smaller limit.

Still need a good light management system to cull lights.

It not diferred shading but the next best thing..i went to deferred shading for other reasons. Crysis does lighting with the basic method.

##### Share on other sites
@MJP
Glow Effect
What way do you do it for your own projects? What are the results of doing it that way?

Linearized Colors
Thanks for the info. Turns out, I misinterpreted the article from which I obtained my information. It was talking in the context of using extensions to automatically convert from linear to sRGB on render targets. Basically, they were saying that while blending with this setup, most cards will incorrectly convert the linear source to sRGB, and perform the blend. The desired effect being to convert the destination to linear, perform the blend, and then convert the result from linear to sRGB. (source: Adventures with Gamma Correct Rendering)

Multipass lighting
2.) Thanks for pointing that out. Kinda feel like a dunce now. :p
3.) Goes back to my misinterpretation of what the article said.

Would you please elaborate on "easier to reference"?
Also, I chose passes in the context of a multipass renderer, with each Pass in the FX file being a different stage/light.

Float Buffer Alternatives
Thanks for the real scenario, it will be most helpful. Curious, while we're on the subject of NAO32, how well does it work as a storage format vs RGBE? Would it work well for a HDR cube-map file?

Questionsi
3.) Won't that cause problems where the lights overlap? Perhaps my understanding of Stencil Ops is still limited, but I thought in order to store multiple values for one pixel, you have to do bitwise ops. Is my understanding incorrect?

@dietepiet
So, let me see if I understand this correctly. I would handle the translucent object's albedo with regular alpha blending, and then handle its lighting passes with premultiplied alpha?

As for sorting, I should just sort all my translucent objects, regardless of material, from far to near?

@Matt Aufderheide
For my own engine, I'm planning to implement something similar to the lighting system outlined in the Project Offset dev blog. Basically, lights that are also projectors, so that projected textures and shadows are more cleanly integrated into the scene. Because this approach requires two textures per light (projected texture, shadow map), it's a little more difficult to cram them all into one shader.
Both the Offset dev blog and the CryEngine 2 pdf link I posted discussed the benefits of world-space shading. So I was planning to use that approach anyway. However, thanks for pointing it out.

@everyone

##### Share on other sites
Quote:
 Original post by n00bodyShader CombinationsWould you please elaborate on "easier to reference"?Also, I chose passes in the context of a multipass renderer, with each Pass in the FX file being a different stage/light.

You could do it with passes, but doing it like that implies that you'lre always going to have the same combination of lights. You could jump around to the different passes out of order, but if you're going to do that you might as well just make them techniques since you can reference them by name (that's what I meant by easier to reference)

Quote:
 Original post by n00bodyFloat Buffer AlternativesThanks for the real scenario, it will be most helpful. Curious, while we're on the subject of NAO32, how well does it work as a storage format vs RGBE? Would it work well for a HDR cube-map file?

It's pretty nice! Works well with multi-sampling, which is why I wanted to use it in the first place. I haven't done any good testing vs RGBE as far as quality goes, but in my experience it's been great at handling a wide range of luminance values. It would probably be very nice for a cubemap. If your dynamic range isn't to wide than NAO24 might also be a good choice, which is the same except with only 8 bits for luminance rather than 16.

Quote:
 Original post by n00body3.) Won't that cause problems where the lights overlap? Perhaps my understanding of Stencil Ops is still limited, but I thought in order to store multiple values for one pixel, you have to do bitwise ops. Is my understanding incorrect?

You can have it so that each light volume would render an explicit value to the stencil buffer. It would go something like this:
light #1:stencilfunc = alwaysstencilzfail = keepstencilpass = replacestencilref = 1-Render light volumestencilfunc = equal-Render objects affected by light #1light #2stencilfunc = alwaysstencilref = 2-Render light volumestencilfunc = equal-Render objects affected by light #2

If you do that it doesn't matter if another light overlaps, because the old stencil value would be replaced with the new one.

1. 1
2. 2
Rutin
19
3. 3
4. 4
5. 5

• 14
• 12
• 9
• 12
• 37
• ### Forum Statistics

• Total Topics
631432
• Total Posts
3000041
×