Bagikan melalui


Operator

Ekspresi adalah urutan variabel dan literal yang diselingi oleh operator. Operator menentukan bagaimana variabel dan literal digabungkan, dibandingkan, dipilih, dan sebagainya. Operator meliputi:

Nama operator Operator
Operator Aditif dan Multiplikatif +, -, *, /, %
Array Operator [i]
Operator Penugasan =, +=, -=, *=, /=, %=
Pemeran Biner Aturan C untuk aturan float dan int, C atau intrinsik HLSL untuk bool
Operator Bitwise ~, <<, >>, &, |, ^, =, <<=, >>&=, |=, ^=
Operator Matematika Boolean & &, ||, ?:
Cast Operator (jenis)
Operator Koma ,
Operator perbandingan <, >, ==, !=, <=, >=
Operator Awalan atau Postfix ++, --
Operator Struktur .
Operator Unary !, -, +

 

Banyak operator per komponen, yang berarti bahwa operasi dilakukan secara independen untuk setiap komponen dari setiap variabel. Misalnya, variabel komponen tunggal memiliki satu operasi yang dilakukan. Di sisi lain, variabel empat komponen memiliki empat operasi yang dilakukan, satu untuk setiap komponen.

Semua operator yang melakukan sesuatu pada nilai, seperti + dan *, bekerja per komponen.

Operator perbandingan memerlukan satu komponen untuk bekerja kecuali Anda menggunakan semua atau fungsi intrinsik apa pun dengan variabel beberapa komponen. Operasi berikut gagal karena pernyataan if memerlukan satu bool tetapi menerima bool4:

if (A4 < B4)

Operasi berikut berhasil:

if ( any(A4 < B4) )
if ( all(A4 < B4) )

Operator pemeran biner mengapung, asint, dan sebagainya bekerja per komponen kecuali untuk asdouble yang aturan khususnya didokumenkan.

Operator pilihan seperti tanda titik, koma, dan array tidak berfungsi per komponen.

Operator cast mengubah jumlah komponen. Operasi pemeran berikut menunjukkan kesetaraannya:

(float) i4 ->   float(i4.x)
(float4)i ->   float4(i, i, i, i)

Operator Aditif dan Multiplikatif

Operator aditif dan multiplikatif adalah: +, -, *, /, %

int i1 = 1;
int i2 = 2;
int i3 = i1 + i2;  // i3 = 3
i3 = i1 * i2;        // i3 = 1 * 2 = 2
i3 = i1/i2;       // i3 = 1/3 = 0.333. Truncated to 0 because i3 is an integer.
i3 = i2/i1;       // i3 = 2/1 = 2
float f1 = 1.0;
float f2 = 2.0f;
float f3 = f1 - f2; // f3 = 1.0 - 2.0 = -1.0
f3 = f1 * f2;         // f3 = 1.0 * 2.0 = 2.0
f3 = f1/f2;        // f3 = 1.0/2.0 = 0.5
f3 = f2/f1;        // f3 = 2.0/1.0 = 2.0

Operator modulus mengembalikan sisa divisi. Ini menghasilkan hasil yang berbeda saat menggunakan bilangan bulat dan angka floating-point. Sisa bilangan bulat yang pecahan akan dipotong.

int i1 = 1;
int i2 = 2;
i3 = i1 % i2;      // i3 = remainder of 1/2, which is 1
i3 = i2 % i1;      // i3 = remainder of 2/1, which is 0
i3 = 5 % 2;        // i3 = remainder of 5/2, which is 1
i3 = 9 % 2;        // i3 = remainder of 9/2, which is 1

Operator modulus memotong sisa pecahan saat menggunakan bilangan bulat.

f3 = f1 % f2;      // f3 = remainder of 1.0/2.0, which is 0.5
f3 = f2 % f1;      // f3 = remainder of 2.0/1.0, which is 0.0

Operator % didefinisikan hanya dalam kasus di mana kedua sisi positif atau kedua sisi negatif. Tidak seperti C, ia juga beroperasi pada jenis data floating-point, serta bilangan bulat.

Array Operator

Operator pemilihan anggota array "[i]" memilih satu atau beberapa komponen dalam array. Ini adalah sekumpulan tanda kurung siku yang berisi indeks berbasis nol.

int arrayOfInts[4] = { 0,1,2,3 };
arrayOfInts[0] = 2;
arrayOfInts[1] = arrayOfInts[0];

Operator array juga dapat digunakan untuk mengakses vektor.

float4 4D_Vector = { 0.0f, 1.0f, 2.0f, 3.0f  };         
float 1DFloat = 4D_Vector[1];          // 1.0f

Dengan menambahkan indeks tambahan, operator array juga dapat mengakses matriks.

float4x4 mat4x4 = {{0,0,0,0}, {1,1,1,1}, {2,2,2,2}, {3,3,3,3} };
mat4x4[0][1] = 1.1f;
float 1DFloat = mat4x4[0][1];      // 0.0f

Indeks pertama adalah indeks baris berbasis nol. Indeks kedua adalah indeks kolom berbasis nol.

Operator Penugasan

Operator penugasan adalah: =, +=, -=, *=, /=

Variabel dapat ditetapkan nilai harfiah:

int i = 1;            
float f2 = 3.1f; 
bool b = false;
string str = "string";

Variabel juga dapat ditetapkan hasil operasi matematika:

int i1 = 1;
i1 += 2;           // i1 = 1 + 2 = 3

Variabel dapat digunakan pada salah satu sisi tanda sama dengan:

float f3 = 0.5f;
f3 *= f3;          // f3 = 0.5 * 0.5 = 0.25

Pembagian untuk variabel floating-point seperti yang diharapkan karena sisa desimal tidak menjadi masalah.

float f1 = 1.0;
f1 /= 3.0f;        // f1 = 1.0/3.0 = 0.333

Berhati-hatilah jika Anda menggunakan bilangan bulat yang mungkin dibagi, terutama ketika pemotongan memengaruhi hasilnya. Contoh ini identik dengan contoh sebelumnya, kecuali untuk jenis data. Pemotongan menyebabkan hasil yang sangat berbeda.

int i1 = 1;
i1 /= 3;           // i1 = 1/3 = 0.333, which gets truncated to 0

Pemeran Biner

Operasi transmisi antara int dan float akan mengonversi nilai numerik menjadi representasi yang sesuai mengikuti aturan C untuk memotong jenis int. Mentransmisikan nilai dari float ke int dan kembali ke float akan mengakibatkan konversi yang kalah berdasarkan presisi target.

Pemeran biner juga dapat dilakukan menggunakan Intrinsic Functions (DirectX HLSL), yang menginterpretasikan kembali representasi bit angka ke dalam jenis data target.

asfloat() // Cast to float
asint()   // Cast to int 
asuint()  // Cast to uint

Operator Bitwise

HLSL mendukung operator bitwise berikut, yang mengikuti prioritas yang sama dengan C sehubungan dengan operator lain. Tabel berikut ini menjelaskan operator.

Catatan

Operator bitwise memerlukan Model Shader 4_0 dengan Direct3D 10 dan perangkat keras yang lebih tinggi.

 

Operator Function
~ Tidak Logis
<< Shift Kiri
>> Shift Kanan
& Logika Dan
| Logika atau
^ Xor Logis
<<= Shift Kiri Sama
>>= Shift Kanan Sama
&= Dan Sama Dengan
|= Atau Sama Dengan
^= Xor Sama dengan

 

Operator bitwise didefinisikan untuk beroperasi hanya pada jenis data int dan uint. Mencoba menggunakan operator bitwise pada jenis data float, atau struct akan mengakibatkan kesalahan.

Operator Matematika Boolean

Operator matematika Boolean adalah: &&, ||, ?:

bool b1 = true;
bool b2 = false;
bool b3 = b1 && b2 // b3 = true AND false = false
b3 = b1 || b2                // b3 = true OR false = true

Tidak seperti evaluasi sirkuit pendek &&, ||, dan ?: di C, ekspresi HLSL tidak pernah mengevaluasi sirkuit pendek karena merupakan operasi vektor. Semua sisi ekspresi selalu dievaluasi.

Operator Boolean berfungsi berdasarkan per komponen. Ini berarti bahwa jika Anda membandingkan dua vektor, hasilnya adalah vektor yang berisi hasil Boolean dari perbandingan untuk setiap komponen.

Untuk ekspresi yang menggunakan operator Boolean, ukuran dan jenis komponen setiap variabel dipromosikan agar sama sebelum operasi terjadi. Jenis yang dipromosikan menentukan resolusi di mana operasi berlangsung, serta jenis hasil ekspresi. Misalnya ekspresi int3 + float akan dipromosikan ke float3 + float3 untuk evaluasi, dan hasilnya adalah jenis float3.

Cast Operator

Ekspresi yang didahului oleh nama jenis dalam tanda kurung adalah jenis eksplisit yang ditransmisikan. Jenis cast mengonversi ekspresi asli ke jenis data pemeran. Secara umum, jenis data sederhana dapat ditransmisikan ke jenis data yang lebih kompleks (dengan pemeran promosi), tetapi hanya beberapa jenis data kompleks yang dapat ditransmisikan ke dalam jenis data sederhana (dengan pemeran demosi).

Hanya transmisi jenis sisi kanan yang legal. Misalnya, ekspresi seperti (int)myFloat = myInt; ilegal. Gunakan myFloat = (float)myInt; sebagai gantinya.

Pengkompilasi juga melakukan jenis cast implisit. Misalnya, dua ekspresi berikut setara:

int2 b = int2(1,2) + 2;
int2 b = int2(1,2) + int2(2,2);

Operator Koma

Operator koma (,) memisahkan satu atau beberapa ekspresi yang akan dievaluasi secara berurutan. Nilai ekspresi terakhir dalam urutan digunakan sebagai nilai urutan.

Berikut adalah satu kasus yang layak untuk memanggil perhatian. Jika jenis konstruktor secara tidak sengaja ditinggalkan dari sisi kanan tanda sama dengan, sisi kanan sekarang berisi empat ekspresi, dipisahkan oleh tiga koma.

// Instead of using a constructor
float4 x = float4(0,0,0,1); 

// The type on the right side is accidentally left off
float4 x = (0,0,0,1); 

Operator koma mengevaluasi ekspresi dari kiri ke kanan. Ini mengurangi sisi kanan untuk:

float4 x = 1; 

HLSL menggunakan promosi skalar dalam hal ini, sehingga hasilnya seolah-olah ini ditulis sebagai berikut:

float4 x = float4(1,1,1,1);

Dalam hal ini, meninggalkan jenis float4 dari sisi kanan mungkin merupakan kesalahan yang tidak dapat dideteksi oleh pengkompilasi karena ini adalah pernyataan yang valid.

Operator perbandingan

Operator perbandingan adalah: <, , >==, !=, <=, >=.

Bandingkan nilai yang lebih besar dari (atau kurang dari) nilai skalar apa pun:

if( dot(lightDirection, normalVector) > 0 )
   // Do something; the face is lit
if( dot(lightDirection, normalVector) < 0 )
   // Do nothing; the face is backwards

Atau, bandingkan nilai yang sama dengan (atau tidak sama dengan) nilai skalar apa pun:

if(color.a == 0)
   // Skip processing because the face is invisible

if(color.a != 0)
   // Blend two colors together using the alpha value

Atau gabungkan dan bandingkan nilai yang lebih besar dari atau sama dengan (atau kurang dari atau sama dengan) nilai skalar apa pun:

if( position.z >= oldPosition.z )
   // Skip the new face because it is behind the existing face
if( currentValue <= someInitialCondition )
   // Reset the current value to its initial condition

Masing-masing perbandingan ini dapat dilakukan dengan jenis data skalar apa pun.

Untuk menggunakan operator perbandingan dengan jenis vektor dan matriks, gunakan semua atau fungsi intrinsik apa pun.

Operasi ini gagal karena pernyataan if memerlukan satu bool tetapi menerima bool4:

if (A4 < B4)

Operasi ini berhasil:

if ( any(A4 < B4) )
if ( all(A4 < B4) )

Operator Awalan atau Postfix

Operator awalan dan pascafiks adalah: ++, --. Operator awalan mengubah konten variabel sebelum ekspresi dievaluasi. Operator postfix mengubah konten variabel setelah ekspresi dievaluasi.

Dalam hal ini, perulangan menggunakan konten i untuk melacak jumlah perulangan.

float4 arrayOfFloats[4] = { 1.0f, 2.0f, 3.0f, 4.4f };

for (int i = 0; i<4; )
{
    arrayOfFloats[i++] *= 2; 
}

Karena operator peningkatan postfix (++) digunakan, arrayOfFloats[i] dikalikan dengan 2 sebelum i bertambah. Ini bisa sedikit disusun ulang untuk menggunakan operator kenaikan awalan. Yang satu ini lebih sulit dibaca, meskipun kedua contoh setara.

float4 arrayOfFloats[4] = { 1.0f, 2.0f, 3.0f, 4.4f };

for (int i = 0; i<4; )
{
    arrayOfFloats[++i - 1] *= 2; 
}

Karena operator awalan (++) digunakan, arrayOfFloats[i+1 - 1] dikalikan dengan 2 setelah i bertambah bertahap.

Pengurangan awalan dan operator penurunan pascafiks (--) diterapkan dalam urutan yang sama dengan operator kenaikan. Perbedaannya adalah bahwa penurunan mengurangi 1 alih-alih menambahkan 1.

Operator Struktur

Operator pemilihan anggota struktur (.) adalah titik. Mengingat struktur ini:

struct position
{
float4 x;
float4 y;
float4 z;
};

Ini dapat dibaca seperti ini:

struct position pos = { 1,2,3 };

float 1D_Float = pos.x
1D_Float = pos.y

Setiap anggota dapat dibaca atau ditulis dengan operator struktur:

struct position pos = { 1,2,3 };
pos.x = 2.0f;
pos.z = 1.0f;       // z = 1.0f
pos.z = pos.x      // z = 2.0f

Operator Tunggal

Operator unary adalah: , -, +

Operator unary beroperasi pada satu operand.

bool b = false;
bool b2 = !b;      // b2 = true
int i = 2;
int i2 = -i;       // i2 = -2
int j = +i2;       // j = +2

Operator Precedence

Saat ekspresi berisi lebih dari satu operator, prioritas operator menentukan urutan evaluasi. Prioritas operator untuk HLSL mengikuti prioritas yang sama dengan C.

Keterangan

Kurung kurawal ({,}) memulai dan mengakhiri blok pernyataan. Saat blok pernyataan menggunakan satu pernyataan, kurung kurawal bersifat opsional.

Pernyataan (DirectX HLSL)