Sign in to follow this  

Setting Matrices for Shader doesn't work

This topic is 4275 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

Hi, recently i discovered that was loading an effect-file with a vertexshader but not even used it. I still set the matrices with device->SetTransform(D3DTS_WORLD/VIEW/PROJ.,&matrix); so i just changed that to effect->SetMatrix("matWorld"/../..,&matrix) but now my vertices are not transformed at all :( . Here's what my fx file looks like:

string Position_Pass_0_Model : ModelData = "C:/Program Files/ATI Research Inc/RenderMonkey 1.6/Examples/Media/Models/Sphere.3ds";

float4x4 matView : ViewProjection;
float4x4 matProjection : ViewProjection;
float4x4 matWorld : World;

struct VS_INPUT 
{
   float4 Position : POSITION0;
   float3 Normal   : NORMAL0;
   
};

struct VS_OUTPUT 
{
   float4 Position : POSITION0;
   float3 normal : TEXCOORD0;
   
};

VS_OUTPUT Position_Pass_0_Vertex_Shader_vs_main( VS_INPUT Input )
{
   VS_OUTPUT Output;
   float4x4 matViewProjection=mul(matView,matProjection);
   float4 pos = mul( matWorld, Input.Position );
   Output.Position = mul( matViewProjection, pos );
   float4 n=mul( matWorld, float4(Input.Normal, 1.0f) );
   //float4 n2=mul(matViewProjection,n);
   Output.normal=float3(n.x,n.y,n.z);
   
   return( Output );
   
}




float4 Position_Pass_0_Pixel_Shader_ps_main(float3 n : TEXCOORD0) : COLOR0
{   
   float3 l=float3(0.0f, 1.0f, 0.0f);
   return( float4(1.0f,0.0f,0.0f,1.0f)*dot(n,l));
   
}




//--------------------------------------------------------------//
// Technique Section for Position
//--------------------------------------------------------------//
technique Position
{
   pass Pass_0
   {
      PixelShader = compile ps_2_0 Position_Pass_0_Pixel_Shader_ps_main();
   }

}





float4 Position_Pass_0_Pixel_Shader_ps_main(float3 n : TEXCOORD0) : COLOR0
{   
   float3 l=float3(0.0f, 1.0f, 0.0f);
   return( float4(1.0f,0.0f,0.0f,1.0f)*dot(n,l));
   
}




//--------------------------------------------------------------//
// Technique Section for Position
//--------------------------------------------------------------//
technique Position
{
   pass Pass_0
   {
      PixelShader = compile ps_2_0 Position_Pass_0_Pixel_Shader_ps_main();
   }

}



and my rendering loop looks like this:
void ngRenderer::render()
{


	//DO CULLING

	//RENDER BATCHES:
	//Turn on the Z-Test
	ngEngine &engine=ngEngine::getInstance();
	engine.g_pD3DDevice->SetRenderState(D3DRS_ZENABLE,D3DZB_TRUE);

	int size=renderPools.size();
	for(vector<ngRenderPool *>::iterator it=renderPools.begin();it!=renderPools.end();++it)
	{
		ngMaterial *mat=(**it).getMaterial();

		unsigned int numPasses=mat->begin();
	/*engine.g_pD3DDevice->SetTransform(D3DTS_WORLD,(**it).getWorldMatrix());
		engine.g_pD3DDevice->SetTransform(D3DTS_VIEW,&engine.getViewMatrix());
		engine.g_pD3DDevice->SetTransform(D3DTS_PROJECTION,&engine.getProjMatrix());*/
		
		effect->SetMatrix("matWorld",(**it).getWorldMatrix());
		effect->SetMatrix("matView",&engine.getViewMatrix());
		effect->SetMatrix("matProjection",&engine.getProjMatrix());


		for(unsigned int uiPass=0;uiPass < numPasses;uiPass++)
		{
			mat->beginPass(uiPass);

			int meshCount;
			CBaseMesh **mesh=(**it).getMeshPointer(&meshCount);
			for(int i=0;i<meshCount;i++)
			{
			ngVertexBuffer *pVBuffer=(*mesh[i]).pVBuff;
			ngIndexBuffer *pIBuffer=(*mesh[i]).pIBuff;
			Draw(pVBuffer ,pIBuffer);
			}
			mat->endPass();
		}
		
		mat->end();
	}


}


Where's the problem with this? Edit: Ok i found the solution for that problem: i forgot to compile the shader in the technique... But now after adding the compilation i only get 1 black quad(of a cube) that deforms funny when i move the camera... regards, m4gnus

Share this post


Link to post
Share on other sites
no sadly the debug output says nothing but ignoring redundant renderstate. btw noticed that matView and matProjection had the same semantic and fixed that. the error must be in the shader(because the matrices are right) but i don't know what could be wrong there.

regards,
m4gnus

Share this post


Link to post
Share on other sites
oops i think i did something worng with pasting..mom i'll post my new shader(fixed semantics):


//**************************************************************//
// Effect File exported by RenderMonkey 1.6
//
// - Although many improvements were made to RenderMonkey FX
// file export, there are still situations that may cause
// compilation problems once the file is exported, such as
// occasional naming conflicts for methods, since FX format
// does not support any notions of name spaces. You need to
// try to create workspaces in such a way as to minimize
// potential naming conflicts on export.
//
// - Note that to minimize resulting name collisions in the FX
// file, RenderMonkey will mangle names for passes, shaders
// and function names as necessary to reduce name conflicts.
//**************************************************************//

//--------------------------------------------------------------//
// Position
//--------------------------------------------------------------//
//--------------------------------------------------------------//
// Pass 0
//--------------------------------------------------------------//
string Position_Pass_0_Model : ModelData = "C:/Program Files/ATI Research Inc/RenderMonkey 1.6/Examples/Media/Models/Sphere.3ds";

float4x4 matView : matView;
float4x4 matProjection : matProjection;
float4x4 matWorld : matWorld;

struct VS_INPUT
{
float4 Position : POSITION0;
float3 Normal : NORMAL0;

};

struct VS_OUTPUT
{
float4 Position : POSITION0;
float3 normal : TEXCOORD0;

};

VS_OUTPUT Position_Pass_0_Vertex_Shader_vs_main( VS_INPUT Input )
{
VS_OUTPUT Output;
float4x4 matViewProjection=mul(matView,matProjection);
float4 pos = mul( matWorld, Input.Position );
Output.Position = mul( matViewProjection, pos );
float4 n=mul( matWorld, float4(Input.Normal, 1.0f) );
//float4 n2=mul(matViewProjection,n);
Output.normal=float3(n.x,n.y,n.z);

return( Output );

}




float4 Position_Pass_0_Pixel_Shader_ps_main(float3 n : TEXCOORD0) : COLOR0
{
float3 l=float3(0.0f, 1.0f, 0.0f);
return( float4(1.0f,0.0f,0.0f,1.0f)*dot(n,l));

}




//--------------------------------------------------------------//
// Technique Section for Position
//--------------------------------------------------------------//
technique Position
{
pass Pass_0
{
PixelShader = compile ps_2_0 Position_Pass_0_Pixel_Shader_ps_main();
VertexShader = compile vs_2_0 Position_Pass_0_Vertex_Shader_vs_main();
}

}





Hmm if the shader works ok for you then something with setting the matrices is wrong. but i don't see any problem there.

regards,
m4gnus

Share this post


Link to post
Share on other sites
my FVF is:D3DFVF_XYZ|D3DFVF_TEX1|D3DFVF_NORMAL
i changed the shader to:

//**************************************************************//
// Effect File exported by RenderMonkey 1.6
//
// - Although many improvements were made to RenderMonkey FX
// file export, there are still situations that may cause
// compilation problems once the file is exported, such as
// occasional naming conflicts for methods, since FX format
// does not support any notions of name spaces. You need to
// try to create workspaces in such a way as to minimize
// potential naming conflicts on export.
//
// - Note that to minimize resulting name collisions in the FX
// file, RenderMonkey will mangle names for passes, shaders
// and function names as necessary to reduce name conflicts.
//**************************************************************//

//--------------------------------------------------------------//
// Position
//--------------------------------------------------------------//
//--------------------------------------------------------------//
// Pass 0
//--------------------------------------------------------------//
string Position_Pass_0_Model : ModelData = "C:/Program Files/ATI Research Inc/RenderMonkey 1.6/Examples/Media/Models/Sphere.3ds";

float4x4 matView : matView;
float4x4 matProjection : matProjection;
float4x4 matWorld : matWorld;

struct VS_INPUT
{
float4 Position : POSITION0;
float2 tex1 : TEXCOORD0;
float3 Normal : NORMAL0;

};

struct VS_OUTPUT
{
float4 Position : POSITION0;
float3 normal : TEXCOORD1;

};

VS_OUTPUT Position_Pass_0_Vertex_Shader_vs_main( VS_INPUT Input )
{
VS_OUTPUT Output;
float4x4 matViewProjection=mul(matView,matProjection);
float4 pos = mul( matWorld, Input.Position );
Output.Position = mul( matViewProjection, pos );
float4 n=mul( matWorld, float4(Input.Normal, 1.0f) );
//float4 n2=mul(matViewProjection,n);
Output.normal=float3(n.x,n.y,n.z);

return( Output );

}




float4 Position_Pass_0_Pixel_Shader_ps_main(float3 n : TEXCOORD1) : COLOR0
{
float3 l=float3(0.0f, 1.0f, 0.0f);
return( float4(1.0f,0.0f,0.0f,1.0f)*dot(n,l));

}




//--------------------------------------------------------------//
// Technique Section for Position
//--------------------------------------------------------------//
technique Position
{
pass Pass_0
{
PixelShader = compile ps_2_0 Position_Pass_0_Pixel_Shader_ps_main();
VertexShader = compile vs_2_0 Position_Pass_0_Vertex_Shader_vs_main();
}

}





but i still get the same result

regards,
m4gnus

Share this post


Link to post
Share on other sites
that no longer works in fx composer.
id guess the worldviewproj is calculated incorrectly. but i dont have time to play with it now.
you should calc that in your app anyway, and then pass it in. that way youre only calculating it once per mesh instead of once per vertex.

Share this post


Link to post
Share on other sites
Quote:

that no longer works in fx composer.


i think that's because i changed the semantics to matView, matProjection, matWorld instead of just View,Projection,..

Quote:

id guess the worldviewproj is calculated incorrectly. but i dont have time to play with it now.
you should calc that in your app anyway, and then pass it in. that way youre only calculating it once per mesh instead of once per vertex.

i also thought about that but i thought maybe one of my shaders needs them seperated. Should i just pass one combined matrix(matViewProjection or even matWorldViewProjection) AND 2(3) seperated matrices(matView,matProjection,matWorld)?

Edit: sending one combined matrix(world*view*proj) doesn't work. I still results in a strange looking quad.


regards,
m4gnus

Share this post


Link to post
Share on other sites
Hi,

First, try to stick to the standar semantics so your code is more compatible with more effects. So please return the original names.

Second. Create a D3DXHandle object and use:
D3DXHANDLE hWorld = effect->GetParameterBySemantic(NULL, 'WORLD');
Be careful its case sensitive.
The idea behind this is to get a handle which is way faster to use than the parameter name.

Finally. Use your handle:
effect->SetMatrix(hWorld, yourMatrix);

Just make sure you call the GetParameterBySemantic only when you load the effect once and save the handle in a global variable or a class attribute for later use. Calling this function each frame will do nothing.
Also, remember that in DX9c you should call CommitChanges if the change is inside the pass. As it says in the docs:

"If the application changes any effect state using any of the Effect::Setx methods inside of a BeginPass/EndPass matching pair, the application must call CommitChanges to set the update the device with the state changes. If no state changes occur within a BeginPass and EndPass matching pair, it is not necessary to call CommitChanges."


Luck!
Guimo


Share this post


Link to post
Share on other sites
Quote:

Create a D3DXHandle object and use:
D3DXHANDLE hWorld = effect->GetParameterBySemantic(NULL, 'WORLD');
Be careful its case sensitive.
The idea behind this is to get a handle which is way faster to use than the parameter name.

Finally. Use your handle:
effect->SetMatrix(hWorld, yourMatrix);

Yeah i knew that that is faster but for testing purposes my way suffices.
Quote:

Also, remember that in DX9c you should call CommitChanges if the change is inside the pass.


Oh i didn't know that. And i was setting the matrices inside a pass. So i moved them outside. but sadly that didn't change anything.

My fixed rendering loop:

ngEngine &engine=ngEngine::getInstance();
engine.g_pD3DDevice->SetRenderState(D3DRS_ZENABLE,D3DZB_TRUE);

int size=renderPools.size();
for(vector<ngRenderPool *>::iterator it=renderPools.begin();it!=renderPools.end();++it)
{
ngMaterial *mat=(**it).getMaterial();

LPD3DXEFFECT effect=mat->getEffect();
D3DXMATRIX world,view,proj,viewproj,all;
world=*((**it).getWorldMatrix());
view=engine.getViewMatrix();
proj=engine.getProjMatrix();

viewproj=view*proj;
all=viewproj*world;
effect->SetMatrix("matWorld",&world);
effect->SetMatrix("matView",&view);
effect->SetMatrix("matProjection",&proj);
effect->SetMatrix("matWorldViewProjection",&all);
effect->CommitChanges();

unsigned int numPasses=mat->begin();
//engine.g_pD3DDevice->SetTransform(D3DTS_WORLD,(**it).getWorldMatrix());


/*engine.g_pD3DDevice->SetTransform(D3DTS_WORLD,(**it).getWorldMatrix());
engine.g_pD3DDevice->SetTransform(D3DTS_VIEW,&engine.getViewMatrix());
engine.g_pD3DDevice->SetTransform(D3DTS_PROJECTION,&engine.getProjMatrix());*/




for(unsigned int uiPass=0;uiPass < numPasses;uiPass++)
{
mat->beginPass(uiPass);

int meshCount;
CBaseMesh **mesh=(**it).getMeshPointer(&meshCount);
for(int i=0;i<meshCount;i++)
{
ngVertexBuffer *pVBuffer=(*mesh[i]).pVBuff;
ngIndexBuffer *pIBuffer=(*mesh[i]).pIBuff;
Draw(pVBuffer ,pIBuffer);
}
mat->endPass();
}

mat->end();
}



and my shader:

//**************************************************************//
// Effect File exported by RenderMonkey 1.6
//
// - Although many improvements were made to RenderMonkey FX
// file export, there are still situations that may cause
// compilation problems once the file is exported, such as
// occasional naming conflicts for methods, since FX format
// does not support any notions of name spaces. You need to
// try to create workspaces in such a way as to minimize
// potential naming conflicts on export.
//
// - Note that to minimize resulting name collisions in the FX
// file, RenderMonkey will mangle names for passes, shaders
// and function names as necessary to reduce name conflicts.
//**************************************************************//

//--------------------------------------------------------------//
// Position
//--------------------------------------------------------------//
//--------------------------------------------------------------//
// Pass 0
//--------------------------------------------------------------//
string Position_Pass_0_Model : ModelData = "C:/Program Files/ATI Research Inc/RenderMonkey 1.6/Examples/Media/Models/Sphere.3ds";

float4x4 matView : View;
float4x4 matProjection : Projection;
float4x4 matWorld : World;
float4x4 matWorldViewProjection : WorldViewProjection;

struct VS_INPUT
{
float4 Position : POSITION0;
float2 tex1 : TEXCOORD0;
float3 Normal : NORMAL0;

};

struct VS_OUTPUT
{
float4 Position : POSITION0;
float3 normal : TEXCOORD1;

};

VS_OUTPUT Position_Pass_0_Vertex_Shader_vs_main( VS_INPUT Input )
{
VS_OUTPUT Output;
/* float4x4 matViewProjection=mul(matView,matProjection);
float4 pos = mul( matWorld, Input.Position );
Output.Position = mul( matViewProjection, pos );*/


Output.Position = mul(matWorldViewProjection, Input.Position);
float4 n=mul( matWorld, float4(Input.Normal, 1.0f) );
//float4 n2=mul(matViewProjection,n);
Output.normal=float3(n.x,n.y,n.z);

return( Output );

}




float4 Position_Pass_0_Pixel_Shader_ps_main(float3 n : TEXCOORD1) : COLOR0
{
float3 l=float3(0.0f, 1.0f, 0.0f);
return( float4(1.0f,0.0f,0.0f,1.0f)*dot(n,l));

}




//--------------------------------------------------------------//
// Technique Section for Position
//--------------------------------------------------------------//
technique Position
{
pass Pass_0
{
PixelShader = compile ps_2_0 Position_Pass_0_Pixel_Shader_ps_main();
VertexShader = compile vs_2_0 Position_Pass_0_Vertex_Shader_vs_main();
}

}




regards,
m4gnus

Share this post


Link to post
Share on other sites
Hi,
After testing your shader in FXComposer I find a little problem in your matrix operations. I have modified your FX so it provides minimal functions. You should see your models as a simple white object. Note that the World, View and projection matrices are not required for this exaple to work.


float4x4 matView : View;
float4x4 matProjection : Projection;
float4x4 matWorld : World;
float4x4 matWorldViewProjection : WorldViewProjection;

struct VS_INPUT
{
float4 Position : POSITION0;
};

struct VS_OUTPUT
{
float4 Position : POSITION0;

};

VS_OUTPUT Position_Pass_0_Vertex_Shader_vs_main( VS_INPUT Input )
{
VS_OUTPUT Output;
Output.Position = mul(Input.Position, matWorldViewProjection);
return( Output );

}

float4 Position_Pass_0_Pixel_Shader_ps_main() : COLOR0
{
return float4(1.0f,1.0f,1.0f,1.0f);
}

//--------------------------------------------------------------//
// Technique Section for Position
//--------------------------------------------------------------//
technique Position
{
pass Pass_0
{
PixelShader = compile ps_2_0 Position_Pass_0_Pixel_Shader_ps_main();
VertexShader = compile vs_2_0 Position_Pass_0_Vertex_Shader_vs_main();
}

}


Please tell me if you can see anything.

Also, these is one operation in your shader:
Output.Position = mul(matWorldViewProjection, Input.Position);

This may be the problem. Depending on your math and your matrix order, maybe you should multiply vector*matrix instead of Matrix*Vector. I changed the order of the operation.

So, try this simple shader in your program. If you can see your object as a white figure then it means your program setup is fine and the problem may be in the shader.

Luck!
Guimo

P.S. I removed the ModelData semantic as its no standard.

Share this post


Link to post
Share on other sites
ok now it works :/ probably it really was the roder of the multiplications... but now that i have a running version it shouldn't be a problem to find cause for the problem, so thank you.

regards,
m4gnus

Share this post


Link to post
Share on other sites

This topic is 4275 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.

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