Notice
Recent Posts
Recent Comments
Link
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
Archives
Today
Total
관리 메뉴

codingfarm

6. Direct3D의 그리기 연산 - 연습문제 본문

computer graphics/DX12 book

6. Direct3D의 그리기 연산 - 연습문제

scarecrow1992 2021. 6. 30. 23:55

https://developer-kua.tistory.com/21?category=422534

 

1. 다음 정점 구조체를 위한 D3D12_INPUT_ELEENT_DESC 배열을 작성하라

struct Vertex{
    XMFLOAT3 Pos;
    XMFLOAT3 Tangent;
    XMFLOAT3 Normal;
    XMFLOAT2 Tex0;
    XMFLOAT2 Tex1;
    XMCOLOR  Coor;
};

 

proof)

std::vector<D3D12_INPUT_ELEMENT_DESC> mInputLayout =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
        { "TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
        { "NORMAL", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
        { "TEX", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 36, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
        { "TEX", 1, DXGI_FORMAT_R32G32B32_FLOAT, 0, 44, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
        { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 52, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }
    };
}

 

 

2. 상자 예제('Box')를, 정점 버퍼 두개(그리고 입력 슬롯 두 개)를 사용해서 pipeline에 vertex들을 공급하도록 수정하라.

hint : 정점버퍼 하나는 정점의 위치 성분을, 다른 하나는 정점의 색상 성분을 담도록 하면 된다.

 

proof)

정점 구조체를 2개의 다른 구조체로 분할해야한다. 

struct VPosData {
    XMFLOAT3 Pos;
};
struct VColorData {
    XMFLOAT4 Color;
};

구조체가 분할되었으므로 input element desc 배열도 바뀌어야한다.

void BoxApp::BuildShadersAndInputLayout()
{
	...
    mInputLayout =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
        { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
    };
}

2개의 성분이 각기 다른 input slot을 통해 제공되므로 input element desc의 4번째 성분을 각각 0, 1로 바꾼다.

그리고 각 성분들이 다른 slot에 묶이므로 offset은 둘다 0이된다.

 

vertex의 정보를 담은 배열을 정의한다.

std::array<VPosData, 8> vPosDatas =
{
    VPosData({ XMFLOAT3(-1.0f, -1.0f, -1.0f) }),
    VPosData({ XMFLOAT3(-1.0f, +1.0f, -1.0f) }),
    VPosData({ XMFLOAT3(+1.0f, +1.0f, -1.0f) }),
    VPosData({ XMFLOAT3(+1.0f, -1.0f, -1.0f) }),
    VPosData({ XMFLOAT3(-1.0f, -1.0f, +1.0f) }),
    VPosData({ XMFLOAT3(-1.0f, +1.0f, +1.0f) }),
    VPosData({ XMFLOAT3(+1.0f, +1.0f, +1.0f) }),
    VPosData({ XMFLOAT3(+1.0f, -1.0f, +1.0f) })
};
std::array<VColorData, 8> vColorDatas =
{
    VColorData({ XMFLOAT4(Colors::White) }),
    VColorData({ XMFLOAT4(Colors::Black) }),
    VColorData({ XMFLOAT4(Colors::Red) }),
    VColorData({ XMFLOAT4(Colors::Green) }),
    VColorData({ XMFLOAT4(Colors::Blue) }),
    VColorData({ XMFLOAT4(Colors::Yellow) }),
    VColorData({ XMFLOAT4(Colors::Cyan) }),
    VColorData({ XMFLOAT4(Colors::Magenta) })
};

 

이런식으로 후에 buffer도 따로 생성해주고, 서술자도 따로 생성해준 후에 binding도 따로 해야할것이다.

여기서 의문이 생긴다.

두 입력 슬롯으로 공급된 성분들을 조립해서 정점을 만든다

책에는 위와 같이 설명되어 있는데 대체 어떻게 조립해라는 것인가?

 

 

 

 

 

 

6. 정점 셰이더에서 정점을 세계 공간으로 변환하기 전에 다음과 같은 변환을 적용하도록 수정하라.

vin.PosL.xy += 0.5f*sin(vinL.Pos.x)*sin(3.0f*gTime);
vin.PosL.z *= 0.6f + 0.4f*sin(2.0f*gTime);

 

proof)

시간정보를 정점쉐이더에 전달하기 위해 constant buffer를 이용한다.

hlsl 파일의 cbuffer 구조체에 상수 버퍼 변수 gTime을 추가한 후, BoxApp::Update 메서드 내에서 상수버퍼를 갱신하기 전에 이 변수를 GameTimer::TotalTimer() 값에 대응시킨다.

// color.hlsl
cbuffer cbPerObject : register(b0) {
    float4x4 gWorldViewProj; 
    float3 gTime;
};

VertexOut VS(VertexIn vin) {
    VertexOut vout;

    vin.PosL.xy += 0.5f * sin(vin.PosL.x) * sin(3.0f * gTime);
    vin.PosL.z *= 0.6f + 0.4f * sin(2.0f * gTime);

    // Transform to homogeneous clip space.
    vout.PosH = mul(float4(vin.PosL, 1.0f), gWorldViewProj);
	
    // Just pass vertex color into the pixel shader.
    vout.Color = vin.Color;
    
    return vout;
}


// BoxApp.cpp
void BoxApp::Update(const GameTimer& gt) {
	...
    
    // Update the constant buffer with the latest worldViewProj matrix.
    ObjectConstants objConstants;
    objConstants.Time = gt.TotalTime();
    XMStoreFloat4x4(&objConstants.WorldViewProj, XMMatrixTranspose(worldViewProj));

    mObjectCB->CopyData(0, objConstants);
}

시간에 따라 박스의 모습이 변하는것을 볼 수 있다.

 

 

 

 

 

 

 

 

 

 

Comments