   Blending decals with deferred setup
  Hi,I'm currently adding decals for my deferred-shading-renderer. My basic approach is orthogonally project textures into the g-Buffer after the main geometry is drawn. (Any smarter methods for this?)Blending the diffuse color into the g-Buffer works well. But I would very much also be able to affect other parts of the g-Buffer as well.For instance I have R16_G16 target where I store specular-rgb, specular-exponent, translucency and a factor for rim-lighting. As the stuff is compressed it will get a total mess if I use alpha-blending. (Right?) But I could imagine it would look ok, if I use something similar to clip/texkill for those things and just overwrite the values in the g-Buffer.Now for the actual questions: With multiple render targets I cannot simply clip contribution to one target and alpha-blend with the other, right?I hope I could get a similar effect by pushing alpha to either 0 or 1 for one render target. But how does that work with a two channel target? Can I write R, G, nothing, A to an RG rendertarget, at all?I guess I could have my very own custom blending by copying my g-Buffer and using it as input as well, but I don't think I want to spend that much memory.Would be cool to get some input on this!   
Quote:Original post by B_oldHi,I'm currently adding decals for my deferred-shading-renderer. My basic approach is orthogonally project textures into the g-Buffer after the main geometry is drawn. (Any smarter methods for this?)Blending the diffuse color into the g-Buffer works well. But I would very much also be able to affect other parts of the g-Buffer as well.For instance I have R16_G16 target where I store specular-rgb, specular-exponent, translucency and a factor for rim-lighting. As the stuff is compressed it will get a total mess if I use alpha-blending. (Right?) But I could imagine it would look ok, if I use something similar to clip/texkill for those things and just overwrite the values in the g-Buffer.Now for the actual questions: With multiple render targets I cannot simply clip contribution to one target and alpha-blend with the other, right?I hope I could get a similar effect by pushing alpha to either 0 or 1 for one render target. But how does that work with a two channel target? Can I write R, G, nothing, A to an RG rendertarget, at all?I guess I could have my very own custom blending by copying my g-Buffer and using it as input as well, but I don't think I want to spend that much memory.Would be cool to get some input on this!I got a similar problem in my decals code for my deferred engine. Alpha-blending user compressed data will be indeed a mess. The solution or atleast a compromise, depends on your material system. In my special case it was enough to leave some channels untouched and override (alpha=1/0) other channels. There should be an option to enable masking for each MRT where you can enable/disable writing to certain channels (in opengl it is glColorMask ).Example setup with color(RGBA) and material(XYZA) where you want to overwrite the Y material and blend the color:.. in your none-shader code.. activate material bufferglColorMask( FALSE,TRUE,FALSE,FALSE);.. in your fragment shaderglFragData[0].rgb = target_color;glFragData[0].a   = blend_alpha_for_color;glFragData[1].xyz = vec3(0, new_material, 0);glFragData[1].a   = 1; // overwrite YThe mask will ensure that X,Z and A of the material buffer will be untouched.;  Thanks for the answer Ashaman!This is what I do now: Alpha-blending for the color and a additional clip() for very low alpha values, so that the material data covers the entire decal shape.This looks looks very good most of the time, but the non-alpha-blended material data can be apparent when the specular lighting is very visible. All in all I'm quite happy with it and I think it is a practical solution.Now I have another question, which I might have to put in another thread, but maybe you know something about this as well: Normalmapped decals.I don't really know how I can the normals from the texture in the correct space (view space in my case). Maybe if the normalmaps are stored in decal-space I could just multiply them with the decals rotation before I project them? But I think it will only be correct if the decal is projected on a planar surface. Maybe it's possible to compute the tangent space on the fly somehow. Any ideas?   ;Quote:Original post by B_oldNow I have another question, which I might have to put in another thread, but maybe you know something about this as well: Normalmapped decals.I don't really know how I can the normals from the texture in the correct space (view space in my case). Maybe if the normalmaps are stored in decal-space I could just multiply them with the decals rotation before I project them? But I think it will only be correct if the decal is projected on a planar surface. Maybe it's possible to compute the tangent space on the fly somehow. Any ideas?When your decal is just a plane (or "box") the tangent space should be the same as the object space (Assumption: your normals on the normal map points along the same axis as the projection). To avoid setting up one orientation matrix for each decal, I encode the orientation as quaternion as additional vertex attribute. In the vertex shader I decode the orientation to a matrix (=tangent space matrix). That's all, but you might encounter issues with normal blending. Blending a normal could be tricky, especially if you compress your normals. In this case you need to overwrite the normals, which could lead to very hard and distracting edges. In my case most decals lay ontop of the surface without its own surface character other then material and color.;Quote:Original post by Ashaman73When your decal is just a plane (or "box") the tangent space should be the same as the object space (Assumption: your normals on the normal map points along the same axis as the projection).My decal is a box. But the decals can be projected onto arbitrary geometry. I thought I would need the tangentspace of the "recieving" geometry rather than the box used to draw the decal.;Quote:Original post by B_oldQuote:Original post by Ashaman73When your decal is just a plane (or "box") the tangent space should be the same as the object space (Assumption: your normals on the normal map points along the same axis as the projection).My decal is a box. But the decals can be projected onto arbitrary geometry. I thought I would need the tangentspace of the "recieving" geometry rather than the box used to draw the decal.In fact you are projecting a plane on geometry inside your box volumne. Quote:I thought I would need the tangentspace of the "recieving" geometry rather than the box used to draw the decal.Hmm... well, you could be right here :) One way to get the tangent space of your g-buffer is to write the quaternion (4 components or 3 compressed) instead of the normal (3 components or 2 compressed). On the other hand you could try to sample the surrounding pixels to reconstruct the tangent space, but this could be quite expensive and could be prone to artifacts. A simple attempt would be to just add the normals to the existing one and normalize the normals in your lighting pass. In this case a float g-buffer would be preferable.   