Multipass forward rendering?

Started by
7 comments, last by L. Spiro 11 years ago

Hello,

Right now I'm using a forward renderer (OpenGL 3.3+) where I just run one pass with a maximum amount of lights predefined in the scene:


const int numberOfLights = 8;

struct PerLight
{
vec4 position;
vec4 intensity;
}

uniform Lights
{
vec4 ambientIntensity;
float lightAttenuation;
PerLight lights[numberOfLights];
} Lgt;
 

There are some issues, like for example if I only have 2 lights I still have to fill up space for 8, and the maximum amount is set at 8 so its not very flexible and dynamic. I want to be able to support any given amount of lights and I want my code to be independent of the amount of lights in the scene.

I've read something about multipass forward rendering.. but I don't know really what it means, and I cannot find any good sources. From what I've gathered so far, it involves rendering each mesh a number of times equal to the number of lights that affects it and then somehow add the results? So for example if I have one mesh affected by 3 lights, I would render it three times and blend the results?

Do I understand it correctly? Also I do not know how to implement it in practice, is there any complete examples lying around? For example, how do you setup the actual blending between rendering passes, what opengl functions are used, etc? Is there anything else I should know?

Also, I have read about deferred rendering, but from what I've gathered it sounds abit complex and I'd rather try to atleast First get a multipass forward renderer working, since that seems easier and cooperates better with all the other tutorials on the internet (for example I still havnt learned texturing)

Advertisement

I've read something about multipass forward rendering.. but I don't know really what it means, and I cannot find any good sources. From what I've gathered so far, it involves rendering each mesh a number of times equal to the number of lights that affects it and then somehow add the results? So for example if I have one mesh affected by 3 lights, I would render it three times and blend the results?

Yes, light is additive and you can calculate one or more lights in a single pass and add it (blend one/one) to the buffer. Basicly you have two shaders, a base light shader (containing emissive/ambient light) and an additive light shader. The base shader should already handle more than one light (8 sounds good), and for each (8-) block of additional lights render the scene in an additional pass using additve blending.

As you can already see, this will scale really badly with scene complexity/number of lights, therefor you should either optimize it (not each light affects each face) or switch over to deferred rendering/lighting which scales really great only with number of lights.

I see. How does the blending between shader passes work, how do you accumulate the results between shader passes?

I'm using OpenGL 3.3+ btw

You accumulate by using Alpha Blending.

glEnable (GL_BLEND);
glBlendFunc (GL_ONE, GL_ONE);

From the top of my head, no guarantees given.

----------
Gonna try that "Indie" stuff I keep hearing about. Let's start with Splatter.

Something like this then, for drawing one mesh?


glEnable (GL_BLEND);
glBlendFunc (GL_ONE, GL_ONE);

// udate uniform buffer with lights 1 to 8
DrawVAO();

// update uniform buffer with lights 9 to 16 and draw same vao again
DrawVAO();

glDisable (GL_BLEND);

 

?

I'm not your debugger. Try it.

----------
Gonna try that "Indie" stuff I keep hearing about. Let's start with Splatter.

For opaque objects, the first light should have blending disabled, then the following lights should have it enabled with one/one (additive).

In other words, the first light performs a renderTarget=shader, while the rest of the lights do renderTarget+=shader.

You have to be careful with gamma, or use floating point rendertarget

http://www.gamedev.net/topic/631164-does-alpha-blending-shall-be-gamma-corrected/

For alpha objects, which should be drawn after opaque objects as mentioned, the first render should be src = GL_SRC_ALPHA, dst = GL_ONE_MINUS_SRC_ALPHA, but the following passes should be src = GL_SRC_ALPHA, dst = GL_ONE.

L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

This topic is closed to new replies.

Advertisement