我的多维数据集上的某些法线是错误的……需要帮助修复

问题描述 投票:0回答:1

我的照明效果很好,除了立方体上的一张脸。我想我是通过将一些UV坐标归零来找到有问题的脸的。就像这些面孔在通过其他人显示。

我的着色器

#if OPENGL
    #define SV_POSITION POSITION
    #define VS_SHADERMODEL vs_3_0
    #define PS_SHADERMODEL ps_3_0
#else
    #define VS_SHADERMODEL vs_4_0_level_9_1
    #define PS_SHADERMODEL ps_4_0_level_9_1
#endif

float4x4 WorldMatrix;
float4x4 ViewMatrix;
float4x4 ProjectionMatrix;

float4 AmbienceColor = float4(0.1f, 0.1f, 0.1f, 1.0f);

// For Diffuse Lightning
float4x4 WorldInverseTransposeMatrix;
float3 DiffuseLightDirection = float3(-1.0f, 0.0f, 0.0f);
float4 DiffuseColor = float4(1.0f, 1.0f, 1.0f, 1.0f);

// For Texture
texture ModelTexture;
sampler2D TextureSampler = sampler_state {
    Texture = (ModelTexture);
    MagFilter = Linear;
    MinFilter = Linear;
    AddressU = Clamp;
    AddressV = Clamp;
};

struct VertexShaderInput
{
    float4 Position : SV_POSITION0;
    // For Diffuse Lightning
    float4 NormalVector : NORMAL0;
    // For Texture
    float2 TextureCoordinate : TEXCOORD0;
};

struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float4 NormalVector : NORMAL0; 
    float2 TextureCoordinate : TEXCOORD0;
};

VertexShaderOutput MainVS(VertexShaderInput input)
{
    VertexShaderOutput output;

    float4 worldPosition = mul(input.Position, WorldMatrix);
    float4 viewPosition = mul(worldPosition, ViewMatrix);
    output.Position = mul(viewPosition, ProjectionMatrix);

    // For Diffuse Lightning
    output.NormalVector = mul(input.NormalVector, WorldInverseTransposeMatrix);   

    // For Texture
    output.TextureCoordinate = input.TextureCoordinate;

    return output;
}

float4 MainPS(VertexShaderOutput input) : COLOR0
{
    float4 color = AmbienceColor;
    float lightIntensity = dot(input.NormalVector, -DiffuseLightDirection);
    color += saturate(DiffuseColor * lightIntensity);

    return saturate(color) * tex2D(TextureSampler, input.TextureCoordinate);
}

technique BasicColorDrawing
{
    pass P0
    {
        VertexShader = compile VS_SHADERMODEL MainVS();
        PixelShader = compile PS_SHADERMODEL MainPS();
    }
};

生成矩阵和加载内容的代码

        var myEffect = Content.Load<Effect>("Effects/File");
        var checkerboardTexture = Content.Load<Texture2D>("Textures/T_GrandCanyonGround_01_BC");
        effect.AmbientLightColor = new Vector3(0.5f, 0.5f, 0.5f); // a red light
        myEffect.Parameters["AmbienceColor"].SetValue(new Vector4(0.5f, 0.5f, 0.5f, 1)); // a red light
        myEffect.Parameters["DiffuseLightDirection"].SetValue(new Vector3(1, 0, 0.2f));  // coming along the x-axis
       var    camTarget = new Vector3(0f, 0f, 0f);
       var    camPosition = new Vector3(0f, 0f, -100f);
        var   projectionMatrix = Matrix.CreatePerspectiveFieldOfView(
                           MathHelper.ToRadians(45f),
                           GraphicsDevice.DisplayMode.AspectRatio,
            1f, 1000f);
  var         viewMatrix = Matrix.CreateLookAt(camPosition, camTarget,
                     new Vector3(0f, 1f, 0f));// Y up
var           worldMatrix = Matrix.CreateWorld(camTarget, Vector3.
                      Forward, Vector3.Up);
        myEffect.Parameters["WorldMatrix"].SetValue(worldMatrix);
        myEffect.Parameters["ProjectionMatrix"].SetValue(projection);
        Matrix worldInverseTransposeMatrix = Matrix.Transpose(Matrix.Invert(worldMatrix));
        myEffect.Parameters["WorldInverseTransposeMatrix"].SetValue(worldInverseTransposeMatrix);

绘制立方体的代码

private void DrawCubes()
{
    blocks = new List<VertexPositionNormalTexture[]>(squareGrid.squares.GetLength(0) * squareGrid.squares.GetLength(1));

    // Normal vectors for each face (needed for lighting / display)
    Vector3 normalFront = new Vector3(0.0f, 0.0f, 1.0f);
    Vector3 normalBack = new Vector3(0.0f, 0.0f, -1.0f);
    Vector3 normalTop = new Vector3(0.0f, 1.0f, 0.0f);
    Vector3 normalBottom = new Vector3(0.0f, -1.0f, 0.0f);
    Vector3 normalLeft = new Vector3(-1.0f, 0.0f, 0.0f);
    Vector3 normalRight = new Vector3(1.0f, 0.0f, 0.0f);

    // UV texture coordinates
    Vector2 textureTopLeft = new Vector2(1.0f, 0.0f);
    Vector2 textureTopRight = new Vector2(0.0f, 0.0f);
    Vector2 textureBottomLeft = new Vector2(1.0f, 1.0f);
    Vector2 textureBottomRight = new Vector2(0.0f, 1.0f);
    for (int i = 0; i < 3; i++)
    {
        Vector3 Position = new Vector3(i * 40, 0, 0);
        var Size = 20;

        // Calculate the position of the vertices on the top face.
        Vector3 topLeftFront = Position + new Vector3(-1.0f, 1.0f, -1.0f) * Size;
        Vector3 topLeftBack = Position + new Vector3(-1.0f, 1.0f, 1.0f) * Size;
        Vector3 topRightFront = Position + new Vector3(1.0f, 1.0f, -1.0f) * Size;
        Vector3 topRightBack = Position + new Vector3(1.0f, 1.0f, 1.0f) * Size;

        // Calculate the position of the vertices on the bottom face.
        Vector3 btmLeftFront = Position + new Vector3(-1.0f, -1.0f, -1.0f) * Size;
        Vector3 btmLeftBack = Position + new Vector3(-1.0f, -1.0f, 1.0f) * Size;
        Vector3 btmRightFront = Position + new Vector3(1.0f, -1.0f, -1.0f) * Size;
        Vector3 btmRightBack = Position + new Vector3(1.0f, -1.0f, 1.0f) * Size;

        VertexPositionNormalTexture[] vertices = new VertexPositionNormalTexture[36];
        //FRONT face.
        vertices[0] = new VertexPositionNormalTexture(topLeftFront, normalFront, textureTopLeft);
        vertices[1] = new VertexPositionNormalTexture(btmLeftFront, normalFront, textureBottomLeft);
        vertices[2] = new VertexPositionNormalTexture(topRightFront, normalFront, textureTopRight);
        vertices[3] = new VertexPositionNormalTexture(btmLeftFront, normalFront, textureBottomLeft);
        vertices[4] = new VertexPositionNormalTexture(btmRightFront, normalFront, textureBottomRight);
        vertices[5] = new VertexPositionNormalTexture(topRightFront, normalFront, textureTopRight);

        //BACK face.
        vertices[6] = new VertexPositionNormalTexture(topLeftBack, normalBack, textureTopRight);
        vertices[7] = new VertexPositionNormalTexture(topRightBack, normalBack, textureTopLeft);
        vertices[8] = new VertexPositionNormalTexture(btmLeftBack, normalBack, textureBottomRight);
        vertices[9] = new VertexPositionNormalTexture(btmLeftBack, normalBack, textureBottomRight);
        vertices[10] = new VertexPositionNormalTexture(topRightBack, normalBack, textureTopLeft);
        vertices[11] = new VertexPositionNormalTexture(btmRightBack, normalBack, textureBottomLeft);

        //TOP face.
        vertices[12] = new VertexPositionNormalTexture(topLeftFront, normalTop, textureBottomLeft);
        vertices[13] = new VertexPositionNormalTexture(topRightBack, normalTop, textureTopRight);
        vertices[14] = new VertexPositionNormalTexture(topLeftBack, normalTop, textureTopLeft);
        vertices[15] = new VertexPositionNormalTexture(topLeftFront, normalTop, textureBottomLeft);
        vertices[16] = new VertexPositionNormalTexture(topRightFront, normalTop, textureBottomRight);
        vertices[17] = new VertexPositionNormalTexture(topRightBack, normalTop, textureTopRight);

        //BOTTOM face. 
        vertices[18] = new VertexPositionNormalTexture(btmLeftFront, normalBottom, textureTopLeft);
        vertices[19] = new VertexPositionNormalTexture(btmLeftBack, normalBottom, textureBottomLeft);
        vertices[20] = new VertexPositionNormalTexture(btmRightBack, normalBottom, textureBottomRight);
        vertices[21] = new VertexPositionNormalTexture(btmLeftFront, normalBottom, textureTopLeft);
        vertices[22] = new VertexPositionNormalTexture(btmRightBack, normalBottom, textureBottomRight);
        vertices[23] = new VertexPositionNormalTexture(btmRightFront, normalBottom, textureTopRight);

        //LEFT face.
        vertices[24] = new VertexPositionNormalTexture(topLeftFront, normalLeft, textureTopRight);
        vertices[25] = new VertexPositionNormalTexture(btmLeftBack, normalLeft, textureBottomLeft);
        vertices[26] = new VertexPositionNormalTexture(btmLeftFront, normalLeft, textureBottomRight);
        vertices[27] = new VertexPositionNormalTexture(topLeftBack, normalLeft, textureTopLeft);
        vertices[28] = new VertexPositionNormalTexture(btmLeftBack, normalLeft, textureBottomLeft);
        vertices[29] = new VertexPositionNormalTexture(topLeftFront, normalLeft, textureTopRight);

        //RIGHT face. 
        vertices[30] = new VertexPositionNormalTexture(topRightFront, normalRight, textureTopLeft);
        vertices[31] = new VertexPositionNormalTexture(btmRightFront, normalRight, textureBottomLeft);
        vertices[32] = new VertexPositionNormalTexture(btmRightBack, normalRight, textureBottomRight);
        vertices[33] = new VertexPositionNormalTexture(topRightBack, normalRight, textureTopRight);
        vertices[34] = new VertexPositionNormalTexture(topRightFront, normalRight, textureTopLeft);
        vertices[35] = new VertexPositionNormalTexture(btmRightBack, normalRight, textureBottomRight);

        blocks.Add(vertices);
    }
}
public override void Draw(GameTime gameTime)
{
    radians+=0.01f;
    Vector3 camPos = new Vector3(0, -14.1759f, 10f);
    Vector3 lookAt = new Vector3(0, 0, 0);
    var view = Matrix.CreateRotationZ(MathHelper.ToRadians(45f)) * Matrix.CreateLookAt(camPos, lookAt, Vector3.Up);
  //  view *= Matrix.CreateRotationY(radians);
    effect.Parameters["ViewMatrix"].SetValue(view);
    foreach (var pass in effect.CurrentTechnique.Passes)
    {
        effect.Parameters["ModelTexture"].SetValue(checkerboardTexture2);
        pass.Apply();
        for (int i = 0; i < blocks.Count; i++)
        {
            graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, blocks[i], 0, blocks[i].Length / 3);
        }
    }

结果

enter image description here

然后旋转视图矩阵,这些法线看起来很好。

enter image description here

directx monogame hlsl
1个回答
0
投票

似乎您没有启用backface culling。我还没有使用过MonoGame,但是根据一些谷歌搜索,应该是这样的:

RasterizerState rs = new RasterizerState();
rs.CullMode = CullMode.CullClockwiseFace;
© www.soinside.com 2019 - 2024. All rights reserved.