Skip to main content
GameDev.net gamedev.net
🔒 Locked

Shader problem

Started by Aardvajk Jan 9, 2009 at 3:00 PM 0 replies 1.6k views
Original Post
Aardvajk
Aardvajk
[EDIT - not to be a solved-thread-poster, but I've figured this out already. See end of post [smile]] I'm trying to switch between using two different vertex shaders in the same render loop and they seem to be interfering with each other. This is so weird. Am I doing anything wrong in the order of the below (the calls to my wrappers just translate into the normal Direct3D calls)? I understand that I have to finish with one shader before I start setting the constants of the next one, but what the heck is happening here?

void GameMode::Render(GraphicsDevice &Graphics)
{
	D3DXMATRIX CamView=Camera.ViewMatrix();

	D3DXMATRIX World;
	D3DXMatrixIdentity(&World);

	std::vector<D3DXMATRIX> Array(20);
	for(int I=0;I<20;++I) D3DXMatrixIdentity(&(Array));

	Graphics.SetTexture(Level.MapTexture);
	Graphics.SetVertexDeclaration(BasicVertexDecl);

	Graphics.SetVertexShader(BasicShader);

	BasicShader.SetMatrix(Graphics,BasicView,CamView);
	BasicShader.SetMatrix(Graphics,BasicViewProj,CamView*Pro);
	
	Level.MapMesh.Render(Graphics);

	Graphics.SetTexture(Level.PlayerTexture);
	Graphics.SetVertexDeclaration(ModelVertexDecl);

	Graphics.SetVertexShader(ModelShader);
	
	ModelShader.SetMatrix(Graphics,ModelWorld,World);
	ModelShader.SetMatrix(Graphics,ModelView,CamView);
	ModelShader.SetMatrix(Graphics,ModelViewProj,CamView*Pro);

	ModelShader.SetMatrixArray(Graphics,ModelMatrixArray,&(Array[0]),20);

	Level.PlayerMesh.Render(Graphics);
}
The crazy thing is that when the call to ModelShader.SetMatrixArray() happens near the bottom, it is affecting the graphics drawn by the previous call by Level.MapMesh.Render(). Specifically, the previous shader is lighting some map squares darker than they should be. Stops happening if I comment out the ModelShader.SetMatrixArray() line. In case it helps, these are the two shaders: basic:

matrix view;
matrix viewproj;

vector lightdir=vector(-1,1,-1,0);

struct VS_INPUT
{
	vector position : POSITION;
	vector normal   : NORMAL;
	float2 texcoord : TEXCOORD;
};

struct VS_OUTPUT
{
	vector position : POSITION;
	vector diffuse  : COLOR;
	float2 texcoord : TEXCOORD;
};

VS_OUTPUT main(VS_INPUT input)
{
	VS_OUTPUT output=(VS_OUTPUT)0;
	
	output.position=mul(input.position,viewproj);
	output.texcoord=input.texcoord;

	input.normal=normalize(input.normal);
	input.normal.w=0;
	
	lightdir=mul(lightdir,view);
	input.normal=mul(input.normal,view);

	float s=dot(lightdir,input.normal);
	if(s<0.3f) s=0.3f;
	
	output.diffuse=vector(s,s,s,1);
	return output;
}


model:

matrix world;
matrix view;
matrix viewproj;

matrix matrixarray[20];

vector lightdir=vector(-1,1,-1,0);

struct VS_INPUT
{
	vector position : POSITION;
	vector normal   : NORMAL;
	float2 texcoord : TEXCOORD;
	float2 bone     : BLENDINDICES;
	float2 weight   : BLENDWEIGHT;
};

struct VS_OUTPUT
{
	vector position : POSITION;
	vector diffuse  : COLOR;
	float2 texcoord : TEXCOORD;
};

VS_OUTPUT main(VS_INPUT input)
{
	VS_OUTPUT output=(VS_OUTPUT)0;

	vector pos=(vector)0;
	float3 norm=(float3)0;

	pos+=mul(input.position,matrixarray[input.bone[0]])*input.weight[0];
	pos+=mul(input.position,matrixarray[input.bone[1]])*input.weight[1];

	norm+=mul(input.normal,(float3x3)matrixarray[input.bone[0]])*input.weight[0];
	norm+=mul(input.normal,(float3x3)matrixarray[input.bone[1]])*input.weight[1];	

	input.normal=vector(norm.x,norm.y,norm.z,0);
	input.normal=normalize(input.normal);

	output.position=mul(pos,world);
	output.position=mul(output.position,viewproj);

	output.texcoord=input.texcoord;

	vector light=mul(lightdir,view);
	input.normal=mul(input.normal,view);

	float s=dot(light,input.normal);
	if(s<0.3f) s=0.3f;

	output.diffuse=vector(s,s,s,1);
	
	return output;
}


Help! [smile] [EDIT] Okay. So you have to call SetDefaults() every time you switch shaders. Mutter mutter. [Edited by - EasilyConfused on January 9, 2009 4:54:59 PM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.