Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
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
- Porting variabel GLSL ke HLSL
- Porting jenis GLSL ke HLSL
- Porting variabel global GLSL yang telah ditentukan sebelumnya ke HLSL
- Contoh porting variabel GLSL ke HLSL
- Contoh porting kode penyajian OpenGL ke Direct3D
- Topik terkait
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 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
|
jenis vektor
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
|
jenis matriks
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
|
jenis presisi
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);
Topik terkait