2 Mayıs 2014 Cuma

Gerçek-Dünya ve OpenGL Işıklandırma,Ambiyans, Yayılma, Aynamsı ve Yayınımcı Işık

Gerçek-Dünya ve OpenGL Işıklandırma,Ambiyans, Yayılma, Aynamsı ve Yayınımcı Işık

Fiziksel bir yüzeye baktığınızda gözlerinizin renk algısı, konik hücrelerinize ulaşan ve uyaran foton enerjisinin dağılımına bağlıdır. (Renk Algıs bölümüde bunu inceledik”). Bu fotonlar bir ışık kaynağı ve kaynak kombinasyonundan gelir, bir kısmı soğurulur ve bir kısmı da yüzey tarafından yansıtılır. Ek olarak farklı yüzeylerin farklı özellikleri olabilir – kimisi parlaktır ve ışığı belli yönlerde özellikle yansıtırken diğerleri gelen ışığı her yöne eşit şekilde dağıtır. Çoğu yüzey bu ikisinin arasındadır.

OpenGL ışık ve ışıklandırmaya sanki ışık kırmızı, yeşil ve mavi bileşenlere kırılabilirmiş gibi yaklaşır. Böylece bir ışık kaynağının rengi yaydığı kırmızı, yeşil ve mavi ışıkların miktarı ve bir yüzeyin malzemesi, farklı yönlere dağıtılan gelen kırmızı, yeşil ve mavi ışığın yüzdesi ile karakterize edilir. OpenGL ışıklandırma eşitlikleri sadece yaklaşık tahminlerdir ancak oldukça iyi çalışırlar ve nispeten daha hızlı şekilde hesaplanırlar. Eğer daha kesin (veya sadece farklı) bir ışıklandırma modeli istiyorsanız yazılımda kendi hesaplamalarınız yapmak zorundasınız. Böylesi yazılımlar, birkaç saatlik optik ders kitabı okumasının sizi ikna edeceği gibi, muazzam şekilde karmaşıktırlar.
OpenGL ışıklandırma modelinde bir sahnedeki ışık, münferit olarak açıp-kapatılabilen birkaç ışık kaynağından gelir. Bazı ışıklar belli bir yön veya konumdan gelir ve bazıları ise genel olarak sahneye dağılır. Örneğin bir odada ampulü yaktığınızda ışığın çoğu ampulden gelir ancak kimi ışıklar bir, iki, üç veya daha fazla duvardan sekmekten ileri gelir. Bu seken ışıklar (ambiyans ışıkları denir) orijinal yönlerini söylemenin mümkün olmayacağı şekilde dağıldığı varsayılır ancak ışık kaynağının kapatılması durumunda kaybolurlar.
Son olarak, sahnede  sanki o kadar çok sekmiştir ki orijinal kaynağını belirlemenin imkânsız olduğu belli hiçbir kaynaktan gelmeyen genel bir ambiyans ışığı olabilir.
Open GL modelinde ışık kaynaklarının sadece orada ışığı emecek ve yansıtacak nesneler olması durumunda etkisi vardır. Her bir yüzeyin çeşitli özelliklere sahip bir materyalden yapılığı varsayılır. Bir materyal kendi ışığını (bir otomobilin farları gibi) yayabilir, gelen ışığın bir kısmını tüm yönlerde dağıtabilir ve bir kısmını ise tercih edilen yönde yansıtabilir (bir ayna veya başka bir parlak yüzey gibi).
Ambiyans, Yayılma, Aynamsı ve Yayınımcı Işık
Ambiyans ışıklandırma, çevre tarafından orijinal kaynağını belirlemenin imkânsız olacağı şekilde dağıtılmış olan ışıklardır – tüm yönlerden geliyormuş gibi görünürler. Gözünüze ulaşan ışığın çoğu öncelikle pek çok yüzeyden sektiğinden dolayı bir odadaki arka ışık büyük bir ambiyans bileşenine sahiptir. Bir dış mekân spot ışığının çok küçük bir ambiyansı vardır; ışığın çoğu aynı yönde gider ve siz de dışarıda olduğunuzdan çogu ışık nesnelere çarparak gözünüze ulaşır. Ambiyans ışığı bir yüzeye vurduğunda tüm yönlere eşit şekilde dağılır.
Yayılma bileşeni, bir doğrultudan gelen ışık demektir, bu nedenle yüzeye zorlukla değmek yerine dik olarak geldiğinde çok daha parlaktır. Bununla birlikte bir yüzeye çarptığı anda tüm yönlere eşit şekilde dağılır, böylece gözün nereden baktığı önemli olmaksızın aynı parlaklıkta görünür. Belli bir doğrultu ve ya konumdan gelen her türlü ışığın bir yayılım bileşeni vardır.
Aynamsı ışık belli bir doğrultudan gelir ve tercih edilen bir doğrultuda yüzeyden seker. Yüksek kalitedeki bir aynadan seken iyi bir paralelliğe sahip lazer demeti %100’lük aynamsı yansıma üretir. Parlak metal veya plastiğin yüksek bir aynamsı bileşeni ve tebeşir veya halı gibi nesnelerin hiç aynamsı bileşeni yoktur. Aynamsıliği parlaklık olarak düşünebilirsiniz.
Ambiyans, yayılma ve aynamsı renklere ek olarak materyaller, nesnen kaynaklanan ışığa benzeyen bir yayınım rengine sahip olabilir. OpenGL ışıklandırma modelinde bir yüzeyin yayınım rengi nesneye derinlik katar ancak hiçbir ışık kaynağından etkilenmez. Ayrıca yayınım rengi genel sahneye herhangi ek ışık katkısı yapmaz. 

Materyal Renkleri,Işıklar ve Materyaller için RGB Değerleri

Materyal Renkleri,Işıklar ve Materyaller için RGB Değerleri

Materyal Renkleri    
OpenGL ışıklandırma modeli bir materyalin rengini, gelen ışıktan yansıttığı kırmızı, yeşil ve mavi bileşenlerin yüzdesinden tahmin eder. Örneğin  kırmızı  bir toptan  gelen tüm kırmızı ışıkları yansıtır ve tüm yeşil ve mavi ışıkları soğurur. Eğer böyle bir topu beyaz ışıkta görürseniz (eşit miktarlarda kırmızı, yeşil ve mavi renkten oluşan) tüm kırmızı yansıtılmıştır ve siz bir kırmızı top görürsünüz. Eğer top saf kırmızı ışıkta görülürse yine kırmızı görünecektir. Bununla birlikte eğer saf yeşil ışıkta görülürse siyah (tüm yeşil soğurulur ve gelen kırmızı olmadığından yansıtılacak ışık da yoktur).
Işıklar gibi materyallerin de, materyallerin ambiyansını, yayılma ve aynamsı yansımalarını belirleyen farklı ambiyans, yayılma ve aynamsı renkleri vardır. Bir materyalin ambiyans yansıma çarpanı her bir gelen ışık kaynağının ambiyans bileşeni ile birleşmiş, ışığın yayılma bileşeni ile yansıma çarpanı ile karışmıştır ve aynamsı yansıma çarpanı ile aynamsı bileşen için de durum aynıdır. Ambiyans ve yayılma yansıma çarpanları malzemenin rengini tanımlar ve tipik olarak özdeş değilseler bile benzerdirler. Spekular yansıma genellikle beyaz veya gridir, bu nedenle aynamsı spot ışıkları ışık kaynağının aynamsı ışık şiddetinin rengine sahip olur. Beyaz bir ışığın parlak bir kızıl plastik küre üstünde parladığını düşünün, kürenin çoğu kırmızı görünür ana parlak spot beyazdır.
Işıklar ve Materyaller için RGB Değerleri
Işık için belirlenen renk bileşenleri, materyaller için olduğundan daha farklı anlam ifade eder. Bir ışık için sayılar her bir renk için tam şiddetin bir yüzdesine karşılık gelir. Eğer bir ışığın rengi için R, G ve B değerlerinin hepsi 1.0’a eşitse, ışık en parlak olası beyazdır. Eğer değerler 0.5 ise, renk hâlâ beyazdır ancak şiddeti yarıya inmiştir ve bu nedenle gri görünür. Eğer R=G=1 ve B=0 ise (hiç mavi olmaksızın tam kırmızı ve yeşil) ışık sarı görünür.
Materyaller için sayılar, o renklerin yansıyan oranlarına karşılık gelir. Yani, eğer R=2, G=0.5 ve B=0 ise o materyal gelen kırmızı ışığın tümünü ve yeşilin yarısını yansıtır ve gelen hiçbir mavi ışık yoktur. Diğer bir deyişle, eğer bir OpenGL ışığı (LR, LG, LB) bileşenlerine sahipse ve bir materyal karşılık gelen (MR, MG, MB) bileşenlerini içeriyorsa , bu durumda tüm diğer yasıtma etkilerini ihmal ederek, göze gelen ışık (LR.MR, LG.MG, LB.MB) ile verilir.
Benzer olarak, eğer göze (R1, G1, B1) ve (R2, G2, B2) gönderen iki ışığını varsa OpenGL, (R1+R2, G1+G2, B1+B2) vererek bileşen ekler. Herhangi bir toplamın 1’den büyük olamsı durumunda (ekipmanın gösterebileceğinden daha parlak bir renge karşılık gelir) bileşen 1’e kenetlenir.
Basit Bir Örnek: Işıklandırılmış Bir Küreyi Kaplamak
Bunlar, sahnenize ışık eklemek için gerekli adımlar:
  1. Her nesnenin her köşesi için normal vektörler tanımlayın. Bu normaller nesnenin ışık kaynağına göre yönelimini belirler.
  2. Bir veya daha fazla ışık kaynağı yaratın, seçin ve konumlandırın.
  3. Küresel ambiyans ışık seviyesini ve görüş noktasının etkin konumunu belirleyen bir ışıklandırma modeli yaratın ve seçin (ışıklandırma hesapları açısından)
  4. Sahnedeki nesneler için malzeme özellikleri tanımlayın.

Örnek   light.c


#include <GL/glut.h>
void init(void)
{
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shininess[] = { 50.0 };
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
GLfloat white_light[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat lmodel_ambient[] = { 0.1, 0.1, 0.1, 1.0 };
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light);
glLightfv(GL_LIGHT0, GL_SPECULAR, white_light);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glutSolidSphere(1.0, 20, 16);
glFlush();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w,
1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
else
glOrtho(-1.5*(GLfloat)w/(GLfloat)h,
1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}


 Örnekte ile ilgili olarak düşülecek bir not, RGBA renk modunu kullanıyor olduğudur. OpenGL ışıklandırma hesaplaması iki mod için farklıdır ve aslında ışıklandırma kapasiteleri renk-endeks modunda çok daha sınırlıdır. Böylece RGBA ışıklandırma yaparken tercih edilir . 
Her Nesnenin Her Köşesi İçin Normal Vektörler Tanımlamak
Bir nesnenin normalleri ışık kaynaklarıyla ilgili yönelimlerini belirler. Her bir köşe için OpenGL, bu köşenin her bir ışık kaynağından ne kadar ışık aldığını belirlemek için atanmış normal kullanır. Bu örnekte küre için normaller glutSolidSphere() şablonunun parçası olarak kullanılır.
Uygun ışıklandırma için, yüzey normalleri birim uzunlukta olmalıdır. Aynı zamanda model-görüntü dönüşüm matrisinin yüzey normalini artık birim uzunlukta olmayacak şekilde ölçeklendirmemesine dikkat etmek zorundasınız. Normallerin birim uzunlukta olduğundan emin olmak için  GL_NORMALIZE veya GL_RESCALE_NORMALi parametre olarak içeren glEnable()komutunu çağırmanız gerekebilir.
GL_RESCALE_NORMAL, bir yüzey normalindeki her bir bileşenin, model-görüntü dönüşüm matrisi tarafından belirlenen aynı değerle çarpılmasını sağlar. Bu nedenle sadece normal tekdüze olarak ölçeklenmiş ve başlangıçtan itibaren birim uzunlukta ise doğru şekilde çalışır.GL_NORMALIZE,GL_RESCALE_NORMAL’den çok daha dosdoğru bir operasyondur. GL_NORMALIZE etkinleştirildiğinde normal vektörün uzunluğu hesaplanır ve daha sonra normalin her bir bileşeni hesaplanan uzunluğa bölünür. Bu operasyon sonuç normalin birim uzunlukta olmasını garantiler ancak basit yeniden ölçeklendirme normallerinden daha pahalı olabilir.
Not: Bazı OpenGL uygulamaları, aslında normal vektörleri sadece ölçerek değil normalleştirmek suretiyle  GL_RESCALE_NORMAL komutunu uygulayabilir. Bununla birlikte uygulamanızın bunu yapıp yapmadığını veya genellikle buna güvenmeniz gerekip gerekmediğini belirleyemezsiniz. 

Bir veya Daha Fazla Işık Kaynağı Yaratma, Konumlandırma ve Etkinleştirme
light.c örneginde beyaz ışık veren tek bir ışık kaynağı kullanmaktadır. Konumu glLightfv() komutu ile belirlenir. Bu örnek beyazı, yayılma ve ayna-benzeri yansıma hesaplamaları için sıfır ışığın rengi (GL_LIGHT0) olarak belirler. Eğer farklı renkte bir ışık istiyorsanız glLight*()’ı değiştirin.
Ekranınıza çeşitli renklerde en az sekiz farklı ışık kaynağı da dâhil edebilirsiniz. (Open GL’nin kullandığınız özel uygulaması sekizden fazlasına izin verebilir.) Varsayılan ışık rengi GL_LIGHT0 haricinde siyahtır. Işık kaynaklarını aynı zamanda istediğiniz yere de yerleştirebilirsiniz. Örneğin bir masa lambası kimliğinde ekranın yakınına veya güneş ışığını temsil etmek üzere ekranın uzağına yerleştirebilirsiniz. Ek olarak, ışık kaynağının dar, odaklanmış ışık demeti veya daha geniş bir ışık demeti vermesini de kontrol edebilirsiniz. Her bir ışık kaynağının, ekranı kaplamak için gereken hesaplara önemli şekilde ek getirdiğini, bu nedenle performansın ekrandaki ışık kaynağı sayısından etkilendiğini unutmayın. 
İstediğiniz ışık kaynağının karakteristiklerini tanımladıktan sonra onları glEnable() komutu ile açık hale getirmelisiniz. Aynı zamanda, OpenGL’yi ışıklandırma hesaplamalarını gerçekleştirmek üzere hazırlamak için GL_LIGHTING’i bir parametre olarak içeren glEnable() komutunu çağırmanız gerekir.