cocos2D-X源碼分析之從cocos2D-X學習OpenGL(16)----基本光照

       cocos引擎目前已經支持3d功能,之前在3d教程中介紹了cocos2d-x的3d功能中的光照,但是隻是粗略的介紹了四種光源,因爲光照的重要性和複雜性,這個系列文章會分兩篇介紹光照,本篇介紹光照的基礎-ADS模型,下一篇詳細介紹幾種光源。

       ADS模型是光照的基本模型,包括Ambient(環境光),Diffuse(漫反射)和Specular(點光源)三種光照在物體上的效果是這樣的:


       三種光照共同影響物體,模擬出一般的光照效果,被稱作ADS模型,也叫Phong模型。

       環境光是一個來自遠處的光源,它會讓物體顯示一些顏色,全局照明的原理非常簡單,它用光的顏色乘以一個很小的常量ambient因子,然後乘以物體顏色,最後得到環境光照射物體之後的顏色。

       在cocos2d-x中,在Mesh類(網格,3d模型渲染的最小單元)中以uniform的方式向着色器傳遞光照的參數,處理環境光的時候,是直接傳遞環境光顏色,但是在創建環境光的時候要設置一個強度值,在傳遞前,會用光強乘以顏色再傳,在應用程序中處理好計算可以減少着色器的計算量,是個提高效率的好方法。

auto ambLight = static_cast<AmbientLight *>(light);
const Color3B &col = ambLight->getDisplayedColor();
ambientColor.add(col.r / 255.0f * intensity, col.g / 255.0f * intensity, col.b / 255.0f * intensity);
       漫反射就沒那麼簡單了,它模擬一個發光物對物體方向性的影響,它是ADS模型中最重要的組成部分,面向光源的一面比其他面更亮,它涉及到一些數學和物理概念,如圖所示:


       我們在初中物理中學習過光的發射,它是光照和平面的垂直方向(法線方向)形成入射角,反射是入射角等於發射角,光線會從另一個方向反射出去,在模擬計算光照的時候,我們仍然需要法線這個概念,因爲當入射光線和法線夾角爲0時,光照的效果是最大化的,當爲90度時,光照的效果幾乎爲0,我們要模擬出這個效果。

       法線向量是垂直於頂點表面的向量,由於頂點沒有表面的概念,我們利用頂點周圍的頂點計算出這個頂點的表面,因爲向量叉乘可以得到垂直於兩個向量的向量,我們可以用這種方法得到法向量,有時爲了模擬凹凸不平的平面效果,我們還會使用法線貼圖去定義每個點的法線向量。

       下一步我們就獲得光的方向,光源類提供了獲得光照的方法:

Vec3 SpotLight::getDirection() const
{
    Mat4 mat = getNodeToParentTransform();
    return Vec3(-mat.m[8], -mat.m[9], -mat.m[10]);
}

Vec3 SpotLight::getDirectionInWorld() const
{
    Mat4 mat = getNodeToWorldTransform();
    return Vec3(-mat.m[8], -mat.m[9], -mat.m[10]);
}
      兩個向量準備好了,我們就可以計算漫反射光照了:

vec3 computeLighting(vec3 normalVector, vec3 lightDirection, vec3 lightColor, float attenuation)
{
    float diffuse = max(dot(normalVector, lightDirection), 0.0);
    vec3 diffuseColor = lightColor  * diffuse * attenuation;
    
    return diffuseColor;
}
       最後一個參數attenuation是爲計算另外兩種光源準備的,這裏就會傳1,而漫反射光就是法向量乘以光源方向,注意,因爲法向量由平面指向外方向,所以對應的“光方向”就是由物體平面的點指向光源,所以傳的時候,是真正光源方向的相反數:

for (int i = 0; i < MAX_DIRECTIONAL_LIGHT_NUM; ++i)
{
    vec3 lightDirection = normalize(u_DirLightSourceDirection[i] * 2.0);
    combinedColor.xyz += computeLighting(normal, -lightDirection, u_DirLightSourceColor[i], 1.0);
}
       ADS模型就剩下Specular高光了,它也是依照光的方向向量和法向量,另外還會參考視角方向,基本算法就是將光線方向(注意,這次是真正的光線方向了)通過GLSL內置的reflect函數計算出反射光線,然後用反射光線乘以視線方向,從而獲得光照參數,這個光照參數還要進行一次冪操作,之一要多少次冪和光線強度有關,被稱作發光值,發光值越高,反射光的能力越強,散射的越少,高光點越小,下圖就是不同高光值得影響

       cocos2d-x並沒有進行這部分的光照計算,基本採用的都是反射光的計算方法,在聚光燈和點光源的處理上就是乘以不同的attenuation,它們的具體算法會在下一篇中計算,將不同的光照影響加在一起,就得到物體最終顯示的顏色。

       下一篇將分析不同的發光體。

       能力不足,水平有限,如有錯誤,歡迎指出。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章