1

シェーダーに値を渡す際に問題が発生します。アプリケーションは正常にコンパイルされますが、キューブオブジェクトがシェーディングされません。以下は私のコードの大部分です。

シェーダーと通信するためのコードのほとんどは、createObjectメソッドにあります

myGame.cpp

#include "MyGame.h"
#include "OneColorCube.h"
/* This code sets a projection and shows a turning cube. What has been added is the project, rotation and
a rasterizer to change the rasterization of the cube. The issue that was going on was something with the effect file
which was causing the vertices not to be rendered correctly.*/
typedef struct 
{
    ID3D10Effect* pEffect;
    ID3D10EffectTechnique* pTechnique;

    //vertex information
    ID3D10Buffer* pVertexBuffer;
    ID3D10Buffer* pIndicesBuffer;
    ID3D10InputLayout* pVertexLayout;

    UINT numVertices;
    UINT numIndices;
}ModelObject;

ModelObject modelObject;
// World Matrix
D3DXMATRIX                  WorldMatrix;
// View Matrix
D3DXMATRIX                  ViewMatrix;
// Projection Matrix
D3DXMATRIX                  ProjectionMatrix;
ID3D10EffectMatrixVariable* pProjectionMatrixVariable = NULL;
ID3D10EffectVectorVariable* pLightVarible = NULL;


bool MyGame::InitDirect3D()
{
    if(!DX3dApp::InitDirect3D())
    {
        return false;
    }
    
    D3D10_RASTERIZER_DESC rastDesc;
    rastDesc.FillMode = D3D10_FILL_WIREFRAME;
    rastDesc.CullMode = D3D10_CULL_FRONT;
    rastDesc.FrontCounterClockwise = true;
    rastDesc.DepthBias = false;
    rastDesc.DepthBiasClamp = 0;
    rastDesc.SlopeScaledDepthBias = 0;
    rastDesc.DepthClipEnable = false;
    rastDesc.ScissorEnable = false;
    rastDesc.MultisampleEnable = false;
    rastDesc.AntialiasedLineEnable = false;

    ID3D10RasterizerState *g_pRasterizerState;
    mpD3DDevice->CreateRasterizerState(&rastDesc, &g_pRasterizerState);
    //mpD3DDevice->RSSetState(g_pRasterizerState);

    // Set up the World Matrix
    D3DXMatrixIdentity(&WorldMatrix);
    D3DXMatrixLookAtLH(&ViewMatrix, new D3DXVECTOR3(0.0f, 10.0f, -20.0f), new D3DXVECTOR3(0.0f, 0.0f, 0.0f), new D3DXVECTOR3(0.0f, 1.0f, 0.0f));
    // Set up the projection matrix
    D3DXMatrixPerspectiveFovLH(&ProjectionMatrix, (float)D3DX_PI * 0.5f, (float)mWidth/(float)mHeight, 0.1f, 100.0f);

    if(!CreateObject())
    {
        return false;
    }

    return true;
}

//These are actions that take place after the clearing of the buffer and before the present
void MyGame::GameDraw()
{

    static float rotationAngleY = 15.0f;
    static float rotationAngleX = 0.0f;

    static D3DXMATRIX rotationXMatrix;
    static D3DXMATRIX rotationYMatrix;
    
    // create the rotation matrix using the rotation angle
    D3DXMatrixRotationY(&rotationYMatrix, rotationAngleY);
    D3DXMatrixRotationX(&rotationXMatrix, rotationAngleX);
    

    //rotationAngleY += (float)D3DX_PI * 0.002f;
    //rotationAngleX += (float)D3DX_PI * 0.001f;

    WorldMatrix = rotationYMatrix * rotationXMatrix;

    // Set the input layout
    mpD3DDevice->IASetInputLayout(modelObject.pVertexLayout);

    // Set vertex buffer
    UINT stride = sizeof(VertexPos);
    UINT offset = 0;
    mpD3DDevice->IASetVertexBuffers(0, 1, &modelObject.pVertexBuffer, &stride, &offset);
    
    // Set primitive topology
    mpD3DDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    //ViewMatrix._43 += 0.005f;
    
    // Combine and send the final matrix to the shader
    D3DXMATRIX finalMatrix = (WorldMatrix * ViewMatrix * ProjectionMatrix);
    pProjectionMatrixVariable->SetMatrix((float*)&finalMatrix);


    // make sure modelObject is valid
    

    // Render a model object
    D3D10_TECHNIQUE_DESC techniqueDescription;
    modelObject.pTechnique->GetDesc(&techniqueDescription);

    // Loop through the technique passes
    for(UINT p=0; p < techniqueDescription.Passes; ++p)
    {
        modelObject.pTechnique->GetPassByIndex(p)->Apply(0);

        // draw the cube using all 36 vertices and 12 triangles
        mpD3DDevice->Draw(36,0);
    }
}

//Render actually incapsulates Gamedraw, so you can call data before you actually clear the buffer or after you 
//present data
void MyGame::Render()
{
    DX3dApp::Render();
}

bool MyGame::CreateObject()
{

    //Create Layout
    D3D10_INPUT_ELEMENT_DESC layout[] = {
        {"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT, 0 , 0, D3D10_INPUT_PER_VERTEX_DATA, 0},
        {"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT, 0 , 12, D3D10_INPUT_PER_VERTEX_DATA, 0},
        {"NORMAL",0,DXGI_FORMAT_R32G32B32A32_FLOAT, 0 , 24, D3D10_INPUT_PER_VERTEX_DATA, 0}
    };

    UINT numElements = (sizeof(layout)/sizeof(layout[0]));
    modelObject.numVertices = sizeof(vertices)/sizeof(VertexPos);

    for(int i = 0; i < modelObject.numVertices; i += 3)
    {
        D3DXVECTOR3 out;

        D3DXVECTOR3 v1 = vertices[0 + i].pos;
        D3DXVECTOR3 v2 = vertices[1 + i].pos;
        D3DXVECTOR3 v3 = vertices[2 + i].pos;

        D3DXVECTOR3 u = v2 - v1;
        D3DXVECTOR3 v = v3 - v1;

        D3DXVec3Cross(&out, &u, &v);
        D3DXVec3Normalize(&out, &out);

        vertices[0 + i].normal = out;
        vertices[1 + i].normal = out;
        vertices[2 + i].normal = out;
    }
    
    //Create buffer desc
    D3D10_BUFFER_DESC bufferDesc;
    bufferDesc.Usage = D3D10_USAGE_DEFAULT;
    bufferDesc.ByteWidth = sizeof(VertexPos) * modelObject.numVertices;
    bufferDesc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
    bufferDesc.CPUAccessFlags = 0;
    bufferDesc.MiscFlags = 0;

    D3D10_SUBRESOURCE_DATA initData;
    initData.pSysMem = vertices;
    //Create the buffer

    HRESULT hr = mpD3DDevice->CreateBuffer(&bufferDesc, &initData, &modelObject.pVertexBuffer);
    if(FAILED(hr))
        return false;
    
    /*
    //Create indices
    DWORD indices[] =
    {
        0,1,3,
        1,2,3
    };

    ModelObject.numIndices = sizeof(indices)/sizeof(DWORD);

    bufferDesc.ByteWidth = sizeof(DWORD) * ModelObject.numIndices;
    bufferDesc.BindFlags = D3D10_BIND_INDEX_BUFFER;

    initData.pSysMem = indices;

    hr = mpD3DDevice->CreateBuffer(&bufferDesc, &initData, &ModelObject.pIndicesBuffer);
    if(FAILED(hr))
        return false;*/

    
    /////////////////////////////////////////////////////////////////////////////
    //Set up fx files
    LPCWSTR effectFilename = L"effect.fx";
    modelObject.pEffect = NULL;

     hr = D3DX10CreateEffectFromFile(effectFilename,
        NULL,
        NULL,
        "fx_4_0",
        D3D10_SHADER_ENABLE_STRICTNESS,
        0,
        mpD3DDevice,
        NULL,
        NULL,
        &modelObject.pEffect,
        NULL,
        NULL);

    if(FAILED(hr))
        return false;

    pProjectionMatrixVariable = modelObject.pEffect->GetVariableByName("Projection")->AsMatrix();
    pLightVarible = modelObject.pEffect->GetVariableByName("lightSource")->AsVector();
    //Dont sweat the technique. Get it!
    LPCSTR effectTechniqueName = "Render";
    
    D3DXVECTOR3 vLight(10.0f, 10.0f, 10.0f);
    pLightVarible->SetFloatVector(vLight);

    modelObject.pTechnique = modelObject.pEffect->GetTechniqueByName(effectTechniqueName);
    if(modelObject.pTechnique == NULL)
        return false;
    

    //Create Vertex layout
    D3D10_PASS_DESC passDesc;
    modelObject.pTechnique->GetPassByIndex(0)->GetDesc(&passDesc);

    hr = mpD3DDevice->CreateInputLayout(layout, numElements,
        passDesc.pIAInputSignature,
        passDesc.IAInputSignatureSize,
        &modelObject.pVertexLayout);
    if(FAILED(hr))
        return false;

    return true;
}

そして、以下は私のシェーダーです

effect.fx

matrix Projection;
float3 lightSource;
float4 lightColor = {0.5, 0.5, 0.5, 0.5};

// PS_INPUT - input variables to the pixel shader
// This struct is created and fill in by the 
// vertex shader
struct PS_INPUT
{
    float4 Pos : SV_POSITION;
    float4 Color : COLOR0;
    float4 Normal : NORMAL;
};

////////////////////////////////////////////////
// Vertex Shader - Main Function
///////////////////////////////////////////////
PS_INPUT VS(float4 Pos : POSITION, float4 Color : COLOR, float4 Normal : NORMAL)
{
    PS_INPUT psInput;
    
    // Pass through both the position and the color
        psInput.Pos = mul( Pos, Projection );
    psInput.Color = Color;
    psInput.Normal = Normal;
    
    return psInput;
}

///////////////////////////////////////////////
// Pixel Shader
///////////////////////////////////////////////
float4 PS(PS_INPUT psInput) : SV_Target
{
    float4 finalColor = 0; 
    finalColor = saturate(dot(lightSource, psInput.Normal) * lightColor);
    
    return finalColor;
}

// Define the technique
technique10 Render
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );
    }
}
4

1 に答える 1

1

「私の立方体オブジェクトが日陰にならない」とはどういう意味ですか?最終的な色は何ですか?白?

あなたが投稿したものから、いくつかのものが間違っているように見えます。まず、光ベクトルを定義する方法:

D3DXVECTOR3 vLight(10.0f, 10.0f, 10.0f);

これは正規化されておらず、(hlslまたはc ++コードのいずれかで)必要があるため間違っています。そうでない場合、ドット積は無意味です(ドット積のウィキペディアページ、幾何学的解釈を参照)。また、次のようなすでに正規化されたベクトルを使用することもできます。 [-0.577f, 0.577f, -0.577f]または[0.0f, 0.0f, -1.0f]、正規化を気にしないでください。

次に、ではVS、ワールド行列に従って頂点法線を変換しません。これは、光の方向がワールドスペースで定義されていて、立方体の法線がモデルスペースにとどまっている場合は特に悪いことです。これは悪いシェーディングの原因ではないかもしれませんが、異なるスペースに属するベクトルでは数学を実行できないことに言及することが重要です。

3番目のポイントは、立方体の色を初期化するc ++コードです(頂点の位置だけでなく、それも見つかりません)。すべての属性は少なくとも同じCreateObject関数で初期化する必要があるため、私にはコードのアーキテクチャが不適切に見えます。

シェーダーコーディングスタイルについては、次のように宣言することをお勧めしPS_INPUTます。

struct PS_INPUT
{
    float4 Pos : SV_Position;
    float4 Col : TEXCOORD0;
    float3 Norm : TEXCOORD1;
};

したがって、との間COLORで混乱はありませんSV_Target。すべての非SV_*属性はを使用する必要がありますTEXCOORDN

于 2010-05-26T23:04:05.587 に答える