Jump to content
  • Advertisement
Sign in to follow this  
rrr_r

Optimizing HLSL code

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.ambient;
	OUT.diffuse = material.diffuse * lights.diffuse;
	OUT.specular = material.specular * lights.specular;

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

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

		lightDir = normalize(lightDir);

		if (lights.type == 2)
		{
			float2 cosAngles = cos(float2(lights.spotOuterCone, lights.spotInnerCone) * 0.5f);
			float spotDot = dot(lightDir, lights.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.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
Advertisement
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
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
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!