Sign in to follow this  
rrr_r

Optimizing HLSL code

Recommended Posts

rrr_r    122
Hello, I have been scouring the internet for help for some time concerning optimizing my HLSL code. I got a few pointers from MSDN and from various sites around, but I really am stuck here, and was wondering if I could get some pointers from the gamedev community. I have coding an .fx file that handles lighting in my program. On my computer with an GT 8800, it runs alright, but on any machine with a worse graphics card, the framerate drops to ~12 fps. The file is meant to handle blinn-phong lighting with color, alpha, specular, and normal mapping. I have already optimized it a lot, like transferring most of the calculation to the vertex shader. Here is the code:
struct Light
{
	bool enabled;
	int type;			//0 = dir, 1 = point, 2 = spot
	float3 dir;
	float3 pos;
	float4 ambient;
	float4 diffuse;
	float4 specular;
	float spotInnerCone;
	float spotOuterCone;
	float invradius;		// 1 / radius
};

struct Material
{
	bool color;
	bool normal;
	bool spec;
	bool alpha;
	float4 ambient;
	float4 diffuse;
	float4 emissive;
	float4 specular;
	float shininess;
};

//-----------------------------------------------------------------------------
// Globals.
//-----------------------------------------------------------------------------

float4 globalAmbient;

float4x4 worldMatrix;
float4x4 worldInverseTransposeMatrix;
float4x4 worldViewProjectionMatrix;

float3 cameraPos;

float4 tint;


Light lights[8];
Material material;

float Timer;

//-----------------------------------------------------------------------------
// Textures.
//-----------------------------------------------------------------------------

texture colorMapTexture;
texture normalMapTexture;
texture specMapTexture;
texture alphaMapTexture;

sampler2D colorMap = sampler_state
{
	Texture = <colorMapTexture>;
	MagFilter = Linear;
	MinFilter = Anisotropic;
	MipFilter = Linear;
	MaxAnisotropy = 16;
};

sampler2D normalMap = sampler_state
{
	Texture = <normalMapTexture>;
	MagFilter = Linear;
	MinFilter = Anisotropic;
	MipFilter = Linear;
	MaxAnisotropy = 16;
};

sampler2D specMap = sampler_state
{
	Texture = <specMapTexture>;
	MagFilter = Linear;
	MinFilter = Anisotropic;
	MipFilter = Linear;
	MaxAnisotropy = 16;
};

sampler2D alphaMap = sampler_state
{
	Texture = <alphaMapTexture>;
	MagFilter = Linear;
	MinFilter = Anisotropic;
	MipFilter = Linear;
	MaxAnisotropy = 16;
};

//-----------------------------------------------------------------------------
// Vertex Shaders.
//-----------------------------------------------------------------------------

struct VS_LP_INPUT
{
	float3 position : POSITION;
	float2 texCoord : TEXCOORD0;
	float3 normal : NORMAL;
	float4 tangent : TANGENT;
};

struct VS_LP_OUTPUT
{
	float4 position : POSITION;
	float3 worldPos : TEXCOORD0;
	float2 texCoord : TEXCOORD1;
	float3 halfVector : TEXCOORD2;
	float3 lightDir : TEXCOORD3;
	float atten : TEXCOORD4;
	float4 ambient : COLOR0;
	float4 diffuse : COLOR1;
	float4 specular : COLOR2;
};

//-----------------------------------------------------------------------------

VS_LP_OUTPUT VS_LightingPoor(VS_LP_INPUT IN, uniform int i)
{
	VS_LP_OUTPUT OUT;

	float3 worldPos = mul(float4(IN.position, 1.0f), worldMatrix).xyz;
	float atten = 0.0f;

	OUT.halfVector = 0.0f;
	OUT.lightDir = 0.0f;

	OUT.ambient = material.ambient * lights[i].ambient;
	OUT.diffuse = material.diffuse * lights[i].diffuse;
	OUT.specular = material.specular * lights[i].specular;

	if (lights[i].enabled == true)
	{
		float3 lightDir = 0.0f;

		if (lights[i].type == 0)	{lightDir = lights[i].dir * 0.5f;	atten = 1.0f;}
		else	{lightDir = (lights[i].pos - worldPos) * lights[i].invradius;	atten = saturate(1.0f - dot(lightDir, lightDir));}

		lightDir = normalize(lightDir);

		if (lights[i].type == 2)
		{
			float2 cosAngles = cos(float2(lights[i].spotOuterCone, lights[i].spotInnerCone) * 0.5f);
			float spotDot = dot(lightDir, lights[i].dir);
			atten *= smoothstep(cosAngles[0], cosAngles[1], spotDot);
		}


		if (atten > 0.0f)
		{
			float3 n = normalize(mul(IN.normal, (float3x3)worldInverseTransposeMatrix));
			float3 t = normalize(mul(IN.tangent.xyz, (float3x3)worldInverseTransposeMatrix));
			float3 b = normalize(cross(n, t) * IN.tangent.w);

			float3x3 tbnMatrix = float3x3(	t.x, b.x, n.x,
									t.y, b.y, n.y,
									t.z, b.z, n.z	);

			OUT.halfVector = mul(normalize(lightDir + normalize(cameraPos - worldPos)), tbnMatrix);
			OUT.lightDir = mul(lightDir, tbnMatrix);
		}
	}

	OUT.position = mul(float4(IN.position, 1.0f), worldViewProjectionMatrix);
	OUT.worldPos = worldPos;
	OUT.texCoord = IN.texCoord;

	OUT.atten = atten;

	return OUT;
}

//-----------------------------------------------------------------------------
// Pixel Shaders.
//-----------------------------------------------------------------------------

float4 PS_LightingPoor(VS_LP_OUTPUT IN, uniform int i) : COLOR
{
	float4 color = 0.0f;

	if (i == 0)	color += globalAmbient * material.ambient + material.emissive;

	if (lights[i].enabled == true && IN.atten > 0.0f)
	{
		float3 normmap = float3(0.0f, 0.0f, 1.0f);
		float4 specmap = 1.0f;
		float alphamap = 1.0f;
		float4 colmap = 1.0f;

		if (material.normal == true)	{normmap = tex2D(normalMap, IN.texCoord).rgb; normmap = normalize(normmap * 2.0f - 1.0f);}
		if (material.spec == true)	specmap = tex2D(specMap, IN.texCoord);
		if (material.alpha == true)	alphamap = tex2D(alphaMap, IN.texCoord);
		if (material.color == true)	colmap = tex2D(colorMap, IN.texCoord);

		float nDotL = saturate(dot(normmap, IN.lightDir));
		float4 specall = 0.0f;
		float power = 0.0f;

		if (nDotL > 0.0f)
		{
			specall = IN.specular * specmap;
			if (specall[0] != 0.0f || specall[1] != 0.0f || specall[2] != 0.0f)
			{
				float nDotH = saturate(dot(normmap, IN.halfVector));
				if (nDotH > 0.0f)	power = pow(nDotH, material.shininess);
			}
		}

		color += (	IN.ambient +
				IN.diffuse * nDotL +
				specall * power	) * IN.atten;

		color *= float4(1.0f, 1.0f, 1.0f, alphamap) * colmap;
	}

	return color * tint;
}

//-----------------------------------------------------------------------------
// Techniques.
//-----------------------------------------------------------------------------

technique LightingPoorSinglePass
{
	pass p0
	{
		VertexShader = compile vs_3_0 VS_LightingPoor(0);
		PixelShader = compile ps_3_0 PS_LightingPoor(0);
	}
}

technique LightingPoorEightPass
{
	pass p0
	{
		VertexShader = compile vs_3_0 VS_LightingPoor(0);
		PixelShader = compile ps_3_0 PS_LightingPoor(0);
	}
	pass p1
	{
		VertexShader = compile vs_3_0 VS_LightingPoor(1);
		PixelShader = compile ps_3_0 PS_LightingPoor(1);
		ZWriteEnable = false;
		AlphaBlendEnable = true;
		SrcBlend = One;
		DestBlend = One;
	}
	pass p2
	{
		VertexShader = compile vs_3_0 VS_LightingPoor(2);
		PixelShader = compile ps_3_0 PS_LightingPoor(2);
		ZWriteEnable = false;
		AlphaBlendEnable = true;
		SrcBlend = One;
		DestBlend = One;
	}
	pass p3
	{
		VertexShader = compile vs_3_0 VS_LightingPoor(3);
		PixelShader = compile ps_3_0 PS_LightingPoor(3);
		ZWriteEnable = false;
		AlphaBlendEnable = true;
		SrcBlend = One;
		DestBlend = One;
	}
	pass p4
	{
		VertexShader = compile vs_3_0 VS_LightingPoor(4);
		PixelShader = compile ps_3_0 PS_LightingPoor(4);
		ZWriteEnable = false;
		AlphaBlendEnable = true;
		SrcBlend = One;
		DestBlend = One;
	}
	pass p5
	{
		VertexShader = compile vs_3_0 VS_LightingPoor(5);
		PixelShader = compile ps_3_0 PS_LightingPoor(5);
		ZWriteEnable = false;
		AlphaBlendEnable = true;
		SrcBlend = One;
		DestBlend = One;
	}
	pass p6
	{
		VertexShader = compile vs_3_0 VS_LightingPoor(6);
		PixelShader = compile ps_3_0 PS_LightingPoor(6);
		ZWriteEnable = false;
		AlphaBlendEnable = true;
		SrcBlend = One;
		DestBlend = One;
	}
	pass p7
	{
		VertexShader = compile vs_3_0 VS_LightingPoor(7);
		PixelShader = compile ps_3_0 PS_LightingPoor(7);
		ZWriteEnable = false;
		AlphaBlendEnable = true;
		SrcBlend = One;
		DestBlend = One;
	}
}
I did not include the "LightingNice" code because I don't use it at all. Thank you.

Share this post


Link to post
Share on other sites
rrr_r    122
I'm sorry. I did not realize that. Would it be possible to move this to a different subforum, such as the DirectX subforum or should I repost it there?

Once again, I'm really sorry about this.

Share this post


Link to post
Share on other sites
Jarrod1937    522
Quote:
Original post by rrr_r
I'm sorry. I did not realize that. Would it be possible to move this to a different subforum, such as the DirectX subforum or should I repost it there?

Once again, I'm really sorry about this.

Oh, its no biggie, nothing to worry about. But you probably will get better luck in a more programming oriented forum section.
As for pm'ing a mod, i would assume it would be ok to repost this topic in the other forum, just pm a mod to let him/her know to close this topic. No need to wait for a mod if you need help :-)

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