Using two shaders at the same time

Started by
3 comments, last by Headkaze 10 years, 4 months ago
I need to be able combine two different types of pixel shaders. One is for applying an effect and the other is for a transition.

Here is an example transition pixel shader
float Progress;

texture Input1;
sampler Input1Sampler = sampler_state
{
	Texture = <Input1>;
};
texture Input2;
sampler Input2Sampler = sampler_state
{
	Texture = <Input2>;
};

float4 Fade(float2 uv)
{
	float4 c1 = tex2D(Input1Sampler, uv);
	float4 c2 = tex2D(Input2Sampler, uv);

	return (lerp(c1, c2, Progress));
}

float4 main(float2 uv : TEXCOORD) : COLOR
{
	return (Fade(uv));
}

technique FadeTransition
{
	pass FadeTransition
	{
		VertexShader = null;
		PixelShader = compile ps_2_0 main();
	}
}
Here is how I apply it
m_transitionEffect.Technique = m_transitionEffect.GetTechnique(0);

m_transitionEffect.SetTexture("Input1", m_screenTexture[0].DXTexture);
m_transitionEffect.SetTexture("Input2", m_screenTexture[1].DXTexture);

m_transitionEffect.SetValue<float>("Progress", m_progress);

m_transitionEffect.CommitChanges();

m_transitionEffect.Begin();
m_transitionEffect.BeginPass(0);

// Render stuff

m_transitionEffect.EndPass();
m_transitionEffect.End();
Here is an example effect pixel shader
texture SourceTexture;
sampler SourceTextureSampler = sampler_state
{
	Texture = <SourceTexture>;
};

float4 InvertColorFunc(float2 tex : TEXCOORD) : COLOR
{
	float4 texcolor = tex2D(SourceTextureSampler, tex);
	float4 newcolor = 1.0f - texcolor;
	return (float4(newcolor.rgb, texcolor.a));
}

technique InvertColor
{
	pass InvertColor
	{
		VertexShader = null;
		PixelShader = compile ps_2_0 InvertColorFunc();
	}
}
Here is how I apply it.

m_effectEffect.Technique = m_effectEffect.GetTechnique(0);

m_effectEffect.SetTexture("SourceTexture", m_screenTexture[0].DXTexture);

m_effectEffect.CommitChanges();

m_effectEffect.Begin();
m_effectEffect.BeginPass(0);

// Render stuff

m_effectEffect.EndPass();
m_effectEffect.End();
How can I combine these two shaders and keep them in separate files? I have tried nesting the two together but it does not seem to work.
Advertisement

I assume you want to... invert the faded color?

There's no such operation as "combining" two shaders. How does that mean? Run them in sequence? Or perhaps multiplying their results?

You might explore blending operations. D3D9 won't help, albeit D3DX has something you might use.

Personally I'd suggest to just author proper shaders. Designing automated systems to "blend" shaders together is no easy task.

Previously "Krohm"

There are at least two different problems here and you were not that clear on what you want.

Do you want to combine the shaders per object, like let's say fading a mesh from something to something? Then you need the pixel shader to compute the first value and the second value and to lerp between them. You do this by passing in the lerp factor to the shader.

Or maybe you want to combine the shaders using multiple passes, like adding multiple light together. This is not combining, it is blending.

Or maybe you want to combine the shaders doing a full screen pass. You need to render your full scene into a texture and then take that texture as pass it as input to another shader that reads it and writes to the backbuffer.

Try to mix shaders in HLSL code again, and to make it work. Because, even if you will successfully apply two shaders to one object, all pixels of this object will be processed twice. That's not very good for performance, especially when there are a lot of objects

In this particular case I may have to sacrifice performance for convenience. My engine needs to be flexible enough to apply two separate shaders. What I need to know is if it's possible and then the actual code to do it.

The reason I can't mix the shaders is because I have 32 'effects' and 31 'transitions'. That would be 992 shaders to combine them.

Transitions only occur when two 'layouts' transition between each other. A 'layout' is a bunch of objects that could include a 3d model, some quads, some text, a video etc. There can be two layouts in memory at one time. One is 'current' and the other is 'next'. The 'next' layout is only used when transitioning from one layout to the next. The 'current' layout is rendered to render target 0 (m_screenTexture[0].DXTexture) and 'next' is rendered to render target 1 (m_screenTexture[1].DXTexture). As you can see in the code these are assigned to the transition shader as Input1 / Input2. For the 'effect' shader render target 0 (m_screenTexture[0].DXTexture) is assigned to SourceTexture in the shader.

The transitions work great but for the sake of flexibility I need to be able to apply an 'effect' during this transition process.

This topic is closed to new replies.

Advertisement