다음을 통해 공유


GLSL-HLSL 참조

OpenGL ES 2.0에서 Direct3D 11로 그래픽 아키텍처를 포팅하여 UWP(유니버설 Windows 플랫폼)용 게임을 만들 때 GLSL(OpenGL 셰이더 언어) 코드를 Microsoft HLSL(High Level Shader Language) 코드로 포팅합니다. 여기에 언급된 GLSL은 OpenGL ES 2.0과 호환되며, HLSL은 Direct3D 11과 호환됩니다. Direct3D 11과 이전 버전의 Direct3D 간의 차이점에 대한 자세한 내용은 기능 매핑을 참조하세요.

OpenGL ES 2.0과 Direct3D 11 비교

OpenGL ES 2.0 및 Direct3D 11에는 많은 유사점이 있습니다. 둘 다 유사한 렌더링 파이프라인 및 그래픽 기능을 가지고 있습니다. 그러나 Direct3D 11은 사양이 아닌 렌더링 구현 및 API입니다. OpenGL ES 2.0은 구현이 아닌 렌더링 사양 및 API입니다. Direct3D 11 및 OpenGL ES 2.0은 일반적으로 다음과 같은 방식으로 다릅니다.

OpenGL ES 2.0 Direct3D 11
공급업체에서 제공하는 구현을 사용하는 하드웨어 및 운영 체제에 구애받지 않은 사양 Windows 플랫폼에서 하드웨어 추상화 및 인증의 Microsoft 구현
하드웨어 다양성을 위해 추상화된 런타임은 대부분의 리소스를 관리 하드웨어 레이아웃에 직접 액세스하며, 앱은 리소스 및 처리를 관리할 수 있음
타사 라이브러리(예: SDL(Simple DirectMedia Layer))를 통해 상위 수준 모듈을 제공 Direct2D와 같은 상위 수준 모듈은 Windows 앱 개발을 간소화하기 위해 하위 모듈을 기반으로 함
하드웨어 공급업체는 확장을 통해 차별화 Microsoft는 특정 하드웨어 공급업체와 관련이 없도록 일반적인 방식으로 API에 선택적 기능을 추가

 

GLSL 및 HLSL은 일반적으로 다음과 같은 방식으로 다릅니다.

GLSL HLSL
절차, 단계 중심(C와 유사) 개체 지향, 데이터 중심(C++와 유사)
그래픽 API에 통합된 셰이더 컴파일 HLSL 컴파일러는 Direct3D가 드라이버에 전달하기 전에 셰이더를 중간 이진 표현으로 컴파일합니다.
참고 이 이진 표현은 하드웨어 독립적입니다. 일반적으로 앱 런타임이 아닌 앱 빌드 시간에 컴파일됩니다.
 
변수 스토리지 한정자 입력 레이아웃 선언을 통한 상수 버퍼 및 데이터 전송

유형

일반적인 벡터 형식: vec2/3/4

lowp, mediump, highp

일반적인 벡터 형식: float2/3/4

min10float, min16float

texture2D [Function] texture.Sample [datatype.Function]
sampler2D [datatype] Texture2D [datatype]
행 주 행렬(기본값) 열 주 행렬(기본값)
참고 한 변수의 레이아웃을 변경하려면 row_major 형식 한정자를 사용합니다. 자세한 내용은 변수 구문을 참조하세요. 컴파일러 플래그 또는 pragma를 지정하여 전역 기본값을 변경할 수도 있습니다.
 
조각 셰이더 픽셀 셰이더

 

참고 HLSL에는 텍스처와 샘플러가 별도의 두 개체로 있습니다. Direct3D 9와 같은 GLSL에서 텍스처 바인딩은 샘플러 상태의 일부입니다.

 

GLSL에서는 OpenGL 상태의 대부분을 미리 정의된 전역 변수로 표시합니다. 예를 들어, GLSL에서는 gl_Position 변수를 사용하여 꼭짓점 위치를 지정하고 gl_FragColor 변수를 사용하여 조각 색을 지정합니다. HLSL에서는 앱 코드에서 셰이더로 Direct3D 상태를 명시적으로 전달합니다. 예를 들어 Direct3D 및 HLSL을 사용하면 꼭짓점 셰이더에 대한 입력이 꼭짓점 버퍼의 데이터 형식과 일치해야 하며, 앱 코드의 상수 버퍼 구조는 셰이더 코드에서 상수 버퍼(cbuffer)의 구조와 일치해야 합니다.

HLSL로 GLSL 변수 포팅

GLSL에서는 전역 셰이더 변수 선언에 한정자(한정자)를 적용하여 해당 변수에 셰이더의 특정 동작을 제공합니다. HLSL에서는 셰이더에 전달하고 셰이더에서 반환하는 인수를 사용하여 셰이더의 흐름을 정의하기 때문에 이러한 한정자가 필요하지 않습니다.

GLSL 변수 동작 HLSL 해당 항목

uniform

앱 코드에서 꼭짓점 및 조각 셰이더에 균일한 변수를 전달합니다. 삼각형 메시 그리기 전체에서 해당 값이 동일하게 유지되도록 해당 셰이더를 사용하여 삼각형을 그리기 전에 모든 유니폼의 값을 설정해야 합니다. 이러한 값은 균일합니다. 일부 유니폼은 전체 프레임에 대해 설정되고 다른 유니폼은 특정 꼭짓점 픽셀 셰이더 쌍으로 고유하게 설정됩니다.

균일한 변수는 다각형별 변수입니다.

상수 버퍼를 사용합니다.

방법: 상수 버퍼 만들기셰이더 상수를 참조하세요.

varying

꼭짓점 셰이더 내에서 다양한 변수를 초기화하고 조각 셰이더에서 동일한 이름의 다양한 변수로 전달합니다. 꼭짓점 셰이더는 각 꼭짓점에서 다양한 변수의 값만 설정하기 때문에 래스터라이저는 조각별 값을 생성하여 조각 셰이더로 전달하도록 해당 값을 보간합니다(큐브 뷰 올바른 방식으로). 이러한 변수는 각 삼각형에 따라 다릅니다.

꼭짓점 셰이더에서 반환하는 구조를 픽셀 셰이더에 대한 입력으로 사용합니다. 의미 체계 값이 일치하는지 확인합니다.

attribute

특성은 앱 코드에서 꼭짓점 셰이더로만 전달하는 꼭짓점 설명의 일부입니다. 균일한 것과 달리 각 꼭짓점마다 각 특성의 값을 설정하면 각 꼭짓점의 값이 다를 수 있습니다. 특성 변수는 꼭짓점별 변수입니다.

Direct3D 앱 코드에서 꼭짓점 버퍼를 정의하고 꼭짓점 셰이더에 정의된 꼭짓점 입력과 일치합니다. 필요에 따라 인덱스 버퍼를 정의합니다. 방법: 꼭짓점 버퍼 만들기방법: 인덱스 버퍼 만들기를 참조하세요.

Direct3D 앱 코드에서 입력 레이아웃을 만들고 의미 체계 값을 꼭짓점 입력의 값과 일치합니다. 입력 레이아웃 만들기를 참조하세요.

const

셰이더로 컴파일되고 변경되지 않는 상수입니다.

static const를 사용합니다. static은 값이 상수 버퍼에 표시되지 않음을 의미하고, const는 셰이더가 값을 변경할 수 없음을 의미합니다. 따라서 이 값은 이니셜라이저를 기반으로 컴파일 시간에 알려져 있습니다.

 

GLSL에서 한정자가 없는 변수는 각 셰이더에 프라이빗인 일반 전역 변수일 뿐입니다.

텍스처(HLSL의 Texture2D) 및 관련 샘플러(HLSL의 SamplerState)에 데이터를 전달하는 경우 일반적으로 픽셀 셰이더에서 전역 변수로 선언합니다.

GLSL 형식을 HLSL로 포팅

이 표를 사용하여 GLSL 형식을 HLSL로 이식합니다.

GLSL 유형 HLSL 유형
스칼라 형식: float, int, bool

스칼라 형식: float, int, bool

또한 uint, double

자세한 내용은 스칼라 형식을 참조하세요.

벡터 형식

  • 부동 소수점 벡터: vec2, vec3, vec4
  • 부울 벡터: bvec2, bvec3, bvec4
  • 부호 있는 정수 벡터: ivec2, ivec3, ivec4

벡터 형식

  • float2, float3, float4 및 float1
  • bool2, bool3, bool4 및 bool1
  • int2, int3, int4 및 int1
  • 또한 이러한 형식에는 float, bool 및 int와 유사한 벡터 확장이 있습니다.

    • uint
    • min10float, min16float
    • min12int, min16int
    • min16uint

자세한 내용은 벡터 유형키워드를 참조하세요.

벡터는 float4(typedef 벡터 <float, 4> 벡터;)로 정의된 형식이기도 합니다. 자세한 내용은 사용자 정의 형식을 참조하세요.

행렬 형식

  • mat2: 2x2 float 행렬
  • mat3: 3x3 float 행렬
  • mat4: 4x4 float 행렬

행렬 형식

  • float2x2
  • float3x3
  • float4x4
  • 또한, float1x1, float1x2, float1x3, float1x4, float2x1, float2x3, float2x4, float3x1, float3x2, float3x4, float4x1, float4x2, float4x3
  • 또한 이러한 형식에는 float와 유사한 행렬 확장이 있습니다.

    • int, uint, bool
    • min10float, min16float
    • min12int, min16int
    • min16uint

행렬 형식을 사용하여 행렬을 정의할 수도 있습니다.

예: 행렬 <float, 2, 2> fMatrix = {0.0f, 0.1, 2.1f, 2.2f};

행렬은 float4x4(typedef 행렬 <float, 4, 4> 행렬;)로 정의된 형식이기도 합니다. 자세한 내용은 사용자 정의 형식을 참조하세요.

float, int, sampler에 대한 전체 자릿수 한정자

  • highp

    이 한정자는 min16float에서 제공하는 것보다 크고 전체 32비트 부동 소수 자릿수보다 작은 최소 정밀도 요구 사항을 제공합니다. HLSL에 해당하는 항목은 다음과 같습니다.

    highp float -> float

    highp int -> int

  • mediump

    float 및 int에 적용된 이 한정자는 HLSL의 min16float 및 min12int와 동일합니다. min10float과 같지 않은 최소 10비트의 매니타사입니다.

  • lowp

    float에 적용된 이 한정자는 -2~2의 부동 소수점 범위를 제공합니다. HLSL의 min10float에 해당합니다.

정밀도 형식

  • min16float: 최소 16비트 부동 소수점 값입니다.
  • min10float

    최소 고정 소수점 부호 있는 2.8비트 값(정수 2비트 및 소수점 구성 요소 8비트). 8비트 소수 구성 요소는 -2~2의 전체 포함 범위를 제공하기 위해 배타적인 것이 아니라 1을 포함할 수 있습니다.

  • min16int: 최소 16비트 부호 있는 정수입니다.
  • min12int - 최소 12비트 부호 있는 정수입니다.

    이 형식은 정수가 부동 소수점 숫자로 표현되는 10Level9(9_x 기능 수준)입니다. 16비트 부동 소수점 숫자로 정수를 에뮬레이트할 때 얻을 수 있는 정밀도입니다.

  • min16uint: 최소 16비트 부호 없는 정수입니다.

자세한 내용은 스칼라 형식HLSL 최소 정밀도 사용을 참조하세요.

sampler2D Texture2D
samplerCube TextureCube

 

GLSL 미리 정의된 전역 변수를 HLSL로 포팅

이 표를 사용하여 GLSL 미리 정의된 전역 변수를 HLSL로 포팅할 수 있습니다.

GLSL 미리 정의된 전역 변수 HLSL 의미 체계

gl_Position

이 변수는 vec4 형식입니다.

꼭짓점 위치

예 - gl_Position = position;

SV_Position

Direct3D 9의 POSITION

이 의미 체계는 float4 형식입니다.

꼭짓점 셰이더 출력

꼭짓점 위치

예 - float4 vPosition : SV_Position;

gl_PointSize

이 변수는 float 형식입니다.

포인트 크기

PSIZE

Direct3D 9를 대상으로 하지 않는 한 의미가 없습니다.

이 의미 체계는 float 형식입니다.

꼭짓점 셰이더 출력

포인트 크기

gl_FragColor

이 변수는 vec4 형식입니다.

조각 색

예 - gl_FragColor = vec4(colorVarying, 1.0);

SV_Target

Direct3D 9의 COLOR

이 의미 체계는 float4 형식입니다.

픽셀 셰이더 출력

픽셀 색

예 - float4 Color[4] : SV_Target;

gl_FragData[n]

이 변수는 vec4 형식입니다.

색 첨부 파일의 조각 색 n

SV_Target[n]

이 의미 체계는 float4 형식입니다.

n 렌더링 대상에 저장된 픽셀 셰이더 출력 값입니다. 여기서 0 <= n <= 7입니다.

gl_FragCoord

이 변수는 vec4 형식입니다.

프레임 버퍼 내의 조각 위치

SV_Position

Direct3D 9에서는 사용할 수 없음

이 의미 체계는 float4 형식입니다.

픽셀 셰이더 입력

화면 공간 좌표

예 - float4 screenSpace : SV_Position

gl_FrontFacing

이 변수는 부울 형식입니다.

조각이 전면 기본 형식에 속하는지 여부를 확인합니다.

SV_IsFrontFace

Direct3D 9의 VFACE

SV_IsFrontFace는 부울 형식입니다.

VFACE는 float 형식입니다.

픽셀 셰이더 입력

기본형 연결

gl_PointCoord

이 변수는 vec2 형식입니다.

점 내의 조각 위치(점 래스터화에만 해당)

SV_Position

Direct3D 9의 VPOS

SV_Position은 float4 형식입니다.

VPOS는 float2 형식입니다.

픽셀 셰이더 입력

화면 공간의 픽셀 또는 샘플 위치

예 - float4 pos : SV_Position

gl_FragDepth

이 변수는 float 형식입니다.

깊이 버퍼 데이터

SV_Depth

Direct3D 9의 깊이

SV_Depth는 float 형식입니다.

픽셀 셰이더 출력

깊이 버퍼 데이터

 

의미 체계를 사용하여 꼭짓점 셰이더 입력 및 픽셀 셰이더 입력에 위치, 색 등을 지정합니다. 입력 레이아웃의 의미 체계 값을 꼭짓점 셰이더 입력과 일치시켜야 합니다. 예제는 GLSL 변수를 HLSL 로 포팅하는 예를 참조하세요. HLSL 의미 체계에 대한 자세한 내용은 의미 체계를 참조하세요.

HLSL로의 GLSL 변수 포팅 예

여기서는 OpenGL/GLSL 코드에서 GLSL 변수를 사용한 다음 Direct3D/HLSL 코드에 해당하는 예제를 사용하는 예제를 보여 줍니다.

GLSL의 uniform, attribute 및 varying

OpenGL 앱 코드

// Uniform values can be set in app code and then processed in the shader code.
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

// Incoming position of vertex
attribute vec4 position;
 
// Incoming color for the vertex
attribute vec3 color;
 
// The varying variable tells the shader pipeline to pass it  
// on to the fragment shader.
varying vec3 colorVarying;

GLSL 꼭짓점 셰이더 코드

//The shader entry point is the main method.
void main()
{
colorVarying = color; //Use the varying variable to pass the color to the fragment shader
gl_Position = position; //Copy the position to the gl_Position pre-defined global variable
}

GLSL 조각 셰이더 코드

void main()
{
//Pad the colorVarying vec3 with a 1.0 for alpha to create a vec4 color
//and assign that color to the gl_FragColor pre-defined global variable
//This color then becomes the fragment's color.
gl_FragColor = vec4(colorVarying, 1.0);
}

HLSL의 상수 버퍼 및 데이터 전송

다음은 픽셀 셰이더로 이동하는 HLSL 꼭짓점 셰이더에 데이터를 전달하는 방법의 예입니다. 앱 코드에서 꼭짓점 및 상수 버퍼를 정의합니다. 그런 다음 꼭짓점 셰이더 코드에서 상수 버퍼를 cbuffer로 정의하고 꼭짓점별 데이터 및 픽셀 셰이더 입력 데이터를 저장합니다. 여기서는 VertexShaderInputPixelShaderInput이라는 구조를 사용합니다.

Direct3D 앱 코드

struct ConstantBuffer
{
    XMFLOAT4X4 model;
    XMFLOAT4X4 view;
    XMFLOAT4X4 projection;
};
struct SimpleCubeVertex
{
    XMFLOAT3 pos;   // position
    XMFLOAT3 color; // color
};

 // Create an input layout that matches the layout defined in the vertex shader code.
 const D3D11_INPUT_ELEMENT_DESC basicVertexLayoutDesc[] =
 {
     { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0,  0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
     { "COLOR",    0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
 };

// Create vertex and index buffers that define a geometry.

HLSL 꼭짓점 셰이더 코드

cbuffer ModelViewProjectionCB : register( b0 )
{
    matrix model; 
    matrix view;
    matrix projection;
};
// The POSITION and COLOR semantics must match the semantics in the input layout Direct3D app code.
struct VertexShaderInput
{
    float3 pos : POSITION; // Incoming position of vertex 
    float3 color : COLOR; // Incoming color for the vertex
};

struct PixelShaderInput
{
    float4 pos : SV_Position; // Copy the vertex position.
    float4 color : COLOR; // Pass the color to the pixel shader.
};

PixelShaderInput main(VertexShaderInput input)
{
    PixelShaderInput vertexShaderOutput;

    // shader source code

    return vertexShaderOutput;
}

HLSL 픽셀 셰이더 코드

// Collect input from the vertex shader. 
// The COLOR semantic must match the semantic in the vertex shader code.
struct PixelShaderInput
{
    float4 pos : SV_Position;
    float4 color : COLOR; // Color for the pixel
};

// Set the pixel color value for the renter target. 
float4 main(PixelShaderInput input) : SV_Target
{
    return input.color;
}

Direct3D로의 OpenGL 렌더링 코드 포팅 예

여기서는 OpenGL ES 2.0 코드에서 렌더링한 다음 Direct3D 11 코드에 해당하는 예제를 보여 드립니다.

OpenGL 렌더링 코드

// Bind shaders to the pipeline. 
// Both vertex shader and fragment shader are in a program.
glUseProgram(m_shader->getProgram());
 
// Input assembly 
// Get the position and color attributes of the vertex.

m_positionLocation = glGetAttribLocation(m_shader->getProgram(), "position");
glEnableVertexAttribArray(m_positionLocation);

m_colorLocation = glGetAttribColor(m_shader->getProgram(), "color");
glEnableVertexAttribArray(m_colorLocation);
 
// Bind the vertex buffer object to the input assembler.
glBindBuffer(GL_ARRAY_BUFFER, m_geometryBuffer);
glVertexAttribPointer(m_positionLocation, 4, GL_FLOAT, GL_FALSE, 0, NULL);
glBindBuffer(GL_ARRAY_BUFFER, m_colorBuffer);
glVertexAttribPointer(m_colorLocation, 3, GL_FLOAT, GL_FALSE, 0, NULL);
 
// Draw a triangle with 3 vertices.
glDrawArray(GL_TRIANGLES, 0, 3);

Direct3D 렌더링 코드

// Bind the vertex shader and pixel shader to the pipeline.
m_d3dDeviceContext->VSSetShader(vertexShader.Get(),nullptr,0);
m_d3dDeviceContext->PSSetShader(pixelShader.Get(),nullptr,0);
 
// Declare the inputs that the shaders expect.
m_d3dDeviceContext->IASetInputLayout(inputLayout.Get());
m_d3dDeviceContext->IASetVertexBuffers(0, 1, vertexBuffer.GetAddressOf(), &stride, &offset);

// Set the primitive's topology.
m_d3dDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

// Draw a triangle with 3 vertices. triangleVertices is an array of 3 vertices.
m_d3dDeviceContext->Draw(ARRAYSIZE(triangleVertices),0);