1
\$\begingroup\$

I am trying to do simple forward rendering for multiple lights using additive blending in WebGL. Following advice from this SO and this one, I simply turn on blending using glBlendFunc(GL_ONE, GL_ONE) and glEnable(GL_BLEND).

However, while this is combining the contribution from multiple lights, it is also making everything "transparent", as in the front faces of my object are blending with the back faces. I know that rendering transparent objects requires sorting the objects by depth, but this would be extremely slow in javascript, and doesn't seem to be necessary as blending should only occur when faces are at equal depth, which is something the depth test/z-buffer should be able to handle, right?

So is sorting the objects really necessary for forward rendering of multiple lights?

\$\endgroup\$
0
\$\begingroup\$

Yes,you are right. If your program needs any buffer texture to draw result(like light accumulation buffer in light pre-pass rendering),you needs to care about order of objects in scene. Because texture can store only one pixel for a fragment. It means texture can't store any data behind of an object when the texture store the data of most nearest(of course it will be calculated by depth test) object.

\$\endgroup\$
0
\$\begingroup\$

I solved this with some help from Nathan Reed in the comments of this SO answer. The blend function glBlendFunc(GL_ONE, GL_ONE) is purely additive, and because addition is commutative, order doesn't matter. However, what does matter is to establish depth in the z-buffer through an opaque pass before doing any blending. My solution was to simply disable blending and draw a first pass with all objects colored black, and then turn blending on and draw the contribution of each light source.

Nathan Reed suggested here that it is usually done with "a z-prepass with color writes disabled, or another common way is to do ambient/directional light in a first pass with no blending, then add point/spot lights in later passes with blending". I haven't tried those yet so if anybody can contribute more details on how to do it that'd be great!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.