응애맘마조
231017 강의 본문
테셀레이션에 대해서 강의했습니다. 삼각형을 여러 개의 조각으로 나누었다고 볼 수 있으며 조각이 늘어났음에도 정점 개수는 그대로이기 때문에 FPS가 줄어들지 않고 많을수록 더 현실적인 그래픽으로 나타낼 수 있습니다. 이번 테셀레이션은 개념적으로만 설명하고 넘어간다고 했습니다.
#include "Common.hlsl"
struct VertexInput
{
float4 Position : POSITION0;
};
struct CHullOutput
{
float edgeTessFactor[3] : SV_TessFactor;
float insideTessFactor : SV_InsideTessFactor;
};
struct HullOutput
{
float4 Position : POSITION;
};
struct PixelInput
{
float4 Position : SV_POSITION;
};
#define NUM_CONTROL_POINTS 3
cbuffer EdgeInfo : register(b10)
{
float3 edges;
float inside;
}
VertexInput VS(VertexInput input)
{
return input;
}
CHullOutput CHS(InputPatch<VertexInput, NUM_CONTROL_POINTS> input)
{
CHullOutput output;
output.edgeTessFactor[0] = edges.x;
output.edgeTessFactor[1] = edges.y;
output.edgeTessFactor[2] = edges.z;
output.insideTessFactor = inside;
return output;
}
[domain("tri")]
[partitioning("integer")]
[outputtopology("triangle_cw")]
[outputcontrolpoints(3)]
[patchconstantfunc("CHS")]
HullOutput HS(InputPatch<VertexInput, NUM_CONTROL_POINTS> input,
uint i : SV_OutputControlPointID)
{
HullOutput output;
output.Position = input[i].Position;
return output;
}
[domain("tri")]
PixelInput DS(CHullOutput input, float3 uvw : SV_DomainLocation,
const OutputPatch<HullOutput, NUM_CONTROL_POINTS> patch)
{
PixelInput output;
float4 pos = patch[0].Position * uvw.x + patch[1].Position * uvw.y + patch[2].Position * uvw.z;
output.Position = float4(pos.xyz, 1.0f);
return output;
}
float4 PS(PixelInput input) : SV_TARGET
{
return float4(1, 1, 0, 1);
}
삼각형을 나타내기 위한 hlsl입니다.
#pragma once
class Scene1 : public Scene
{
private:
Camera* cam;
Mesh* mesh;
Shader* shader;
struct EdgeBuffer
{
Vector3 edges;
float inside;
}edgeBufferDesc;
ID3D11Buffer* edgeBuffer;
public:
Scene1();
~Scene1();
virtual void Init() override;
virtual void Release() override;
virtual void Update() override;
virtual void LateUpdate() override;
virtual void PreRender() override;
virtual void Render() override;
virtual void ResizeScreen() override;
};
#include "stdafx.h"
Scene1::Scene1()
{
cam = Camera::Create();
cam->LoadFile("Cam.xml");
Camera::main = cam;
shader = new Shader();
shader->LoadFile("TessTri.hlsl");
shader->LoadTessellation();
int vertexCount = 3;
VertexP* vertices = new VertexP[vertexCount];
vertices[0] = Vector3(0, 0.9, 0);
vertices[1] = Vector3(0.9, -0.9, 0);
vertices[2] = Vector3(-0.9, -0.9, 0);
int indexCount = 3;
UINT* indices = new UINT[indexCount];
indices[0] = 0;
indices[1] = 1;
indices[2] = 2;
mesh = new Mesh(vertices, vertexCount, indices, indexCount, VertexType::P);
mesh->primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST;
edgeBufferDesc.edges.x = 1;
edgeBufferDesc.edges.y = 1;
edgeBufferDesc.edges.z = 1;
edgeBufferDesc.inside = 1;
{
D3D11_BUFFER_DESC desc = { 0 };
desc.ByteWidth = sizeof(EdgeBuffer);
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;//상수버퍼
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
desc.StructureByteStride = 0;
HRESULT hr = D3D->GetDevice()->CreateBuffer(&desc, NULL, &edgeBuffer);
assert(SUCCEEDED(hr));
}
}
Scene1::~Scene1()
{
cam->Release();
}
void Scene1::Init()
{
}
void Scene1::Release()
{
}
void Scene1::Update()
{
Camera::main->width = App.GetWidth();
Camera::main->height = App.GetHeight();
Camera::main->viewport.width = App.GetWidth();
Camera::main->viewport.height = App.GetHeight();
Camera::main->Update();
Camera::ControlMainCam();
LIGHT->RenderDetail();
ImGui::Text("FPS: %d", TIMER->GetFramePerSecond());
ImGui::Begin("Hierarchy");
cam->RenderHierarchy();
ImGui::End();
}
void Scene1::LateUpdate()
{
ImGui::DragFloat("Edge0", &edgeBufferDesc.edges.x);
ImGui::DragFloat("Edge1", &edgeBufferDesc.edges.y);
ImGui::DragFloat("Edge2", &edgeBufferDesc.edges.z);
ImGui::DragFloat("Inside0", &edgeBufferDesc.inside);
}
void Scene1::PreRender()
{
}
void Scene1::Render()
{
LIGHT->Set();
Camera::main->Set();
RASTER->Set(D3D11_CULL_NONE, D3D11_FILL_WIREFRAME);
{
//상수버퍼
D3D11_MAPPED_SUBRESOURCE mappedResource;
D3D->GetDC()->Map(edgeBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
memcpy_s(mappedResource.pData, sizeof(EdgeBuffer), &edgeBufferDesc, sizeof(EdgeBuffer));
D3D->GetDC()->Unmap(edgeBuffer, 0);
D3D->GetDC()->HSSetConstantBuffers(10, 1, &edgeBuffer);
}
shader->Set();
mesh->Set();
D3D->GetDC()->Draw(3, 0);
}
void Scene1::ResizeScreen()
{
cam->width = App.GetWidth();
cam->height = App.GetHeight();
cam->viewport.width = App.GetWidth();
cam->viewport.height = App.GetHeight();
}
메인에서 실행될 클래스입니다.
내일 마저 끝낸다고 했고 테셀레이션에 대해 조금 더 한다고 했습니다.
읽어주셔서 감사합니다.
Comments