오늘은 레스터라이저, 샘플스테이트, 블랜드스테이트등에 대해 알아보자

 

레스터라이저는 코딩보다는 설정하는 단계라고 보면된다.

 

일단 레스터라이저를 생성하는 함수와 이에맞는 스테이트 변수를 만들어주자 

 

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);

결과

+ Recent posts