2 puan yazan GN⁺ 2023-10-27 | 1 yorum | WhatsApp'ta paylaş
  • Ana sayfadaki basit CSS border-radius animasyonunu çıkış noktası alarak, birkaç satırlık fragment shader ile akıcı bir blob animasyonunu doğrudan uyguluyor
  • Shader, GPU’da piksel koordinatlarını renge dönüştüren küçük bir programdır; paralel yürütme sayesinde hızlıdır, ancak durum paylaşımı ve üst düzey soyutlamalar konusunda büyük kısıtları vardır
  • GLSL’in temel örneği, vUv koordinatlarını gl_FragColor’ın RGBA değerlerine eşler; varying, uniform, vektör tipleri ve swizzling gibi söz dizimini öğrenme akışı sunar
  • Daire ve blob’lar distance(), step(), smoothstep() ve Signed Distance Function (SDF) ile oluşturulur; birden fazla SDF min() veya smooth minimum ile birleştirilir
  • u_time ile topların hareketi oluşturulup u_mouse merkez dizisine eklendiğinde, kullanıcıların fareyle bir kısmını kontrol edebildiği etkileşimli shader’a dönüşür

Shader’ların yaptığı iş ve kısıtları

  • Shader, GPU’da çalışan küçük bir programdır ve en temel hâliyle piksel koordinatını girdi olarak alıp renk üretir
  • Video oyunlarında ışıklandırma, özel efektler, çizgi film tarzı render gibi görsel efektler için kullanılır ve modern oyun grafiklerinin önemli temellerinden biridir
  • Hızın anahtarı, birçok piksel üzerinde aynı anda çalışan paralelleştirmedir
  • Bu giriş, tarayıcı dostu OpenGL Shading Language’a, yani GLSL’e odaklanır
  • Performansın bedeli olarak shader’ların küçük ve düşük seviyeli yazılması gerekir
    • Üst düzey soyutlamalara veya kütüphane içe aktarmaya yaslanmak zordur
    • Paralel yürütmenin doğası nedeniyle pikseller arasında veri saklama veya paylaşma mümkün olmayan durumsuz ve belleksiz bir modeldir

Koordinatı renge dönüştüren ilk GLSL örneği

  • Shader, normalize edilmiş koordinatları RGBA renge dönüştürür
    • Koordinatlar genellikle 0 ile 1 arasında normalize edilir
    • (0, 0) sol altı, (1, 1) sağ üstü ifade eder
    • Bu koordinatlar geleneksel olarak st veya uv diye adlandırılır
  • En basit örnek, x koordinatı büyüdükçe kırmızının, y koordinatı büyüdükçe yeşilin arttığı bir gradyandır
varying vec2 vUv;

void main() {
  vec2 st = vUv;
  gl_FragColor = vec4(st.x, st.y, 0.0, 1.0);
}
  • Mavi gradyan, gl_FragColor = vec4(0.0, 0.0, st.x, 1.0); gibi mavi kanala x koordinatı verilerek oluşturulur
  • Söz dizimindeki önemli unsurlar şunlardır
    • varying: değeri pikselden piksele değişen girdi
    • uniform: tüm piksellerde aynı olan girdi
    • vec2, vec3, vec4, mat2, mat3: C’de olduğu gibi tipi açıkça belirtilen vektör ve matris tipleri
    • swizzling: vec4(1, 2, 3, 4).xy gibi bir vektörün bir kısmını alma gösterimi
    • gl_FragColor: main() sonunda her pikselin rengini belirleyen çıktı

distance(), step(), smoothstep() ile daire oluşturma

  • Daire gibi keskin şekiller çizerken de drawCircle() benzeri bir fonksiyon değil, matematiksel mesafe kullanılır
  • Geçerli piksel ile dairenin merkezi arasındaki mesafe distance(vec2 p1, vec2 p2) ile hesaplanabilir
  • Mesafeyi doğrudan renge eşlerseniz dairesel bir gradyan elde edilir; dolu daire ise step(float threshold, float value) ile yapılır
    • Mesafe eşik değeri aşarsa 1
    • Aksi hâlde 0
  • step() geçişi keskin yaptığı için daire kenarında aliasing oluşabilir
  • Daha yumuşak kenarlar smoothstep(float t_start, float t_end, float x) ile oluşturulabilir

Signed Distance Function ile şekil ifade etme

  • Signed Distance Function (SDF), uzaydaki bir noktanın bir şekilden ne kadar uzakta olduğunu işaretli mesafe olarak ifade eder
    • Şeklin içi negatif
    • Dışı pozitif
    • Sınırı 0’dır
  • Dairenin SDF’si, merkeze göre mesafeden yarıçap çıkarılarak oluşturulabilir
float circleSDF(vec2 p, float r) {
    return length(p) - r;
}
  • Piksel konumu uv temel alınarak nokta kaydırıldığında, UV uzayındaki herhangi bir konumda bulunan daireye olan mesafe hesaplanabilir
  • d < 0.0 ise piksel dairenin içindedir; bu yüzden farklı bir renkle boyanabilir
  • Daha çeşitli 2D SDF şekilleri Inigo Quilez’in kapsamlı listesinde görülebilir

Birden çok SDF’yi birleştirerek blob oluşturma

  • SDF’lerle Boole işlemleri kullanarak yeni şekiller oluşturmak kolaydır
  • İki SDF’nin birleşimi, iki mesafenin min() değerini almakla elde edilir
    • İki şekilden herhangi birinin içindeyse minimum mesafe negatif olur
    • İkisi de dışındaysa minimum mesafe pozitif olur
  • 1. - smoothstep() kullanılmasının nedeni, step() ve smoothstep()’in eşik değerinden büyük mesafelerde, yani şeklin dışında 1 üretmesidir
  • Basit min(), iki dairenin birleştiği noktada keskin bir süreksizlik oluşturur
  • Blob gibi yumuşak biçimde karışmasını istiyorsanız smooth minimum kullanılır
    • Ek argüman k, yumuşaklığın şiddetini kontrol eder
    • Örnek, polynomial smooth min fonksiyonunu kullanır
float smin(float a, float b, float k)
{
    float h = max( k-abs(a-b), 0.0 )/k;
    return min( a, b ) - h*h*k*(1.0/4.0);
}

Zaman uniform’u ile metaball animasyonu oluşturma

  • Shader’a, slider gibi isteğe bağlı değerler uniform olarak aktarılabilir
  • Animasyon, JavaScript’te oluşturulan u_time değerinin shader girdisi olarak verilmesi ve bunun daire merkez koordinatlarının hesaplanmasında kullanılmasıyla yapılır
  • Shader temelde saniyede 60 kez yeni u_time değeriyle güncellenerek akıcı bir hareket üretir
  • Daire merkezleri sin, cos gibi periyodik fonksiyonlarla salındırılabilir
  • Birden çok daireyi metaball olarak birleştirirken merkez koordinatları bir dizide tutulur ve SDF döngüyle biriktirilir
vec2 centers[4] = vec2[4](c1,c2,c3,c4);

float d = 99.;

for (int i = 0; i < 4; i++) {
  vec2 c = centers[i];
  float sdf = circleSDF(uv, c, .1*u_slider);
  d = smin(d, sdf, K);
}
  • Ortaya çıkan blob işlevsel olarak çalışır, ancak tek renklidir; bu yüzden sonrasında renk ve etkileşim eklenir

Fareyle kontrol edilen son etkileşim

  • Son adım, fare koordinatlarını u_mouse uniform’u olarak alıp blob içindeki toplardan birini kullanıcının doğrudan kontrol etmesini sağlamaktır
uniform vec2 u_mouse;
  • Fare koordinatlarını top merkezleri dizisine eklemek, etkileşimi tek satırda devreye alır
vec2 centers[5] = vec2[5](c1,c2,c3,c4,u_mouse);
  • Nihai shader, farenin y eksenini canvas koordinatlarına uyacak şekilde ters çevirir ve hareket eden 4 merkezi fare merkeziyle birlikte birleştirir
  • Renkler mix(colorA, colorB, percent) birkaç kez kullanılarak harmanlanır
    • percent boolean gibi kullanıldığında if/else’e benzer çalışır
    • metaball değeri, merkez noktası mesafesi, shine ve membrane hesaplaması nihai renge yansıtılır
  • Aynı ilkeleri anladığınızda Blender’s shader nodes veya Unity’s Shader Graph gibi düğüm tabanlı shader editörlerinin içeride nasıl çalıştığını da daha iyi anlayabilirsiniz

Bakılabilecek diğer kaynaklar

1 yorum

 
GN⁺ 2023-10-27
Hacker News yorumları
  • Sonunda internette yazı yazıp kendimi ortaya koyacak cesareti topladım. Eskiden beri shader öğrenmek istiyordum ve öğrenme sürecimi belgeleyip başkalarıyla paylaşmanın iyi olacağını düşündüm

    • Kişisel blogunda yazıp bunu interaktif bir yazı haline getirmen gerçekten hoşuma gitti. Berbat Notion/Medium/Dev akışlarıyla Google algoritmasını ya da yapay zeka kopyala-yapıştırını beslemekten farklı.
      Samimi blog yazarlığı, her şeye gücü yeten algoritmanın gölgesinde görünmez şekilde ölüyor; internet de Star Wars Bölüm IV'ün tam ortasına gelmiş gibi hissettiriyor. Tek geri bildirimim var: teşekkürler, umarım daha çok yazarsın
    • İnternete hoş geldin, superMayo!
      Ustaların shader'larla neler yapabildiğini görmek istersen Inigo Quilez'i ve shader sanatını önermek isterim: https://www.youtube.com/watch?v=BFld4EBO2RE
      Ek: Yazarı olduğunu fark etmemişim. Yazı çok iyi olmuş; shader kodlama sanatını daha erişilebilir ve interaktif biçimde ele alan eğitimler arıyordum
    • İyi desteklenen OES_standard_derivatives uzantısını ya da WebGL 2'yi kullanmaya açıksan kenar yumuşatmayı iyileştirebilirsin. smoothstep(0.0f, 0.01f, dist); gibi sabitleri kabaca seçmek yerine smoothstep(fwidth(dist), -fwidth(dist), dist); kullanman yeterli
    • Shader'ların tamamen grafiksel şeyler olduğu düşünülürse, bu yazı shader'lara giriş için neredeyse en iyi yöntem gibi hissettiriyor. İnteraktif kodun alıştırma bağlantılarına atmak yerine yazının içine doğrudan gömülü olması çok iyi oturmuş
  • Yazı oldukça iyi, ama shader'ların temel sorununu fazla hafife alıyor.
    Shader'lar çoğu programın ve uygulamanın istemediği bir baş belası. 3D üçgenleri sever, GPU da bu soyutlamaya iyi uyar; shader'lar da bu üçgenlerin üzerinde enterpolasyon yapmakta faydalıdır.
    Ama 3D olmayan neredeyse her yerde üçgenler pek iyi değildir. 2D render işlemleri path ister, font render işlemleri path ya da pixmap ister, GUI'ler için path ve pixmap çok daha uygundur, compositor pixmap ister, video decoder ise pixmap ve paralel render ister.
    3D dışı tarafın istediği şey dikdörtgen pixmap'ler ve bu pixmap'lere doğrudan hesaplama erişimidir; GPU bunu pek sevmez, shader'lar da buraya pek iyi oturmaz

    • 2D eğri renderer yazmış biri olarak paralel hesaplamaya ve yüksek bant genişliğine ihtiyacım vardı; GPU da bunu sağlıyor. Özellikle scatter-write destekleyen yeni arayüzlerde daha da böyle, ama tarayıcılarda ne kadar yaygınlaştığını bilmiyorum.
      Üst düzeyde istenen biçim olmadığı doğru, ama daha yüksek seviyeli soyutlamaları uygulamak için temel olarak yeterince iyi. Donanımda doğrudan desteklenebilir belki, ama avantajı bariz değil. Kimse CPU'nun for döngüsünü mimari düzeyde desteklemediğinden şikayet etmiyor.
      Tekrar okuyunca GPU ile ilgili sorunun ne olduğunu tam anlayamadım. Vertex işleme hattını tamamen yok sayıp tek bir tam ekran dikdörtgen çizebilir ya da compute shader kullanabilirsin; GPU bunu gayet iyi işler. Bağlantı verilen yazı da bu tür şeylerden bahsediyor
    • Karşı taraftan bakarsak, çoğu program istenen sonucu elde etmek için GPU'ya mutlaka ihtiyaç duymaz. Buna karşılık 3D'de çok küçük ölçeklerin ötesine geçildiğinde bu tür paralellik neredeyse zorunludur.
      En azından 2000'lerde düşünce biçimi buydu. Yazılım daha karmaşık hale geldikçe GPU istenen optimizasyon olabilir, ama GPU pipeline'ı her zaman katı ve kapalıydı; tek çekirdekten çok çekirdekli programlamaya geçişteki paradigma da çoğu zaman farklı algoritmalar gerektirir.
      Genel amaçlı GPU programlama üçgenlere bağlı kalmaktan kurtarır, ama o paralellikten yararlanmak için hâlâ tamamen farklı bir yaklaşım gerekir
    • Pixel/fragment shader'ın hangi kısmının pixmap'e iyi eşlenmediğini anlamadım
  • Harika! Son zamanlarda SDF tavşan deliğine biraz dalmıştım. iq sitesinin linkini koymana sevindim; oradaki materyaller gerçekten çok iyi.
    Onun “happy bouncing” shader'ına link vermeden edemem. Bence olağanüstü: https://www.shadertoy.com/view/3lsSzf
    Yapım sürecini gösteren 6 saatlik bir YouTube videosu da var. Yaklaşık 500 satırlık dopdolu bir kod

    • Inigo Quilez bir sihirbaz ve shader topluluğunun ona gerçekten çok borcu var
  • Bu konuya ilgi duymayı birkaç kez denedim ama erişilebilir bir giriş noktası bulamamıştım; bu tanıtım yazısında buldum. Gerçekten eğlenceli ve oyunbaz bir yaklaşım, hoşuma gitti; sonraki yazıyı da bir an önce okumak istiyorum

  • Küçük bir kusur arama olacak ama cel shading'den bahsederken cell yazmışsın. Bu terim, elle çizilmiş animasyonda kullanılan cel'den ve bu gölgelendirmenin kuantize edilmiş tonlarından geliyor

  • Gerçekten iyi. Sanatçılıktan programcılığa geçmiş biri olarak bazen grafik programlamayı kurcalama isteği duyuyorum.
    Birkaç çok temel shader yazdım, ama matematik işin içine girmeye başlayınca — aslında epey erken bir noktadan itibaren — duvara tosluyorum. Bilgisayar bilimi değil güzel sanatlar okuduğum için matematik becerim fiilen yok denecek kadar az.
    Her neyse, iyi yazılmış ve yazıyı sevdim

  • Harika bir giriş yazısı; umarım devamı gelir. Böyle yazılar çok sık güzel bir girişle başlayıp sonra yarıda kalıyor

  • Shader’larla hiç uğraşmadığım için çok temel bir soru olabilir. Bir oyunun tek bir karesinde, özünde her şeyi shader mı çiziyor?
    Yoksa üçgen, dörtgen, daire gibi temel şekiller var da shader bunların üzerine gölge ya da kenar düzeltme gibi şeyler mi ekliyor?
    Örneklere bakınca sahnedeki herhangi bir nesneyi çizen bir shader yazılabiliyor, sonra başka shader’lar birleştirilerek gölge ve aydınlatma gibi şeyler elde ediliyor gibi görünüyor. Benim çok sınırlı çizim deneyimimde şekiller çiziyordum, shader ile çizmiyordum. Shader’ın nesnenin kendisini çizmediğini düşünmüştüm

    • Aşağıdaki, klasik forward rendering sürecinin basitleştirilmiş bir açıklaması; deferred rendering denen yöntem biraz farklıdır
      GPU, üç tepe noktası ve her tepe noktasına bağlı normal gibi verilerle tanımlanan üçgen benzeri soyut vektör şekilleri, çıktı tamponunda o şeklin kapladığı her piksel için bir tane, multisampling varsa daha da fazla olacak şekilde bir fragment akışına dönüştürür. Bu kısmın tamamını donanım yapar
      Fragment, piksel koordinatları ve kullanıcı tarafından sağlanan verilerden oluşur. Bu veri sabit olan uniform ya da az önce bahsedilen tepe noktası verisinin üçgen yüzeyi boyunca enterpole edilmiş hâli olan varying olabilir. Bu enterpolasyonu da donanım yapar ve programlanamaz
      Fragment shader, fragment’ı girdi olarak alır, o verilere göre rengi hesaplar ve birkaç aşamadan sonra ekrandaki ya da offscreen buffer’daki ilgili piksel rengi olarak çıktı verir. Bu tek renk de olabilir, karmaşık bir aydınlatma hesabı da olabilir
      GPU rendering’de tüm bunlar büyük ölçekte paralel gerçekleşir; çok sayıda fragment aynı anda işlenir. Shader saf ve durumsuz bir fonksiyondur; yalnızca girdilerine erişebilir ve yapabildiği etki de renk ve derinlik değeri gibi birkaç şeyi döndürmekten ibarettir
      Özetle GPU donanımı, her üçgeni çizmek için hangi piksellerin doldurulması gerektiğini hesaplar; fragment shader ise bu piksellerin her birinin renk değerini belirler
    • Shader’lar tüm çizimi yapar, ama bu iş birkaç aşamaya ayrılmıştır. Tüm graphics pipeline’ı[1] açıklamayacağım; insanların aydınlatma efektleri için kabaca “shader” dediği şeyin büyük kısmı, %90’dan fazlası, renderer’ın fragment/pixel shader aşamasıdır
      Fragment shader sahnenin “üzerine” çizmeden önce vertex, tessellation gibi başka aşamalar temel şekilleri çizer
      Fragment shader konusunda da anlatılandan çok daha fazlası var. Örneğin deferred rendering[2] buna girer ve o da kendi başına büyük bir konudur
      1: https://vulkan-tutorial.com/Drawing_a_triangle/Graphics_pipe...
      2: https://learnopengl.com/Advanced-Lighting/Deferred-Shading
    • Doğru, her pikselin rengine nihayetinde bir shader programı karar verir; ama tahmin edeceğiniz gibi bundan daha karmaşıktır
      Sabit işlevli donanım aşamaları ile programlanabilir aşamaların karıştığı bir graphics pipeline vardır. Üst düzeyde bakarsak: 1) GPU, CPU’dan bir 3B üçgen kümesi alır, 2) vertex shader 3B üçgen tepe noktalarını piksel koordinatlarına sahip 2B üçgen tepe noktalarına dönüştürüp düzleştirir, 3) GPU 2B üçgeni rasterize ederek tam olarak hangi piksellerin üçgen tarafından kaplandığını belirler, 4) kaplanan her piksel için pixel shader çalıştırılır ve piksel rengini belirler, 5) ortaya çıkan piksel rengi framebuffer’a kaydedilir. Bu sırada mevcut renkle blend edilebilir
      Bu pipeline, tüm frame çizilene kadar farklı üçgen mesh’leri ve shader’larla birçok kez tekrarlanır
    • Genel olarak doğru anlamışsınız. Bildiğim kadarıyla GPU’da çalışan her tür koda shader deniyor. Örneğin özel veri işlemlerine de compute shader denir, ama doğası farklıdır
      Renk, gölge, shading, görüntü efektleri, genel görüntü işleme gibi işler, birden fazla veri dizisini birleştiren paralel hesaplamalarla yapılır. Tepe noktaları ve öznitelikleri, kaynak texture’lar, önceden hesaplanmış fonksiyonlar, hedef texture’lar, buffer’lar vb. buna dahildir
      Örneğin ışık ve gölge elde etmek için shader’ın spotlight’ın konumu ve yönü gibi, muhtemelen global değişkenlere erişebilmesi gerekir. Kompozit aydınlatma çoğu zaman birden fazla shader pass’inin birleştirilmesiyle elde edilir. Global aydınlatma için bir temel pass ve her ışık için bir pass gibi yapılandırılır; her pass kelimenin tam anlamıyla ışık ekler
      Şimdi, ışık kaynağının engellendiği piksellere, yani gölgelere ışık eklememek için en yaygın teknik Z-buffer denen şeyi kullanmaktır. Aslında bu bir floating-point texture’dır. Sahnedeki her ışığın nereye kadar ulaştığını bilmek istediğimiz için, tüm aydınlatmayı uygulamadan önce sahnedeki tüm katı geometriyi birleştiren tek bir shader pass ayarlarız; ışığın konumunu ve yönünü kamera dönüşümü gibi kullanır ve yalnızca nesneye olan mesafeyi Z-buffer’a yazan özel bir shader kullanırız
      Daha sonra uzaydaki bir noktaya ışığın ulaşıp ulaşmadığını bilmek istediğimiz her seferinde, biraz geometri hesabından sonra bu Z-buffer’ı sample eder ve o yönde kaydedilmiş değerle söz konusu noktanın mesafesini karşılaştırırız. Bu bol hatalı olabilir ve hassasiyet hataları da yaygındır. İyi bir engine bunu zaten sizin için yapar, ama süreci değiştirmenize de izin verir
      Geri kalan her şey bu konunun varyasyonlarıdır. Deferred rendering, rengi değil veriyi ara texture’lara render edip daha sonra işleyerek rengi elde etme yöntemidir. Blur efekti, render texture üzerinde 2B konvolüsyonla, örneğin Gaussian kernel ile yapılır. Tessellation shader, vertex shader’da yeni geometri üretmekle ilgilidir. Metin çizimi bile font atlası ve küçük dikdörtgenler üzerinden yapılır
    • Fragment, yani pixel shader ile herhangi bir nesneyi çizebilirsiniz. Çünkü teknikten bağımsız olarak şekil çizmeye yarayan belirli matematiksel yöntemler, örneğin SDF ya da trigonometri kullanılabilir
      Bu yüzden yetenekli sanatçılar fragment shader içinde sınırları zorlar ve performans ödünleriyle mücadele eder
      Fragment shader daha yaygın olarak tam ekran filtre efektlerinde, örneğin renk düzeltmede kullanılır
      Shader’lar temel nesnelerin texture ve material’larını oluşturmak için de kullanılır. Material artist’ler çoğu zaman shader matematiğiyle texture üretir
      Pek çok görsel efekt, shader’ların yaratıcı kullanımıyla yapılır
      Shader’lar GPU’da paralel, dalga benzeri bir biçimde çalıştırılır. Çok sayıda thread aynı wave içinde aynı veri üzerinde çalışır
      Bazı durumlarda shader, CPU’daki dallanmalı koddan çok daha hızlıdır. Shader’lar bazı rendering verilerine de daha kolay erişebilir

Bu yüzden yaratıcı özel efektler oluşturmak için iyi bir alan. Oyunlarda yüzey ayrıntısı yüksek nesneler, bu ayrıntıyı shader’a taşımak için yaygın hedeflerdir. Deniz yüzeyi, tessellation mesh’leri vb. buna örnektir; GPU güçlü ve esnek olduğu için başka pek çok kullanım alanı da vardır.

  • Görüntü titreşen bir gürültü gibi görünüyorsa, tarayıcıda görüntüyü kopyalayıp başka bir yere yapıştırarak çözdüm. Böylece görüntü düzgün görülebiliyor.
    Bu bir Imgur bağlantısı. İlk görüntü tarayıcıda görünen ekranın ekran görüntüsü; diğerleri ise Imgur'a yapıştırıldıktan sonraki gerçek görüntüler.
    https://imgur.com/a/F4203rz

    • Tuhaf. Hangi tarayıcıyı kullanıyorsun?
  • Shader'ları ben şöyle anlıyorum.
    CPU'da bir çizgi çizerken, A noktası ile B noktası arasındaki her pikselin üzerinden geçip pikselleri tek tek sırayla çizen bir fonksiyon çalışır. Çizgideki piksel sayısı kadar tam olarak adım vardır ve bir kez çalıştırılır.
    GPU'da bir çizgi çizerken ise, ilgili pikselin çizginin üzerinde olup olmadığını kontrol eden ve öyleyse çizen bir fonksiyon çalışır. Çizgiden epey uzaktaki pikseller de dahil olmak üzere ekrandaki tüm piksellerde aynı anda çalıştırılır.
    Bu doğru mu?

    • Tam olarak değil. Birincisi, GPU piksel shader'ını tüm pikseller için aynı anda çalıştıramaz. Tipik bir ekranda yaklaşık 2 milyon piksel vardır; GPU'nun eşzamanlı yürütme thread sayısı ise en fazla birkaç bindir, dolayısıyla pratikte birkaç bin piksellik bloklar halinde çizer.
      İkincisi, GPU'nun tüm ekran için piksel shader'ını çalıştırması da gerekmez. Üçgenler kullanarak shader'ı yalnızca istediğiniz herhangi bir şekil için çalıştırabilirsiniz. Bu yüzden bir çizgiyi verimli çizmenin yolu, istediğiniz çizgi geometrisine karşılık gelen iki üçgeni GPU'ya göndermek ve piksel shader'ını yalnızca bu üçgenlerin üst üste geldiği pikseller için çalıştırmaktır. Bu çok daha verimlidir.