오늘은 레스터라이저, 샘플스테이트, 블랜드스테이트등에 대해 알아보자
레스터라이저는 코딩보다는 설정하는 단계라고 보면된다.
일단 레스터라이저를 생성하는 함수와 이에맞는 스테이트 변수를 만들어주자
Game.h
//RS
ComPtr<ID3D11RasterizerState> _rasterizerState = nullptr;
Game.cpp
void Game::CreateRasterizerState()
{
D3D11_RASTERIZER_DESC desc;
ZeroMemory(&desc, sizeof(desc));
//기본 솔리드 / 백
desc.FillMode = D3D11_FILL_SOLID;
desc.CullMode = D3D11_CULL_BACK;
desc.FrontCounterClockwise = false;
HRESULT hr = _device->CreateRasterizerState(&desc, _rasterizerState.GetAddressOf());
CHECK(hr);
}
void Game::Init(HWND hwnd)
{
_hwnd = hwnd;
_width = GWinSizeX;
_height = GwinSizeY;
CreateDeviceAndSwapChain();
CreateRenderTargetView();
SetViewport();
//삼각형 그리기 파트
CreateGeometry();
CreateVS();
CreateInputLayout();
CreatePS();
CreateRasterizerState();
CreateSRV();
CreateConstantBuffer();
}
//RS
_deviceContext->RSSetState(_rasterizerState.Get());
이대로 실행하면 레스터라이저 단계에서 변화를 주지않았기때문에 변화가 없다.

레스터라이저 단계에서
필모드를
desc.FillMode = D3D11_FILL_WIREFRAME;
로 바꾸게된다면

이런 화면이 나오는데 이것은 실제로 삼각형을 출력해주고 있는 화면인 것이다.
여기서 컬링은 나오지않는 부분은 스킵하는 것인데 후면 인식이라고 보면 된다. 후면인식은 정점의 구성방식에 따라 달라지는데 이 것은 FrontCounterClockwise 를 통해 정해주게 된다.
desc.FrontCounterClockwise = false; //앞은 반시계방향
desc.FrontCounterClockwise = true; //앞은 시계방향
이제 텍스처와 uv를 통해 결과값을 주는 샘플과 관련된 SamplerState에 대해 알아보자
이 부분은 uv좌표와 연관이 많다 만약 uv좌표에서 1을 초과할 경우 빈 부분은 어떻게 채우는 지 정해주는 것이다.
즉 샘플링 규칙을 가지고 있는 것이다.
코드는
Game.h
ComPtr<ID3D11SamplerState> _samplerState = nullptr;
Game.cpp
void Game::CreateSamplerState()
{
D3D11_SAMPLER_DESC desc;
ZeroMemory(&desc, sizeof(desc));
_device->CreateSamplerState(&desc, _samplerState.GetAddressOf());
}
여기서 기본 설정대로 함수를 완성하게 되면
void Game::CreateSamplerState()
{
D3D11_SAMPLER_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.AddressU = D3D11_TEXTURE_ADDRESS_BORDER;
desc.AddressV = D3D11_TEXTURE_ADDRESS_BORDER;
desc.AddressW = D3D11_TEXTURE_ADDRESS_BORDER;
//순서대로 RGBA
desc.BorderColor[0] = 1;
desc.BorderColor[1] = 0;
desc.BorderColor[2] = 0;
desc.BorderColor[3] = 1;
desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
desc.MaxAnisotropy = 16;
desc.MaxLOD = FLT_MAX;
desc.MinLOD = FLT_MIN;
desc.MipLODBias = 0.0f;
_device->CreateSamplerState(&desc, _samplerState.GetAddressOf());
}
그리고 이것을 Render 단계에서 PS 단계에 붙여준다.
//PS
_deviceContext->PSSetShader(_pixelShader.Get(), nullptr, 0);
_deviceContext->PSSetShaderResources(0, 1, _shaderResourceView.GetAddressOf()); //0번슬롯에 1개
_deviceContext->PSSetSamplers(0, 1, _samplerState.GetAddressOf());
지금은 아무런 조작을 하지않고 기본값을 넣어줬기 때문에 변화가 없다.

변화를 주고자 정점단계에서 uv 좌표를 늘린후에 테스트를 해보자
//정점정보
{
_vertices.resize(4);
//13 -> 012
//02 -> 213
_vertices[0].position = Vec3(-0.5f, -0.5f, 0.f);
_vertices[0].uv = Vec2(0.f, 5.f);
//_vertices[0].color = Color(1.f, 0.f, 0.f, 1.f);
_vertices[1].position = Vec3(-0.5f, 0.5f, 0.f);
_vertices[1].uv = Vec2(0.f, 0.f);
//_vertices[1].color = Color(1.f, 0.f, 0.f, 1.f);
_vertices[2].position = Vec3(0.5f, -0.5f, 0.f);
_vertices[2].uv = Vec2(5.f, 5.f);
//_vertices[2].color = Color(1.f, 0.f, 0.f, 1.f);
_vertices[3].position = Vec3(0.5f, 0.5f, 0.f);
_vertices[3].uv = Vec2(5.f, 0.f);
//_vertices[3].color = Color(1.f, 0.f, 0.f, 1.f);
}

결과화면을 보면 1을 초과한 부분은 빨간색으로 돼있는 것을 볼 수 있다. 이것을 결정해주는 게 샘플러 단계인 것이다.
다른모드를 보면 미러로 설정했을 때는 거울에 반사된 것과 같이 나오는 것을 알 수 있다.
desc.AddressU = D3D11_TEXTURE_ADDRESS_MIRROR;
desc.AddressV = D3D11_TEXTURE_ADDRESS_MIRROR;
desc.AddressW = D3D11_TEXTURE_ADDRESS_MIRROR;

경우에 따라서 반복전인 타일을 배치할 때 사용할 수 도 있다.
마지막으로 BlendState의 코를 보자
이 부분은 Blend과 관련된 부분으로 밑의 코드에서 BlendEnable을 true로 했을 때 블랜드를 하겠다는 의미로 쓰인다.
나머지 값들도 어떻게 값을 섞어 줄 것인지를 보여주는 코드들이다.
배경이나 벽에 대한 색을 섞을 때 사용하게 될 것이다.
void Game::CreateBlenderState()
{
D3D11_BLEND_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.AlphaToCoverageEnable = false;
desc.IndependentBlendEnable = false;
desc.RenderTarget[0].BlendEnable = true;
desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
HRESULT hr = _device->CreateBlendState(&desc, _blendState.GetAddressOf());
CHECK(hr);
}
이 부분은 OutputMerge 단계에서 이루어지기 때문에 이 단계에 추가해주자
/OM
_deviceContext->OMSetBlendState(_blendState.Get(), nullptr, 0xFFFFFFFF);

'게임공부 > Directx11' 카테고리의 다른 글
| [Directx11][C++]9. 프레임워크 제작(Graphics,Input Assembler,Geometry) (0) | 2024.07.31 |
|---|---|
| [Directx11]8. Simple Math (0) | 2024.07.15 |
| [Directx11]6. Constant Buffer(상수 버퍼) (1) | 2024.07.09 |
| [Directx11][C++]5. 텍스처와 UV (0) | 2024.07.01 |
| [Directx11][C++]4. 삼각형 그리기 (2) | 2024.07.01 |