Can't Set Vertex Shader Constant?

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
cooljayman
Posts: 22
Joined: Wed Mar 05, 2008 8:25 am

Can't Set Vertex Shader Constant?

Post by cooljayman »

Im trying to set mWorldViewProj as a Shader Constant like below but getting an error on the console window saying 'HLSL variable to set not found "mWorldViewProj" Available variables are:'.

Code: Select all

virtual void OnSetConstants(video::IMaterialRendererServices* services, irr::s32 userData)
   {
	video::IVideoDriver* driver = services->getVideoDriver();

	// set clip matrix
    core::matrix4 worldViewProj;
    worldViewProj = driver->getTransform(video::ETS_PROJECTION);			
    worldViewProj *= driver->getTransform(video::ETS_VIEW);
    worldViewProj *= driver->getTransform(video::ETS_WORLD);

    
	services->setVertexShaderConstant("mWorldViewProj", worldViewProj.pointer(), 16);
		//core::matrix4 invWorld = driver->getTransform(video::ETS_WORLD);
		//services->setVertexShaderConstant("mInvWorld", invWorld.pointer(), 16);
		
   }

HLSL code:

Code: Select all

float4x4 mWorldViewProj;  

struct VS_OUTPUT
{
float4 Pos: POSITION;
float2 texCoord: TEXCOORD0;
};

.
.
.
ect
Has any one had this problem before? Why can't it find the variable to set?
Halifax
Posts: 1424
Joined: Sun Apr 29, 2007 10:40 pm
Location: $9D95

Post by Halifax »

Are you sure that shader code there is in the vertex shader, or the pixel (fragment) shader?

Also could you post your other code, the problem definitely doesn't appear to be there.
TheQuestion = 2B || !2B
cooljayman
Posts: 22
Joined: Wed Mar 05, 2008 8:25 am

Post by cooljayman »

It's in the vertex shader, this is straight out from the shaders demo. I can't see what im doing differently, here is the rest of the hlsl code, it doesn't do anything at the moment.

Code: Select all

float4x4 mWorldViewProj;

struct VS_OUTPUT
{
   float4 Pos: POSITION;
   float2 texCoord: TEXCOORD0;
};

VS_OUTPUT vertexMain( in float4 Pos : POSITION)
{
   VS_OUTPUT Out;

   Out.Pos = float4(Pos.xy, 0, 1);

   Out.texCoord.x = 0.5 * (1 + Pos.x - 0.00125);
   Out.texCoord.y = 0.5 * (1 - Pos.y - 0.00166);
   
   return Out;
}




struct PS_OUTPUT
{
    float4 RGBColor : COLOR0;  // Pixel color   
};


sampler2D tex0;
   
PS_OUTPUT pixelMain( float2 TexCoord : TEXCOORD0,
                     float4 Position : POSITION,
                     float4 Diffuse  : COLOR0 )
{
   PS_OUTPUT Output;

   float4 col = tex2D( tex0, TexCoord );

   Output.RGBColor= col;

   return Output;
}

And the callback:

Code: Select all

class MyShaderCallBack : public video::IShaderConstantSetCallBack
{
public:
   virtual void OnSetConstants(video::IMaterialRendererServices* services, irr::s32 userData)
   {
	video::IVideoDriver* driver = services->getVideoDriver();


	// set clip matrix
    core::matrix4 worldViewProj;
    worldViewProj = driver->getTransform(video::ETS_PROJECTION);			
    worldViewProj *= driver->getTransform(video::ETS_VIEW);
    worldViewProj *= driver->getTransform(video::ETS_WORLD);

    
	services->setVertexShaderConstant("mWorldViewProj", worldViewProj.pointer(), 16);
		//core::matrix4 invWorld = driver->getTransform(video::ETS_WORLD);
		//services->setVertexShaderConstant("mInvWorld", invWorld.pointer(), 16);
		
   }
};


Help is much appreciated.

Cheers
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

The problem is that you are not using mWorldViewProj to produce the final product in your shader, so it gets discarded. Even if it is declared in the shader file, even if it is used in some random expression in the shader, if a uniform does not contribute to the final output value of the shader it is optimized out, and setting it in Direct3D will yield that error message.

Try:

Code: Select all

Out.Pos = mul(float4(Pos.xyz , 1), mWorldViewProj); 

// Or it might be "mWorldViewProj, float4(Pos.xyz , 1)", I forgot the order of multiplication for D3D, been doing too much GLSL lately...
Though I'm not sure what you're shader is trying to achieve by only using the first 2 components of the position...
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
cooljayman
Posts: 22
Joined: Wed Mar 05, 2008 8:25 am

Post by cooljayman »

Thanks blindside, that was it..
Halifax
Posts: 1424
Joined: Sun Apr 29, 2007 10:40 pm
Location: $9D95

Post by Halifax »

Once again I am dupped my BlindSide's shader awesomeness. Sorry for steering you in the wrong way, I'm more of a GLSL guy. :wink:
TheQuestion = 2B || !2B
poulpi33
Posts: 31
Joined: Tue Jan 06, 2009 8:01 pm
Location: Bordeaux, France

Post by poulpi33 »

hello,

Same error here, but mWorldViewProj is actually used in my very simple shader.
I know it does not directly contribute to the pixel output, but is still needed for vertex POSITION. Is there any way to make it not being discarded ?
Or am i doing something wrong ?
(this shader works in other engines)

Code: Select all

// VARIABLES
float4x4 mWorldViewProj;

// TEXTURES
sampler2D diffuseMap : register(s0);

// VS
struct VS_INPUT
{
	float4 pos			: POSITION;
	float2 texCoord0	: TEXCOORD0;
};

struct VS_OUTPUT
{
	float4 pos   		: POSITION;
	float2 texCoord0	: TEXCOORD0;
};

VS_OUTPUT vertexMain(VS_INPUT In, VS_OUTPUT Out)
{
	Out.pos = mul(In.pos, mWorldViewProj);
	Out.texCoord0 = In.texCoord0;
	return Out;
}

// PS
struct PS_OUTPUT
{
    float4 target0 : COLOR0; 
};
	
PS_OUTPUT pixelMain(VS_OUTPUT In, PS_OUTPUT Out) 
{ 
	float4 color = tex2D(diffuseMap, In.texCoord0);
	Out.target0 = color;
	return Out;
}
poulpi33
Posts: 31
Joined: Tue Jan 06, 2009 8:01 pm
Location: Bordeaux, France

Post by poulpi33 »

After recompiled Irrlicht with directx sdk august 2007 (was previously june 2006), and d3dx9d.dll only in the linker (no d3dx8d.dll), it's working.
Strange...
Post Reply