OpenGL ES ????????????光照計算

光照基礎

  • 環境光
  • 漫反射光
  • 鏡面光

光照特性

  • 發射光:由物體自身發光
  • 環境光:環境中充分散射的光,而且無法分辨它的方向
  • 漫反射光:光線來自某個方向,但在物體各個方向反射
  • 鏡面高光:光線來自一個特定的方向,然后在物體表面上以一個特定的方向反射出去
  • 材質屬性

    • ?泛射材質
    • ?漫反射材質?
    • ?鏡面反射材質
    • ?發射材質

    光照計算

    環境光的計算

    1. 環境光的計算
    ? ? ?????環境光 = 光源的環境光顏色 * 物體的材質顏色


    環境光的計算(亮度)

    2. 環境光GLSL實現

    varying vec3 objectColor;
    void main()
    {
    //?至少有%10的光找到物體所有?面
    ?float ambientStrength = 0.1;
    //環境光顏?色
    vec3 ambient = ambientStrength * lightColor;
    //最終顏?色?=?環境光顏?色?*?物體顏?色
    vec3 result = ambient * objectColor;
    ?l_FragColor = vec4(result, 1.0);
    }

    發射光的計算

    ? ? ? ? 發射顏色 = 物體反射材質的顏色

    漫反射光的計算

    ? ??????漫反射顏?色?=?光源的漫反射顏?色?*?物體的漫發射材質顏?色?* DiffuseFactor
    ? ??????DiffuseFactor = max(0,dot(N,L))

    ????????漫反射因子DiffuseFactor?是光線與頂點法線向量的點積

    漫反射


    ? ? ? ? 漫反射光計算代碼實現

    ? ? ? ? ? ? uniform vec3 lightColor;
    ? ? ? ? ? ? ?uniform vec3 lightPo;
    ? ? ? ? ? ? uniform vec3 objectColor;
    ? ? ? ? ? ? uniform vec3 viewPo;
    ? ? ? ? ? ? varying vec3 outNormal;
    ? ? ? ? ? ? //確保法線為單位向量
    ? ? ? ? ? ?vec3 norm = normalize(outNormal); //頂點指向光源單位向量
    ? ? ? ? ? ?vec3 lightDir = normalize(lightPo - FragPo); //得到兩向量的cos值小于0則為0
    ? ? ? ? ? float diff = max(dot(norm, lightDir),0.0); // 得到漫反射收的光源向量
    ? ? ? ? ? vec3 diffuse = diff * lightColor;
    ? ? ? ? ? vec3 result? = diffuse * ojbectColor;
    ? ? ? ? ? gl_FragColor = vec4(result,1.0);

    鏡面光計算


    鏡面光強度與視點位置相關

    N : 平?面法線
    ?I : 入射光線?
    H : 反射光線?
    E : 視線
    ? : 視點與反射光的夾角

    鏡面反射顏色?=?光源的鏡面光的顏色?*?物體的鏡面材質顏色?* SpecularFactor
    SpecularFactor = power(max(0,dot(N,H)),shininess)

    H?:視線向量E?與 光線向量L?的半向量
    dot(N,H):H,N的點積幾何意義,平方線與法線夾角的cos值
    shiniess :??高光的反光度;

    鏡面光計算代碼實現

    //鏡面強度
    float specularStrength = 0.5;
    //頂點指向觀察點的單位向量
    vec3 viewDir = normalize(viewPo - FragPo);
    //求得光線在頂點的反射線(傳入光源指向頂點的向量)
    vec3 reflectDir = reflect(-lightDir ,outNormal);
    //?求得夾角cos值取256次冪 注意?pow(float,float)函數參數類型
    float spec = pow(max(dot(viewDir, reflectDir),0.0),256.0);
    vec3 specular = specularStrength * spec * lightColor;

    光照計算

    ? ??????光照顏色?=(環境顏色?+?漫反射顏色?+?鏡面反射顏色)*?衰減因?

    ? ? ??

    衰減因子

    衰減因子

    衰減因? = 1.0/(距離衰減常量?+?線性衰減常量?*?距離?+ 二次衰減常量?*?距離的平?)

    注意:環境光,漫反射光和鏡面光的強度都會受距離的增大而衰減,只有發射光和全局環境光的強度不會受影響

    衰減因子代碼

    //距離衰減常量
    float constantPara = 1.0f;
    //線性衰減常量
    float linearPara = 0.09f;
    //二次衰減因?
    float quadraticPara = 0.032f;
    //距離
    float LFDistance = length(lightPo - FragPo);
    //衰減因?
    float lightWeakPara = 1.0/(constantPara + linearPara* LFDistance + quadraticPara (LFDistance*LFDistance));

    聚光因子

    聚光燈夾角cos值?= power(max(0,dot(單位光源位置,單位光線向量)),聚光燈指數);

    • 單位光線向量:從光源指向頂點的單位向量?
    • 聚光燈指數:表示聚光燈的亮度程度
    • 公式解讀:單位光源位置 *?單位光線向量點積的聚光燈指數次?。
    增加過渡計算
    聚光燈因? = clamp((外環的聚光燈角度cos值?-?當前頂點的聚光燈角度cos值)/ (外環的聚光燈角度cos值-?內環聚光燈的角度的cos值),0,1);

    聚光燈過度計算代碼實現

    //(?一些復雜的計算操作 應該讓CPU做,提?高效率,不不變的量量也建議外部傳輸,避免 重復計算)
    //內錐?角cos值
    float inCutOff = cos(radians(10.0f));?
    //外錐?角cos值
    float outCutOff = cos(radians(15.0f));?
    //聚光朝向
    vec3 spotDir = vec3(-1.2f,-1.0f,-2.0f);
    //光源指向物體的向量和聚光朝向的cos值
    float theta = dot(lightDir ,normalize(-spotDir));
    ?//內外錐角cos差值
    float epsilon = inCutOff - outCutOff;
    //clamp(a,b,c);若b<a<c則函數返回值為a,若不是則返回最小值b、最大值c
    // (theta - outCutOff)/epsilon 若theta的角度小于內錐角 則其值>=1?若theta的角度大于外錐角 則其值<=0?這樣光線就在內外錐角之間平滑變 化.
    float intensity = clamp((theta - outCutOff)/epsilon, 0.0,1.0);

    光照計算終極公式

    光照顏色?=?發射顏色?+?全局環境顏色?+ (環境顏色?+?漫反射顏色?+?鏡?反射顏色) *?聚光燈效果?*?衰減因?

    平面光計算代碼實現

    //環境因?
    float ambientStrength = 0.3;
    ?//鏡面強度
    float specularStrength = 2.0;
    ?//反射強度
    float reflectance = 256.0;
    //平行光方向
    vec3 paraLightDir = normalize(vec3(-0.2,-1.0,-0.3));
    //環境光
    vec3 ambient = ambientStrength * texture(Texture ,outTexCoord).rgb;
    //漫反射
    vec3 norm = normalize(outNormal);
    vec3 lightDir = normalize(lightPo - FragPo);?
    //當前頂點至光源的的單位向量
    float diff = max(dot(norm ,paraLightDir),0.0);
    vec3 diffuse = diff * lightColor*texture(Texture ,outTexCoord).rgb;
    //鏡面反射
    vec3 viewDir = normalize(viewPo - FragPo);
    vec3 reflectDir = reflect(-paraLightDir ,outNormal);
    float spec = pow(max(dot(viewDir, reflectDir),0.0),reflectance);
    vec3 specular = specularStrength * spec * texture(specularTexture ,outTexCoord).rgb;
    //最終光照顏色
    vec3 res = ambient + diffuse + specular;
    FragColor = vec4(res,1.0);

    點光源計算代碼實現

    float ambientStrength = 0.3;//環境因子
    float specularStrength = 2.0;//鏡面強度
    float reflectance = 256.0;//反射強度
    float constantPara = 1.0f;//常量
    float linearPara = 0.09f;//線性部分因子
    float quadraticPara = 0.032f; //二次項部分因數
    //環境光
    vec3 ambient = ambientStrength * texture(Texture ,outTexCoord).rgb;
    //漫反射
    vec3 norm = normalize(outNormal);
    vec3 lightDir = normalize(lightPo - FragPo); //當前頂點至光源的的單位向量
    //點光源
    float diff = max(dot(norm ,lightDir),0.0); //光源與法線夾?角
    vec3 diffuse = diff * lightColor*texture(Texture ,outTexCoord).rgb;
    //鏡面反射
    vec3 viewDir = normalize(viewPo - FragPo);
    vec3 reflectDir = reflect(-lightDir ,outNormal);
    float spec = pow(max(dot(viewDir, reflectDir),0.0),reflectance);
    vec3 specular = specularStrength * spec * texture(specularTexture ,outTexCoord).rgb;
    //光線衰弱
    float LFDistance = length(lightPo - FragPo);
    float lightWeakPara = 1.0/(constantPara + linearPara * LFDistance + quadraticPara * (LFDistance*LFDistance));
    vec3 res = (ambient + diffuse + specular)*lightWeakPara;?
    FragColor = vec4(res,1.0);

    最后編輯于
    ?著作權歸作者所有,轉載或內容合作請聯系作者
    平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
    • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
      沈念sama閱讀 228,412評論 6 532
    • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
      沈念sama閱讀 98,514評論 3 416
    • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
      開封第一講書人閱讀 176,373評論 0 374
    • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
      開封第一講書人閱讀 62,975評論 1 312
    • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
      茶點故事閱讀 71,743評論 6 410
    • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
      開封第一講書人閱讀 55,199評論 1 324
    • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
      沈念sama閱讀 43,262評論 3 441
    • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
      開封第一講書人閱讀 42,414評論 0 288
    • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
      沈念sama閱讀 48,951評論 1 336
    • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
      茶點故事閱讀 40,780評論 3 354
    • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
      茶點故事閱讀 42,983評論 1 369
    • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
      沈念sama閱讀 38,527評論 5 359
    • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
      茶點故事閱讀 44,218評論 3 347
    • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
      開封第一講書人閱讀 34,649評論 0 26
    • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
      開封第一講書人閱讀 35,889評論 1 286
    • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
      沈念sama閱讀 51,673評論 3 391
    • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
      茶點故事閱讀 47,967評論 2 374

    推薦閱讀更多精彩內容

    • 光照是OpenGL ES里很重要的一部分,下面我們來學習總結一下如何計算不同的光照效果。 光照基礎1?環境光照2?...
      jakeXu閱讀 643評論 1 14
    • 現實世界的光照是極其復雜的,而且會受到諸多因素的影響,這是以目前我們所擁有的處理能力無法模擬的。因此OpenGL的...
      zhongxiaoyue閱讀 735評論 0 1
    • 馮氏光照模型:主要結構由3個元素組成:環境(Ambient)光照、漫反射(Diffuse)光照和鏡面(Specul...
      盾子閱讀 548評論 0 0
    • 光照基礎 1.環境光照(ambient) 2.漫反射光照(diffuse) 3.鏡面光照(specular) 光照...
      ChiLeung閱讀 541評論 0 0
    • 追氣球的少年們目前為止看起來似乎是首戰告捷,大獲全勝。感恩周日,特別是下著淅淅瀝瀝的小雨的涼涼的周日(定基調),不...
      Carol124閱讀 346評論 0 1