Sign in to follow this  
sofakng

What do I use for parameters on this shader I downloaded? (shader inside)

Recommended Posts

I'm trying to create a very simple 2D game and I want to have glowing lines for a special effect like seen here: http://devimg.net/?Post=448 http://www.introversion.co.uk/defcon/about/screenshots.html From what I've read the best way to do this is to apply a simple bloom shader to the scene. Well, I've found a couple of shaders but they all require shader model v2.0 and I'm trying to target my game to a lower specification (shader model v1.3 or lower) So I've finally found a shader model 1.1 complaint bloom shader but I can't figure it out. I'm using a Delphi DirectX 9.0 wrapper called Asphyre and it fully supports shaders but I simply don't understand what parameters I need to give to this shader to make it work. If I don't specify any parameters to the shader I just get a white or a black screen. Please help... Here is the shader code:
//////////////////////////////////////////////
// Glow Shader:
// Glows are rendered as a separate pass
// to the rest of the scene.  Glowing objects
// get rendered to a texture, the texture is
// blurred, then the texture is overlaid onto 
// the main scene.
//////////////////////////////////////////////

texture glowTexture;
// texTrans is a transform used to map a 1x1 quad
// to fill the screen.
float4x4 texTrans : WorldProjection;
// pSize is the pixel size of the texture,
// equivalent to the inverse of the texture width.
float pSize;

sampler GlowSampler = sampler_state
{
    Texture   = (glowTexture);
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
};

//Passed to the vertex shader from the pipeline
struct GLOW_INPUT
{
	float4 pos : POSITION;
	float2 texCoord : TEXCOORD;
};

//VS output / PS input:
struct GLOW_OUTPUT
{
    float4 pos : POSITION;
    float2 texCoord0 : TEXCOORD0;
    float2 texCoord1 : TEXCOORD1;
    float2 texCoord2 : TEXCOORD2;
    float2 texCoord3 : TEXCOORD3;
};

struct TEXTURE_OUTPUT
{
    float4 pos : POSITION;
    float2 texCoord0 : TEXCOORD0;
};
//PS output:
struct pixel
{
	float4 color : COLOR;
};

//////////////////////////
//  Vertex Shaders:
//////////////////////////
// These glow vertex shaders blur the texture in 
// specific direction - up, down, left, and right.
// They are used one after the other to obtain a full blur.
// VS1.3 hardware could do this in 2 passes rather than 4,
// but I only have a lowly Geforce4...
// They work by offsetting the texture coordinates into 
// 4 texCoord streams.  The pixel shader then reads the
// texture color at each of these texcoords and averages them
// together, effectively sampling a cluster of pixels.

GLOW_OUTPUT glowVSHorizontal1(GLOW_INPUT IN)
{
	GLOW_OUTPUT OUT;
	
	OUT.pos =  mul(IN.pos, texTrans);
	OUT.texCoord0 = IN.texCoord + float2(-pSize*3, 0); 
	OUT.texCoord1 = IN.texCoord + float2(-pSize*2, 0); 
	OUT.texCoord2 = IN.texCoord + float2(-pSize*1, 0); 
	OUT.texCoord3 = IN.texCoord + float2(0, 0 ); 
	
	return OUT;
}
GLOW_OUTPUT glowVSHorizontal2(GLOW_INPUT IN)
{
	GLOW_OUTPUT OUT;
	
	OUT.pos =  mul(IN.pos, texTrans);
	OUT.texCoord0 = IN.texCoord + float2(pSize*3,0); 
	OUT.texCoord1 = IN.texCoord + float2(pSize*2, 0); 
	OUT.texCoord2 = IN.texCoord + float2(pSize*1, 0); 
	OUT.texCoord3 = IN.texCoord + float2(0, 0 ); 
	
	return OUT;
}
GLOW_OUTPUT glowVSVertical1(GLOW_INPUT IN)
{
	GLOW_OUTPUT OUT;
	
	OUT.pos =  mul(IN.pos, texTrans);
	OUT.texCoord0 = IN.texCoord + float2(0,-pSize*3); 
	OUT.texCoord1 = IN.texCoord + float2(0,-pSize*2); 
	OUT.texCoord2 = IN.texCoord + float2(0,-pSize*1); 
	OUT.texCoord3 = IN.texCoord + float2(0,0); 
	
	return OUT;
}
GLOW_OUTPUT glowVSVertical2(GLOW_INPUT IN)
{
	GLOW_OUTPUT OUT;
	
	OUT.pos =  mul(IN.pos, texTrans);
	OUT.texCoord0 = IN.texCoord + float2(0,pSize*3); 
	OUT.texCoord1 = IN.texCoord + float2(0,pSize*2);  
	OUT.texCoord2 = IN.texCoord + float2(0,pSize*1); 
	OUT.texCoord3 = IN.texCoord + float2(0,0);  
	
	return OUT;
}


// This is the plain vertex shader used to overlay the 
// final glow texture over the rest of the scene.
TEXTURE_OUTPUT outputGlowVS(GLOW_INPUT IN)
{
	TEXTURE_OUTPUT OUT;
	OUT.pos =  mul(IN.pos, texTrans);
	OUT.texCoord0 = IN.texCoord;
	
	return OUT;
}



//////////////////////////
//  Pixel Shaders:
//////////////////////////

// Add the texture values at each of the supplied texCoords
// together, weighted by some arbitary function that gives 
// a reasonable appearance.
// These weights are critical to the glow behaviour,
// and tiny changes in the values can suddenly make the glow
// invisible or overpowering.  If anyone knows how to make this 
// better, please let me know...
pixel glowPS(GLOW_OUTPUT IN)
{
	pixel OUT;
	float4 color = tex2D( GlowSampler, IN.texCoord0 ) * 0.1;
	color += tex2D( GlowSampler, IN.texCoord1 ) * 0.3;
	color += tex2D( GlowSampler, IN.texCoord2 ) * 0.4;
	color += tex2D( GlowSampler, IN.texCoord3 ) * 0.25;
	
	OUT.color = color;
	OUT.color.a = 1.0f;
	
	return OUT;
}

// This is the pixel shader used to overlay the final glow image
// onto the rest of the scene.
pixel outputGlowPS(TEXTURE_OUTPUT IN)
{
	pixel OUT;
	OUT.color =  tex2D( GlowSampler, IN.texCoord0 );	
	return OUT;
}


//////////////////////////
//  Techniques:
//////////////////////////

// Four passes blur the texture in different directions.
// The final one overlays the texture onto the rest of 
// the scene.
// Annotations are used so my application can automatically
// sort these passes into the appropriate rendering stage.

technique T0
{
	pass P0 <string renderStage="texture";>
	{
		Sampler[0] = (GlowSampler);
		vertexshader = compile vs_1_1 glowVSHorizontal1();
		pixelshader  = compile ps_1_1 glowPS();
		fvf = XYZ | Tex1;
	}
	pass P1 <string renderStage="texture";>
	{
		Sampler[0] = (GlowSampler);
		vertexshader = compile vs_1_1 glowVSVertical1();
		pixelshader  = compile ps_1_1 glowPS();
		fvf = XYZ | Tex1;
	}
	pass P2 <string renderStage="texture";>
	{
		Sampler[0] = (GlowSampler);
		vertexshader = compile vs_1_1 glowVSHorizontal2();
		pixelshader  = compile ps_1_1 glowPS();
		fvf = XYZ | Tex1;
	}
	pass P3 <string renderStage="texture";>
	{
		Sampler[0] = (GlowSampler);
		vertexshader = compile vs_1_1 glowVSVertical2();
		pixelshader  = compile ps_1_1 glowPS();
		fvf = XYZ | Tex1;
	}

	pass P4 <string renderStage="post";>
	{
		Sampler[0] = (GlowSampler);
		vertexshader = compile vs_1_1 outputGlowVS();
		pixelshader  = compile ps_1_1 outputGlowPS();
		fvf = XYZ | Tex1;
		
		AlphaBlendEnable = true;
		BlendOp = Min;
		SrcBlend = One;
		DestBlend = One;
	}	
}

EDIT: 'source' tags are preferred to 'code' tags for longer listings. [Edited by - jollyjeffers on May 23, 2007 3:36:01 PM]

Share this post


Link to post
Share on other sites
Howdy,

I'm at work right now, so I'll just give you a general idea of what you need to do rather than specific code. If it's too difficult to go from my rough outline to looking up the actual function names then perhaps you should consider whether you're diving into shaders a little too soon (I don't mean that in a bad way).

1. The parameters that you need to pass in are basically the globals at the top of the file. glowTexture, texTrans and pSize.

The command you want is something like this:


pShader->SetFloatParameter("pSize", 0.4f);


where pShader is the compiled shader.

2. Your vertex buffer or model needs to contain at least the parameters mentioned in the vertex shader's input. Namely pos and texCoord. If it's your own vertex buffer, make sure that it contains this data (it doesn't need to be named the same, but it should be the same size (e.g. your vertex buffer's texCoord could be stored as float u; float v;)).
If it's a model, you may need to clone the model to another vertex format and then add the data.
This is a pretty big topic in itself.

3. Applying the shader.

Again, off the top of my head:


UINT passes = pShader->Begin();
for (UINT n = 0; n < passes; n++)
{
pShader->BeginPass(n);
// Do your rendering here
pShader->EndPass(n);
}
pShader->End();


good luck!

Share this post


Link to post
Share on other sites
Thanks for the excellent reply!

I'm using a Delphi DirectX wrapper called Asphyre, so the syntax is slightly different but I get the idea.

I can set pSize no problem (but I have no idea what value to put in there), but I'm not sure how to set glowTexture or texTrans.

These are my available parameter types: (in Asphyre)

TShaderParameterType = (sptCustom, sptTexture, sptWorldViewProjection,
sptViewProjection, sptWorldInverseTranspose, sptCameraPosition, sptWorld,
sptWorldInverse, sptWorldView, sptProjection);


My game is only in 2D so I don't think I have to worry about models, etc.

Eventually I'd like to learn about shaders, but my game will be very simple. However I'd like to use this simple bloom shader but can't figure it out... :(

Share this post


Link to post
Share on other sites
hey no worries. I think I might also appropriate the shader you've downloaded ;)

According to the comment, pSize = "the pixel size of the texture, equivalent to the inverse of the texture width".

The inverse of a number is 1 / that number. So the inverse of 4 is 1/4 or 0.25.

I think what he or she (let's face it, it's not a she), is getting at, is the size of a pixel in UV scale. So if you have a square that has UVs 0...2 in both dimensions and a texture that is 256x256 then pSize = 2 / 256.
If you don't know about UVs then assume 0..1 in both dimensions.

glowTexture and texTrans are obviously both textures. IIRC the command, in C, is just this:

pShader->SetTexture("glowTexture", theTextureYouveLoaded);

where theTextureYouveLoaded is, I think, a LPDIRECT3D9TEXTURE. I think the command to load a texture in turn is device->LoadTexture. Where "device" is the LPDIRECT3D9DEVICE that you had to set up to get anything working at all.

Share this post


Link to post
Share on other sites
Once again, thanks a ton for your help...

Actually, it looks like there is only one texture parameter, glowTexture. The other parameter is a float4x4 (eg. a matrix?).

float4x4 texTrans : WorldProjection;


In Asphyre (my DirectX wrapper), would it be an "sptWorld" shader parameter type? The others that seem possible are "sptWorldView or sptWorldViewProjection".

What kind of texture should be used for the glowTexture parameter? Is this my rendering target? (I thought my rendering target was automatically passed into the shader?)

...or is this shader looking for a special glow texture file? (eg. a texture that just contains a "glow" image or something)

Thanks again for all of your help... I really, really appriciate it!

Share this post


Link to post
Share on other sites
Doh! You're right of course, texTrans is the transformation matrix.

There are three matrices involved in calculating the position of a given vertex on the screen. The world matrix is unique for each model/billboard/whatever and is basically a given object's position and orientation. The view matrix can be considered the camera's matrix: by changing the view matrix everything on screen moves without you needing to recalculate any world matrices.
The projection matrix is how to project the 3d world on to your 2d screen. Different matrices here can go from fish-eye to regular lens or even views where objects don't diminish in size with distance.

Anyhoo, in answer to your question, I'd try sptWorldViewProjection. Although the code only specifies WorldProjection, often the "world" is assumed to already be multiplied by the view (you have to do this in OpenGL, so former OpenGL programmers rarely differentiate between "world" and "world x view").

If it doesn't work, get the matrices separately, something like this:

pDevice->GetRenderState( D3DMATRIX_WORLD, &world);
pDevice->GetRenderState( D3DMATRIX_PROJECTION, &proj);
worldProj = world * proj;

----

Regarding the other question, yes, glowTexture is a bitmap file that you must provide. Remember, load it in using pDevice->LoadTexture and then set it via pShader->SetTexture.

I'd use a 256x256 texture (this is probably bigger than necessary or optimal here, but I always use this size first as it's the "safest". Try with a smaller texture once you've got it working with a 256 texture). Just a white circle on a black background, but with a gradient (so the circle appears more opaque towards the centre), and see what effect you get.

Share this post


Link to post
Share on other sites
You've answered my questions perfectly! Thank you very, very much.

I'll fool around with the glowTexture and texTrans and let you know what I end up with.

If you are fooling around with it yourself and find a good glowTexture or pSize please let me know... :)

Thanks,
John

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this