인프런 커뮤니티 질문&답변

김도형님의 프로필 이미지
김도형

작성한 질문수

[게임 프로그래머 도약반] DirectX11 입문

ConstantBuffer에 대해서 질문이 있습니다.

해결된 질문

작성

·

259

0

안녕하세요 ConstantBuffer에 관련되어 강의를 듣는도중 질문이 3가지 정도 생겼습니다.

  1. VertexBuffer에 있는 내용을 직접 변경해서 다시 랜더링하기 위해선 처음 설정할때 GPU에서 초기화하고 읽기 전용으로만 생성했기때문에 VertexBuffer를 다시 생성하고 GPU로 다시 복사해줘야 한다고 말하셨는데 GPU에서 읽기, 쓰기 둘다 가능한 D3D11_USAGE_DEFAULT 타입으로 생성해준 뒤 GPU내부에 VertexBuffer를 다시 생성할 필요가 없이 쓰기 작업만 해주면 안되는 건가요?

 

  1. 1번 경우가 어떤 이유때문에 안될것이지만 왜 저렇게 하면 안될까 이유가 궁금해서 쓴 것이고 VertexBuffer를 ReadOnly로 설정하고 Offset을 더해주어 모델링이 움직일때 이러한 개념으로 생각해도 되나요?

    우선 현재 렌더링 되고있는 Enemy 100마리가 존재하고 100마리 전부의 위치를 각기 다르게 수정해준다고 가정.
    2-1. VertexBuffer를 통해 위치 정보를 직접 수정하는 경우
    첫 번재, 현재 VRAM에 100마리 만큼의 모델링 정보가 있는 상태에서 100마리 만큼의 위치변환 정보만 전송해주는 방법.
    두 번째, CPU가 GPU로 정보를 보내줄때 아예 그냥 100마리만큼의 모델링 정보 + 100마리 만큼의 위치변환 정보를 전부 전달해주는 방법.
    이 있는데 첫 번째 경우로 한다하면 VRAM에 100마리 만큼의 모델링 정보를 감당할 메모리가 존재하지 않아 불가능하고 두 번째 경우로 한다면 보내주는 용량이 너무 많아 전송 시간이 너무 오래 걸리기 때문에 힘들다라고 이해했습니다.

    그래서 제가 이해해본 강사님께서 말한 방식이 2-2 방법인데

    2-2. ConstantBuffer를 통해 위치 정보를 간접 수정하는 경우
    CPU에서 GPU로 정보를 보내줄때 100마리의 위치 정보만 보내주고 VRAM에 존재하는 하나의 모델링에 100개의 각기 다른 위치 정보를 더해주어 렌더링함으로써 C++에서 l-value 하나에 여러 상수를 더하면서 여러 r-value를 쓰듯이 사용하는 방법.
    이 경우를 통해 1개의 모델링과 100개의 위치변화 정봅만 있으면 100개의 Enemy를 렌더링 할 수 있다 라고 이해했습니다 혹시 이게 맞나요?

     

     

  2. 마지막 질문입니다

    Update 함수에서 memcpy를 사용해서 subResource.pData에 들어온 데이터를 통해 constantBuffer의 상수 데이터를 변경시킨다고 알고 있는데 이 함수 내용에선 직접적으로 constantBuffer에 subResource.pData의 데이터를 할당하는 부분이 없는데 어디서 할당이 되는 건가요? 혹시 몰라서 subResource.pData와 constantBuffer.Get()의 포인터 정보도 찍어봤는데 서로 다른 곳이였어서 deviceContext에서 자동으로 알아서 전달해주는 건가요?

제가 궁금한게 생기면 못 넘어가는 성격이라 질문이 길어서 죄송합니다.

답변 1

1

Rookiss님의 프로필 이미지
Rookiss
지식공유자

일단 궁금한게 생기면 못 넘어가는 성격은 최대한 빠르게 버리셔야 합니다.
하나 다 짚고 넘어가며 공부하는게 바람직한 과목은 (알고리즘, C++문법) 등이 있고
반대로 (DX, 언리얼/유니티 등)은 일일히 파고 들면서 공부하면 정말 본인만 피곤해집니다.
어차피 한 회차를 다 돌고나면 자연스럽게 해결되는 질문이 거의 태반이기 때문입니다.

1~2는 언젠가 스스로 답을 얻게 되실겁니다.
100개 물체를 그리는 등은 Instancing 관련 내용이라 ConstBuffer랑은 결이 조금 다릅니다.
굳이 바뀌는 데이터가 아닌 상수라면, ReadOnly로 하면 버퍼를 만들면
조금이나마 더 속도가 빨라지지만 매 프레임 혹은 주기적으로
데이터가 수정되어야 한다면, ReadWrite가 둘다 되어야겠죠.

다만 2-2에서 이해하신 내용은 맞습니다.
100개의 물체를 '한번의 DrawCall'에 그리는 게 아니라,
각기 다른 위치에 그리는 것이라면 ConstBuffer를 이용해 할 수가 있습니다.

마지막 질문은, '당연히' Map() 함수를 호출하면서
subResource 내용이 채워지겠죠!

김도형님의 프로필 이미지
김도형
질문자

감사합니다

김도형님의 프로필 이미지
김도형

작성한 질문수

질문하기