   post process is way too expensive? =(
  I am working on deferred lighting, but performance is very poort with many lights.for example I also implemented shadow volume algorithm. Whole scene has a shadow mesh with ~45000 triangles. And with 10 lighting, if shadowing is on it is about 30 fps, if it is off it is 15-20 fps. I first thought it is the shadow volumes which are causing the problem but it is not :SGame runs fine with 1 lighting, fps is about 70-90.why a post-process effect causes too much strain. I knew texture fetching is expensive but not that much :S light post process has 4 texture fecthing, 3 for color, normal and position g-buffers and another 1 fetching old light results.here is my code, I hope problem is about my code rather than post process it self.my light shaderfloat4 LightPS(in V2P IN) : COLOR0{  IN.TexCoord.x += dx/2;  IN.TexCoord.y += dy/2;    float4 Color =  tex2D( ColorSampler0, IN.TexCoord );  float4 Normal =  tex2D( ColorSampler1, IN.TexCoord );  float4 Pos =  tex2D( ColorSampler2, IN.TexCoord );    Normal = (Normal - 0.5)*2;    float d =  dot( Normal.xyz, normalize(lightCoor-Pos.xyz));  d *= saturate((lightRange-distance(lightCoor, Pos.xyz))/lightFallOff);Color.x *= lightColor.x*d;  Color.y *= lightColor.y*d;  Color.z *= lightColor.z*d;   return Color + tex2D( ColorSampler4, IN.TexCoord );}and part of rendering responsible for lights and shadows  postProcessingEffect->SetTexture("ColorTex0", QuadTexture[0]); //color buffer  postProcessingEffect->SetTexture("ColorTex1", QuadTexture[1]); //normal buffer  postProcessingEffect->SetTexture("ColorTex2", QuadTexture[2]); //position buffer (D3DFMT_A16B16G16R16F)  postProcessingEffect->SetTexture("ColorTex4", QuadTexture[4]); //light buffer, result of all lights added to here  ClearTexture(QuadTexture[4], 0xFF000000);  Tools::D3DDevice->SetRenderTarget(0, RenderSurface[4]);  for(int i=0; i<lightNum; i++){    if(hasShadow){ Tools::D3DDevice->Clear( 0, NULL, D3DCLEAR_STENCIL, 0x00000000, 1.0f, 0 ); for(int j=0; j<ShadowVolume::shadowSize; j++){   ShadowVolume::allShadows[j]->drawShadowVolume(lightPos); }    }   postProcessingEffect->SetFloatArray("lightCoor", lightPos, 3);    postProcessingEffect->SetFloatArray("lightColor", lightColors, 3);    postProcessingEffect->SetFloat("lightRange", lightRanges);    postProcessingEffect->SetFloat("lightFallOff", lightFallOffs);  if(hasShadow){ postProcessingEffect->SetTechnique( "Light");    }else{ postProcessingEffect->SetTechnique( "LightWithoutShadow");    }    renderQuad();   }can you notice anything else which can cause a problem?   
  Are talking about postprocessing or deferred light?Post processing is usually used to refer to image processing effects such as blurring, tonemapping and other effects. Unless you are doing both together, you need to specify which is which. If you are talking about just the lighting aspect, then you may want to use simple geometry for your lights( See the NVidia paper on Deferred Shading for optimization). If you are talking about post-processing then you may want to see if whatever post-processing kernel you are running is separable and try and do it in separate pass to alleviate the situation.   ;  I am working on deferred shading and its post process part (which light effects using g-buffers) is the one that causes low performance. I am wondering if I did something stupid or post processes (or texture fetching) are really that expensive   ;  For the lighting pass of your deferred renderer, your GPU performance will most likely be directly tied to the number of pixels shaded. Any optimizations you can use to reduce that number are likely to help a lot. These include:-Rendering light bounding volumes instead of full-screen quads-Using the depth buffer to cull pixels that don't need to be lit-Using the stencil buffer to cull pixels that don't need to be litAside from that, 4 texture fetches is pretty heavy. Are you not using hardware blending to sum the results of your lighting pass? You may also want to look into packing your G-Buffer more tightly, by storing depth and reconstructing position from that rather than explicitly storing view-space or world-space position. It's not only better for performance, but unless you use 32-bit floats for storing position the precision will be better as well.   ;Quote:Original post by MJPFor the lighting pass of your deferred renderer, your GPU performance will most likely be directly tied to the number of pixels shaded. Any optimizations you can use to reduce that number are likely to help a lot. These include:-Rendering light bounding volumes instead of full-screen quads-Using the depth buffer to cull pixels that don't need to be lit-Using the stencil buffer to cull pixels that don't need to be litAside from that, 4 texture fetches is pretty heavy. Are you not using hardware blending to sum the results of your lighting pass? You may also want to look into packing your G-Buffer more tightly, by storing depth and reconstructing position from that rather than explicitly storing view-space or world-space position. It's not only better for performance, but unless you use 32-bit floats for storing position the precision will be better as well.please tell me if I get it right"-Rendering light bounding volumes instead of full-screen quads"so instead of rendering a screen quad I will render a cube for each the light, it will be centered on light position and its sides' lenthgs are light range. if a light is off screen, it will not be rendered at all."-Using the depth buffer to cull pixels that don't need to be lit"this is a side benefit of rendering a cube with depth testing right? if cube is behind of an object it will not be rendered again. or does this mean anything else?"-Using the stencil buffer to cull pixels that don't need to be lit"sorry, I didn't get this. I am doing a stencil test for not rendering on shadowed areas caused by shadow volumes but I guess that is not it.I never thought about using depth value for finding world position, but is 8 bit enough for that? I am already storing depth of each pixel for another algorithm  on normal buffer's 4th element. I will certainly try thiscan you explain how I can use hardware blending to sum light results? Currently it adds lights together in pixel shader (return Color + tex2D( ColorSampler4, IN.TexCoord );). ColorSampler4 is the render target it is writing on.   ;Original post by shultaysso instead of rendering a screen quad I will render a cube for each the light, it will be centered on light position and its sides' lenthgs are light range. if a light is off screen, it will not be rendered at all.Original post by shultaysYes. It also makes sure you don't waste time shading pixels in areas of the screen where your light wouldn't be active. You can also use a sphere if you want to use a bit more geometry for a tighter fit to a point light, and you can use a cone for a spot light.Quote:Original post by shultaysthis is a side benefit of rendering a cube with depth testing right? if cube is behind of an object it will not be rendered again. or does this mean anything else?Yes, basically. You really only want to run your light shader for pixels where the light volume intersects with other geometry. This means you want to reject pixels where the light is "floating in air" or "buried underground". When you render bounding volumes you have to use backface or frontface culling, which means with a z-test you can only reject one of those two cases (with backface culling you can reject buried underground pixels, with frontface culling you can reject floating pixels). If you combine this with a stencil test you can get both cases, but since you're using stencil for shadows it may not be practical. On Nvidia hardware you can also use the depth bounds test for culling lights.Quote:Original post by shultaysI never thought about using depth value for finding world position, but is 8 bit enough for that? I am already storing depth of each pixel for another algorithm  on normal buffer's 4th element. I will certainly try thisUsing depth is a pretty common optimization. 8-bits would definitely not be enough...you really need at least a 16-bit depth value. You can look at my blog article for an idea of the sort of error you can expect.Quote:Original post by shultayscan you explain how I can use hardware blending to sum light results? Currently it adds lights together in pixel shader (return Color + tex2D( ColorSampler4, IN.TexCoord );). ColorSampler4 is the render target it is writing on.Just set SRCBLEND to ONE and DESTBLEND to ONE, and the output from your pixel shader will be summed with the contents of the render target.;  thanks again, I think I get what you meant with stencil testing. It is pretty much like shadow volume algorithm, we have a volume which defines the region that light can illimunate except. thanks for all your help, it works better now. here is my scene with 10 lights, 3 of them generating shadows. fps is around 30, still not good as I hope but at least it is better now.I will check your article about using depth buffers for generating world positions, but if 8 bits are not enough, it will not help me for reducing texture fetches. but at least an 32bit buffer should be more efficent than using A16B16G16R16F.;  The house seems like squidward's house from spongebob...   ;  Well, I think that your implementation is quite ineffective. For each light you do a full-screen pass, this is 4 texture fetches which sums up to 40 texture fetches for 10 lights.One solution, already mentioned, is to add culling per stencil buffer or just render the light volumns, but if your lights lit large areas of your screen I would suggest an other approach.Do the lighting of all of your lights in a single pass. This leaves 4 texture fetches for 10 or 50 lights. Set your light data as parameters and run a little loop in your shader. This way I render up to 50 lights. You could still try to reduce the lighting by stencil masks.;Quote:Original post by Ashaman73Do the lighting of all of your lights in a single pass. This leaves 4 texture fetches for 10 or 50 lights. Set your light data as parameters and run a little loop in your shader. This way I render up to 50 lights. You could still try to reduce the lighting by stencil masks.If you want to do that, you can bin your lights according to screen-space tiles. Then for each tile you only render the lights that intersect.