Three.js · İleri konular · TSL
TSL nedir? Node tabanlı shader devrimi
TSL (Three.js Shading Language), Three.js’in WebGPU yolculuğuyla birlikte öne çıkan node tabanlı shader sistemidir. Geleneksel akışta GLSL veya WGSL’i uzun metin dizgileri olarak yazarken; TSL ile aynı mantığı JavaScript / TypeScript içinde düğümler ve fonksiyon çağrılarıyla kurarsınız — motor, bu grafiği ihtiyaca göre hedef dile çevirir.
Bu sayfa dil dersi veya tam API rehberi değildir: GLSL sözdizimi, Shader mantığı · veri akışı, Render pipeline ve WebGPU tasarım çerçevesi ayrı dosyalarda anlatılır; burada yalnızca TSL’nin zihinsel modeli ve Holodepth haritasındaki yeri özetlenir.
Neden TSL?
Dilden bağımsızlık: tek mantık, çoklu hedef
Siz TSL ile ifadeyi kurarsınız; Three.js arka planda bu grafiği WebGPU için WGSL veya WebGL için GLSL’e yakın bir çıktıya dönüştürmeyi hedefler — yani «önce hangi dili ezberleyeyim?» sorusunu, proje ihtiyacına göre ertelemiş olursunuz. Hedef derleyici ve sürüm farkları yine vardır; fakat okuma yönü «metin dosyası»ndan «tip güvenli grafiğe» kayar.
WGSL sözleşmesinin tasarım tonu için WebGPU · WGSL başlığı yeterli üst köprüdür; burada tekrarlanmaz.
Tip güvenliği ve erken geri bildirim
TSL ifadesi JS / TS dünyasında yaşadığı için, birçok hatayı yalnızca GPU derleyicisinde değil; düzenleyici ve derleme zincirinde daha erken görebilirsiniz. Bu, «her şeyi yine de son anda yakalarım» demek değildir — özellikle sınır koşulları ve sürüm uyumu hâlâ sizin test disiplininizdedir; fakat yanlış birleştirme ve «unutulan uniform» sınıfı hatalar için ek bir güvenlik filtresi oluşur.
Modülerlik ve operatör taşınması
Shader parçalarını JavaScript fonksiyonları gibi birleştirip
yeniden kullanabilir; ortak matematik ve renk kararlarını tek yerde
toplayabilirsiniz.
TSL, uygun bağlamlarda +, -, *
gibi operatörleri düğüm grafiğine çevirerek okunabilirliği artırır — bu, klasik metin
shader’da sık görülen «uzun tek satır» alışkanlığını kırmaya yardım eder.
Küçük uyarı: okunabilirlik artışı, otomatik olarak düşük maliyet demek değildir; grafik derinliği ve derleyici çıktısı yine ölçülmelidir. Performans düşüncesi için Shader mantığı · veri paketi ve Render pipeline metinleriyle birlikte okumak daha dengeli bir resim verir.
TSL’nin temel yapı taşları: düğümler
TSL dünyasında değişkenler ve işlemler düğüm (node) olarak düşünülür. Pratikte en sık karşılaşılan iskelet üç aileden oluşur — vertex ve fragment istasyonlarının «kim ne okuyor?» hikâyesi yine Shader mantığı sayfasındadır; burada yalnızca TSL tarafındaki isimlendirme ve grafik düşüncesi oturtulur.
Metin tabanlı shader’da aynı ifade ağacı zihinde «iç içe parantez» olarak okunurken; TSL’de kökten yapraklara akan değerler kenarlı bir grafik olarak kalır. Bu grafik hem JavaScript içinde yeniden kullanılabilir parçalara bölünebilir hem de motor tarafından hedef dile çevrilir — dil ayrıntısı ve depolama sözleşmesi için GLSL girişi yeterli üst katmandır; burada tekrarlanmaz.
Uniform düğümleri
Zaman (timerLocal gibi), fare veya sahne sabitleri gibi CPU’dan
gelen değerler, çizim çağrısı ölçeğinde genelde her köşe için
tekrarlanmayan
veri olarak düşünülür — klasik uniform sezgisinin düğüm karşılığıdır. Paketin
«çağrı anında kim güncelliyor?» sorusu
Shader
mantığı
· Uniforms
başlığında anlatılır; TSL tarafında dikkat edilecek nokta, bu
değerlerin grafik içinde nereye bağlandığıdır: aynı uniform dalını birden
çok yerde kullanmak, metin kopyalamaktan daha kontrollü bir yeniden kullanım sağlar.
Attribute düğümleri
uv(), normalLocal veya yerel konum gibi okumalar, geometri
tamponlarındaki özniteliklerin shader tarafındaki yüzüdür — yani «bu köşe için hangi kanal
değeri geliyor?» sorusunun cevabıdır. Öznitelik tamponlarının sözleşmesi
Shader
mantığı · Attributes
ile çerçevelenir.
UV’nin geometri ve açma (unwrapping) düşüncesi ise UV mapping konusunda kalır; TSL sayfasında tekrar edilmez.
Matematik ve işlev düğümleri
add, mul, sin, cos gibi çağrılar
doğrudan
düğüm üretir; klasik dilde iç içe yazdığınız ifade ağacı burada adım adım görünür
kenarlar haline gelir. Aynı matematiksel çekirdek
GLSL / WGSL ile paylaşılsa da, TSL’deki kazanç «satır içi sihir» yerine bileştirilebilir
küçük
fonksiyonlar yazabilmektir — örneğin bir «parlaklık maskesi» dalını tek yerde
tanımlayıp farklı materyallere bağlamak.
Doku örneklemesi gibi okumalar da yine düğüm olarak modellenir; hangi koordinat uzayında örneklediğiniz (ör. dünya / teğet / UV) kararı, sahne ve materyal bağlamınızla birlikte düşünülmelidir — genel materyal girişi Materyaller haritasında açılır.
Varying ve istasyonlar arası taşıma
Vertex çıktısından fragment’e taşınan enterpole edilmiş veriler, klasik dünyada varying ile adlandırılır. TSL tarafında bu köprüyü yine düğüm grafiği kurar; fakat «rasterizasyon enterpolasyonu aynı addaki değeri nasıl değiştirir?» sorusunun cevabı Shader mantığı · Varyings ve Rasterizasyon köprüsü başlıklarındadır — burada yalnızca şunu ekleyelim: TSL ile grafik kurarken hangi dalın hangi istasyonda üretildiğini motorun kurallarına göre düşünmek, hata ayıklamada «ben fragment’teyim sanıyordum» tuzağını azaltır.
Operatör taşınması ve zincirleme
Uygun düğüm tiplerinde +, * gibi operatörler arka planda yine
grafik üretir; bu, «kısa yazım» ile «şeffaf grafik» arasında köprüdür. Çoğu zaman aynı
işi .mul(), .add() gibi zincirleme (method chaining) ile de kurabilirsiniz — ikisi de aynı fikrin farklı
yüzey sözdizimidir; önemli olan, derleyiciye gidenin yine tek bir düğüm
grafiği
olduğunu unutmamaktır.
TSL ile shader yazımı: kısa bir karşılaştırma
Aşağıdaki iki blok aynı renk fikrini farklı katmanlarda gösterir: soldaki klasik GLSL fragment, sağdaki ise TSL ile aynı mantığın JS tarafında düğüm olarak kurulmasıdır. Vertex tarafı ve varyingsiz minimal örnekler bilinçli olarak kısaltılmıştır; tam «iki istasyon» hikâyesi için yine Shader mantığı metnine dönün.
precision mediump float;
uniform float uTime;
varying vec2 vUv;
void main() {
gl_FragColor = vec4(vUv.x, vUv.y, abs(sin(uTime)), 1.0);
}
import { MeshBasicNodeMaterial } from "three/webgpu";
import { timerLocal, uv, vec4 } from "three/tsl";
const material = new MeshBasicNodeMaterial();
const red = timerLocal(1).sin().abs();
material.colorNode = vec4(uv().x, uv().y, red, 1.0);
timerLocal örneği, zamanı düğüm grafiğine doğrudan bağlı bir
dal olarak düşündürür; uv() ise öznitelik düğümü ailesinden okunur. Gerçek
projede import yolları ve materyal sınıfları Three.js sürümünüze göre değişebilir —
aşağıdaki
kısa notu mutlaka okuyun.
Sürüm ve import uyarısı
TSL ve three/tsl düzeni, Three.js
sürümüne göre evrilen bir yüzeydir; bu sayfadaki satırlar
«kopyala–yapıştır kurulum rehberi» değil, kavramsal iskelet olarak
düşünülmelidir. Üretim öncesi mutlaka seçtiğiniz sürümün resmi örnekleriyle
doğrulayın.
Holodepth projelerinde TSL avantajı
Dinamik materyaller
Shader mantığını uzun metinleri birleştirerek değil; JavaScript kontrol akışıyla çalışma anında yeniden düzenleyebilirsiniz. Bu, prototip ve görsel deneylerde «bir düğümü değiştir, sonucu gör» ritmini güçlendirir.
WebGPU ve hesaplama yolu
TSL, Three.js ekosisteminde WebGPU tarafındaki gelişmiş yollarla birlikte anılır; özellikle bazı iş yüklerinde Compute shader konusuna geçişi zihinde kolaylaştırır — fakat compute’un kendi bellek ve senkron gerçekliği yine WebGPU sayfasında çerçevelenir; burada tekrar edilmez.
Hızlı prototipleme
Karmaşık görsel efektleri, görsel programlama diline benzer bir düğüm düşüncesi ile kurmak mümkündür — özellikle ekip içi paylaşımda «ortak bir dil» oluşturması kolaydır.
Geleceğe bakış: WebGL ile WebGPU arasında köprü
TSL yalnızca «yeni bir yazım biçimi» değil; Three.js’in klasik WebGL motoru ile WebGPU motoru arasında ortak ifade katmanı olma iddiasını taşır. Bir kez bu düğüm düşüncesini oturttuğunuzda, aynı fikirleri farklı hedeflerde yeniden kullanma yolu açılır — tabii ki fallback ve tarayıcı gerçekliği için WebGPU · geçiş ve fallback başlığı hâlâ zorunlu okumadır.
Holodepth teknik notu
Bu site statik bir haritadır; canlı proje hata ayıklaması veya sürüm matrisi sunmaz. TSL seçimi yaparken, ekibinizin Three.js sürümünü, hedef tarayıcıları ve WebGPU desteğini aynı tabloda tutun — aksi halde «grafik güzel, dağıtım zor» tuzağına düşmek kolaydır.