Sign in to follow this  
Paul7

Shader / RenderMonkey Problem

Recommended Posts

Ive created a shader in render monkey for per pixel lighting and bump mapping. It works fine. I then appied it to my terrain in my directX program making a few alterations to get it to work properly. This worked fine the first time I used it. Later on in the day having turned off my computer I came back to programming my terrain and found that it no longer worked! Closeup I then found that if I run the original shader in rendermonkey (the version before making alteration to it to get it working in directX prog) and then run my terrain engine it works fine again. If I restart my computer it also continues to work until I shutdown my computer completely. This problem didnt occur when I just had the per pixel lighting with no bump mapping so I`m guessing its something related to that. This seems real strange to me. Anyone have any ideas why this is happening? thanks.

Share this post


Link to post
Share on other sites
Something to do with the card's internal state, most likely.

Does DX actually guarantee the hardware to be in a certain state after device creation? I dont think it does....

Make sure of *every* renderstate that your shader requires to work correctly, and ensure that your app is setting them all.

The result (when it works) looks very impressive btw :D.

Share this post


Link to post
Share on other sites
Just found that running the catalyst control center that comes with catalyst 4.10 drivers also makes my prog work correctly so both these must do something that my prog isnt, will look into the renderstates.

If seeing some of my code mite help to solve the problem let me know and I`ll post it.

Thanks again.

Share this post


Link to post
Share on other sites
right i`m not really too sure on what renderstates I should be setting? the only one that I am setting at the moment is:

gDevice->SetRenderState( D3DRS_ZENABLE, TRUE);

Should I be setting some others also?

Share this post


Link to post
Share on other sites
Ive been trying to find other programs that make my program work that I have the source code for so I can make comparisons. Unfortunatly I havnt found any yet but while I was doing so I ran a fur shader demo I have and that resulted in my terrain giving me different effects.



Could it somehow be something to do with the tangents I am passing to my shader. I dont see how this could be stored from other programs but its all I can think of being a problem. I wasnt exactly sure on how to calculate them and pass them as part of my fvf.

At the moment I am calculating my tangents by just taking the cross product between the vertex normal and a specified vector that the normal couldnt possibly be (0.0 0.0 1.0). Not sure if this is the right way to do it?

My fvf is as follows:


struct Vertex_pos_norm
{
D3DXVECTOR3 position; // Vertex position
D3DXVECTOR3 normal;
D3DXVECTOR2 UV;
D3DXVECTOR3 tangent;
};


#define D3DFVF_VERTEX_POS_NORM (D3DFVF_XYZ | D3DFVF_NORMAL| D3DFVF_TEX1| D3DFVF_XYZ)




I`m not really sure on the what to use for the tangent in the definition. At the moment I am using D3DFVF_XYZ. As there isnt a D3DFVF_TANGENT I didnt no which to use?

Thanks.

Share this post


Link to post
Share on other sites
Tried downloading the latest Rendermonkey? it fixes alot of bugs.

If you have exported the project as an fx file then there might be some name clashes. Check through the fx file to make sure there are no name clashes ( since it worked before shutting down then it probably isn't this problem... but then it might be )

Try checking on the "Render state" flag on your RenderMonkey IDE project and take note of the "Value" and "Incoming" state changes, then put them on your effect file manually (assuming that you did export it as fx file.

By looking at the close up picture you posted, im guessing that its not using the textures correctly. You can actually see the outline of some of the triangles. Hope this helps pointing to a solution

Share this post


Link to post
Share on other sites
I've had the exact same problem with rendermonkey. I remember fixing it, but I barely remember how. I believe it was due to the stream mapping and the input parameters (within the program), whereas they differ in any way, such as a bad index ID. IIRC, the artifacts would also show up even if not using a texture.

I never tested the shaders out in any other app to see what happens, only within rendermonkey.

Share this post


Link to post
Share on other sites
Its not actually a problem within rendermonkey its just when I use it in my own prog.

Heres a copy of my code if it can help anyone solve this problem:

my .fx shader file

float4x4 matWorldViewProjection;
float4x4 matWorld;
float4 vecLightDir;
float4 vecEye;

texture base_Tex;
texture base_Tex_bump;
texture Layer1_Tex;
texture Layer1_Tex_bump;
texture Layer2_Tex;

sampler Basetexture = sampler_state
{
Texture = (base_Tex);
MIPFILTER = LINEAR;
MINFILTER = LINEAR;
MAGFILTER = LINEAR;
};

sampler Basetexture_bump = sampler_state
{
Texture = (base_Tex_bump);
MIPFILTER = LINEAR;
MINFILTER = LINEAR;
MAGFILTER = LINEAR;
};

sampler Layer1texture = sampler_state
{
Texture = (Layer1_Tex);
MIPFILTER = LINEAR;
MINFILTER = LINEAR;
MAGFILTER = LINEAR;
};

sampler Layer1texture_bump = sampler_state
{
Texture = (Layer1_Tex_bump);
MIPFILTER = LINEAR;
MINFILTER = LINEAR;
MAGFILTER = LINEAR;
};

sampler Layer2texture = sampler_state
{
Texture = (Layer2_Tex);
MIPFILTER = LINEAR;
MINFILTER = LINEAR;
MAGFILTER = LINEAR;
};

struct VS_OUTPUT
{
float4 Pos: POSITION;
float3 Light : TEXCOORD0;
float3 View : TEXCOORD1;
float2 Tex : TEXCOORD2;
};

VS_OUTPUT VertexShader_terrain( float4 inPos: POSITION, float3 Normal : NORMAL, float2 inTex: TEXCOORD, float3 Tangent : TANGENT )
{
VS_OUTPUT Out = (VS_OUTPUT)0;

Out.Pos = mul(inPos, matWorldViewProjection);

float3x3 worldToTangentSpace;
worldToTangentSpace[0] = mul(Tangent, matWorld);
worldToTangentSpace[1] = mul(cross(Tangent, Normal), matWorld);
worldToTangentSpace[2] = mul(Normal, matWorld);

Out.Light = mul(worldToTangentSpace, vecLightDir);
float3 PosWorld = mul(inPos, matWorld);
Out.View = vecEye - PosWorld; // V

Out.Tex = inTex;

return Out;
}


float4 PixelShader_terrain(float3 Light: TEXCOORD0,
float3 View : TEXCOORD1, float2 Tex : TEXCOORD2) : COLOR
{
float base_tile_factor = 10.0;
float layer1_tile_factor = 20.0;

float4 base = tex2D( Basetexture, Tex * base_tile_factor);
float4 layer1_mask = tex2D( Layer1texture, Tex);
float4 layer1_tile = tex2D( Layer1texture, Tex*layer1_tile_factor);
float4 layer2 = tex2D( Layer2texture, Tex);

float4 colour = lerp(base, layer1_tile, layer1_mask.a);
//colour = lerp(colour, layer2, layer2.a);

float3 bumpNormal_base = 2 * (tex2D(Basetexture_bump, Tex * base_tile_factor) - 0.5); // bump map
float3 bumpNormal_layer1 = 2 * (tex2D(Layer1texture_bump, Tex * layer1_tile_factor) - 0.5); // bump map
float3 bumpNormal = lerp(bumpNormal_base, bumpNormal_layer1, layer1_mask.a);

float4 ambient = {0.2, 0.2, 0.2, 1.0};
float3 LightDir = normalize(Light);
float3 ViewDir = normalize(View);
float4 diff = saturate(dot(bumpNormal, LightDir)); // diffuse comp.

// compute self-shadowing term
float shadow = saturate(4* diff);

float3 Reflect = normalize(2 * diff * bumpNormal - LightDir); // R
//float4 specular = 0;//pow(saturate(dot(Reflect, ViewDir)), 100); // R.V^n
float4 specular = min(pow(saturate(dot(Reflect, ViewDir)), 100), colour.r);

return ambient * colour + shadow * (colour * diff + specular);
}



technique Effect_terrain
{
pass Pass_0
{
VertexShader = compile vs_2_0 VertexShader_terrain();
PixelShader = compile ps_2_0 PixelShader_terrain();
}

}



DirectX initialiasation code:

if( NULL == ( gD3dObject=Direct3DCreate9(D3D_SDK_VERSION) ) )
return E_FAIL;

D3DDISPLAYMODE d3ddm;
if( FAILED( gD3dObject->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) )
return E_FAIL;

D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;

if( FAILED( gD3dObject->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &gDevice ) ) )
{
return E_FAIL;
}
gDevice->SetRenderState( D3DRS_ZENABLE, TRUE);



Shader setup:

Initialise()
{
if (FAILED(hr=D3DXCreateEffectFromFile(gDevice,"specular_lighting.fx",NULL,NULL,0,NULL,&m_pEffect,NULL)))
{
return hr;
}

if( FAILED( D3DXCreateTextureFromFile( gDevice, "rock.png", &m_basetexture ) ) )
{
return E_FAIL;
}
if( FAILED( D3DXCreateTextureFromFile( gDevice, "rock_bump.png", &m_basetexture_bump ) ) )
{
return E_FAIL;
}
if( FAILED( D3DXCreateTextureFromFile( gDevice, "layer1.tga", &m_layer1texture ) ) )
{
return E_FAIL;
}
if( FAILED( D3DXCreateTextureFromFile( gDevice, "layer2.tga", &m_layer2texture ) ) )
{
return E_FAIL;
}
if( FAILED( D3DXCreateTextureFromFile( gDevice, "layer1_bump.tga", &m_layer1texture_bump ) ) )
{
return E_FAIL;
}

return TRUE;
}

Render(D3DXVECTOR3 CamPos)
{
D3DXMATRIXA16 matWorld, matView, matProjection, matWVP;

gDevice->GetTransform(D3DTS_WORLD,&matWorld);
gDevice->GetTransform(D3DTS_VIEW,&matView);
gDevice->GetTransform(D3DTS_PROJECTION,&matProjection);

D3DXVECTOR4 View;
View.x = CamPos.x;
View.y = CamPos.y;
View.z = CamPos.z;
View.w = 1.0;

matWVP = matWorld * matView * matProjection;

D3DXVECTOR4 Lightvec;
Lightvec.x = 0.0; Lightvec.y = 0.5; Lightvec.z = -0.5; Lightvec.w = 1.0;

m_pEffect->SetMatrix("matWorldViewProjection", &matWVP);
m_pEffect->SetMatrix("matWorld", &matWorld);
m_pEffect->SetVector("vecLightDir", &Lightvec);
m_pEffect->SetVector("vecEye", &View);

m_pEffect->SetTexture( "base_Tex", m_basetexture );
m_pEffect->SetTexture( "base_Tex_bump", m_basetexture_bump );
m_pEffect->SetTexture( "Layer1_Tex", m_layer1texture );
m_pEffect->SetTexture( "Layer2_Tex", m_layer2texture );
m_pEffect->SetTexture( "Layer1_Tex_bump", m_layer1texture_bump );

m_pEffect->SetTechnique( m_pEffect->GetTechniqueByName("Effect_terrain"));

gDevice->SetStreamSource( 0, gVB, 0, sizeof(Vertex_pos_norm));
gDevice->SetFVF(D3DFVF_VERTEX_POS_NORM);
gDevice->SetIndices( gIB);

UINT iPass, cPasses;
m_pEffect->Begin(&cPasses, 0);
for (iPass = 0; iPass < cPasses; iPass++)
{
m_pEffect->BeginPass(iPass);

gDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST,0,0,num_vert,0, num_tris);

m_pEffect->EndPass();
}
m_pEffect->End();
}

Share this post


Link to post
Share on other sites
Have you got the debug runtimes turned on and the warnings turned up? Try doing that and ticking 'maximum validation' as well and see if you get any debug spew.

Are you rendering anything else in your app? If you are try disabling the rendering of everything else (including things like FPS counters, menu text etc.) and seeing if that fixes the problem. If it does it's highly likely that you're relying on some render state being set to a particular value and some other bit of code is changing it. The other thing to check is that you're not leaving any other streams set - SetStreamSource() to NULL for streams you're not using.

I'd also suggest using vertex declarations rather than FVFs - FVFs are deprecated and were only kept around to ease the transition to DX9 from earlier versions of DX. Using SetVertexDeclaration() instead lets you be much more explicit about the layout of your streams and doesn't have the restrictions on ordering and the limitation to a single stream that FVFs do. I think that's probably not your problem here but I find it's much easier to tell what the data layout is supposed to be from looking at a vertex declaration than from an FVF.

Share this post


Link to post
Share on other sites
Actually, I just looked at your FVF and I was wrong about it probably not being your problem - it almost certainly is. Those FVF flags are just ordinary bit flags so when you do

#define D3DFVF_VERTEX_POS_NORM (D3DFVF_XYZ | D3DFVF_NORMAL| D3DFVF_TEX1| D3DFVF_XYZ)

that's exactly the same as

#define D3DFVF_VERTEX_POS_NORM (D3DFVF_XYZ | D3DFVF_NORMAL| D3DFVF_TEX1)

If you want to use a tangent with an FVF you need to pass it as another set of tex coords. Again, I'd recommend you ditch FVFs and use vertex declarations where you won't have this sort of problem. Vertex declarations actually have a usage for tangents and binormals as well so you don't have to use a texture coordinate.

Share this post


Link to post
Share on other sites
Thanks for that, so to use setvertex declaration do I do this:


//Initialisation code
D3DVERTEXELEMENT9 g_VertexDeclaration[] =
{
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
{ 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
{ 0, 32, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 2 },
D3DDECL_END()
};


if( FAILED(gDevice->CreateVertexDeclaration(g_VertexDeclaration, &vertex_decl)))
return FALSE;



//then to render replace setFVF with:

gDevice->SetVertexDeclaration(vertex_decl);






Do I still need to use the FVF with DrawIndexedPrimitive() or can the vertex declaration be used?

The way I have set it up to use the vertex declaration (as above) still results in the same problem!

Turning the debug output up gives me this:


Direct3D9: :====> ENTER: DLLMAIN(00c636a0): Process Attach: 000006a4, tid=000006a8
Direct3D9: :====> EXIT: DLLMAIN(00c636a0): Process Attach: 000006a4
Direct3D9: (INFO) :Direct3D9 Debug Runtime selected.
Direct3D9: (INFO) :======================= Hal HWVP device selected

Direct3D9: (INFO) :HalDevice Driver Style 9

Direct3D9: :BackBufferCount not specified, considered default 1
Direct3D9: :DoneExclusiveMode
Direct3D9: (INFO) :Failed to create driver indexbuffer
D3D9 Helper: Warning: Default value for D3DRS_POINTSIZE_MAX is 2.19902e+012f, not 7.79599e-317f. This is ok.
D3D9 Helper: Error: Default value for D3DSAMP_DMAPOFFSET[0] is incorrect. Expected 0x100, Returned 0x0
D3D9 Helper: Error: Default value for D3DSAMP_DMAPOFFSET[1] is incorrect. Expected 0x100, Returned 0x0
D3D9 Helper: Error: Default value for D3DSAMP_DMAPOFFSET[2] is incorrect. Expected 0x100, Returned 0x0
D3D9 Helper: Error: Default value for D3DSAMP_DMAPOFFSET[3] is incorrect. Expected 0x100, Returned 0x0
D3D9 Helper: Error: Default value for D3DSAMP_DMAPOFFSET[4] is incorrect. Expected 0x100, Returned 0x0
D3D9 Helper: Error: Default value for D3DSAMP_DMAPOFFSET[5] is incorrect. Expected 0x100, Returned 0x0
D3D9 Helper: Error: Default value for D3DSAMP_DMAPOFFSET[6] is incorrect. Expected 0x100, Returned 0x0
D3D9 Helper: Error: Default value for D3DSAMP_DMAPOFFSET[7] is incorrect. Expected 0x100, Returned 0x0
D3D9 Helper: Error: Default value for D3DSAMP_DMAPOFFSET[8] is incorrect. Expected 0x100, Returned 0x0
D3D9 Helper: Error: Default value for D3DSAMP_DMAPOFFSET[9] is incorrect. Expected 0x100, Returned 0x0
D3D9 Helper: Error: Default value for D3DSAMP_DMAPOFFSET[10] is incorrect. Expected 0x100, Returned 0x0
D3D9 Helper: Error: Default value for D3DSAMP_DMAPOFFSET[11] is incorrect. Expected 0x100, Returned 0x0
D3D9 Helper: Error: Default value for D3DSAMP_DMAPOFFSET[12] is incorrect. Expected 0x100, Returned 0x0
D3D9 Helper: Error: Default value for D3DSAMP_DMAPOFFSET[13] is incorrect. Expected 0x100, Returned 0x0
D3D9 Helper: Error: Default value for D3DSAMP_DMAPOFFSET[14] is incorrect. Expected 0x100, Returned 0x0
D3D9 Helper: Error: Default value for D3DSAMP_DMAPOFFSET[15] is incorrect. Expected 0x100, Returned 0x0
Direct3D9: (WARN) :Ignoring redundant SetRenderState - 7

'CgpProject.exe': Loaded 'C:\WINDOWS\system32\hid.dll', No symbols loaded.
'CgpProject.exe': Loaded 'C:\WINDOWS\system32\setupapi.dll', No symbols loaded.
'CgpProject.exe': Loaded 'C:\WINDOWS\system32\wintrust.dll', No symbols loaded.
'CgpProject.exe': Loaded 'C:\WINDOWS\system32\crypt32.dll', No symbols loaded.
'CgpProject.exe': Loaded 'C:\WINDOWS\system32\msasn1.dll', No symbols loaded.
'CgpProject.exe': Loaded 'C:\WINDOWS\system32\imagehlp.dll', No symbols loaded.
D3DX: (INFO) Using SSE2 Instructions
D3DX: Matrix should be 16-byte aligned for better performance
Direct3D9: (WARN) :Ignoring redundant SetSamplerState Sampler: 0, State: 13

Direct3D9: (WARN) :Ignoring redundant SetSamplerState Sampler: 0, State: 14

Direct3D9: (WARN) :Ignoring redundant SetSamplerState Sampler: 0, State: 25

Direct3D9: (WARN) :Ignoring redundant SetSamplerState Sampler: 0, State: 15

Direct3D9: (WARN) :Ignoring redundant SetSamplerState Sampler: 0, State: 16

Direct3D9: (WARN) :Ignoring redundant SetSamplerState Sampler: 0, State: 17

Direct3D9: (WARN) :Ignoring redundant SetSamplerState Sampler: 0, State: 18

Direct3D9: (WARN) :Ignoring redundant SetSamplerState Sampler: 0, State: 19




with the Ignoring redundant SetSamplerState Sampler lines repeating continuously while the program is running. It does this when the program is working properly also so I dont think this is the problem. Would like to stop it doing this though!

[Edited by - Paul7 on October 19, 2004 11:10:35 AM]

Share this post


Link to post
Share on other sites
You don't need FVFs anywhere if you're using vertex declarations. Make sure you're not setting an FVF when you're creating your vertex buffer - just use 0. There should be no SetFVF() calls or any other FVF references in your code once you've switched over to vertex declarations.

The code you posted looks more or less right but I'm not sure why you're putting 2 for the usage index for the tangents - shouldn't that be 0? Also, a little tip - use the ANSI C macro offsetof() from stddef.h rather than hardcoding the offset of the elements:

#include <cstddef>

struct Vertex_pos_norm
{
D3DXVECTOR3 position; // Vertex position
D3DXVECTOR3 normal;
D3DXVECTOR2 UV;
D3DXVECTOR3 tangent;
};

D3DVERTEXELEMENT9 g_VertexDeclaration[] =
{
{ 0, offsetof(Vertex_pos_norm, position), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 0, offsetof(Vertex_pos_norm, normal), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
{ 0, offsetof(Vertex_pos_norm, UV), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
{ 0, offsetof(Vertex_pos_norm, tangent), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0 },
D3DDECL_END()
};


If changing the usage index doesn't fix things try some of the other suggestions (making sure the other streams are all cleared, checking the debug output, disabling any other rendering in the app).

Share this post


Link to post
Share on other sites
The warnings about redundant sampler states are harmless - it just means you're setting a state to the same value it's already set to. That is an unnecessary performance cost but it doesn't do any harm. To eliminate it you need to do redundant state checking yourself - track the current render state at all times and only call SetRenderState/SetSamplerState/SetTextureStageState when you actually need to.

Share this post


Link to post
Share on other sites
Just copied the code from somewhere else thats y the usage index was 2 for the tangent.

Changing thats fixed the problem! thanks alot mattnewport youve made my day!

Share this post


Link to post
Share on other sites

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