İçeriğe geç

Kategori: Uncategorized

WEBGL nedir? -5 Ekrana üçgen, dörtgen çizdirme

Bu yazıda artık ilk 4 yazıda öğrenmemiz gereken şeyleri öğrendikten sonra birşeyler çizmeye başlayabiliriz. webgl ile ekrana bir kırmızı üçgen ve dörtgen çizimi şlemi yapacağız. Kaynak kodlara buradan ulaşabilirsiniz.

Kaynak kodu verdikten sonra biraz kodumuzu incelemeye geçelim.

gereksinimler

ilk olarak shader sınıfı ve matematik kütüphanesini import ediyorum. Webgl için gerekli matrix ve matematiksel işlemler için gl-matrix kütüphanesini kullandım. İsterseniz kaynak kodunu inceleyebilirsiniz. Uzun uzun matematik kodlarına girmeyeceğim.

import { CreateShaderProgram } from “../Shader/shader.js”
import { mat4, mat3, glMatrix} from “../lib/Math/gl-matrix.js”

gl parametrelerinin ayarlanması

Canvas ve shader programını oluşturduktan sonra gl objemi alıyorum. Daha sonra bazı gl kodları ile başlıyorum:

this.gl.viewport(0,0,this.canvas.width, this.canvas.height) // görüntü alanı 
                    //olarak kanvasın bütününü kullanacamızı belirtiyoruz
this.gl.enable(this.gl.DEPTH_TEST) // eğer derinlik oalrak üst üste gelen
                                   // bir pixel değeri varsa fragment shaderde 
                                   //işleneceğini ayarlıyor.
this.gl.clearColor(0.4689,0.5006,1,1) // arka fona verdiğim renk
this.gl.clear(this.gl.COLOR_BUFFER_BIT) // ayarlanan renk ile ekranı siler
this.gl.useProgram(this.shaderProgram) // shader kullnaımını set ediyorum.

Shader adresleri

Bu ksımdan sonra önceki shader yazılarından anlayacağımız üzere shaderden model matrix, position ve renk değişken adreslerini alıyorum:

this.vertexPos= this.gl.getAttribLocation(this.shaderProgram,"aVertexPosition")
this.ModelLoc = this.gl.getUniformLocation(this.shaderProgram,"uModelViewMatrix")
this.colorPos= this.gl.getUniformLocation(this.shaderProgram,"vColor")

Gene önceki yazılardan tanıdığımız bir kod vertexPos attribute adresini aktif ediyorum

this.gl.enableVertexAttribArray(this.vertexPos)

Model matrisi ve çizim

Sonraki adımda model düzlemimi belirleyen matrisi ayarlıyorum. Ben ortogonal yani dikey düzlem kullanacağım. dikey düzlemde perspektif olmaz. Dümdüz görürsünüz.
this.ModelMatrix = new Float32Array(16)
mat4.ortho(this.ModelMatrix,-2,2,-2,2,-2,2) // ilk iki sayı genişlik, sonraki yükseklik ve ensondaki derinliği ifade eder.
console.log(this.ModelMatrix);

Daha sonra çizim işlemi için vertex verileri ve bufferları dolduruyorum ve çizim yapıyorum.

var vertex =[
-0.5,-0.5,0,
-0.5, 0.5,0,
0.5,-0.5,0,
]

var vertexBuffer=this.FillBuffer(vertex)

this.gl.uniformMatrix4fv(this.ModelLoc, false, this.ModelMatrix)
this.gl.uniform4fv(this.colorPos, [1,0,0,1])

this.gl.bindBuffer(this.gl.ARRAY_BUFFER,vertexBuffer)
this.gl.vertexAttribPointer(this.vertexPos, 3, this.gl.FLOAT, false, 0 ,0)
this.gl.drawArrays(this.gl.TRIANGLES,0,3)

Ve sonuç biçok yazıdan sonraki sonuç:

webgl

WEBGL nedir? -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.

WEbGL nedir? -3 GLSL değişkenler ve yazım kuralları nedir?

Önceki yazımda webgl e hızlı bir giriş yaptım ve bu yazımda GLSL değişkenler ve yazımı üzerinde duracağım.Bu değişkenler ve kurallar önemli çünkü bunları bilirsek daha karmaşık shaderler üretebiliriz. Shaderimizin içinde sadece main fonksiyonu olmak zoruna değil yeni fonksiyonlar ekleyip bunları çağırabiliriz.

Veri tipleri:

Standart bildiğimiz int, float, bool, void tiplerinin yanında grafik kartına özel başka değişkenler var bunlar:
mat2(2×2) mat3(3×3) mat4(4×4) matris(iki boyutlu dizi) oluşturmak için kullanılıyor.
vec2, vec3, vec4 float point vektör(tek boyutlu dizi) oluşturmak için kullanılıyor.
bvec2, bvec3, bvec4 boolean değerleri tutan vektörler oluşturmak içni kullanılıyor.
ivec2, ivec3, ivec4 işaretli int değerler tutan vektörler oluşturmak için kullanılıyor.
sampler2D texture(doku) a ulaşmak için kullanılan değer.
samplerCube texture ile alakalı bir değer bunu kullanmadım.

3 adet niteleyicimiz var bunlar:

Attribure:

Shaderin her çalışmasında her vertex için kullanılan değişkendir, değeri her draw işleminde değişir.Yani hesaplamalrda tekrar tekrar kullandığımız değişkenlerdir. Örneğin önceki yazıdaki :

ttribute vec3 aVertexPosition;
attribute vec4 aVertexColor;

değişkenleri gibi. Bu değişkenler her vertex için kullanılır ve her seferinde değer o vertex için hesaplanır.

Uniform:

Bu değişkenler sabit değere sahiptir shader içinde sadece okuma özelliği olan değişkenlerdir dışarıdan bizim müdahalemiz ile değişebilir ancak shader programı bu değeri değiştiremez. Bir kere atadığımızda hep o değer geçerli olur. Örneğin önceki yazıdaki fragment shader deki

uniform lowp vec4 vColor; //lowp ve vec4 aşağıda açıklanacak

değişkeni gibi. Bu değişkene değer atarken şu şekilde atadığımızda hep o değişken sabit kalır

gl.uniform4fv([0,0,255,1]) // daha sonra açıklayacağım

Varying:

Vertex shader ve Fragment shader arasındaki bağlantılı olan değişkenleri ifade eder. Örneğin vertex shader deki bir değişkeni fragment shader de kullanmak istediğimizde o değişkeni varying olarak belirtmemiz gerekir. Örneğin

//vertex shader da
uniform vec4 baskaDeger;
varying vec4 vector;
void main(void){
vector = baskaDeger;
}

//fragment shader da
varying vec4 vector;
void main(void){
//baskaDeger değişkenini değeri burada vector değişkeninden kullanılabilir.
}

Sayı limitleri:

Shader lerde kullandığımız sayı değerlerine bellirli limitler ekleyerek istediğimiz aralıkta sayılar üretilmesini sağlayabiliriz. Tabi bu aralığı vermezsek default aralıkta program gene çalışır.Ancak ayar yapma gereği duyduğumuzda bunları kullanabiliriz.

Bu aralıklar highp, mediump ve lowp olarak adlandırılıyor. Aşağıdaki grafikte aralıkları görebilirsiniz.

GLSL sayı limtleri

WEBGL nedir? -2 Shader Language

Shader language yada OpenGL SL(Shader Language) yada GLSL, opengl in yeni sürümlerinde kullanılan grafik kartı üzerinde küçük programcıklar çalıştırmaya yarayan C diline benzer yazım kuralları olan bir dildir. WEBgl GLSL kullanır. GLSL ile artık grafik kartında işlenecek koda daha fazla müdehale edebiliyoruz ve işlem yoğunluğu gerektiren kısımları grafik kartına yıkarak daha hızlı bir şekilde yapabiliyoruz.

Ben WEBgl yazı dizisi oluşturduğum için WEBgl ile kullanım biçimine göre anlatımımı yapacağım.

Vertex Shader:

Grafik kartına her vertex i nasıl işleyeceği ve bu vertexler için gerekli matematiksel işlemleri(matris çarpımı) nasıl yapacağını belirttiğimiz yer. Temel olarak projeksiyon matris, model matris ve vertex vektörünü çarparak bir uzay elde edildiği kısım.

Fragment Shader:

Fragment Shader ise her pixel için herekli renk veya texture işlemlerinin belirtildiği yer.

Aşağıdaki resimde nasıl olduğuna dair bir resim paylaşıyorum:

fragment shader,vertex shader
fragment shader,vertex shader

Aşağıdaki örnekte ES6 ile yazığım bir classta shaderleri nasıl oluşturduğum yer alıyor, bunları örnek olarak koyuyorum ileriki yazılarda Vertex Shader ve Fragment Shader e daha detaylıca değineceğim.:


class CreateShaderProgram {
  constructor() {

  }
  CreateShader(gl){

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

      uniform mat4 uModelViewMatrix;
      uniform mat4 uProjectionMatrix;

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

    const vertShader = gl.createShader(gl.VERTEX_SHADER)

    gl.shaderSource(vertShader,vsSource)

    gl.compileShader(vertShader)


    const fsSource = `
      uniform lowp vec4 vColor;

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

    const fragShader = gl.createShader(gl.FRAGMENT_SHADER)

    gl.shaderSource(fragShader,fsSource)

    gl.compileShader(fragShader)

    const shaderProgram = gl.createProgram()
    gl.attachShader(shaderProgram, vertShader)
    gl.attachShader(shaderProgram, fragShader)
    gl.linkProgram(shaderProgram)

    return shaderProgram
  }
}

export { CreateShaderProgram }

Webpack katili Parcel nedir ?

Neden parcel ?

 

Günümüzde web uygulamaları için geniş özelliklere sahip birçok demetleyici bulunmaktadır, bunların en çok kullanılanları webpack ve browserify da dahil.

Bir çok demetleyici konfigurasyon ve eklentiler ile kurulur ve sadece birşeylerin çalışması için 500 satırdan fazla satır sayısı olan konfigurasyon doslayarı genellikle var olan şeyler. Bu konfigurasyonlar sadece sıkıcı ve zaman harcayan şeyler değil ayrıca her uygulama için çoğaltmak ve doğru ayarı yapmak da zor. Sıklıkla ürün kısmına geçmede alt optimizasyonların gerektiği bir hal alabiliyor. Parcel sıfır configurasyon ayarı olacak şekilde tasarlanmıştır. SAdece giriş noktanızı belirtmeniz yeterli o geri kalanı doğru bir şekilde yapacaktır.

Var olan demetleyicilerin bir olumsuz yanı da çok yavaş olmalarıdır. Geliştirme sürecinde fazlaca değişiklierin yapılması çok fazla bağımlılığı ve fazla dosyaların olduğu büyük uygulamalarda demetleme sürecinin dakikalar alması acı verici bir durumdur. Parcel modern çok çekirdekli işlemcilerden yaralanarak kodunuzu paralel işlemlerle derler. Sonuç olarak ilk demetlemede büyük bir hız artışı olur. Ayrıca her dosya için dosya sistemi önbelleğine sahiptir, böylece ileriki başlangıçlarda da hızlıdır.

Sonuç olarak var olan demetleyiciler string yükleyiciler/dönüştürücüler üzerine kurulmuştur. Bir stringi alırlar parse ederler bazı dönüşümlerden eçirerek tekrar kod üretirler.Bu da bir dosya için fazla sayıdadönüşüm ve kod üretme anlamına gelir, pek etkili bir yol değildir bunu aksine Parcel her dosya için bir kere parse eder, birçok kez dönüşüm uygular ve birçok dönüşümden geçirerek bir defa kod üretir.

 

Yükelemek için :

yarn global add parcel-bundler

Başlangıç noktası göstermek için :

parcel index.html

Bu kadar artık geliştirme işlemine başlayabiliriz.

 

Ana sayfası: https://parceljs.org/

Github sayfası: https://github.com/parcel-bundler/parcel

Kullanımı video: