HLSL 쉐이더는 실제로 렌더링 출력에 어떤 영향을 미칩니 까?


11

나는 HLSL의 구문을 이해한다. 예를 들어 이것을 HLSL로 여기는 척하자.

struct VOut
{
    float4 position : SV_POSITION;
    float4 color : COLOR;
};

VOut VShader(float4 position : POSITION, float4 color : COLOR)
{
    VOut output;

    output.position = position;
    output.position.xy *= 0.7f;    // "shrink" the vertex on the x and y axes
    output.color = color;

    return output;
}


float4 PShader(float4 position : SV_POSITION, float4 color : COLOR) : SV_TARGET
{
    return color;
}

그리고 나는 이것을 다음과 같이 컴파일합니다 :

D3DX11CompileFromFile(L"shaders.hlsl", 0, 0, "VShader", "vs_5_0", 0, 0, 0, &VS, 0, 0);
D3DX11CompileFromFile(L"shaders.hlsl", 0, 0, "PShader", "ps_5_0", 0, 0, 0, &PS, 0, 0);

HLSL과 화면의 실제 픽셀 / 버텍스 사이의 파이프 라인이 무엇인지 정확히 혼동하고 있습니다.

이것이 실제로 "적용되는"것입니까?

dev->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &pVS);
dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pPS);

// set the shader objects
devcon->VSSetShader(pVS, 0, 0);
devcon->PSSetShader(pPS, 0, 0);

나는 이 물건에 대한 문자 초보자 와 같습니다. 누군가가 어쩌면 설명 할 수 무엇 은하고있어? 정점 HLSL 함수가 모든 정점을 통과 한 다음 함수에있는 것으로 변경한다고 가정하고 출력은 픽셀 쉐이더에 대해 변경된 것과 비슷합니까?

또 다른 혼란은 픽셀이 무엇인지 알고 정점이 무엇인지 이해합니다 ...하지만 픽셀 쉐이더가 정확히 무엇을합니까?


괜찮아요, 아무도 없습니다
bobobobo

답변:


10

어떻게 변경해야하는지 알고 싶습니다 .... HLSL과 화면의 실제 픽셀 / 정점 사이의 파이프 라인에서 정확히 혼동됩니다.

드로우 콜 (DrawPrimitives, D3D의 DrawIndexedPrimitives, Draw in 10+ 등)을 발행하면 파이프 라인에 바인딩 한 지오메트리 데이터 (정점 버퍼)가 처리됩니다. 모든 정점에 대해 정점 셰이더가 실행되어 클립 공간에 출력 정점이 생성됩니다.

그런 다음 GPU는 클리핑 / 컬링 및 정점을 화면 공간으로 가져와 삼각형을 래스터 화하기 시작하는 등의 클립 공간 정점에서 일부 고정 기능을 수행합니다. 각 삼각형의 래스터 화 동안 GPU는 해당 삼각형의 표면을 가로 질러 정점 속성을 보간하여 각 보간 된 속성을 픽셀 쉐이더에 공급하여 해당 픽셀에 대한 준결승 색상을 생성합니다 (픽셀 쉐이더가 실행 된 후 블렌딩이 적용되므로 "세미- 결정적인").

이것이 실제로 "적용되는"것입니다.

먼저 게시 한 코드는 셰이더를 컴파일 한 다음 변경 될 때까지 후속 그리기 호출에 대해 활성 상태로 유지되는 파이프 라인에 바인딩합니다. 실제로는 실행되지 않습니다.

누군가 Vertex HLSL 함수가 모든 정점을 통과한다고 가정하고 (입력 위치 : 위치 및 색상 : COLOR) 모든 함수를 내가 함수에있는 것으로 변경하면 출력이 변경된 것입니다. ... (픽셀 쉐이더와 동일).

또 다른 혼란, 나는 픽셀이 무엇인지 알고 정점이 무엇인지 이해합니다 .....하지만 픽셀 쉐이더가 정확히 무엇을합니까 ...

정점 셰이더는 정점을 모델 공간에서 클립 공간으로 변환합니다.

픽셀 셰이더는 보간 된 정점 속성을 기반으로 픽셀에 대한 두 번째 색상 / 깊이를 계산합니다.


9

많은 전문 용어를 사용하지 않고 어떻게 작동하는지 설명하려고 노력할 것입니다.

대화식 속도가 아닌 단순성이 문제라면 컴퓨터의 3D 표면은 공간의 거대한 점 구름이 될 것이므로 밀도가 높아서 각 점을 간격없이 개별적으로 렌더링 할 수 있습니다.

모델을 메모리에 한 번만 저장하려고하지만 다양한 크기와 다양한 각도로 모델을 표시해야하므로 3D 모델을 렌더링 할 때 메모리에서 읽을 때 모든 점을 "변환"해야합니다. 예를 들어 모델을 50 % 크게 렌더링하려면 점의 위치를 ​​절반으로 조정해야합니다.

out.position = in.position * 0.5;
out.color = in.color;

이것은 생각할 수있는 가장 간단한 "버텍스 셰이더"입니다. in은 메모리에서 정점 위치로 가고 out은 큰 정점 위치입니다. 큰 반 정점은 메모리에 다시 저장되지 않습니다. 렌더링에 즉시 사용 된 다음 버립니다.

있지만 핵심 개념이 결여 총 단순화 ,이 정신 영화 그래픽 작업을 수행하는 방법의 측면을 설명합니다.

대화 형 그래픽 (게임)은 영화보다 몇 배나 빠른 그래픽을 렌더링해야하기 때문에 이처럼 단순 할 수 없습니다.

게임에서는 화면의 각 픽셀에 대해 한 점씩 렌더링 할 수 없으며 그 차이를 보완 할 수있는 추가 기능도 제공 할 수 없습니다. 따라서 타협점으로, 근처의 세 지점 사이의 간격은 삼각형으로 표시되며, 다양한 기술적 이유로 화면에서 10 픽셀 이상인 것을 선호합니다.

3D 삼각형을 2D 화면에 투사 한 다음 1D 라인 스택으로 나눌 수 있으며, 각각 0D 픽셀 스택으로 나눌 수 있습니다. 따라서 3D 삼각형을 렌더링하는 문제를 많은 0D 픽셀을 독립적으로 렌더링하는 간단한 문제로 나눌 수 있습니다. 컴퓨터는 짧은 시간 안에 더 간단한 문제를 해결할 수 있습니다.

픽셀 쉐이더는 각 픽셀에서 실행되는 작은 프로그램으로 삼각형을 분해하여 생성됩니다.

out.color = in.color;

이것은 생각할 수있는 가장 간단한 "픽셀 쉐이더"입니다. in은 세 개의 삼각형 정점의 색상을 혼합하고 out은 같은 색상을냅니다. 입력은 "vertex shader"의 출력에서 ​​나오며 출력은 메모리의 화면에 기록됩니다.

따라서 "버텍스 쉐이더"는 GPU 칩 내부에서 실행되는 프로그램입니다. 입력은 GPU 메모리의 "버텍스 버퍼"이며 출력은 "픽셀 셰이더"로 직접 공급됩니다. "픽셀 셰이더"는 GPU 칩 내부에서 실행되는 프로그램입니다. 입력은 정점 셰이더의 3 개의 정점을 혼합 한 것이며 출력은 화면의 픽셀입니다.



-2

지금 픽셀 쉐이더에 대해 걱정하지 마십시오. 초보자라면, 정점 및 프래그먼트 셰이더 만있는 GLSL / HLSL의 세계가되어야합니다. 익숙하고 가변적 인 움직임 등을 이해하기 시작하면 시야를 넓 힙니다.

API가 어떻게 작동하는지에 대한 교재를 강력히 추천합니다. OpenGL 서적 은 고정 파이프 라인에서 동적 프로그래밍 가능 파이프 라인으로 수년에 걸쳐 어떻게 변화 했는지를 잘 보여줍니다 .

챔피언 이동!


1
프래그먼트 셰이더는 픽셀 셰이더와 동일한 기능을 수행합니다.

1
OP가 모든 게임 프로그래밍의 초보자인지 질문에서 알 수 없다고 생각합니다. 그는 자신이 셰이더 코드 작성의 초보자라고 말했습니다. 당신이에서만 아니라면 쉐이더를 작성하는 학습 게임 개발자의 창고에있는 아주 중요한 도구입니다, 나는 단지 그 (것)들을 얼버무하지 않을 매우 게임 개발 학습의 초기 단계.
Olhovsky
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.