Three.js · Kamera türleri
ArrayCamera (dizi kamera)
ArrayCamera — tek render, çoklu kamera görünümü
ArrayCamera, sahneyi önceden tanımlanmış bir dizi alt kamera ile
tek bir renderer.render(scene, camera) çağrısında ekranın
farklı bölgelerine eşzamanlı olarak çizmeyi kolaylaştırır. Dört ayrı bakış için dört kez
ayrı ayrı render döngüsü kurmak yerine, alt kameralar ve viewport ile
bölünmüş ekran (split-screen) mantığını tek geçişte yönetirsiniz — CPU tarafında daha az
çağrı, GPU tarafında düzenli çoklu görünüm akışı. Genel kamera modeli için
Kamera Giriş;
tek bakış perspektif için
PerspectiveCamera.
Çoklu bakış açısı ve split-screen mantığı
ArrayCamera, ekranın belirli bölgelerini farklı alt kameralara tahsis eder.
Her alt kamera (sub-camera), yalnızca kendisine ayrılan viewport
dikdörtgeni
içinde sahneyi görür; böylece dört oyunculu bölünme, izleme monitörü veya dikiz aynası
düzeni tek sahne üzerinde birleşir.
Kullanım senaryoları
- Yarış / simülasyon: dikiz aynası veya cockpit içi ek görünümler
- Çok oyunculu split-screen: aynı karede birden fazla bakış
- Güvenlik / gözetim: tek tuvalde dört kamera akışı
- Karmaşık VR / çoklu ekran prototipleri: bölgelere ayrılmış görünüm
Kritik nüans: tek
render() çağrısı, içeride birden çok geçiş
ArrayCamera ile yaptığınız tek
renderer.render(scene, arrayCamera) çağrısı, uygulama düzeyinde
“tek draw” anlamına gelmez. WebGLRenderer içinde her alt kamera
için sırayla viewport ayarlanır ve çizim listesi o bakış açısıyla
yeniden işlenir — yani motor tarafında internal bir döngü vardır.
Kazanç çoğunlukla API ve akış sadeleşmesi (tek çağrı, aynı kare
zamanı, daha az el yapımı senkron) ve doğru ayarlandığında daha tutarlı
pencerelemedir; “GPU yükü görünüm sayısıyla çarpılır” satırıyla da örtüşür.
Bu desen WebXR stereo mantığına da yakındır: her göz için ayrı
projeksiyon ve dikdörtgen, tek kare ömründe eşleştirilir; ArrayCamera
köken itibarıyla bu tür çok bölgeli, çok bakışlı düzenlere dayanır —
VR dışında split-screen ve izleme panelinde aynı okuma geçerlidir.
Yapısal anatomi: alt kameralar ve viewport
ArrayCamera, bir dizi PerspectiveCamera (nadiren
OrthographicCamera) nesnesini bir arada tutan bir kapsayıcı
kameradır. En kritik parça, her alt kameranın tuval üzerindeki yerini belirleyen
viewport ayarıdır.
- Viewport: Genelde tuvale göre normalize (0–1) veya
piksel biriminde verilen
(x, y, genişlik, yükseklik)dörtlüsü; GPU’ya “çizimi yalnızca bu dikdörtgen içine sığdır” emrini iletir (makaslama / scissor ile birlikte düşünülür). - Senkronizasyon: Tüm alt kameralar aynı sahneyi
paylaşır; her birinin
position,rotation,fovgibi özellikleri bağımsızdır, böylece aynı anda farklı bakışlar üretilir.
Normalize tuval koordinatları (WebGL): Viewport genelde tuvale göre
0–1 arası ifade edilir; (0, 0) köşe
sol alt, (1, 1) sağ üsttür (y ekseni
yukarı doğru büyür). CSS ile üst/sol köşeden konumlandırma alışkanlığı olanlar için bu
fark önemlidir: aynı “üstteki panel” WebGL’de yüksek y değerine karşılık
gelir.
İleri: viewport ve scissor
Viewport: Projeksiyonu bu dikdörtgene sığdırır — yani “kamera görüntüsü hangi piksel alanına yayılacak?”
Scissor (makas) testi: Çizimin yazılacağı piksel alanını kırpar; çoklu alt render’da genelde viewport ile birlikte kullanılır ki bir alt görünüm komşu bölgelere taşmasın. Three.js çoklu bakış yollarında bu ikisi pratikte sık yan yana gelir.
Viewport + scissor birlikte: Viewport, NDC’den ekrana
projeksiyonun hangi dikdörtgende ölçekleneceğini söyler; scissor ise
raster aşamasında renk ve derinlik yazımını hangi piksel alt kümesine
kısıtlar. Döngülü render() yazarken ikisini çoğu zaman
aynı piksel dikdörtgeninde eşleştirmek, komşu panele taşmayı ve
“hayalet” fragment’leri kesmek için en güvenli kalıptır.
Derinlik tamponu (tek hedef): Varsayılan çerçeve tamponunda tipik olarak tek bir depth buffer paylaşılır; her alt geçiş yalnızca kendi viewport alanındaki piksellere yazar. Paneller birbirinden ayrık olduğu sürece bir panelin derinlik değeri komşunun piksellerini budamaz — bu, çoklu bakışta doğruluk için önemlidir. Aynı panel içinde üst üste binen yüzeylerde z-fighting algısı yine oluşabilir; çoklu bakış bunu tek başına çözmez.
Etkileşimli demo: tek sahne, dört bakış
Aşağıda aynı sahne ortak: zemin ızgarası, merkezde anker küp (biraz daha büyük; yüz tonları + hafif emissive, belirgin kenar), köşede eksen okları (X/Y/Z). Dört alt kamera öğretici set: Front / Right / Top / Free (Türkçe: ön · sağ · üst · serbest orbit). Ön / sağ hafif yukarı, üst tam tepe değil (ufak X/Z offset) — blueprint düzü yerine 3B derinlik okunur. Renkli küre ve sahnedeki görüş çizgileri hangi alt kameranın ankere baktığını gösterir; köşe etiketinin üzerine gelince hem etiket hem çizgi hem de tuval kenarında viewport glow ile eşleşme güçlenir.
Üstteki şema, 2×2 Front / Right / Top / Free düzenini özetler (kavramsal). Alttaki canlı demo aynı mantıkla tuvali viewport’lara böler; köşe yazıları WebGL normalize düzlemde (0,0) sol alt, (1,1) sağ üst köşesine karşılık gelir.
Tek render() —
ArrayCamera; her alt kamerada çizim tamponu pikseli
viewport.
Bu demo yalnızca ArrayCamera + tek render()
yolunu gösterir: aynı sahne, alt kameraların her birinde tanımlı
piksel viewport ile tek çağrıda çizilir. Üretimde
alternatif olarak her kamera için döngüde setViewport /
setScissor + ayrı render() da kullanılabilir; bu sayfa o
kalıbı teoride anlatır, arayüzde ise yalnızca ArrayCamera vardır.
Görünüm sayısı 1 / 2 / 4 olarak değiştikçe hem viewport düzeni hem de
aktif alt kamera sayısı güncellenir. GPU, kaç panel olursa olsun sahneyi her görünüm
için yeniden rasterize eder; ArrayCamera’nın pratik kazancı çoğu
projede tek çağrı ve daha sade senkronizasyon tarafındadır. İlk
yüklemede tek görünüm seçilidir; 2 veya 4 paneli radyo ile açarak
düzeni inceleyebilirsiniz.
Aynı karede çoklu bakış: Tek render() ile tüm alt
kameralar aynı zaman damgasında işlendiği için çoklu viewport
düzenleri genelde stabil ve okunaklı kalır. Hizasız küp veya ızgara
çoğu zaman aspect / projeksiyon ile viewport pikselinin uyuşmamasıdır;
doğrulama ve ince ayar için
Son karar (doğrulama
ve demo kapsamı) bölümüne bakın.
İpucu: Az sayıda viewport ve statik sahnelerde fark küçük olabilir;
ancak kamera sayısı arttıkça ArrayCamera avantajı daha belirgin hale gelir.
Özellikle dört panelde küp veya ızgara hizası “biraz kaymış” görünüyorsa önce
viewport ile aspect / projeksiyon eşleşmesine bakın
(aşağıdaki tablo, notlar ve kontrol listesi).
Bağlantı: Her köşe etiketi, aynı renkteki alt kamera küresi ve ankere giden çizgi ile eşleşir. Fareyi etiketin veya o paneldeki sahnenin üzerine getirince vurgu artar — hangi viewport’un hangi bakışa ait olduğunu bir bakışta kapatırsınız.
Üstteki etkileşimli sahne (diagram-array-camera.js, kök
data-array-camera-demo) ile aynı sayıları ön harita
tabloda topladık; aşağıdaki kod özeti demodaki anker, klip düzlemleri, alt kamera
yerleşimi ve viewportNorm → piksel dönüşümünü hatırlatır. Ara yüzde
değişenler HUD satırında; kalan satırlar dosyadaki sabitlerdir.
Tür sütunu: ekran kontrolleri ile kaynak koddaki değerleri ayırır.
| Sahne / rol | Parametre | Değer | Tür |
|---|---|---|---|
| Ortak · renderer | WebGLRenderer |
antialias: true, alpha: false,
powerPreference: "high-performance"
|
🔒 Sabit |
| Piksel oranı / renk | min(devicePixelRatio, 2) · çıkış
SRGBColorSpace (destekleniyorsa) ·
setClearColor(0x05060c)
|
🔒 Sabit | |
| Ortak · sahne | Scene.background |
0x05060c |
🔒 Sabit |
| Işıklar | AmbientLight |
0xffffff, yoğunluk 0.42 |
🔒 Sabit |
DirectionalLight |
0xffffff · 1.15; konum (4, 9, 6) |
🔒 Sabit | |
| Zemin | GridHelper |
Boyut 16, bölüm 32; renkler
0x3a4a6a / 0x1a2030; position.y =
-0.6
|
🔒 Sabit |
| Anker küp | BoxGeometry / çoklu yüz |
Kenar 1.32; merkez yaklaşık y = 0.35 ·
MeshStandardMaterial (yüz başına ton + hafif emissive)
|
🔒 Sabit |
| Çerçeve + eksen | EdgesGeometry · AxesHelper |
Kenar opaklık 0.88; eksen uzunluk 1.58 (küp ile
hizalı) |
🔒 Sabit |
| Alt kamera · ortak | PerspectiveCamera |
FOV 40°, clip 0.08 … 80 |
🔒 Sabit |
Renk kodları · COLORS |
front 0x5ec8ff · side 0xc86bff ·
top 0x7dff9a · orbit 0xff9f6e
|
🔒 Sabit | |
viewportNorm → piksel · resize /
updateAspects
|
0–1 yerleşim userData.viewportNorm; çizim tamponu
canvas.width / height ile
subCamera.viewport ve aspect = pw/ph
|
🔒 Sabit | |
Dört panel yerleşimi · normalize (x,y,w,h) |
Örn. 4 görünüm: üst sıra (0,0.5,0.5,0.5),
(0.5,0.5,0.5,0.5); alt sıra (0,0,0.5,0.5),
(0.5,0,0.5,0.5) — WebGL sol alt köşe
|
🔒 Sabit | |
Yardımcı + çizgi · küre · Line |
Küre yarıçap 0.17; çizgi opaklığı taban 0.28
(hover’da artar) |
🔒 Sabit | |
| Front / Right / Top | position + lookAt(origin) |
(0, 1.2, 4) · (4, 1.2, 0) ·
(0, 5, 0.01); origin = (0, 0.35, 0)
|
🔒 Sabit |
| Free (orbit) | dairesel yörünge | Yarıçap 6.15; açı += dt×0.058; dikey
y ≈ 1.48 + sin×0.34; lookAt(origin)
|
🔒 Sabit |
| HUD | Görünüm sayısı | ArrayCamera + tek render() · 1 /
2 / 4 panel
|
🔧 HUD |
// diagram-array-camera.js — Sayfa Demosu Sabitleri (üstteki tablo ile; özet)
const COLORS = {
front: 0x5ec8ff,
side: 0xc86bff,
top: 0x7dff9a,
orbit: 0xff9f6e,
};
const NEAR = 0.08;
const FAR = 80;
const CUBE_SIZE = 1.32;
const ORIGIN = new THREE.Vector3(0, 0.35, 0); // anker (küp merkezi)
// Alt kamera şablonu: FOV 40° — viewport pikseli resize’ta userData.viewportNorm’dan
// aspect = (norm.z * bufW) / (norm.w * bufH); updateProjectionMatrix()
// Bakış konumları (lookAt → ORIGIN)
// Front (0, 1.2, 4) · Right (4, 1.2, 0) · Top (0, 5, 0.01)
// Free: orbit yarıçap 6.15; orbitAng += dt * 0.058; y = 1.48 + sin(orbitAng * 0.38) * 0.34
// ArrayCamera: new THREE.ArrayCamera(subCameras.slice(0, viewCount));
// renderer.render(scene, arrayCamera); // 1 panel: doğrudan subCameras[0]
“Sahne yok” gibi — ne zaman endişe?
ArrayCamera yolunda yalnızca köşe yazıları görünüp 3B içerik boş
hissediliyorsa, bu çoğu zaman “sahne yok” değil; tek
render() içinde viewport / projeksiyon / bakış vektörü zinciri
tam oturmamış demektir. Aynı sahneyi hata ayıklamak için döngüde her kamera için
ayrı render() denemek de yaygındır; bu demoda yalnızca
ArrayCamera yolu gösterilir.
Kontrol listesi (üretimde de aynı):
- Viewport (r170, WebGLRenderer + ArrayCamera)
Alt kameranın
viewportdeğeri bu yolda çizim tamponu pikseli olarakgl.viewport’a iletilir; 0–1 normalize bırakırsanız pratikte birkaç piksel alanına sıkışır ve sahne “yok” görünür. Bu demoda yerleşimuserData.viewportNorm(0–1, sol alt orijin) olarak tutulur;resizesonrasısubCamera.viewport.set(nx*bufW, ny*bufH, nw*bufW, nh*bufH)ile piksele çevrilir. Çoklurender()döngüsündesetViewport/ makas ile aynı ölçeği koruyun. - Aspect + matris
Her alt görünüm için
aspect= o panelin viewport piksel eni ÷ boyu; ardındanupdateProjectionMatrix()— atlanırsa veya viewport ile uyumsuzsa küp/ızgara “kaymış” veya sıkışmış görünür. Çoklurender()döngüsünde her iterasyondasetViewport/setScissorile aynıw,hüzerinden hesaplayın. - Bakış
position+lookAt(veya eşdeğeri) sahneye kilitlenmezse “boş” veya tek renk alan hissi oluşur.
Viewport, aspect ve
(alternatif) döngüde çoklu render()
Dört görünümde bazı panellerde küpün hafif yan kaymış veya
ızgaranın tam oturmamış görünmesi çoğu zaman “kamera kötü” değil,
genişlik ÷ yükseklik ile çizim alanının uyuşmamasıdır: yani
camera.aspect güncellenmeden viewport değişmiş demektir. Bu demoda
resize sonrası her alt kamera için
aspect = viewportGenişliği / viewportYüksekliği ve
updateProjectionMatrix() uygulanır.
Çoklu render() kullanırken (genel kural): her alt görünüm
için, o pass’ten hemen önce sırayla şunların tutarlı olması gerekir:
renderer.setViewport(x, y, w, h)ve gerekiyorsarenderer.setScissor(x, y, w, h)ile aynı dikdörtgen;setScissorTest(true)komşu bölgelere taşmayı keser.camera.aspect = w / hardındancamera.updateProjectionMatrix()— atlanırsa projeksiyon yanlış en-boy oranında kalır ve sahne “kaymış” görünür.
Bu tür algı farkları eğitim ve keşif içeriğinde genelde sorun teşkil etmez; ürün veya stüdyo demosunda ise son ince ayar (tam senkron pipeline, sabit zaman adımı vb.) tercih edilebilir. Bu sayfadaki dört bakış (ön, sağ, hafif tilt üst, orbit) üretim tarafında da tutarlı, okunaklı bir set olarak düşünülebilir.
Son karar: doğrulama, ince hizalama ve demo kapsamı
Kalan fark ne? Viewport / aspect düzeltmelerinden sonra
görüntü belirgin şekilde daha stabil; bariz bir hata kalmaması
beklenir. Motor ve sürüme göre viewport piksel yuvarlaması veya
kayan nokta hassasiyeti kaynaklı çok ince farklar görülebilir; bu
tür durumlar çoğu eğitim demosunda pratik sorun teşkil etmez. Bu bir
bug değildir; “piksel mükemmel” hizalama gerekiyorsa ek doğrulama ve
sabit çözünürlük senaryoları düşünülür.
Sistem doğru mu? Pratik doğrulama: 1 görünümde tek panel tutarlı; 2 görünümde düzen simetrik; 4 görünümde her bakış doğru eksen / açıdan okunuyorsa, kamera dönüşümü + projeksiyon hattı tutarlı demektir. Ön bakış net ve ankere kilitli; sağ eksen okunabilir; üst tam düz değil, hafif tilt — derinlik için doğru tercih; serbest orbit dinamik bakış hissi verir. Bu set salt “tutorial” değil; ürün / eğitim içeriğinde rahatlıkla kullanılabilecek düzeyde okunaklıdır.
Ek model gerekir mi? Hayır — bu demodaki amaç zengin sahne göstermek değil, viewport + ArrayCamera render hattını okunaklı göstermektir. Fazla obje dikkati dağıtır; mevcut sade küp + ızgara + eksen bu hedef için uygun seçimdir.
İsteğe bağlı “bir üst seviye” dokunuşlar (hiçbiri zorunlu değildir): aktif viewport’ta hafif vurgu, hover’da kamera → küp çizgisinin güçlenmesi, köşe etiketlerinde kısa giriş animasyonu. Canlı demoda fareyle panel / sahne üzerinde glow ve çizgi opaklığı zaten güncellenir; ekstra animasyon tamamen tercihe bağlıdır.
Uygulama: dörtlü bölünme kurulumu
Aşağıdaki örnek, ekranı dört eşit panele böler; her alt kamera farklı bir konumdan sahneye
bakar. Üretimde pencere oranı değişince her alt kameranın aspect ve
viewport değerlerini güncellemeyi unutmayın. Canlı demodaki
(diagram-array-camera.js)
yerleşim ve hata ayıklama notları için bölüm 3’teki kontrol listesine bakın.
// diagram-array-camera.js ile aynı fikir:
// — yerleşimi 0–1 (sol alt) userData.viewportNorm’da tut
// — ArrayCamera yolunda subCamera.viewport = çizim tamponu pikseli + aspect = pw/ph
const subCameras = [];
const origin = new THREE.Vector3(0, 0.35, 0); // anker (demodaki küp merkezi)
const layoutsNorm = [
new THREE.Vector4(0, 0.5, 0.5, 0.5),
new THREE.Vector4(0.5, 0.5, 0.5, 0.5),
new THREE.Vector4(0, 0, 0.5, 0.5),
new THREE.Vector4(0.5, 0, 0.5, 0.5),
];
const positions = [
new THREE.Vector3(0, 1.2, 4),
new THREE.Vector3(4, 1.2, 0),
new THREE.Vector3(0, 5, 0.01),
new THREE.Vector3(3.5, 1.5, 3.5), // Free: demoda orbit; burada örnek sabit bakış
];
function applyViewportPixels(subCamera, norm, bufW, bufH) {
subCamera.userData.viewportNorm = norm.clone();
const pw = norm.z * bufW;
const ph = norm.w * bufH;
subCamera.aspect = pw / Math.max(1, ph);
subCamera.updateProjectionMatrix();
subCamera.viewport.set(norm.x * bufW, norm.y * bufH, pw, ph);
}
for (let i = 0; i < 4; i++) {
const subCamera = new THREE.PerspectiveCamera(40, 1, 0.08, 80);
subCamera.position.copy(positions[i]);
subCamera.lookAt(origin);
const canvas = renderer.domElement;
applyViewportPixels(subCamera, layoutsNorm[i], canvas.width, canvas.height);
subCameras.push(subCamera);
}
// Her resize / setSize sonrası: layoutsNorm[i] ile applyViewportPixels(...) tekrar
// 2. ArrayCamera
const camera = new THREE.ArrayCamera(subCameras);
// 3. Render döngüsünde tek çağrı
renderer.render(scene, camera);
Teknik tablo: ArrayCamera avantajları
| Özellik | Geleneksel çoklu render | ArrayCamera yaklaşımı |
|---|---|---|
| GPU / çağrı düzeni | Her görünüm için ayrı render döngüsü veya manuel viewport yönetimi | Tek render() içinde çoklu görünüm; viewport atamaları
çerçevelenmiş akış |
| CPU / JS gecikmesi | Döngüde birden çok .render() — senkronizasyon zorlaşabilir |
Tek çağrı; tüm alt görünümler aynı kare zamanında planlanır |
| Senkronizasyon | Kareler arasında mikro kaymalar olabilir | Aynı sahne anı; bakışlar tutarlı güncellenir |
| Kod karmaşıklığı | Manuel viewport, makaslama ve temizleme sırası | Alt kameralara viewport bağlama; ArrayCamera ile toplu kullanım
|
| GPU yükü (netleştirme) | Her alt görünüm için geometri ve piksel işi yapılır — yani sahne karmaşıklığı görünüm sayısıyla çarpılır. Kazanç, çoğunlukla tek render pipeline / tek çağrı düzeni ve daha iyi senkronizasyondadır; “bedava dört kamera” değildir. | |
Post-processing ve tam ekran geçişler
Hazır post zincirleri (ör. bloom, SSAO, TAA, tonemap) çoğu zaman tek tam ekran
dikdörtgeni ve tek kamera projeksiyonu üzerinden tasarlanır.
ArrayCamera ile birlikte kullanmak, bu geçişleri her alt görünüm için
ayrı hedef / ayrı rect düşünmeyi gerektirir; aksi halde efekt yanlış
bölgeye uygulanır veya birleştirme (kompozit) adımı eksik kalır. Yoğun post için çoklu
bakışı genelde ikinci bir tampon, düşük çözünürlüklü ortak geçiş veya son kompozitör
katmanıyla planlamak gerekir — bu yüzden bölüm 6’daki “post-processing zorlaşır”
uyarısı pratikte “pipeline’ı baştan bölersiniz” anlamına gelir.
Döngülü render() ve clear / autoClear
Bu sayfadaki canlı demo yalnızca ArrayCamera yolunu gösterir; üretimde ise
klasik desen olarak her bakış için setViewport ve çoğu zaman
setScissorTest(true) ile döngüde birden fazla render()
yazılabilir. Bu kalıpta hangi adımda renk veya derinlik temizlediğiniz
doğrudan sonucu belirler: örneğin kare başında bir kez tam ekran
clear, sonraki panellerde yalnızca clearDepth; veya ara
geçişlerde autoClear’i kapatıp yalnızca ihtiyaç duyulan bölgeleri
temizlemek. Sıra, makas ve viewport hizası; bir panelde “sahne yok” veya garip üst üste
binme hissinin sık nedenlerindendir.
Sınırlar, ne zaman kullanılmaz ve dikkat
ArrayCamera kullanışlıdır; yine de sınırları vardır:
- Homojen türler: Dizideki kameraların çoğu senaryoda aynı türde
(ör. hepsi
PerspectiveCamera) olması beklenir; karışık türler özel durumlarda ek dikkat ister. - Dinamik boyutlandırma: Pencere
resizeolduğunda her alt kameranınaspectveviewportdeğerlerini döngüyle güncellemek gerekir. - Gölge ve ışık: Işık hesapları sahne için ortaktır; çok sayıda bakış ve gölge haritası yine de maliyeti artırır — alt kamera sayısı fazlaysa profil çıkarın.
Ne zaman (genelde) tercih etmeyin?
- Tek bakış yeterliyse: ek karmaşıklık ve test yükü gereksiz olur.
- Mobil / düşük güç: çok viewport, küçük ekranda hem okunabilirlik hem GPU maliyeti sorun çıkarabilir.
- Yoğun post-processing zinciri: her alt görünüm için ayrı geçiş
gerektiren efektler
ArrayCameraile zorlaşır; efektler çoğu zaman fullscreen pass varsaydığı için ya her panel için ayrı hedef (RT) ve kompozit gerekir ya da önce ortak tamponda birleştirip sonra tek geçişte işlenir.
Holodepth notu: neden viewport?
Varsayılan olarak renderer tüm tuvali boyar. ArrayCamera kullanırken her
alt kameraya bir çizim alanı (viewport) vermezseniz, görünümler
üst üste binebilir veya yalnızca son ayar öne çıkabilir. Viewport, GPU’ya şunu söyler:
“Bu kameranın çıktısını tuvale yalnızca şu koordinatlar arasına yaz.” — split-screen
ve çoklu monitör düzeninin teknik karşılığı budur.
Pratik hata ayıklama için bölüm 3’teki “Sahne yok” kontrol listesine bakın; özellikle
normalize mi piksel mi ve aspect güncellemesi çoğu “boş panel” vakasını
çözer.