-
|
|
normal map & custom vertex problem
|
Hi.
I tried to use a custom vertex (because the normal map looked very strange all ATI card, but with this, it looks well) :
| public struct VertexPositionNormalTextureTangent |
| { |
| public Vector3 Position; |
| public Vector3 Normal; |
| public Vector2 TextureCoordinate; |
| public Vector3 Tangent; |
| |
| public static readonly VertexElement[] VertexElements = new VertexElement[] |
| { |
| new VertexElement(0, 0, VertexElementFormat.Vector3, VertexElementMethod.Default, VertexElementUsage.Position, 0), |
| new VertexElement(0, sizeof(float) * 3, VertexElementFormat.Vector3, VertexElementMethod.Default, VertexElementUsage.Normal, 0), |
| new VertexElement(0, sizeof(float) * 6, VertexElementFormat.Vector2, VertexElementMethod.Default, VertexElementUsage.TextureCoordinate, 0), |
| new VertexElement(0, sizeof(float) * 8, VertexElementFormat.Vector3, VertexElementMethod.Default, VertexElementUsage.Tangent, 0) |
| }; |
| |
| public VertexPositionNormalTextureTangent(Vector3 position, Vector3 normal, Vector2 textureCoordinate, Vector3 tangent, Vector3 binormal) |
| { |
| Position = position; |
| Normal = normal; |
| TextureCoordinate = textureCoordinate; |
| Tangent = tangent; |
| } |
| public static int SizeInBytes { get { return sizeof(float) * 14; } } |
| } |
In my entity class:
| protected VertexDeclaration vertexDeclaration; |
| |
| //LoadContent |
| vertexDeclaration = new VertexDeclaration(game.GraphicsDevice, VertexPositionNormalTextureTangent.VertexElements); |
| game.GraphicsDevice.VertexDeclaration = vertexDeclaration; |
| |
| |
| //Draw |
| for (int i = 0; i < mesh.Meshes.Count; i++) |
| { |
| game.GraphicsDevice.Indices = mesh.Meshes[i].IndexBuffer; |
| game.GraphicsDevice.VertexDeclaration = vertexDeclaration; |
| |
| SetEffectParameters(i); |
| |
| Effect.Begin(); |
| Effect.CurrentTechnique.Passes[0].Begin(); |
| Effect.CommitChanges(); |
| |
| foreach (ModelMeshPart part in mesh.Meshes[i].MeshParts) |
| { |
| game.GraphicsDevice.Vertices[0].SetSource(mesh.Meshes[i].VertexBuffer, part.StreamOffset, part.VertexStride); |
| game.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, part.BaseVertex, 0, |
| part.NumVertices, part.StartIndex, part.PrimitiveCount); |
| } |
| |
| Effect.CurrentTechnique.Passes[0].End(); |
| Effect.End(); |
| } |
The HLSL code:
float4x4 world;
float4x4 worldViewProj;
float3 lightPosition;
float4 lightDiffuse;
float4 lightAmbient = float4(0.3f, 0.3f, 0.3f, 1.0f);
texture diffuseTexture;
sampler diffuseSampler = sampler_state
{
Texture = <diffuseTexture>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = LINEAR;
//AddressU = CLAMP;
//AddressV = CLAMP;
};
texture normalTexture;
sampler normalSampler = sampler_state
{
Texture = <normalTexture>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = LINEAR;
//AddressU = CLAMP;
//AddressV = CLAMP;
};
// --------------------------
// ----- Normal mapping -----
// --------------------------
struct VSOUT
{
float4 Position : POSITION;
float2 TexCoord : TEXCOORD0;
float3 Light : TEXCOORD1;
};
VSOUT VS(float4 pos : POSITION, float3 n : Normal, float2 texcoord : TEXCOORD0, float3 t : TANGENT)
{
VSOUT Out = (VSOUT)0;
Out.Position = mul(pos, worldViewProj);
float3x3 wtt;
wtt[0] = mul(normalize(t), world);
wtt[1] = mul(normalize(cross(t, n)), world);
wtt[2] = mul(normalize(n), world);
Out.TexCoord = texcoord;
Out.Light = normalize(mul(wtt, lightPosition));
return Out;
}
float4 PS(VSOUT In) : COLOR0
{
float4 outColor = tex2D(diffuseSampler, In.TexCoord);
float3 normal = (2.0 * (tex2D(normalSampler, In.TexCoord))) - 1.0;
float diffuse = saturate(dot(normal, In.Light));
return outColor * (lightAmbient + (diffuse * lightDiffuse));
}
technique NormalMap
{
pass p0
{
//FillMode = Solid;
CullMode = CCW;
ZEnable = true;
ZWriteEnable = true;
AlphaBlendEnable = false;
AlphaTestEnable = false;
VertexShader = compile vs_2_0 VS();
PixelShader = compile ps_2_0 PS();
}
}
And here is an image what represent my problem: (In real-time the white "leak" is black)
http://ilab.hu/jf/datas/users/1403-screenshot1.png
Any idea?
Thanks,
screat
P.S.:
If I use the "mesh.Meshes[i].Draw()" method, it's working...
And sorry for my bad english :)
|
|
-
-
- (1696)
-
premium membership
-
Posts
1.063
|
Re: normal map & custom vertex problem
|
|
|
-
|
|
Re: normal map & custom vertex problem
|
MJP:Are you using SizeInBytes anywhere? Because it's wrong (it should be sizeof(float) * 11, not 14).
Yeah, I forgot write back to 11 from 14. (I used Binormal too)
But I don't use SizeInBytes (maybe later to compute bounding box).
new VertexElement(0, sizeof(float) * 8, VertexElementFormat.Vector3, VertexElementMethod.Default, VertexElementUsage.Tangent, 0)
If here, I write 4 instead of 8, it's working... But why?
|
|
-
-
- (10849)
-
Team XNA
-
Posts
8.007
|
Re: normal map & custom vertex problem
|
I would guess that maybe you aren't setting something correctly onto the device, or your buffers don't contain the data you think they should, or maybe your shader isn't doing the right computation with this data?
The easiest way to debug such things is using PIX (part of the DirectX SDK) in single frame capture mode. That will let you debug your vertex and pixel shaders, so you can see exactly what data is coming into them, what computations they are doing, what their outputs are, etc.
XNA Framework Developer -
blog - homepage
|
|
-
|
|
Re: normal map & custom vertex problem
|
Shawn Hargreaves:I would guess that maybe you aren't setting something correctly onto the device, or your buffers don't contain the data you think they should, or maybe your shader isn't doing the right computation with this data?
The easiest way to debug such things is using PIX (part of the DirectX SDK) in single frame capture mode. That will let you debug your vertex and pixel shaders, so you can see exactly what data is coming into them, what computations they are doing, what their outputs are, etc.
Thanks, I'm going to try it.
EDIT:
But if I use the basic mesh.Meshes[i].Draw(), the program works correctly.
|
|
-
-
- (10849)
-
Team XNA
-
Posts
8.007
|
Re: normal map & custom vertex problem
|
Screat:But if I use the basic mesh.Meshes[i].Draw(), the program works correctly.
If that works correctly, why not just use that? :-)
XNA Framework Developer -
blog - homepage
|
|
-
|
|
Re: normal map & custom vertex problem
|
Shawn Hargreaves: Screat:But if I use the basic mesh.Meshes[i].Draw(), the program works correctly.
If that works correctly, why not just use that? :-)
Well... I dont know :D
I think, my code is faster than the basic mesh.Draw(); (or not... :))
Ok i'm going to use the basic draw. Thanks
|
|
-
-
- (10849)
-
Team XNA
-
Posts
8.007
|
Re: normal map & custom vertex problem
|
Screat:I think, my code is faster than the basic mesh.Draw(); (or not... :))
Not really. It's basically just doing the same thing that ModelMesh.Draw does internally, only not quite so robust since you don't handle things like models with non identity bone transforms, and you are forcing the vertex declaration to a fixed setting rather than using the one specified by the model data.
If ModelMesh.Draw works but your code does not, PIX would be a perfect way to find out why. Take two captures and compare the device states (vertex declaration, shaders, shader parameters, etc) for this draw call. What is different between the two?
XNA Framework Developer -
blog - homepage
|
|
-
|
|
Re: normal map & custom vertex problem
|
Hmm. I've never useed the PIX. What should I see? :)
|
|
-
-
- (10849)
-
Team XNA
-
Posts
8.007
|
Re: normal map & custom vertex problem
|
|
|
|