Hlsl pixelshader interpolated vars count



Hi all,

I’m writing a shader in hlsl and my current problem is that I fight with the count of interpolated vars I have in sm3.0

my current input in the pixel shader is this

	float4 Pos: POSITION;
	float2 TexCoord0 : TEXCOORD0;
	float3 Normal : NORMAL; // tangent space
	float4 Tangent : TANGENT;
	float3 CamVec : TEXCOORD1;
	float4 VertCol :  TEXCOORD2;
	float DistanceToCam : TEXCOORD3; // used to blend out the rimlight based on the camera distance
	float3 tLightDirArray[MaxLights] : TEXCOORD4;
	// TEXCOORD5 used with 2 lights
	// TEXCOORD6 used with 3 lights
	// TEXCOORD7 used with 4 lights
	float3 wCamVec : TEXCOORD5;
	float3 wNormal : TEXCOORD6;
	float3 wTangent  : TEXCOORD7;
	float faceDir : VFACE;

I would love to use up to 3 lights but atm I can only pass one light as I’m already at the limit…

Now my question is… Is there another way of supporting more lights and could I drop some of the vars and calculate them in the pixel shader without killing the performance?

the Tangent var carries info from the model so I need it
the w… vars are for the reflection stuff (cubemap) and some custom stuff I do in the shader
To make it short. I need the vars somehow in the pixel shader, so dropping some of them wouldn’t be a useful option.


It seems unusual to me to pass both Normal and Tangent AND wNormal and wTangent into the shader.

Why do you need to pass the tangent in both world and object space into the pixel shader?

Second, calculating the light vector and or camera vector in vertex shader and pass into pixel shader can be a calculation optimization, but I wouldn’t do that myself for the lightvector in sm3. I would calculate the light vector in the pixel shader.

The camera vector could still be done in the vertex shader since you only have one of those. But it can also be done in the pixel shader to free up another texcoord.


Hi kees,

I’m doing most of the calculation in the vs because of performance optimization. I have no idea how big the real influence ingame is though.

Everything I may calculate in the pixel shader is great.

To get from one coordinate system to another I need to multiply with a matrix right? I have no idea how expensive this is.

so you say this wouldn’t be a big hit for the performance?


Lets start with the 3 light vectors and the camera vector.
Those require a single subtract to calculate.

No matrix math.

So those are your first 4 to do in the pixel shader.

Second you can consider putting things in the .w coordinate of your texcoords (and .z coordinate of your UV texcoords).

Generally speaking your normal, binormal and tangent are passed as a float3 from vertex to pixel. So that leaves the .w coordinate (if you make them float4) to store additional things you pre-calculated.

UV texcoords (of which you have only 1 it seems) you only use .xy. So that leaves .zw to store additional calculations.

If after that you need more texcoords freed up, you want to look at redesigning your shader so you don’t need more then 1 ‘space’ in your pixel shader.

Perhaps you can do everything in world space or tangent space instead of needing both. But…it depends on what you are designing your shader for.

Its not that bad to do a matrix mul in the pixel shader, though, if you cannot redesign it. It will not instantly kill performance.


thx kees!

got 3 lights in and with your idea to use the open spots in the float vectors I even have some vars free for stuff that might be added in the future.
Great info!