I've been working on a deferred decal system. So far I have finished the projection part, meaning I can click something in the scene and it will properly project a decal onto the surface of the object.

There are a couple other things I wish to add to this system: normal clipping and normal mapped decals. Normal clipping is when I discard fragments that are stretched across a sharp angle. Seen here. A way to solve this is to discard fragments that have a large difference between the normal in the G-Buffer and the decal's normal. This would require reading the G-buffer's normal texture.

In order to do decal normal mapping, I need to blend the decal's normal (from a normal map) with the G-buffer's normal. The requires writing to the G-buffer's normal texture.

I hope it's clear that in order to support these two features, I need to read and write to the normal texture in the same shader pass. Sadly, this is undefined behavior, so I'm wondering if there is some other way to implement these features.


1 Answer 1


Which rendering system do you use? The following information should be valid for all rendering systems, but in DX11 or later OpenGL versions there might be a better solution using UAV's.


You will have to copy the normal buffer before each pass. As long as you know that the decals do not modify the same screen space fragments you do not have to update the copy.

You could also render all your decals into seperate buffers and only do one blend pass into your normal buffer using a single normal buffer copy. This would scale much better with the amount of decals you have.

As long as you do not write the normal buffer, eg only perform normal clipping, as you call it, you can just sample the original normal buffer but you may not bind it as a render target.

In DX9 I found that reading and writing to the same texture results in the expected output as long as you do only use nearest point filtering and never read a different pixel than the one you currently write to, BUT! as this is undefined behaviour there might be drivers and graphic cards that do not behave this way. DX10 will prevent you from doing this by unbinding textures currently bound as render targets.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .