holodepth

Shader & GLSL · Vertex / fragment

Interpolation

Köşe değerlerinin piksele karışması

Veri akışı sayfasında varying vertex’te yazılır, raster sonrası fragment’te okunur denildi — aradaki adım bu sayfanın konusudur. Enterpolasyon, shader dosyasında yazdığınız bir fonksiyon değildir; GPU rasterizer’ının vertex çıkışlarını üçgen içindeki her aday piksele dağıtma işlemidir.

Uniforms · varying bildirim sözdizimini ve Three.js eşleşmesini anlatır; Veri akışı · §2 zincirinde 4. adımı işaretler. Burada odak: karışım nasıl düşünülür, hangi hatalar akış kaynaklıdır, flat / perspektif gibi nitelikler nereye bağlanır.

Tam donanım pipeline tablosu Shader pipeline, clip uzayı ve gl_Position türevleri Coordinate spaces konusundadır. Aşağıdaki §1–§7 yalnızca varying köprüsünün «arada» kısmını açar.

Neden enterpolasyon?

Vertex shader seyrek, fragment shader yoğun çalışır ( Veri akışı · seyrek vertex). Köşede bir kez bilinen UV, normal veya renk fragment’te her pikselde farklı olmalıdır — arada otomatik bir dağıtım katmanı gerekir. Bu katman enterpolasyondur; JavaScript veya Three.js API’sinde «şimdi enterpolasyon yap» diye bir çağrı yoktur.

Shader yazarken siz yalnızca köşe değerlerini varying ile vertex çıkışına yazarsınız; GPU üçgen raster ederken aradaki değerleri üretir. Fragment shader bu üretilmiş değeri okur — attribute’u doğrudan okuyamaz.

Bu sayfa ne anlatır, ne anlatmaz?

Veri akışı «varying vertex’te yazılır, fragment’te okunur» der ve zincirde 4. adımı işaret eder; bu sayfa o adımın içini açar — «karışım nasıl düşünülür, shader dosyasında nerede yazılmaz?». Sözdizimi serisi ne bildirilir; vertex / fragment serisi hangi adımda okunur; Interpolation ise «arada ne olur?» sorusuna odaklanır.

Anlatır:

  • Raster adımında varying’lerin nasıl karıştığına dair sezgi ( §3); tam formül sonraya bırakılır.
  • Vertex → raster → fragment sözleşmesi ve aynı isim/tür kuralı ( §4).
  • UV köprüsü örneği — vertex vUv = uv;, fragment texture2D(uMap, vUv) ( §5).
  • flat, smooth ve perspektife kısa giriş — her varying aynı karışmaz ( §6).
  • Yanlış aşamada veri arama; uv vs vUv ( §7).

Anlatmaz (bilinçli sınır):

  • uniform / attribute / varying bildirimi, üç soru, { value: … }Uniforms & varyings serisi.
  • CPU → draw → vertex → fragment tam zinciri ve taşıyıcı tablosu — Veri akışı · §2.
  • Derinlik testi, blending, framebuffer — tam pipeline listesi — Shader pipeline.
  • Tam baryantrik koordinat türevi ve perspektif bölümü matematiği — §3 ve §6’da ileride derinleşir; burada sezgi yeter.
  • texture2D, sampler2D sözdizimi — Built-in · doku.
  • Model / view / projection ve gl_Position öncesi matris zinciri — Coordinate spaces.

Seri içindeki yer

Vertex / fragment alt serisinde önerilen sıra: Veri akışıShader pipeline → Interpolation (bu sayfa) → Coordinate spaces. Önce taşıyıcılar ve adımlar, sonra donanım listesi, sonra «köprü nasıl karışıyor?», en son «konum hangi uzayda?».

Her kardeş sayfa tek soruya odaklanır; burada yalnızca bağlantılar hatırlatılır. Veri akışı varying’in 3 → 4 → 5 zincirini ve attribute/uniform ayrımını kurar — enterpolasyonun neden gerekli olduğu orada. Shader pipeline raster öncesi/sonrası donanım adımlarını listeler; bu sayfa yalnızca 4. adımın «shader yazılmaz» kısmını açar. Coordinate spaces perspektif enterpolasyonun uzay bağlamını tamamlar; §6’daki perspektif notu oraya köprü kurar.

Veri akışı ve Uniforms · varying okunduysa bu sayfaya doğrudan §2 raster adımıyla da girilebilir. İlk kez okuyorsanız §1 → §2 → §3 sırası «arada ne olur?» sorusunu netleştirir; §5 örnek ve §7 hatalar pratiği kapatır.

Aşağıdaki §2, enterpolasyonun pipeline’daki tam yerini sabitler; §3’ten itibaren karışım sezgisi ve kod örnekleri gelir.

Raster adımı: shader yazılmaz

Başlıktaki «shader yazılmaz» ifadesi, enterpolasyon için ayrı bir .glsl dosyası açmayacağınız anlamına gelir. Raster adımı GPU pipeline’ının sabit aşamasıdır; Three.js veya WebGL’de «raster shader» diye bir hook yoktur.

Veri akışı · §2 listesinin 4. maddesi buradadır: vertex shader (3) gl_Position ve varyings ürettikten sonra rasterizer çalışır; fragment shader (5) ancak ondan sonra devreye girer. attribute ve uniform bu adımda okunmaz — yalnızca vertex çıkışları tüketilir ( Veri akışı · taşıyıcılar hangi adımda?).

Rasterizer ne yapar?

Rasterizer kabaca üç işi üstlenir. Bir: clip uzayına yakın konumlarla gelen üçgenleri ekran piksellerine projekte eder — hangi piksellerin üçgene «aday» olduğunu belirler; bu karar gl_Position çıkışına dayanır, varying’lere değil. İki: her aday piksel için köşe varying değerlerinden enterpolasyonlu sonuç üretir. Üç: bu paketi fragment shader invokasyonlarına besler.

Bu hesap sizin main() fonksiyonunuzda değildir — donanım / sürücü pipeline’ının parçasıdır. Tam donanım adım listesi (derinlik testi, blending vb.) Shader pipeline konusundadır; burada yalnızca varying köprüsünün «arada» kısmı öne çıkar.

Girdi ve çıktı

Girdi, vertex shader çıkışlarıdır — iki ayrı rol taşır:

  • gl_Position — Hangi piksellerin üçgene dahil olacağını belirler; taşıyıcı değil, zorunlu konum çıkışıdır. Clip / ekran uzayı ayrıntısı Coordinate spaces konusundadır.
  • varying atamaları — Köşe başına yazdığınız vUv, vNormal, renk vb.; raster bunları üçgen içinde karıştırır.

Çıktı: fragment shader’a giden enterpolasyonlu varying paketi. Her fragment invokasyonu kendi vUv, vNormal değerini görür — komşu piksel farklı karışım alır. Uniform’lar bu adımda değişmez; draw call paketinden fragment’e aynen taşınmaya devam eder.

Shader dosyasında ne yoktur?

Vertex’te vUv = mix(...) ile «manuel enterpolasyon» yazmak raster’ın işini tekrarlamaya çalışmaktır — pratikte yalnızca köşe değerini atarsınız ( vUv = uv;), karışım GPU’dadır. Fragment’te attribute okumak da bu adımda mümkün değildir; attribute 3. adımda biter ( §7).

Aşağıdaki §3, karışımın sezgisini açar; §5 vertex → raster → fragment örneğini kodla gösterir.

Doğrusal karışım sezgisi

§2 raster adımının «ne yaptığını» söyledi; bu bölüm nasıl düşünüleceğini sabitler. Enterpolasyonu formül ezberlemeden okuyabilirsiniz — üç köşe değeri, üçgen içi nokta, arada ağırlıklı birleşim.

En yaygın düşünce: üç köşedeki değerler, üçgen içindeki bir noktada «aralarında doğrusal karışım» olarak birleşir. UV için: köşe A’da (0,0), B’de (1,0), C’de (0.5,1) ise iç noktadaki vUv bu üç değerin ağırlıklı ortalamasına yakındır — ağırlıklar o noktanın köşelere uzaklığına bağlıdır ( barycentric koordinatlar). Köşeye yakın noktada o köşenin rengi/UV’si baskındır; kenar ortasında iki köşe paylaşılır; üçgen merkezine yakınsa üç köşe de dengeli katkı verir.

Tam baryantrik formül ve perspektif düzeltmesi bu bölümde ileride ayrı alt başlıklarda derinleştirilecek ( §6 · perspektif). Şimdilik shader yazarken yeterli sezgi: fragment’te gördüğünüz varying, yalnızca o pikselin ait olduğu üçgenin köşe varyings’lerinin karışımıdır — başka üçgenin köşeleri karışmaz.

Üç köşe, tek üçgen

Enterpolasyon her zaman «şu draw call’daki şu üçgen» bağlamındadır. Vertex shader bir köşe invokasyonunda vUv yazar; raster aynı üçgenin üç köşe çıkışını bir araya getirir. Komşu üçgenin köşe değerleri bu piksele karışmaz — sınırda «dikiş» görünüyorsa çoğu zaman normal/UV discontinuity veya farklı materyal draw call’ıdır, enterpolasyon formülü değil.

Skaler (float), vektör (vec2 UV, vec3 normal) ve renk kanalları aynı mantıkla kanal kanal karışır. Vertex’te vNormal = normalMatrix * normal; yazdıysanız fragment’te gördüğünüz normal de üç köşe normalinin karışımıdır — aydınlatma hesabı fragment’te bu karışık vektörle yapılır.

UV örneği üzerinden

Tipik akış: attribute uv yalnızca vertex’te ( Veri akışı · §3); atama vUv = uv; üç köşede farklı UV üretir. Raster (4) üçgen içinde karıştırır; fragment (5) texture2D(uMap, vUv) ile örnekler — uMap uniform, vUv enterpolasyonlu varying.

Üçgen ortasındaki piksel, köşe A/B/C UV’lerinin karışımını görür; doku o koordinatla okunur. Doku «bükülmesi» veya çizgi kırığı çoğu zaman UV seam, geometry kesri veya attribute layout kaynaklıdır; enterpolasyonun kendisi «köşeden içeri doğru yumuşak geçiş» üretmek için vardır. Sözdizimi Built-in · doku konusundadır.

Hata kalıbı: fragment’te texture2D(uMap, uv)uv attribute adıdır, 5. adımda yoktur; doğrusu enterpolasyonlu vUv ( §7).

Uniform enterpolasyon görmez

uTime, uResolution veya projectionMatrix gibi uniform’lar draw call boyunca sabittir; raster adımında köşeler arasında karışmazlar. Vertex ve fragment aynı paketi okur; arada yalnızca varying kanalları enterpolasyon görür ( Veri akışı · taşıyıcılar hangi adımda?).

Zamanı veya global ışık rengini varying ile taşımak, raster’ın köşe verisi sanıp karıştırmasına yol açar — her pikselde farklı «zaman» üretir; animasyon için uniform float uTime; ve render öncesi güncelleme doğrudur ( Uniforms · üç soru, birinci madde; Veri akışı · akış hataları).

Özet: köşeden köşeye değişen → attribute + (gerekirse) varying; çağrı boyunca sabit → uniform. §4 vertex–fragment sözleşmesini; §5 kod örneğini tamamlar.

Varying sözleşmesi

§3 karışımı sezgisel anlattı; bu bölüm sözleşmeyi sabitler: hangi dosyada ne yazılır, hangi adımda kim okur. Enterpolasyon yalnızca vertex’te yazılan ve fragment’te aynı isim + türle okunan varying (veya GLSL ES 3.00’da out / in) kanallarında çalışır.

Bildirim, precision ve flat gibi nitelikler Uniforms · varying bölümündedir. Burada üç adımlı akış sözleşmesi:

  • Vertex (3. adım) — Bildirim + atama. Attribute’tan kopya ( vUv = uv;) veya dönüşüm ( vNormal = normalMatrix * normal;). Burada «iç nokta» değeri hesaplanmaz; yalnızca köşe değeri yazılır.
  • Raster (4. adım) — Otomatik karışım; shader dosyasında satır yok ( §2).
  • Fragment (5. adım) — Aynı isimle okuma ( texture2D(uMap, vUv), normalize(vNormal)). Yeni atama fragment’e taşımak değildir; tüketimdir.

İsim ve tür: çift dosya sözleşmesi

Vertex ve fragment shader ayrı derlenir; program link aşamasında varying çiftleri eşleştirilir. varying vec2 vUv; vertex’te, varying vec2 vUv; fragment’te — isim ve tür bire bir aynı olmalıdır. Holodepth’te v öneki ( vUv, vNormal) attribute (uv) ile karışmayı azaltır; zorunlu değildir ama önerilir.

Tür uyuşmazlığı (vec2 vs vec3) veya fragment’te eksik bildirim çoğu zaman link hatası verir. Vertex’te atamayı unutmak ise derlemeyi geçebilir — fragment anlamsız veya sabit değer görür; hata ayıklamada önce vertex main() içindeki atamayı kontrol edin ( §7).

Varying değil: attribute ve uniform

attribute vec2 uv; yalnızca vertex girişidir; fragment’te aynı isimle geçemez — enterpolasyonlu karşılığı vUv’dir. uniform float uTime; her iki shader’da okunur ama raster karıştırmaz; varying ile taşınmamalıdır ( §3 · uniform karışmaz, Uniforms · üç soru).

Yeni bir kanal eklerken önce «köşede mi üretiliyor, fragment’te de lazım mı?» sorun — evet ise varying; çağrı boyunca sabitse uniform ( Veri akışı · taşıyıcılar).

GLSL ES 3.00 notu

WebGL2 ve GLSL ES 3.00’da vertex’te out vec2 vUv;, fragment’te in vec2 vUv; — anlam klasik varying ile aynıdır; yalnızca giriş/çıkış anahtar sözcükleri ayrışır. Attribute tarafında in vec3 position; benzer şekilde aynı buffer eşleşmesini sürdürür.

Holodepth örnekleri çoğu zaman klasik attribute / varying çiftini gösterir; WebGL2 projelerinde bire bir çevrilebilir ( Uniforms · in/out). flat ve perspektif nitelikleri §6 ve GLSL giriş · varying bölümünde kalır.

Sözleşme netleştiyse §5 aynı materyalde vertex ve fragment dosyalarını yan yana gösterir.

Örnek: UV köprüsü

Aynı materyalde vertex varying yazar, fragment enterpolasyonlu vUv ile doku örnekler. Attribute yalnızca vertex’te; fragment’te uv geçersizdir.

attribute vec2 uv;
varying vec2 vUv;

void main() {
  vUv = uv;  // raster enterpolasyonu buradan sonra
  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
varying vec2 vUv;
uniform sampler2D uMap;

void main() {
  gl_FragColor = texture2D(uMap, vUv);  // enterpolasyonlu UV
}

Nitelikler: smooth, flat, perspektif

Varsayılan davranış çoğu kanal için smooth (köşeler arası karışım) enterpolasyondur. flat niteliği köşe değerlerinden birini (provoking vertex) üçgen boyunca sabit tutar — tipik kullanım: yüz başına normal veya materyal id. Ayrıntı GLSL giriş · varying bölümünde; bu sayfada yalnızca «her varying aynı karışmaz» notu yeterlidir.

Perspektif enterpolasyon

Derinlik varken ekran uzayındaki doğrusal karışım, dünya uzayında eşit hızlı dağılım vermeyebilir. GPU konum ve derinlik için perspektif düzeltmeli enterpolasyon uygular; UV ve renk kanallarında da pipeline kuralları geçerlidir. Matematik türevi ve clip uzayı bağlantısı bu alt başlıkta ileride açılacak; Coordinate spaces ile birlikte okunmalıdır.

Enterpolasyona özel karışıklıklar

Aşağıdaki liste yanlış aşamada veya enterpolasyonu atlayarak veri aramayı vurgular — «varying doğru bildirildi ama köprü kopuk» durumları. Derleme geçip ekranda düz renk, sabit UV, doku kayması veya «her pikselde aynı değer» çoğu zaman 4. adımın atlandığını veya 5. adımda attribute arandığını gösterir.

Yanlış uniform adı, { value: … } veya attribute kanalı eksikliği Uniforms · sık hatalar bölümündedir. render zamanlaması ve sahne position karışıklığı Veri akışı · akış hataları konusundadır — burada yalnızca enterpolasyon zinciri.

Her madde Veri akışı · §2 adım numarasıyla okunur (3 vertex → 4 raster → 5 fragment).

  • Fragment’te (5) texture2D(uMap, uv)uv yalnızca vertex’te (3) okunan attribute’tur. Doğrusu: 3’te vUv = uv;, 4’te enterpolasyon, 5’te vUv ( §3 · UV, §5).
  • Vertex’te vUv = uv; atamasını unutmak — varying bildirimi olsa bile 4. adım beslenmez; fragment anlamsız veya köşe değerlerinden birine «yapışık» görünür. Kontrol: vertex main() ( §4 · isim ve tür).
  • Sabit veriyi (uTime, ışık rengi) varying ile taşımak — raster köşe verisi sanıp karıştırır; her pikselde farklı «zaman» üretir. Doğrusu uniform ( §3 · uniform karışmaz).
  • Vertex’te vUv = mix(a,b,t) ile iç nokta hesaplamaya çalışmak — karışım 4. adımda GPU’dadır; vertex yalnızca köşe değeri yazar ( §2 · shader’da ne yoktur?).
  • Vertex ve fragment’te farklı varying ismi veya türü (vUV vs vUv, vec2 vs vec3) — çoğu zaman link hatası; nadiren sessiz uyumsuzluk. Çift dosyada aynı satırı kopyalayın ( §4).
  • Fragment’te attribute okumaya çalışmak — pipeline kuralına aykırı; enterpolasyonu «atlamak» mümkün değildir. WebGL2 in sözdizimi de aynı köprüyü ister ( §4 · GLSL ES 3.00).
  • flat veya perspektif beklentisi karışıklığı — tüm kanallar aynı smooth karışmaz; yüz başına sabit normal istiyorsanız flat bilinçli seçilmelidir ( §6).

Şüphede: 3 → 4 → 5 zincirini işaretleyin

Değişken için üç durak çizin: vertex’te yazıldı mı? (3), raster karıştırdı mı? (4 — siz yazmazsınız, otomatik), fragment’te okundu mu? (5). Örnek: doku — vUv 3’te atanır, 5’te texture2D; uMap uniform olarak 2’de paketlenir, 5’te okunur, 4’te karışmaz.

Sonuç yanlışsa önce 3→4→5 kopukluğunu, sonra isim/tür sözleşmesini kontrol edin. Veri akışı · taşıyıcılar hangi adımda? özeti ve bu sayfanın §4 sözleşmesi birlikte okunmalıdır; Uniforms · sık hatalar Three.js ve bildirim katmanına kalır.

Holodepth notu

Materyal yazarken kağıda üçgen çizin; köşelere vUv değerlerini yazın, iç noktaya «karışım» oku çizin — raster adımı böylece somutlaşır. Sonra Coordinate spaces ile konum uzayına geçin.