Bagikan melalui


Referensi GLSL-to-HLSL

Anda memindahkan kode OpenGL Shader Language (GLSL) ke kode Microsoft High Level Shader Language (HLSL) saat Anda mem-port arsitektur grafis dari OpenGL ES 2.0 ke Direct3D 11 untuk membuat game untuk Platform Windows Universal (UWP). GLSL yang disebut di sini kompatibel dengan OpenGL ES 2.0; HLSL kompatibel dengan Direct3D 11. Untuk informasi tentang perbedaan antara Direct3D 11 dan versi Direct3D sebelumnya, lihat Pemetaan fitur.

Membandingkan OpenGL ES 2.0 dengan Direct3D 11

OpenGL ES 2.0 dan Direct3D 11 memiliki banyak kesamaan. Keduanya memiliki alur penyajian dan fitur grafis yang sama. Tetapi Direct3D 11 adalah implementasi rendering dan API, bukan spesifikasi; OpenGL ES 2.0 adalah spesifikasi rendering dan API, bukan implementasi. Direct3D 11 dan OpenGL ES 2.0 umumnya berbeda dengan cara-cara berikut:

OpenGL ES 2.0 Direct3D 11
Spesifikasi agnostik perangkat keras dan sistem operasi dengan implementasi yang disediakan vendor Implementasi Microsoft dari abstraksi dan sertifikasi perangkat keras pada platform Windows
Diabstraksi untuk keragaman perangkat keras, runtime mengelola sebagian besar sumber daya Akses langsung ke tata letak perangkat keras; aplikasi dapat mengelola sumber daya dan pemrosesan
Menyediakan modul tingkat yang lebih tinggi melalui pustaka pihak ketiga (misalnya, Simple DirectMedia Layer (SDL)) Modul tingkat yang lebih tinggi, seperti Direct2D, dibangun berdasarkan modul yang lebih rendah untuk menyederhanakan pengembangan untuk aplikasi Windows
Vendor perangkat keras membedakan melalui ekstensi Microsoft menambahkan fitur opsional ke API dengan cara umum sehingga tidak spesifik untuk vendor perangkat keras tertentu

 

GLSL dan HLSL umumnya berbeda dengan cara-cara berikut:

GLSL HLSL
Prosedural, berpusat pada langkah (seperti C) Berorientasi objek, data-sentris (seperti C++)
Kompilasi shader terintegrasi ke dalam API grafis Pengkompilasi HLSL mengkompilasi shader ke representasi biner perantara sebelum Direct3D meneruskannya ke driver.
Catatan Representasi biner ini independen perangkat keras. Biasanya dikompilasi pada waktu build aplikasi, bukan pada waktu proses aplikasi.
 
Pengubah penyimpanan variabel Buffer konstanta dan transfer data melalui deklarasi tata letak input

Jenis

Jenis vektor umum: vec2/3/4

lowp, mediump, highp

Jenis vektor umum: float2/3/4

min10float, min16float

texture2D [Fungsi] tekstur. Sampel [jenis data. Fungsi]
sampler2D [datatype] Texture2D [datatype]
Matriks baris-utama (default) Matriks utama kolom (default)
Catatan Gunakan pengubah jenis row_major untuk mengubah tata letak untuk satu variabel. Untuk informasi selengkapnya, lihat Sintaks Variabel. Anda juga dapat menentukan bendera kompilator atau pragma untuk mengubah default global.
 
Shader fragmen Piksel shader

 

Perhatikan bahwa HLSL memiliki tekstur dan sampler sebagai dua objek terpisah. Di GLSL, seperti Direct3D 9, pengikatan tekstur adalah bagian dari status sampler.

 

Di GLSL, Anda menyajikan sebagian besar status OpenGL sebagai variabel global yang telah ditentukan sebelumnya. Misalnya, dengan GLSL, Anda menggunakan variabel gl_Position untuk menentukan posisi vertex dan variabel gl_FragColor untuk menentukan warna fragmen. Di HLSL, Anda meneruskan status Direct3D secara eksplisit dari kode aplikasi ke shader. Misalnya, dengan Direct3D dan HLSL, input ke shader vertex harus cocok dengan format data dalam buffer vertex, dan struktur buffer konstan dalam kode aplikasi harus cocok dengan struktur buffer konstanta (cbuffer) dalam kode shader.

Porting variabel GLSL ke HLSL

Di GLSL, Anda menerapkan pengubah (kualifikasi) ke deklarasi variabel shader global untuk memberikan variabel tersebut perilaku tertentu dalam shader Anda. Di HLSL, Anda tidak memerlukan pengubah ini karena Anda menentukan alur shader dengan argumen yang Anda teruskan ke shader Anda dan bahwa Anda kembali dari shader Anda.

Perilaku variabel GLSL Setara HLSL

seragam

Anda meneruskan variabel seragam dari kode aplikasi ke vertex dan shader fragmen. Anda harus mengatur nilai semua seragam sebelum menggambar segitiga apa pun dengan shader tersebut sehingga nilainya tetap sama di seluruh gambar jala segitiga. Nilai-nilai ini seragam. Beberapa seragam diatur untuk seluruh bingkai dan yang lain secara unik ke satu pasangan shader vertex-pixel tertentu.

Variabel seragam adalah variabel per poligon.

Gunakan buffer konstanta.

Lihat Cara: Membuat Konstanta Buffer dan Shader Konstanta Konstanta.

Berbagai

Anda menginisialisasi variabel yang bervariasi di dalam shader vertex dan meneruskannya ke variabel yang diberi nama yang berbeda secara identik dalam shader fragmen. Karena shader vertex hanya mengatur nilai variabel yang bervariasi di setiap vertex, rasterizer menginterpolasi nilai-nilai tersebut (dengan cara yang benar perspektif) untuk menghasilkan nilai per fragmen untuk diteruskan ke shader fragmen. Variabel ini bervariasi di setiap segitiga.

Gunakan struktur yang Anda kembalikan dari shader vertex sebagai input ke shader piksel Anda. Pastikan nilai semantik cocok.

atribut

Atribut adalah bagian dari deskripsi vertex yang Anda teruskan dari kode aplikasi ke shader vertex saja. Tidak seperti seragam, Anda mengatur nilai setiap atribut untuk setiap puncak, yang, pada gilirannya, memungkinkan setiap vertex untuk memiliki nilai yang berbeda. Variabel atribut adalah variabel per vertex.

Tentukan buffer vertex dalam kode aplikasi Direct3D Anda dan cocokkan dengan input vertex yang ditentukan dalam shader vertex. Secara opsional, tentukan buffer indeks. Lihat Cara: Membuat Buffer Vertex dan Cara: Membuat Buffer Indeks.

Buat tata letak input di kode aplikasi Direct3D Anda dan cocokkan nilai semantik dengan yang ada di input vertex. Lihat Membuat tata letak input.

const

Konstanta yang dikompilasi ke dalam shader dan tidak pernah berubah.

Gunakan const statis. statis berarti nilai tidak diekspos ke buffer konstanta, const berarti shader tidak dapat mengubah nilai. Jadi, nilai diketahui pada waktu kompilasi berdasarkan inisialisasinya.

 

Dalam GLSL, variabel tanpa pengubah hanyalah variabel global biasa yang bersifat pribadi untuk setiap shader.

Saat Anda meneruskan data ke tekstur (Texture2D di HLSL) dan sampel terkaitnya (SamplerState di HLSL), Anda biasanya mendeklarasikannya sebagai variabel global dalam shader piksel.

Porting jenis GLSL ke HLSL

Gunakan tabel ini untuk memindahkan jenis GLSL Anda ke HLSL.

Jenis GLSL Jenis HLSL
jenis skalar: float, int, bool

jenis skalar: float, int, bool

juga, uint, double

Untuk informasi selengkapnya, lihat Jenis Skalar.

jenis vektor

  • vektor floating-point: vec2, vec3, vec4
  • Vektor Boolean: bvec2, bvec3, bvec4
  • vektor bilangan bulat yang ditandatangani: ivec2, ivec3, ivec4

jenis vektor

  • float2, float3, float4, dan float1
  • bool2, bool3, bool4, dan bool1
  • int2, int3, int4, dan int1
  • Jenis ini juga memiliki ekspansi vektor yang mirip dengan float, bool, dan int:

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

Untuk informasi selengkapnya, lihat Jenis Vektor dan Kata Kunci.

vektor juga didefinisikan sebagai float4 (float vektor <typedef, 4> vektor;). Untuk informasi selengkapnya, lihat Jenis yang Ditentukan Pengguna.

jenis matriks

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

jenis matriks

  • float2x2
  • float3x3
  • float4x4
  • juga, float1x1, float1x2, float1x3, float1x4, float2x1, float2x3, float2x4, float3x1, float3x2, float3x4, float4x1, float4x2, float4x3
  • Jenis-jenis ini juga memiliki ekspansi matriks yang mirip dengan float:

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

Anda juga dapat menggunakan jenis matriks untuk menentukan matriks.

Misalnya: float matriks <, 2, 2> fMatrix = {0,0f, 0,1, 2,1f, 2,2f};

matriks juga didefinisikan sebagai float4x4 (typedef matrix <float, 4, 4> matriks;). Untuk informasi selengkapnya, lihat Jenis yang Ditentukan Pengguna.

kualifikasi presisi untuk float, int, sampler

  • highp

    Kualifikasi ini memberikan persyaratan presisi minimum yang lebih besar dari yang disediakan oleh min16float dan kurang dari float 32-bit penuh. Setara dalam HLSL adalah:

    highp float -> float

    highp int -> int

  • mediump

    Kualifikasi ini diterapkan pada float dan int setara dengan min16float dan min12int di HLSL. Minimum 10 bit mantissa, tidak seperti min10float.

  • lowp

    Kualifikasi yang diterapkan pada float ini menyediakan rentang titik mengambang -2 hingga 2. Setara dengan min10float di HLSL.

jenis presisi

  • min16float: nilai floating point minimum 16-bit
  • min10float

    Nilai minimum yang ditandatangani titik tetap 2,8 bit (2 bit dari bilangan buletin dan komponen pecahan 8 bit). Komponen pecahan 8-bit dapat termasuk 1 alih-alih eksklusif untuk memberinya rentang inklusif penuh -2 hingga 2.

  • min16int: bilangan bulat bertanda tangan 16-bit minimum
  • min12int: bilangan bulat bertanda tangan minimum 12-bit

    Jenis ini untuk 10Level9 (9_x tingkat fitur) di mana bilangan bulat diwakili oleh angka titik mengambang. Ini adalah presisi yang bisa Anda dapatkan ketika Anda meniru bilangan bulat dengan angka titik mengambang 16-bit.

  • min16uint: bilangan bulat minimum 16-bit yang tidak ditandatangani

Untuk informasi selengkapnya, lihat Jenis Skalar dan Menggunakan presisi minimum HLSL.

sampler2D Texture2D
samplerCube TextureCube

 

Porting variabel global GLSL yang telah ditentukan sebelumnya ke HLSL

Gunakan tabel ini untuk mem-port variabel global GLSL yang telah ditentukan sebelumnya ke HLSL.

Variabel global GLSL yang telah ditentukan sebelumnya Semantik HLSL

gl_Position

Variabel ini adalah jenis vec4.

Posisi puncak

misalnya - gl_Position = posisi;

SV_Position

POSISI dalam Direct3D 9

Semantik ini adalah jenis float4.

Output shader vertex

Posisi puncak

misalnya - float4 vPosition : SV_Position;

gl_PointSize

Variabel ini adalah jenis float.

Ukuran titik

PSIZE

Tidak ada arti kecuali Anda menargetkan Direct3D 9

Semantik ini adalah jenis float.

Output shader vertex

Ukuran titik

gl_FragColor

Variabel ini adalah jenis vec4.

Warna fragmen

misalnya - gl_FragColor = vec4(colorVarying, 1.0);

SV_Target

WARNA dalam Direct3D 9

Semantik ini adalah jenis float4.

Output shader piksel

Warna piksel

misalnya - float4 Color[4] : SV_Target;

gl_FragData[n]

Variabel ini adalah jenis vec4.

Warna fragmen untuk lampiran warna n

SV_Target[n]

Semantik ini adalah jenis float4.

Nilai output shader piksel yang disimpan dalam target render n, di mana 0 <= n <= 7.

gl_FragCoord

Variabel ini adalah jenis vec4.

Posisi fragmen dalam buffer bingkai

SV_Position

Tidak tersedia di Direct3D 9

Semantik ini adalah jenis float4.

Input shader piksel

Koordinat ruang layar

misalnya - float4 screenSpace : SV_Position

gl_FrontFacing

Variabel ini adalah jenis bool.

Menentukan apakah fragmen termasuk dalam harga yang menghadap ke depan.

SV_IsFrontFace

VFACE di Direct3D 9

SV_IsFrontFace adalah jenis bool.

VFACE adalah jenis float.

Input shader piksel

Menghadap primitif

gl_PointCoord

Variabel ini adalah jenis vec2.

Posisi fragmen dalam titik (hanya rasterisasi titik)

SV_Position

VPOS di Direct3D 9

SV_Position adalah jenis float4.

VPOS adalah jenis float2.

Input shader piksel

Piksel atau posisi sampel dalam ruang layar

misalnya - float4 pos : SV_Position

gl_FragDepth

Variabel ini adalah jenis float.

Data buffer kedalaman

SV_Depth

KEDALAMAN dalam Direct3D 9

SV_Depth adalah jenis float.

Output shader piksel

Data buffer kedalaman

 

Anda menggunakan semantik untuk menentukan posisi, warna, dan sebagainya untuk input shader vertex dan input pixel shader. Anda harus mencocokkan nilai semantik dalam tata letak input dengan input shader vertex. Misalnya, lihat Contoh porting variabel GLSL ke HLSL. Untuk informasi selengkapnya tentang semantik HLSL, lihat Semantik.

Contoh porting variabel GLSL ke HLSL

Di sini kami menunjukkan contoh penggunaan variabel GLSL dalam kode OpenGL/GLSL lalu contoh yang setara dalam kode Direct3D/HLSL.

Seragam, atribut, dan bervariasi dalam GLSL

Kode aplikasi 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;

Kode shader vertex 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
}

Kode shader fragmen 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);
}

Buffer konstan dan transfer data di HLSL

Berikut adalah contoh cara Anda meneruskan data ke shader vertex HLSL yang kemudian mengalir ke shader piksel. Dalam kode aplikasi Anda, tentukan puncak dan buffer konstan. Kemudian, dalam kode shader vertex Anda, tentukan buffer konstan sebagai cbuffer dan simpan data per vertex dan data input shader piksel. Di sini kita menggunakan struktur yang disebut VertexShaderInput dan PixelShaderInput.

Kode aplikasi 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.

Kode shader vertex 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;
}

Kode shader piksel 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;
}

Contoh porting kode penyajian OpenGL ke Direct3D

Di sini kami menunjukkan contoh penyajian dalam kode OpenGL ES 2.0 lalu contoh yang setara dalam kode Direct3D 11.

Kode penyajian 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);

Kode penyajian 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);