Vertex Shader and Pixel Shader (HLSL)
Direct3D 의 Shader 프로그램은 HLSL (High Level Shading Language) 언어로 작성 된다.
HLSL 은 OpenGL 의 GLSL 과 전체적으로는 유사한 언어구조를 갖는다. 그러나 다른점이 많다.
가정 먼저 나타나는 차이는 바로 main 함수의 존재이다.
GLSL 에서는 Shader의 진입 함수로 main() 함수가 사용되었다. 그러나 HLSL은 이러한 역할을 수행하는 함수가 있지만 그 함수 이름이 main으로 고정되지는 않는다.
즉 진입 함수를 프로그램적으로 정의 할 수 있다는 것이다.
이렇게 진입 함수 이름을 다르게 정할 수 있는데에는 나름대로 장점이 있다.
우리는 Vertex Shader와 Pixel Shader를 모두 작성하게 된다.
GLSL에서는 이 두개의 쉐이더에 각각 main 함수가 있어야 하기 때문에 이 두 파일을 따로 컴파일 하여야 한다. 쉐이더 코드를 각각 준비해야 된다는 것이다.
그러나 이렇게 진입호출 함수를 직접 정할 수 있다면, 하나의 파일로 Vertex Shader 와 Pixel Shader를 관리 할 수 있다는 것이다.
GLSL 과 또다른 차이는 Semantics 가 있고 없고의 차이 이다.
GLSL 에서는 Semantics 이 없다. 그러나 HLSL 에서는 Semantics 가 있어야 한다.
그러면 Semantics가 과연 무엇인지를 알아야 GLSL 의 지식에 기반하여 HLSL 프로그램을 이해할 수 있게 된다. GLSL 은 Semantic 이라는 것이 필요가 없다.
struct VOut
{ float4 position : SV_POSITION; }; VOut VShader(float4 position : POSITION) { VOut output; output.position = position; return output; } float4 PShader(float4 position : SV_POSITION) : SV_TARGET { return float4(1.0,1.0,1.0,1.0); } |
위의 코드는 HLSL 로 작성한 버텍스 쉐이어와 픽셀쉐이더이다. 두개의 서로다른 쉐이더를 같은 파일에 작성 할 수 있는 것은 앞서 말했듯이 main가 없고, 직접 쉐이더 프로그램을 C/C++ 코드에서 직접 지정할 수 있기 때문이다.
GLSL 의 코드와 차이가 있음을 알 수 있다.
우선 쉐이더 main 함수가 없고, 직접 이름을 지정하여 호출하게 되는데, 이 함수들이 입력 파라미터를 갖고 있고 또한 return 값도 갖고 있다.
우리가 GLSL 의 main 함수는 void main(); 으로 return 값이 없었다는 것과 입력 파라미터가 없었다는 것을 기억하기 바란다.
또한 변수의 선언에 차이를 보인다.
float4 position : POSITION
와 같이 선언 된것을 볼 수 있다.
HLSL에서 변수의 선언(함수의 선언도 비슷하다) 구조는 다음과 같다.
[Storage_Class] [Type_Modifier] Type Name[Index]
[: Semantic] [: Packoffset] [: Register]; [Annotations] [= Initial_Value] |
좀 복잡하기도 하다.. 생략 가능한 몇가지를 제거하고 좀 단순화 시켜보자.
Type Name [: Semantic];
|
Type Name 은 GLSL 과 같은 모습이다. 물론 C 언어와도 같은 모습이다.
여기에 이어서 : (콜론 기호) 를 입력한 후 Semantic 을 추가 할 수 있다.
시멘틱에 대해서는 다음 링크를 읽어보기 바란다.
시멘틱은 해당 변수의 성격을 정해준다. POSITION 이라는 것은 시멘특에서 보면 버텍스 쉐이더에서 사용하는 input 값중 하나로 object 의 버텍스 위치를 의미한다고 되어 있다.
POSITION[n]
Vertex position in object space. |
VOut VShader(float4 position : POSITION)
버텍스 쉐이더 이다. 버텍스 버퍼의 위치정보가 position 인수로 전달되어 온다.
VOut 이라는 구조체를 return 하게 된다.
VOut 은 float4 position : SV_POSITION 정보를 갖도록 선언된 구조체이다.
여기서 SV_POSITION 도 시멘틱이다.
float4 PShader(float4 position : SV_POSITION) : SV_TARGET
픽셀쉐이더 이다.
위의 쉐이더에 의하여 출력되는 화면은 다음과 같다.
이또한 픽셀쉐이더에서 색상을 변경할 수 있다.
float4 PShader(float4 position : VPOS) : SV_Target
{
return float4(1.0,.0,.0,1.0);
}
위의 경우 버텍스 쉐이더에서 픽셀쉐이더로 position이 전달되고 있는데 쉐이더 코드에서는 직접 사용하지 않고 있기는 하다.
댓글 없음:
댓글 쓰기