   Question about shader passes
  Hi there!In some shaders I've seen multiple passes. And I guess they are quite useful in some situations. But I don't know much about them. Are they only woring with alpha blending? Because when I write yellow in the first pass and blue in the second, the blue will overlay the yellow. So I have to render a transparent blue? But this turns into another question: For what situations can I use them?When I would like to render yellow with a transparent blue overlay, I can simply do this in 1 pass.So, why are they there? And for what can I use them? Maybe you can give me some examples. I'm making PostProcessing at the moment, and maybe I need them there...   
  Suppose you want to write a shader that does a box blur. In the first pass you do a horizontal blur and in the second pass you do a vertical blur. You could do it one pass but it takes more instructions.   ;  Yes, thats what I want to do. But lets assume I first du the HorizontalBlur and then the VerticalBlur. The texture from the scene won't change, and I need to vertically blur the horizontally blurred scene, or can I just add the Vertically blurred scene to the Horizontally blurred scene?Why does it save my instruction count? The instructions will be executed anyways (in the 2nd pass), or not?   ;Quote:Original post by mind in a boxYes, thats what I want to do. But lets assume I first du the HorizontalBlur and then the VerticalBlur. The texture from the scene won't change, and I need to vertically blur the horizontally blurred scene, or can I just add the Vertically blurred scene to the Horizontally blurred scene?Why does it save my instruction count? The instructions will be executed anyways (in the 2nd pass), or not?Not quite, in the case of gaussian blur its far less expensive to run a one dimensional blur twice than to run a two dimensional blur once.IIRC 2 one dimensional blurs require 2*n*p lookups (where n is the size of the blur kernel and p is the number of pixels in the image) while one 2D blur requires n*n*p lookups. (So if the blur kernel is bigger than 2 it will always be faster to do the 1D version twice)   ;I'm wondering though, can you actually do a seperated H/V blur by using true shader passes? I was always under the impression that you can't read back results from earlier passes and that as a consequence multiple passes were mainly useful for multiple lights and other effects that can be (additively) blended onto earlier results.;  All you need to do is set the texture for the second pass to be the owner of the surface used as the target for the first pass. You have bounce between two targets essentially.   ;Quote:Original post by DaveAll you need to do is set the texture for the second pass to be the owner of the surface used as the target for the first pass. You have bounce between two targets essentially.This does involve switching render targets, right? If that's what you mean, you can't do something like this, can you?technique Blur{    pass Horizontal    {VertexShader = compile vs_3_0 SomeVertexShaderFunction();   PixelShader = compile ps_3_0 HorizontalBlurShader();    }   pass Vertical    {VertexShader = compile vs_3_0 SomeVertexShaderFunction();   PixelShader = compile ps_3_0 VerticalBlurShader();    }}As I've always understood effect passes, this 2nd pass would overwrite the results of the 1st horizontal pass (assuming there's no blending set up), effectively leaving you with a result on the render target that's only blurred vertically. To actually apply vertical blurring to the already horizontally blurred results, you'd indeed need to swap RTs but then you wouldn't be using 2 effect passes like this but rather 2 techniques, right?To be sure, I'm not trying to be a pain, I'm only trying to figure out if I haven't misunderstood shader passes all these years [smile];  So before you can do the blur post process you need to make sure that the pipeline prior to this has rendered it's final image on to a surface of a texture that you have created. Set the render target for the prior rendering to be the surface at level 0 of the texture. For a two pass post process like the box blur, set the render target to be the top surface of another texture you have created and the input texture as the texture the prior scene was rendered to. For the second pass you set the output surface to be the devices back buffer surface and the input to be the output texture from the first pass.In terms of implementation, you could have a class called BoxBlur that when Draw() is called on it knows what the two passes do and when iterating through the passes, sets up the appropriate textures to the effect and the render targets to the device.Oh and remigius, yes that's how it might look. Your vertex shader just processes a full screen quad while the pixel shaders perform the blurs with a blur kernel.Disclaimer: I could be talking rubbish, it's been a while since i used effects.   ;  EDIT: @Dave: Sorry, typed to slow :PHere, this is why I asked this question://-----------------------------------------------------------------------------// Technique: Bloom// Desc: //-----------------------------------------------------------------------------technique10 BloomTech{    pass p0    {   SetDepthStencilState( NoDepthStencil, 0 );   SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );SetVertexShader( vsCompiledQuad );   SetGeometryShader( gsCompiledQuad );   SetPixelShader( CompileShader( ps_4_0, BloomHorizontal() ) );    }pass p1    {   SetDepthStencilState( NoDepthStencil, 0 );   SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );SetVertexShader( vsCompiledQuad );   SetGeometryShader( gsCompiledQuad );   SetPixelShader( CompileShader( ps_4_0, BloomVertical() ) );    }}This code is from the nVidia SDK 10, Volumetric light example.And here are both pixel shaders://-----------------------------------------------------------------------------// Name: Bloom// Type: Pixel shader   // Desc: Blur the source image along the horizontal using a gaussian//  distribution//-----------------------------------------------------------------------------float4 BloomHorizontal( PSInQuad input ) : SV_TARGET{   float4 vSample = 0.0f;    float4 vColor = 0.0f;    float2 vSamplePosition;   for( int iSample = 0; iSample < 15; iSample++ )    {   // Sample from adjacent points   vSamplePosition = input.texCoord + g_avSampleOffsetsHorizontal[iSample].xy;   vColor = s0.Sample( samplerLinearClamp, vSamplePosition ); vSample += g_avSampleWeights[iSample] * vColor;    }   return vSample;}float4 BloomVertical( PSInQuad input ) : SV_TARGET{   float4 vSample = 0.0f;    float4 vColor = 0.0f;    float2 vSamplePosition;   for( int iSample = 0; iSample < 15; iSample++ )    {   // Sample from adjacent points   vSamplePosition = input.texCoord + g_avSampleOffsetsVertical[iSample].xy;   vColor = s0.Sample( samplerLinearClamp, vSamplePosition ); vSample += g_avSampleWeights[iSample] * vColor;    }   return vSample;}And this is the result:And all this confused me heavily... :(How did they do that? I implemented blooming with this switch-rendertargets method before, but I didn't liked the result, made a mistake somewhere. And now I'm going rewrite it all. I found this sample and thougt "Hey cool, they do it within the shader!" ...   ;  I'm not quite sure what you're confused about. It looks like normal bloom to me.   