Correct way of using multipass effects in Effects framework

This topic is 1232 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hello.

I am using sharpDX with effect framework and I want to render multipass effect, but faced with the issue that I could not apply second pass:

Here is my effect code:

Texture2D Texture;
SamplerState TextureSampler;

matrix OrthoMatrix;

struct VertexInputType
{
float4 position : SV_POSITION;
float4 color: COLOR;
float2 tex : TEXCOORD0;
};

struct PixelInputType
{
float4 position : SV_POSITION;
float4 color: COLOR;
float2 tex : TEXCOORD0;
};

{
PixelInputType output;
output.color = float4(0, 0, 0, 0);
output.position = float4(0, 0, 0, 0);

// Change the position vector to be 4 units for proper matrix calculations.
input.position.w = 1.0f;

output.position = mul(input.position, OrthoMatrix);

// Store the texture coordinates for the pixel shader.
output.tex = input.tex;
output.color = input.color;
return output;
}

float4 SpritePixelShader(PixelInputType input) : SV_TARGET
{
return Texture.Sample(TextureSampler, input.tex)* input.color;
}

float4 SpritePixelShader2(PixelInputType input) : SV_TARGET
{
/*return Texture.Sample(TextureSampler, input.tex)+ input.color;*/
return float4(0,1,0,0);
}

technique10 SpriteBatch
{
pass P0
{
}

pass P1
{
}
}


And here is how I use effect:

var effectByteCode = ShaderBytecode.CompileFromFile(@"Content\Effects\SpriteBatchEffect.fx", "fx_5_0");
effect = new Effect(this.graphicsDevice, effectByteCode);

int passesCount = effect.GetTechniqueByName("SpriteBatch").Description.PassCount;
var technique = effect.GetTechniqueByName("SpriteBatch");

graphicsDevice.SetVertexBuffers(0, vertexBufferBinding);
EffectPass localpass;
for (int i = 0; i < passesCount; i++)
{
localpass = technique.GetPassByIndex(i);

var passSignature = localpass.Description.Signature;

layout = new InputLayout(graphicsDevice, passSignature, inputElements);

graphicsDevice.InputLayout = layout;

localpass.Apply(graphicsDevice);

graphicsDevice.DrawIndexed(indexCount, 0, 0);
}


On this line var

passSignature = localpass.Description.Signature;

in the second pass I receive outofrange exception.

If I comment that line, There is no exception, but the second pass will never apply.

Could someone, please, say what I am doing wrong here?

Share on other sites

Input layouts are probably not something you want to allocate on the fly per drawcall like that.

But other than that, you might check that localpass.IsValid.  I've had cases where everything compiled but IsValid was false, and I can't remember what caused it.

Also don't you need a vertex shader for your second pass?

Share on other sites

I do like this now:

spriteBatchEffect.GetVariableByName("TextureSampler").AsSampler().SetSampler(0, textureSampler);
spriteBatchEffect.GetVariableByName("OrthoMatrix").AsMatrix().SetMatrix(Ortho);

int passesCount = spriteBatchEffect.GetTechniqueByName("SpriteBatch").Description.PassCount;
var technique = spriteBatchEffect.GetTechniqueByName("SpriteBatch");
EffectPass localpass;
for (int i = 0; i < passesCount; i++)
{
localpass = technique.GetPassByIndex(i);
if (localpass.IsValid)
{
localpass.Apply(graphicsDevice);
graphicsDevice.DrawIndexed(indexCount, 0, 0);
}

}

}


and add vertex shader to 2nd pass

pass P1
{
}


But now I just dont see sprites. No errors, but also no image, but passes are valid.

Update:

I missed setting vertex buffer and now It rendering, but still only one path. I dont know why, but it ignores the second one.

Edited by BlackJoker

Share on other sites

If you put a breakpoint on the drawindexed, and see it calling on the second pass, my guess is your renderstates are to blame.

I use 2pass for drawing point and directional shadows onto my world geometry, so I set my depthfunc to EQUAL, and BlendOp to REV_SUBTRACT to get the shadow to draw onto what is already there.

In your case for spritey stuff, you might want to DepthEnable false, and do a traditional alpha blend (states very on that depending on if you are premultiplying or not)

Share on other sites

Interesting.... Could you please explain me a little about that. I just tested with depth disabled and second path applied to sprites, but for now I dont really understand why?

Does shader takes depth into account?

Share on other sites

Yes I think the default is only to draw a pixel if the depth is less than the current depth.  Usually for 2D stuff you'd just turn it off.

You can also manually reject a pixel with the clip() instruction.

1. 1
Rutin
26
2. 2
3. 3
JoeJ
20
4. 4
5. 5

• 9
• 9
• 9
• 46
• 41
• Forum Statistics

• Total Topics
631750
• Total Posts
3002060
×