Terrain

ㅋㅋ·2022년 7월 29일
0

DirectX12강의

목록 보기
36/39

지형을 항상 만드는건 아님 (메쉬를 지형으로 사용하는 경우)

삼각형 메쉬를 바닥면에 일정한 간격으로 생성하여 사각형을 만듬

이 후 높이를 조절 후 높이 값만 저장해두고 사용 height map


terrain 쉐이더 파일

PatchTess ConstantHS(InputPatch<VS_OUT, 3> input, int patchID : SV_PrimitiveID)
{
    ...

    edge0Pos = mul(float4(edge0Pos, 1.f), g_matWorld).xyz;
    edge1Pos = mul(float4(edge1Pos, 1.f), g_matWorld).xyz;
    edge2Pos = mul(float4(edge2Pos, 1.f), g_matWorld).xyz;

    float edge0TessLevel = CalculateTessLevel(g_vec4_0.xyz, edge0Pos, minDistance, maxDistance, 4.f);
    float edge1TessLevel = CalculateTessLevel(g_vec4_0.xyz, edge1Pos, minDistance, maxDistance, 4.f);
    float edge2TessLevel = CalculateTessLevel(g_vec4_0.xyz, edge2Pos, minDistance, maxDistance, 4.f);

    output.edgeTess[0] = edge0TessLevel;
    output.edgeTess[1] = edge1TessLevel;
    output.edgeTess[2] = edge2TessLevel;
    output.insideTess = edge2TessLevel;

    return output;
}

constant hull shader에서는

카메라와 삼각형의 빗변들 거리를 통하여 테셀레이션 레벨을 정함


struct DS_OUT
{
    float4 pos : SV_Position;
    float2 uv : TEXCOORD;
    float3 viewPos : POSITION;
    float3 viewNormal : NORMAL;
    float3 viewTangent : TANGENT;
    float3 viewBinormal : BINORMAL;
};

[domain("tri")]
DS_OUT DS_Main(const OutputPatch<HS_OUT, 3> input, float3 location : SV_DomainLocation, PatchTess patch)
{
    ...

    float3 localPos = input[0].pos * location[0] + input[1].pos * location[1] + input[2].pos * location[2];
    float2 uv = input[0].uv * location[0] + input[1].uv * location[1] + input[2].uv * location[2];

    ...

    float2 fullUV = float2(uv.x / (float)tileCountX, uv.y / (float)tileCountZ);

    localPos.y = g_tex_2.SampleLevel(g_sam_0, fullUV, 0).x;

    float2 deltaUV = float2(1.f / mapWidth, 1.f / mapHeight);
    float2 deltaPos = float2(tileCountX * deltaUV.x, tileCountZ * deltaUV.y);

    ...
    
    output.pos = mul(float4(localPos, 1.f), g_matWVP);
    output.viewPos = mul(float4(localPos, 1.f), g_matWV).xyz;

    output.viewTangent = normalize(mul(float4(localTangent, 0.f), g_matWV)).xyz;
    output.viewBinormal = normalize(mul(float4(localBinormal, 0.f), g_matWV)).xyz;
    output.viewNormal = normalize(cross(output.viewBinormal, output.viewTangent));

    output.uv = uv;

    return output;
}

도메인 쉐이더에서 정점 위치가 바뀌기 때문에 버텍스 쉐이더에서 하던 역할을 해야함

높이 맵 텍스쳐에서 높이를 추출하여 해당 좌표의 y 값을 변경

변경된 좌표를 기준으로 deferred 렌더에 필요한 행렬들을 다시 계산해주게 됨


terrain 클래스 추가

class Terrain : public Component
{
public:
	...

	void Init(int32 sizeX, int32 sizeZ);

	virtual void FinalUpdate() override;

private:
	int32 _sizeX = 15;
	int32 _sizeZ = 15;
	float _maxTesselation = 4.f;

	...
};

초기화 시 지형의 크기를 입력 받아 세팅하도록 정의

void Terrain::FinalUpdate()
{
	...

	Vec3 pos = mainCamera->GetTransform()->GetLocalPosition();
	_material->SetVec4(0, Vec4(pos.x, pos.y, pos.z, 0));
}

final update 시에 메인 카메라의 위치를 받아와 쉐이더에서 계산 시 사용할 수 있도록 입력

0개의 댓글