Blinn – Phong yansıma modeli - Blinn–Phong reflection model

Blinn – Phong yansıma modeli, aynı zamanda değiştirilmiş Phong yansıma modeli, tarafından geliştirilen bir değişikliktir Jim Blinn için Phong yansıma modeli.[1]

Blinn – Phong, kullanılan varsayılan gölgeleme modelidir. OpenGL ve Direct3D sabit işlevli ardışık düzen (Direct3D 10 ve OpenGL 3.1'den önce) ve her bir tepe noktasından geçerken gerçekleştirilir. grafik ardışık düzeni; piksel köşeler arasındaki değerlerin enterpolasyonu Gouraud gölgelendirme hesaplama açısından daha pahalı olanlardan ziyade varsayılan olarak Phong gölgeleme.[2]

Açıklama

Phong ve Blinn – Phong gölgelendirmesini hesaplamak için vektörler

Phong gölgelendirmede, kişi sürekli olarak yeniden hesaplanmalıdır. nokta ürün bir izleyici arasında (V) ve bir ışık kaynağından gelen ışın (L) yansıdı (R) bir yüzeyde.

Bunun yerine bir hesaplanırsa yarım vektör izleyici ve ışık kaynağı vektörleri arasında,

ile değiştirilebilir , nerede ... normalleştirilmiş yüzey normal. Yukarıdaki denklemde, ve her ikisi de normalleştirilmiş vektörlerdir ve denklemin çözümü nerede ... Hane sahibi matrisi hiper düzlemde orijini içeren ve normal

Bu iç çarpım, Phong'un iç çarpımı ile temsil edilen açının yarısı olan bir açının kosinüsünü temsil eder. V, L, N ve R hepsi aynı düzlemde yatıyor. Vektörler aynı düzlemde bulunmadığında, özellikle açılar küçük olduğunda, açılar arasındaki bu ilişki yaklaşık olarak doğru kalır. Arasındaki açı N ve H bu nedenle bazen yarım açı olarak adlandırılır.

Yarı yol vektörü ile normal yüzey arasındaki açının, arasındaki açıdan daha küçük olması muhtemeldir. R ve V Phong'un modelinde kullanılır (yüzey, büyük olması muhtemel olan çok dik bir açıdan görülmedikçe) ve Phong kullandığından beri bir üs ayarlanabilir öyle ki önceki ifadeye daha yakındır.

Önden aydınlatmalı yüzeyler için (izleyiciye bakan yüzeylerdeki speküler yansımalar), ilgili Phong yansımalarıyla çok yakından eşleşen aynasal vurgularla sonuçlanacaktır. Bununla birlikte, Phong yansımaları her zaman düz bir yüzey için yuvarlak iken, yüzeye dik bir açıdan bakıldığında Blinn-Phong yansımaları eliptik hale gelir. Bu, güneşin ufka yakın denizde yansıtıldığı veya uzaktaki bir sokak ışığının ıslak kaldırımda yansıtıldığı, yansımanın her zaman yataydan çok daha fazla dikey olacağı durumla karşılaştırılabilir.[3]

Görsel karşılaştırma: Blinn-Phong vurguları, aynı üslü Phong'dan daha büyüktür, ancak üssü düşürerek neredeyse eşdeğer hale gelebilirler.

Ek olarak, Phong modeline bir yaklaşım olarak görülebilse de, deneysel olarak belirlenen daha doğru modeller üretir. çift ​​yönlü yansıma dağılım fonksiyonları Birçok yüzey türü için Phong'dan daha fazla.[4]

Verimlilik

Blinn-Phong, izleyicinin ve ışığın yaklaşma veya sonsuzluk gibi çok uzak olduğu düşünüldüğünde Phong'dan daha hızlı olacaktır. Yönlü ışıklar ve ortografik / izometrik kameralar için durum budur. Bu durumda, yarım yol vektörü konumdan ve yüzey eğriliğinden bağımsızdır çünkü yarı yol vektörü, izleyicinin konumunun yönüne ve bu uzak mesafede ayrı ayrı birleşen ışığın konumunun yönüne bağlıdır, dolayısıyla yarı yol vektörü düşünülebilir. bu durumda sabittir. bu nedenle her ışık için bir kez hesaplanabilir ve daha sonra tüm çerçeve için veya aslında ışık ve bakış açısı aynı göreceli konumda kalırken kullanılabilir. Aynı durum, Phong'un yüzey eğriliğine bağlı olan ve görüntünün her pikseli için (veya köşe aydınlatması durumunda modelin her tepe noktası için) yeniden hesaplanması gereken yansıma vektörünü kullanma yöntemi için doğru değildir. Perspektif kameralı 3B sahnelerde bu optimizasyon mümkün değildir.

Kod örnekleri

Üst Düzey Gölgelendirme Dili kod örneği

Bu örnek Üst Düzey Gölgeleme Dili bir nokta ışıktan yaygın ve speküler ışığı belirleme yöntemidir. Işık yapısı, yüzey uzayındaki konumu, görünüm yön vektörü ve yüzeyin normali geçilir. Bir Aydınlatma yapısı döndürülür;

Aşağıdakilerin ayrıca, olumsuz yanıtlar durumunda belirli nokta ürünlerini sıfıra sabitlemesi gerekir. Bu olmadan, kameradan uzaklaşan ışık, ona doğru gelen ışıkla aynı şekilde ele alınır. Speküler hesaplama için, bir nesnenin kenarlarından ve kameradan uzağa bakan yanlış bir ışık "halesi", ışığın doğrudan kameraya doğru yansıdığı kadar parlak görünebilir.

yapı Aydınlatma{    float3 Dağınık;    float3 Speküler;};yapı PointLight{	float3 durum;	float3 diffuseColor;	yüzen  diffusePower;	float3 specularColor;	yüzen  specularPower;};Aydınlatma GetPointLight(PointLight ışık, float3 pos3D, float3 viewDir, float3 normal){	Aydınlatma DIŞARI;	Eğer (ışık.diffusePower > 0)	{		float3 lightDir = ışık.durum - pos3D; // Yüzey uzayında 3B konum		yüzen mesafe = uzunluk(lightDir);		lightDir = lightDir / mesafe; // = normalize (lightDir);		mesafe = mesafe * mesafe; // Bu çizgi Ters karekök kullanılarak optimize edilebilir		// Dağınık ışığın yoğunluğu. 0-1 aralığında tutmak için doyurun.		yüzen NdotL = nokta(normal, lightDir);		yüzen yoğunluk = doyurmak(NdotL);		// Yaygın ışık faktörlemesini açık renk, güç ve zayıflama olarak hesaplayın		DIŞARI.Dağınık = yoğunluk * ışık.diffuseColor * ışık.diffusePower / mesafe;		// Işık vektörü ile görünüm vektörü arasındaki yarım vektörü hesaplayın.		// Bu genellikle gerçek yansıma vektörünü hesaplamaktan daha yavaştır		// normalize işlevinin karşılıklı karekökü nedeniyle		float3 H = normalleştirmek(lightDir + viewDir);		// Aynasal ışığın yoğunluğu		yüzen NdotH = nokta(normal, H);		yoğunluk = pow(doyurmak(NdotH), aynasal Sertlik);		// Aynasal ışık faktörlemesini özetleyin		DIŞARI.Speküler = yoğunluk * ışık.specularColor * ışık.specularPower / mesafe; 	}	dönüş DIŞARI;}

OpenGL Gölgelendirme Dili kod örneği

Bu örnek OpenGL Gölgeleme Dili iki kod dosyasından oluşur veya gölgelendiriciler. İlki sözde köşe gölgelendiricisi ve uygular Phong gölgeleme, köşeler arasındaki yüzey normalini enterpolasyon yapmak için kullanılır. İkinci gölgelendirici sözde parça gölgelendiricisi ve bir noktasal ışık kaynağından yayılan ve speküler ışığı belirlemek için Blinn-Phong gölgeleme modelini uygular.

Köşe gölgelendiricisi

Bu köşe gölgelendiricisi, Phong gölgeleme:

nitelik vec3 inputPosition;nitelik vec2 inputTexCoord;nitelik vec3 inputNormal;üniforma mat4 projeksiyon, modelview, normalMat;değişen vec3 normalInterp;değişen vec3 vertPos;geçersiz ana() {    gl_Position = projeksiyon * modelview * vec4(inputPosition, 1.0);    vec4 vertPos4 = modelview * vec4(inputPosition, 1.0);    vertPos = vec3(vertPos4) / vertPos4.w;    normalInterp = vec3(normalMat * vec4(inputNormal, 0.0));}

Parça gölgelendirici

Bu parça gölgelendiricisi, Blinn – Phong gölgeleme modelini uygular[5] ve gamma düzeltmesi:

hassas vasat yüzen;içinde vec3 normalInterp;içinde vec3 vertPos;üniforma int mod;sabit vec3 lightPos = vec3(1.0, 1.0, 1.0);sabit vec3 açık renk = vec3(1.0, 1.0, 1.0);sabit yüzen ışık gücü = 40.0;sabit vec3 ambientColor = vec3(0.1, 0.0, 0.0);sabit vec3 diffuseColor = vec3(0.5, 0.0, 0.0);sabit vec3 specColor = vec3(1.0, 1.0, 1.0);sabit yüzen parlaklık = 16.0;sabit yüzen ekran Gama = 2.2; // Monitörün sRGB renk alanına kalibre edildiğini varsayıngeçersiz ana() {  vec3 normal = normalleştirmek(normalInterp);  vec3 lightDir = lightPos - vertPos;  yüzen mesafe = uzunluk(lightDir);  mesafe = mesafe * mesafe;  lightDir = normalleştirmek(lightDir);  yüzen lambertian = max(nokta(lightDir, normal), 0.0);  yüzen aynasal = 0.0;  Eğer (lambertian > 0.0) {    vec3 viewDir = normalleştirmek(-vertPos);    // bu blinn phong    vec3 halfDir = normalleştirmek(lightDir + viewDir);    yüzen specAngle = max(nokta(halfDir, normal), 0.0);    aynasal = pow(specAngle, parlaklık);           // bu phong (karşılaştırma için)    Eğer (mod == 2) {      vec3 yansıtmak = yansıtmak(-lightDir, normal);      specAngle = max(nokta(yansıtmak, viewDir), 0.0);      // üssün burada farklı olduğuna dikkat edin      aynasal = pow(specAngle, parlaklık/4.0);    }  }  vec3 colorLinear = ambientColor +                     diffuseColor * lambertian * açık renk * ışık gücü / mesafe +                     specColor * aynasal * açık renk * ışık gücü / mesafe;  // gama düzeltmesini uygulayın (ambientColor, diffuseColor ve specColor olduğunu varsayın  // doğrusallaştırıldı, yani içlerinde gama düzeltmesi yok)  vec3 colorGammaCorrected = pow(colorLinear, vec3(1.0 / ekran Gama));  // parçadaki gama düzeltilmiş rengi kullanın  gl_FragColor = vec4(colorGammaCorrected, 1.0);}

Renkler ambientColor, diffuseColor ve specColor olmaması gerekiyordu gama düzeltildi. Gama düzeltmeli görüntü dosyalarından elde edilen renkler ise (JPEG, PNG, vb.), onlarla çalışmadan önce doğrusallaştırılmaları gerekir; bu, kanal değerlerini aralığa ölçeklendirerek gerçekleştirilir. [0, 1] ve bunları görüntünün gama değerine yükselterek sRGB renk uzayının yaklaşık 2.2 olduğu varsayılabilir (bu belirli renk uzayı için, basit bir güç ilişkisi sadece gerçek dönüşüm ). Modern grafikler API'ler bu gama düzeltmesini otomatik olarak gerçekleştirme yeteneğine sahip olmak doku veya bir framebuffer.[6]

Ayrıca bakınız

Referanslar

  1. ^ James F. Blinn (1977). "Bilgisayarla sentezlenmiş resimler için ışık yansıması modelleri". Proc. 4. yıllık bilgisayar grafikleri ve interaktif teknikler konferansı: 192–198. CiteSeerX  10.1.1.131.7741. doi:10.1145/563858.563893.
  2. ^ Shreiner, Dave; Khronos OpenGL ARB Çalışma Grubu (2010). "Aydınlatmanın Matematiği". OpenGL programlama kılavuzu: OpenGL'yi öğrenmek için resmi kılavuz, sürüm 3.0 ve 3.1 (7. baskı). Pearson Education, Inc. s. 240–245. ISBN  978-0-321-55262-4.
  3. ^ Krus, Kristofer (2014), Deniz Durumunun Simülasyonu için Dalga Modeli ve Deniz Taşıtı Modeli, Linköping Üniversitesi, s. 97
  4. ^ Ngan, Addy; Durand, Frédo; Matusik, Wojciech (2004). "Analitik BRDF modellerinin deneysel doğrulaması". ACM SIGGRAPH 2004 Eskizler - SIGGRAPH '04. ACM Basın. doi:10.1145/1186223.1186336. Alındı 23 Nisan 2019.
  5. ^ "WebGL Örneği: Phong / Blinn Phong Gölgelendirme". www.mathematik.uni-marburg.de. Alındı 2019-09-13.
  6. ^ https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_framebuffer_sRGB.txt