Ketika menulis HLSL program warna, input dan variabel output harus memiliki "intent" mereka yang ditunjukkan melalui semantics. Ini adalah konsep standar dalam bahasa naungan HLSL; lihat Dokumentasi semantik pada MSDN untuk lebih detail.
Fungsi vertex shaderProgram yang berjalan di GPU. More info
Lihat di Glossary utama (diindikasikan oleh arahan #pragma vertex
) perlu memiliki semantik pada semua parameter input. Ini sesuai dengan elemen data MeshGrafik utama primitif Unity. Mesh membuat sebagian besar dunia 3D Anda. Unity mendukung mesh poligon triangulat atau Quadrangulasi. Nurbs, Nurms, permukaan Subdiv harus dikonversi ke poligon. More info
Lihat di Glossary individual, seperti posisi simpul, mesh normal, dan koordinat tekstur. Lihat input program vertex untuk rincian lebih lanjut.
Berikut ini contoh vertex shaderProgram yang berjalan pada setiap simpul model 3D ketika model sedang diberikan. More info
Lihat di Glossary sederhana yang mengambil posisi simpul dan koordinat tekstur sebagai input. Naungan pixelUnit terkecil dalam gambar komputer. Ukuran piksel tergantung pada resolusi layar Anda. Pencahayaan pixel dihitung pada setiap piksel layar. More info
Lihat di Glossary memvisualisasikan koordinat tekstur sebagai warna.
Shader "Unlit/Show UVs"
{
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
struct v2f {
float2 uv : TEXCOORD0;
float4 pos : SV_POSITION;
};
v2f vert (
float4 vertex : POSITION, // vertex position input
float2 uv : TEXCOORD0 // first texture coordinate input
)
{
v2f o;
o.pos = UnityObjectToClipPos(vertex);
o.uv = uv;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
return fixed4(i.uv, 0, 0);
}
ENDCG
}
}
}
Alih-alih ejaan dari semua input individu satu per satu, itu juga dimungkinkan untuk menyatakan struktur mereka, dan menunjukkan semantik pada setiap variabel anggota individu dari bangunan.
Paling sering fragmen (piksel) naungan menghasilkan warna, dan memiliki semantik SV_Target
. Korporasi fragmen dalam contoh di atas apakah persis itu:
fixed4 frag (v2f i) : SV_Target
Fungsi frag
memiliki jenis pengembalian fixed4
(warna RGBA presisi rendah). Seperti hanya mengembalikan nilai tunggal, semantik ditunjukkan pada fungsi itu sendiri, : SV_Target
.
Hal ini juga dimungkinkan untuk mengembalikan struktur dengan output. Penyiraman fragmen di atas dapat ditulis ulang dengan cara ini juga, dan itu akan melakukan persis sama:
struct fragOutput {
fixed4 color : SV_Target;
};
fragOutput frag (v2f i)
{
fragOutput o;
o.color = fixed4(i.uv, 0, 0);
return o;
}
Struktur pengembalian dari naungan fragmen sebagian besar berguna bagi naungan yang tidak hanya mengembalikan satu warna. Obat tambahan yang didukung oleh output naungan fragmen adalah sebagai berikut.
SV_Target1
, SV_Target2
, dll: Ini adalah warna tambahan yang ditulis oleh naungan. Ini digunakan ketika rendering ke lebih dari satu target render sekaligus (dikenal sebagai teknik rendering Multiple Render Target, atau MRT). SV_Target0
adalah sama dengan SV_Target
.
Biasanya warna fragmen tidak menimpa nilai penyangga Z, dan nilai default digunakan dari segitiga biasa rasterizationProses menghasilkan gambar dengan menghitung piksel untuk setiap poligon atau segitiga dalam geometri. Ini adalah alternatif untuk ray tracing.
Lihat di Glossary. Namun, untuk beberapa efek itu berguna untuk output nilai kedalaman penyangga Z kustom per pixel.
Perhatikan bahwa pada banyak GPU ini mematikan beberapa optimasi depth bufferSebuah toko memori yang memegang kedalaman nilai z setiap pixel dalam gambar, di mana nilai z adalah kedalaman untuk setiap piksel yang diberikan dari pesawat proyeksi. More info
Lihat di Glossary, jadi jangan menimpa nilai buffer Z tanpa alasan yang baik. Biaya yang dikeluarkan oleh SV_Depth
bervariasi tergantung pada arsitektur GPU, tetapi secara keseluruhan cukup mirip dengan biaya pengujian alfa (menggunakan fungsi clip()
built-in di HLSL). Render naungan yang memodifikasi kedalaman setelah semua naungan buram biasa (misalnya, dengan menggunakan AlphaTest
rendering queue.
Nilai output kedalaman perlu menjadi satu float
.
Sebuah naungan simpul perlu untuk output posisi ruang klip akhir dari simpul, sehingga GPU tahu di mana di layar untuk menjebaknya, dan pada kedalaman apa. Output ini perlu memiliki semantik SV_POSITION
, dan menjadi tipe float4
.
Setiap output lain (“interpolators” atau “varyings”) yang diproduksi oleh naungan simpul adalah apa pun kebutuhan naungan khusus Anda. Nilai output dari naungan simpul akan diinterpolasi di seluruh wajah segitiga rendered, dan nilai-nilai pada setiap pixel akan dilewati sebagai masukan ke naungan fragmen.
Banyak modern GPU tidak benar-benar peduli apa semantik variabel ini memiliki; namun beberapa sistem lama (paling, model naungan 2 GPU di Direct3D 9) memiliki aturan khusus tentang semantik:
TEXCOORD0
, TEXCOORD1
dll digunakan untuk menunjukkan data presisi tinggi arbitrase seperti koordinat tekstur dan posisi.COLOR0
dan COLOR1
semantik pada output simpul dan input fragmen adalah untuk data low-precision, 0–1 range (seperti nilai warna sederhana).Untuk dukungan platform salib terbaik, output vertex label dan input fragmen sebagai semantik TEXCOORDn
.
Ada batasan untuk berapa banyak variabel interpolator dapat digunakan secara total untuk melewati informasi dari simpul ke dalam naungan fragmen. Batas tergantung pada platform dan GPU, dan pedoman umum adalah:
float4
(.xy untuk satu koordinat, .zw untuk koordinat kedua).#pragma target 3.0
).#pragma target 4.0
).Terlepas dari perangkat keras target tertentu Anda, umumnya merupakan ide yang baik untuk digunakan sebagai beberapa interpolator mungkin untuk alasan kinerja.
Naungan fragmen dapat menerima posisi pixel yang diberikan sebagai semantik VPOS
khusus. Fitur ini hanya ada yang dimulai dengan model naungan 3.0, sehingga naungan perlu memiliki directive kompilasi #pragma target 3.0
.
Di platform yang berbeda dari jenis dasar posisi ruang layar bervariasi, sehingga untuk portabilitas maksimum menggunakan tipe UNITY_VPOS_TYPE
untuk itu (itu akan menjadi float4
pada sebagian besar platform, dan float2 pada Direct3D 9).
Selain itu, menggunakan posisi pixel semantik membuatnya sulit untuk memiliki posisi ruang klip (SV_POSITION) dan VPOS dalam struktur vertex-to-fragment yang sama. Jadi naungan simpul harus output posisi ruang klip sebagai variabel "out". Lihat contoh naungan di bawah ini:
Shader "Unlit/Screen Position"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
// note: no SV_POSITION in this struct
struct v2f {
float2 uv : TEXCOORD0;
};
v2f vert (
float4 vertex : POSITION, // vertex position input
float2 uv : TEXCOORD0, // texture coordinate input
out float4 outpos : SV_POSITION // clip space position output
)
{
v2f o;
o.uv = uv;
outpos = UnityObjectToClipPos(vertex);
return o;
}
sampler2D _MainTex;
fixed4 frag (v2f i, UNITY_VPOS_TYPE screenPos : VPOS) : SV_Target
{
// screenPos.xy will contain pixel integer coordinates.
// use them to implement a checkerboard pattern that skips rendering
// 4x4 blocks of pixels
// checker value will be negative for 4x4 blocks of pixels
// in a checkerboard pattern
screenPos.xy = floor(screenPos.xy * 0.25) * 0.5;
float checker = -frac(screenPos.r + screenPos.g);
// clip HLSL instruction stops rendering a pixel if value is negative
clip(checker);
// for pixels that were kept, read the texture and output it
fixed4 c = tex2D (_MainTex, i.uv);
return c;
}
ENDCG
}
}
}
Naungan fragmen dapat menerima variabel yang menunjukkan apakah permukaan rendered menghadap ke cameraKomponen yang menciptakan gambar sudut pandang tertentu di tempat kejadian Anda. Output ditarik ke layar atau ditangkap sebagai tekstur. More info
Lihat di Glossary, atau menghadap jauh dari kamera. Ini berguna ketika rendering geometri yang harus terlihat dari kedua sisi - sering digunakan pada daun dan benda tipis serupa. Variabel input semantik VFACE
akan mengandung nilai positif untuk segitiga front-facing, dan nilai negatif untuk satu back-facing.
Fitur ini hanya ada dari model naungan 3.0 seterusnya, sehingga naungan perlu memiliki directive kompilasi #pragma target 3.0
.
Shader "Unlit/Face Orientation"
{
Properties
{
_ColorFront ("Front Color", Color) = (1,0.7,0.7,1)
_ColorBack ("Back Color", Color) = (0.7,1,0.7,1)
}
SubShader
{
Pass
{
Cull Off // turn off backface culling
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
float4 vert (float4 vertex : POSITION) : SV_POSITION
{
return UnityObjectToClipPos(vertex);
}
fixed4 _ColorFront;
fixed4 _ColorBack;
fixed4 frag (fixed facing : VFACE) : SV_Target
{
// VFACE input positive for frontbaces,
// negative for backfaces. Output one
// of the two colors depending on that.
return facing > 0 ? _ColorFront : _ColorBack;
}
ENDCG
}
}
}
Naungan di atas menggunakan state Cull untuk mematikan culling backface (oleh segitiga back-facing default tidak diberikan sama sekali). Berikut ini adalah naungan yang diterapkan pada sekelompok mesh QuadObjek primitif yang menyerupai pesawat tetapi tepinya hanya satu unit panjang, hanya menggunakan 4 simpul, dan permukaan berorientasi pada pesawat XY ruang koordinat lokal. More info
Lihat di Glossary, diputar pada orientasi yang berbeda:
Naungan simpul dapat menerima variabel yang memiliki “nomor vertex” sebagai bilangan bulat yang tidak ditentukan. Ini sebagian besar berguna ketika Anda ingin mengambil data per-vertex tambahan dari tekstur atau ComputeBuffers.
Fitur ini hanya ada dari DX10 (model bentuk 4.0) dan GLCore / OpenGL ES 3, sehingga warna perlu memiliki langsung kompilasi #pragma target 3.5
.
Shader "Unlit/VertexID"
{
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.5
struct v2f {
fixed4 color : TEXCOORD0;
float4 pos : SV_POSITION;
};
v2f vert (
float4 vertex : POSITION, // vertex position input
uint vid : SV_VertexID // vertex ID, needs to be uint
)
{
v2f o;
o.pos = UnityObjectToClipPos(vertex);
// output funky colors based on vertex ID
float f = (float)vid;
o.color = half4(sin(f/10),sin(f/100),sin(f/1000),0) * 0.5 + 0.5;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
return i.color;
}
ENDCG
}
}
}