0

さて、この問題はちょっと巨大です。同じ理由で、できるだけ少ないコードを投稿したいと思いますが、それが何であるかについてのアイデアを持ってきてください. 問題があると思われるコードを投稿します。もっと見たい場合は、お尋ねください。提供します。

だから、私は自分のゲームのシェーダーを「盗んだ」だけです。盗んだとは、以前に行ったチュートリアルを見つけて、最終結果をコピーしたことを意味します。したがって、以前に使用したことがあるので、シェーダーが機能するはずです。

カスタム メッシュ クラスとカスタム頂点構造体があります。これまで xertex 構造体を作成したことがないので、最初はここに問題があると思いました。しかし、後で見つけたいくつかの反論があります。それらの変数はすべて正しいようで、バンプマッピング以外はすべて機能します。タンジェントや従法線を変更しても、シェーディングには何の影響もないようです。したがって、間違いは計算方法ではなく、使用方法にあると思います。

http://imageshack.us/photo/my-images/838/w6kv.png/

これは私が得る出力です。これはボクセル エンジンであることに注意してください。ご覧のとおり、すべてのボックスに同じ奇妙な法線マップ シャドウがあります。ただし、これは法線マップです。

http://imageshack.us/photo/my-images/268/r7jt.jpg/

ご覧のとおり、それらはまったく適合しません。さて、これは私が見ているように、次の 3 つのことのいずれかである可能性があります。

  1. それは、xna でシェーダーをセットアップする方法かもしれません。
  2. 頂点構造体の何かである可能性もあります
  3. それは、実際の描画関数を呼び出す方法でもあります。

これら 3 つのコード (およびシェーダーも) は次のとおりです。

シェーダーのセットアップ: ((ここでは、シェーダーのデータをセットアップし、メッシュを描画します))

// Bind the parameters with the shader.
BBS.Parameters["World"].SetValue(Matrix.Identity);
BBS.Parameters["View"].SetValue(camera.viewMatrix);
BBS.Parameters["Projection"].SetValue(camera.projectionMatrix);

BBS.Parameters["AmbientColor"].SetValue(Color.White.ToVector4());
BBS.Parameters["AmbientIntensity"].SetValue(0.5f);

Vector3 LD = new Vector3(0, 1, -1);
LD.Normalize();

BBS.Parameters["DiffuseColor"].SetValue(Color.White.ToVector4());
BBS.Parameters["DiffuseIntensity"].SetValue(0);
BBS.Parameters["LightDirection"].SetValue(LD);

BBS.Parameters["EyePosition"].SetValue(new Vector3(0.0f, 2.0f, 5.0f));
BBS.Parameters["SpecularColor"].SetValue(Color.White.ToVector4());
BBS.Parameters["ColorMap"].SetValue(cubeTexture);
BBS.Parameters["NormalMap"].SetValue(Content.Load<Texture2D>("images"));


BBS.CurrentTechnique = BBS.Techniques["Technique1"];

for (int i = 0; i < BBS.CurrentTechnique.Passes.Count; i++)
{
    //EffectPass.Apply will update the device to
    //begin using the state information defined in the current pass
    BBS.CurrentTechnique.Passes[i].Apply();

    //theMesh contains all of the information required to draw
    //the current mesh
    graphics.DrawUserPrimitives(PrimitiveType.TriangleList, Mesh.Vertices, 0, Mesh.NUM_TRIANGLES);
}

頂点構造体:

public struct VertexPositionNormalTangentBinormalTexture : IVertexType
{ 
    public Vector3 Position; 
    public Vector3 Normal; 
    public Vector2 TextureCoordinate; 
    public Vector3 Tangent; 
    public Vector3 Binormal;

    public static readonly VertexDeclaration VertexElements = new VertexDeclaration
    ( 
        new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0), 
        new VertexElement(12, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0), 
        new VertexElement(24, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0), 
        new VertexElement(32, VertexElementFormat.Vector3, VertexElementUsage.Tangent, 0), 
        new VertexElement(44, VertexElementFormat.Vector3, VertexElementUsage.Binormal, 0)
    );


    VertexDeclaration IVertexType.VertexDeclaration { get { return VertexElements; } }

    public static readonly int SizeInBytes = sizeof(float) * (3 + 3 + 2 + 3 + 3);
}

シェーダー:

    // XNA 4.0 Shader Programming #4 - Normal Mapping

// Matrix
float4x4 World;
float4x4 View;
float4x4 Projection;

// Light related
float4 AmbientColor;
float AmbientIntensity;

float3 LightDirection;
float4 DiffuseColor;
float DiffuseIntensity;

float4 SpecularColor;
float3 EyePosition;


texture2D ColorMap;
sampler2D ColorMapSampler = sampler_state
{
    Texture = <ColorMap>;
    MinFilter = linear;
    MagFilter = linear;
    MipFilter = linear;
};

texture2D NormalMap;
sampler2D NormalMapSampler = sampler_state
{
    Texture = <NormalMap>;
    MinFilter = linear;
    MagFilter = linear;
    MipFilter = linear;
};

// The input for the VertexShader
struct VertexShaderInput
{
    float4 Position : POSITION0;
    float2 TexCoord : TEXCOORD0;
    float3 Normal : NORMAL0;
    float3 Binormal : BINORMAL0;
    float3 Tangent : TANGENT0;
};

// The output from the vertex shader, used for later processing
struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float2 TexCoord : TEXCOORD0;
    float3 View : TEXCOORD1;
    float3x3 WorldToTangentSpace : TEXCOORD2;
};

// The VertexShader.
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
    VertexShaderOutput output;

    float4 worldPosition = mul(input.Position, World);
    float4 viewPosition = mul(worldPosition, View);
    output.Position = mul(viewPosition, Projection);
    output.TexCoord = input.TexCoord;

    output.WorldToTangentSpace[0] = mul(normalize(input.Tangent), World);
    output.WorldToTangentSpace[1] = mul(normalize(input.Binormal), World);
    output.WorldToTangentSpace[2] = mul(normalize(input.Normal), World);

    output.View = normalize(float4(EyePosition,1.0) - worldPosition);

    return output;
}

// The Pixel Shader
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
    float4 color = tex2D(ColorMapSampler, input.TexCoord);

    float3 normalMap = 2.0 *(tex2D(NormalMapSampler, input.TexCoord)) - 1.0;
    normalMap = normalize(mul(normalMap, input.WorldToTangentSpace));
    float4 normal = float4(normalMap,1.0);

    float4 diffuse = saturate(dot(-LightDirection,normal));
    float4 reflect = normalize(2*diffuse*normal-float4(LightDirection,1.0));
    float4 specular = pow(saturate(dot(reflect,input.View)),32);

    return  color * AmbientColor * AmbientIntensity + 
            color * DiffuseIntensity * DiffuseColor * diffuse + 
            color * SpecularColor * specular;
}

// Our Techinique
technique Technique1
{
    pass Pass1
    {
        VertexShader = compile vs_2_0 VertexShaderFunction();
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}
4

1 に答える 1

0

これは正しい順序で行われていません:

output.WorldToTangentSpace[0] = mul(normalize(input.Tangent), World);
output.WorldToTangentSpace[1] = mul(normalize(input.Binormal), World);
output.WorldToTangentSpace[2] = mul(normalize(input.Normal), World);

次のようになります。

output.WorldToTangentSpace[0] = normalize(mul(input.Tangent, World));
output.WorldToTangentSpace[1] = normalize(mul(input.Binormal, World));
output.WorldToTangentSpace[2] = normalize(mul(input.Normal, World));

そうしないと、法線がワールド空間変換からスケーリングされ、非常に明るいパッチと非常に暗いパッチが生成されます (これは問題のように見えます)。ところで、ボクセル エンジンの法線マッピングに興味があるので、私が作成した以下をチェックしてください。

http://www.youtube.com/watch?v=roMlOmNgr_w http://www.youtube.com/watch?v=qkfHoGzQ8ZY

インスピレーションを得て、プロジェクトを完成させてください。

于 2014-01-11T23:38:03.713 に答える