WEBGL yazı dizisi-4 Vertex Shader ve Fragment Shader açıklama

Bu yazıda shaderlerden bahsedip sonra shader programla olan ilişkisini açıklayacağım. Daha sonaki yazılarda webgl kısmı ile ekrana birşeyler çizdirmeye başlayacağım. Vertex shader ve Fragment shader webgl tarafında çizim için çok gerekliler bu yüzden bu kısımları iyi öğrenmemiz gerekiyor. Çok hızlı bir süreç değil fazla şey bilmek gerekiyor ama bildikten sonra yapması eğlenceli.

Vertex Shader:

Öncelikle shader language yazısında kullandığım vertex shader kodundan açıklamaya başlayalım.

const vsSource = `
attribute vec3 aVertexPosition;
attribute vec4 aVertexColor;

uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;

void main(void) {
gl_Position = uModelViewMatrix * vec4(aVertexPosition,1);
}
`;

yukarıdaki vertex shader kod parçacığında ilk olarak attribure değişkenleri olarak aVertexPosition, ve aVertexColor değişkenleri tanımlıyoruz bunlar attribute tipinde çünkü her vertexin kendine özel koordinat ve renk bilgisi var. Sonra sabit dışarıdan verdiğimiz uModelViewMatrix ve uProjectionMatrix 4×4 matrisleri var bunlarında tipi uniform yani dışarıdan biz tekar set etmediğimiz sürece aynı kalan değişkenler. Zaten bu değişken tiplerine önceki yazımda değinmiştim.

Peki yukarıdaki olay nedir? Model matris ile vertex vektörünü çarpıp cismin clip spacedeki yeni buluyoruz. yukarıdaki kodda uProjectionMatrix ile çarpmadım yani herhangi bir perspektife sahip değil. Eğer perspektif eklemek istiyorsak en başa uProjectionMatrix i çarpım olarak yazmamız gerekirdi.

Mesela yukarıdak kodda aVertexPosition vec3 tipinde yani 3 eksenli bir koordinat ama bu 2 eksenli de olabilirdi iki eksenli olsaydı yani vec2 aVertexPosition; o zaman çarpımda kullandığımız değer şu şekilde olacaktı *vec4(aVertexPosition,0,1)

 

Fragment shader :

Gene shader language yazımdaki fragment shader kodunu alacağım.

const fsSource = `
uniform lowp vec4 vColor;

void main(void) {
gl_FragColor = vColor;
}
`;

Burada ilk olarak dikkat ettiğimiz vColor değişkeninin lowp limitinde olması bunun nedeni renk değeri 0 ile 1 arasında oluyor. yani beyaz vec3(1,1,1) rengi opaklığı da eklersek vec4(1,1,1,1) şeklinde olur. Bu renklerde de çok çok büyük sayılar kullanmıyorsak en düşük limitler işimi çok rahatlıkla görecektir. Buradaki shader kodlar en sade haliyle mesela fragment shaderde şu an texture eklemedik. Çizdiğimiz şeye sadece renk veriyoruz.

 

Shader Program:

Shader kodları bu şekilde tanımlandıktan sonra gl ile vertex shader ve fragment shader nesneleri oluşturuluyor.

const vertShader = gl.createShader(gl.VERTEX_SHADER)
const fragShader = gl.createShader(gl.FRAGMENT_SHADER)

daha sonra bu shaderlere yukarıdaki kaynak kodlar gösterilip bu kodlar bu nesneler için derleniyor.

gl.shaderSource(vertShader,vsSource)
gl.compileShader(vertShader)

gl.shaderSource(fragShader,fsSource)
gl.compileShader(fragShader)

Bu adımdan sonra gl ile gpu da koşacak programımızı oluşturuyoruz.

const shaderProgram = gl.createProgram()

Ve oluşturulan bu programa shaderer tutuşturulup vertex shader ve fragment shader birbirine bağlanıyor.

gl.attachShader(shaderProgram, vertShader)
gl.attachShader(shaderProgram, fragShader)
gl.linkProgram(shaderProgram)

Yani shader programı yaratılırken hangi shaderleri derleyip hangisinin birbiriyle bağlanacağına biz karar veriyoruz. Program GPU da koşuyor ama yönetim bizde oluyor. Bir sonraki yazıda artık ekrana birşeyler çizdireceğim. Tabi bu aşamada da shader programına hangi değişkenlere hangi değerlerin gideceği konusunda bizim yardım etmemiz gerekiyor bu adımları da görmüş olacağız.