Jump to content
  • Advertisement
Sign in to follow this  
michaelmk86

HLSL and Normals question

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

How to pass the correct texture normals from a ID3DXMesh to HLSL?

what i have done so far is only pass the textures in the wrong positions

lightingFX.fx->SetMatrix(lightingFX.xWorld, &position);
lightingFX.fx->SetMatrix(lightingFX.xWorldViewProjection, &(position*view*proj));
lightingFX.fx->Begin(&numPasses,0);

for (unsigned int i = 1; i<numMtrls; i++)
{
lightingFX.fx->BeginPass(0);
lightingFX.fx->SetTexture("xColoredTexture", texture);
lightingFX.fx->CommitChanges();
mesh->DrawSubset(i);
lightingFX.fx->EndPass();
}[/quote]

//the HLSL file

float4x4 xWorldViewProjection;

float4x4 xWorld;
float3 xLightPos;
float xLightPower;
float xAmbient;
float4 color = float4(1, 0.8, 0.8, 1);


Texture xTexture;

sampler TextureSampler = sampler_state { texture = <xTexture> ; magfilter = LINEAR; minfilter = LINEAR; mipfilter=LINEAR; AddressU = mirror; AddressV = mirror;};
struct VertexToPixel
{
float4 Position : POSITION;
float2 TexCoords : TEXCOORD0;
float3 Normal : TEXCOORD1;
float3 Position3D : TEXCOORD2;
};

struct PixelToFrame
{
float4 Color : COLOR0;
};

float DotProduct(float3 lightPos, float3 pos3D, float3 normal)
{
float3 lightDir = normalize(pos3D - lightPos);
return dot(-lightDir, normal);
}

float distance(float3 lightPos, float3 PixelPos3D)
{
float xd = lightPos.x - PixelPos3D.x;
float yd = lightPos.y - PixelPos3D.y;
float zd = lightPos.z - PixelPos3D.z;
return sqrt(xd*xd + yd*yd + zd*zd);
}

VertexToPixel SimplestVertexShader( float4 inPos : POSITION0, float3 inNormal: NORMAL0, float2 inTexCoords : TEXCOORD0)
{
VertexToPixel Output = (VertexToPixel)0;

Output.Position =mul(inPos, xWorldViewProjection);
Output.TexCoords = inTexCoords;
Output.Normal = normalize(mul(inNormal, (float3x3)xWorld));
Output.Position3D = mul(inPos, xWorld);

return Output;
}

PixelToFrame OurFirstPixelShader(VertexToPixel PSIn)
{
PixelToFrame Output = (PixelToFrame)0;

float diffuseLightingFactor = DotProduct(xLightPos, PSIn.Position3D, PSIn.Normal);
diffuseLightingFactor = saturate(diffuseLightingFactor);
diffuseLightingFactor *= xLightPower;

float dis = distance(xLightPos, PSIn.Position3D)/10;

PSIn.TexCoords.y--;
float4 baseColor = tex2D(TextureSampler, PSIn.TexCoords);
Output.Color = baseColor*(diffuseLightingFactor + xAmbient)*color/dis;

return Output;
}

technique Simplest
{
pass Pass0
{
VertexShader = compile vs_2_0 SimplestVertexShader();
PixelShader = compile ps_2_0 OurFirstPixelShader();
}
}[/quote] Edited by michaelmk86

Share this post


Link to post
Share on other sites
Advertisement
Where did the mesh come from? Usually the normals are set in the modeling software as well as the texture cords.

In your code I noticed you're looping through the materials, which is correct but you start out with an index of 1 in your for loop:


for (unsigned int i = 1; i{
lightingFX.fx->BeginPass(i-1);
lightingFX.fx->SetTexture("xColoredTexture", texture);
lightingFX.fx->CommitChanges();
mesh->DrawSubset(i);
lightingFX.fx->EndPass();
}



Usually arrays are zero based. If this is not the problem then check the code that assigns the textures arrays (i.e. texture);


For the normal- in the shader you would "mul" your input normal by the world transformation matrix. Edited by DJTN

Share this post


Link to post
Share on other sites
mesh came from D3DXLoadMeshFromX and textures came from D3DXCreateTextureFromFileEx

the thing is that IF I don't use HLSL the textures are displayed on the correct positions

for (unsigned int i = 1; i<numMtrls; i++)
{
Device->SetMaterial(&materials);
Device->SetTexture(0,texture);
mesh->DrawSubset(i);
}[/quote]



but with HLSL I get the wrong positions

for (unsigned int i = 1; i<numMtrls; i++)
{
lightingFX.fx->BeginPass(0);
lightingFX.fx->SetTexture("xColoredTexture", texture);
lightingFX.fx->CommitChanges();
mesh->DrawSubset(i);
lightingFX.fx->EndPass();
}[/quote]

sidenote: I start with i=1 because the first material is nothing(white) this is some kind of a bug when you export the model from sketchup. (if i start with 0 will have NO effect with HLSL OR without HLSL, but starting with 1 it is better for performance reasons, you save one loop per model)

Share this post


Link to post
Share on other sites
Your render loop for a shader looks wrong. You are starting a new pass for each material. It should look like this:


// Apply the technique contained in the effect
g_pEffect->Begin(&cPasses, 0);
for (iPass = 0; iPass < cPasses; iPass++)
{
g_pEffect->BeginPass(iPass);
// Only call CommitChanges if any state changes have happened
// after BeginPass is called
g_pEffect->CommitChanges();
// Render the mesh with the applied technique
g_pMesh->DrawSubset(0);
g_pEffect->EndPass();
}
g_pEffect->End();



Since you have multiple materials you'll need another loop inside the "passe's" for loop. Make sure you commit changes when changing the texture for the next subset. Edited by DJTN

Share this post


Link to post
Share on other sites
If you continue to have issues I'd suggest rendering a simple built-in box using the D3DXCreateBox() function. Once you have that well established you can move on to imported models.

Share this post


Link to post
Share on other sites
Still I haven't figured out why the textures are not display correctly

here is screenshot to better illustrate the problem with textures:
84609635.png

Share this post


Link to post
Share on other sites
[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

[background=rgb(247, 247, 247)]sampler TextureSampler = sampler_state { texture = <xTexture> ; magfilter = LINEAR; minfilter = LINEAR; mipfilter=LINEAR; AddressU = mirror; AddressV = mirror;};[/background]

[/font]

Seems that your textures are mirrored (at least the surface in foreground), as defined by your fx file. Check that you use same addressing mode with HLSL as without it.

Cheers!

Share this post


Link to post
Share on other sites

[background=rgb(247, 247, 247)]sampler TextureSampler = sampler_state { texture = <xTexture> ; magfilter = LINEAR; minfilter = LINEAR; mipfilter=LINEAR; AddressU = mirror; AddressV = mirror;};[/background]




Seems that your textures are mirrored (at least the surface in foreground), as defined by your fx file. Check that you use same addressing mode with HLSL as without it.

Cheers!

thanx
I change the [background=rgb(247, 247, 247)]AddressU = mirror AddressV = mirror [/background] to AddressU = Wrap AddressV = Wrap and it fix all the problems with textures.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!