日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

(转)光照模型及cg实现

發(fā)布時間:2025/4/9 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 (转)光照模型及cg实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?

經(jīng)典光照模型(illumination model)

物體表面光照顏色由入射光、物體材質(zhì),以及材質(zhì)和光的交互規(guī)律共同決定。

由于環(huán)境光給予物體各個點的光照強度相同,且沒有方向之分,所以在只有環(huán)境光的情況下,同一物體各點的明暗程度均一樣。

?

環(huán)境光是對光照現(xiàn)象的最簡單抽象,局限性很大。它僅能描述光線在空間中無方向并均勻散布時的狀態(tài)。

?

還有一種是平行光,即光線都從同一個方向照射。通過模擬方向光和物體表面的交互模式,可以渲染出具有高真實感(明暗變化、鏡面反射等)的三維場景。

?

漫反射與Lambert 模型

?

粗糙的物體表面向各個方向等強度地反射光,這種等同地向各個方向散射的現(xiàn)象稱為光的漫反射(diffuse reflection)

?

對于僅暴露在環(huán)境光下的朗伯反射體,可以用公式(9-1)表示某點處漫反射的光強:?

?

其中Ia表示環(huán)境光強度(簡稱光強),dk(0<dk<1)為材質(zhì)對環(huán)境光的反射系數(shù),Iam是漫反射體與環(huán)境光交互反射的光強。

?

當方向光照射到朗伯反射體上時,漫反射光的光強與入射光的方向和入射點表面法向夾角的余弦成正比,這稱之為Lambert 定律,并由此構(gòu)造出Lambert漫反射模型:

?

?

I是點光源強度,θ是入射光方向與頂點法線的夾角,稱為入射(0≤θ ≤90°)

?

若N 為頂點單位法向量,L 表示從頂點指向光源的單位向量(注意,是由頂點指向光源,不要弄反了),則cosθ 等價于N 與L 的點積。所以公式(9-2)可以表示為公式(9-3):

?

?

綜合考慮環(huán)境光和方向來,Lambert 光照模型可寫為:

?

?

漫反射渲染

?

漫反射光照模型頂點著色程序(使用結(jié)構(gòu)體)

?

[cpp]?view plaincopyprint?
  • struct?VertexIn??
  • {??
  • ??float4?position?:?POSITION;??
  • ??float4?normal?:?NORMAL;??
  • };??
  • ??
  • struct?VertexScreen??
  • {??
  • ??float4?oPosition?:?POSITION;??
  • ??float4?color?:?COLOR;??
  • };??
  • ??
  • void?main_v(VertexIn?posIn,??
  • ??out?VertexScreen?posOut,??
  • ??uniform?float4x4?modelViewProj,??
  • ??uniform?float4x4?worldMatrix,??
  • ??uniform?float4x4?worldMatrix_IT,??
  • ??uniform?float3?globalAmbient,??
  • ??uniform?float3?lightPosition,??
  • ??uniform?float3?lightColor,??
  • ??uniform?float3?Kd)??
  • {??
  • ??posOut.oPosition?=?mul(modelViewProj,?posIn.position);??
  • ??float3?worldPos?=?mul(worldMatrix,?posIn.position).xyz;??
  • ??float3?N?=?mul(worldMatrix_IT,?posIn.normal).xyz;??
  • ??N?=?normalize(N);??
  • ??//計算入射光方向??
  • ??float3?L?=?lightPosition?-?worldPos;??
  • ??L?=?normalize(L);??
  • ??//計算方向光漫反射光強??
  • ??float3?diffuseColor?=?Kd*lightColor*max(dot(N,?L),?0);??
  • ??//計算環(huán)境光漫反射光強??
  • ??float3?ambientColor?=?Kd*globalAmbient;??
  • ??posOut.color.xyz?=?diffuseColor+ambientColor;??
  • ??posOut.color.w?=?1;??
  • }??
  • ??

    ?

    鏡面反射與Phong 模型

    Lambert 模型較好地表現(xiàn)了粗糙表面上的光照現(xiàn)象,但表現(xiàn)不出光澤,主要原因是該模型沒有考慮這些表面的鏡面反射效果。

    ?

    ?

    Phong Bui Tuong 提出一個計算鏡面反射光強的經(jīng)驗模型,稱為phong模型,認為鏡面反射的光強與反射光線和視線的夾角相關(guān),其數(shù)學表達如公式(9-5)所示:

    ?

    ?

    k 為材質(zhì)的鏡面反射系數(shù), Ns是高光指數(shù),V表示從頂點到視點的觀察方向, R代表反射光方向。

    ?

    高光指數(shù)反映了物體表面的光澤程度。Ns越大,反射光越集中,當偏離反射方向時,光線衰減的越厲害,只有當視線方向與反射光線方向非常接近時才能看到鏡面反射的高光現(xiàn)象,此時,鏡面反射光將會在反射方向附近形成亮且小的光斑; Ns越小,表示物體越粗糙,反射光分散,觀察到的光斑區(qū)域小,強度弱。

    ?

    反射光的方向R 可以通過入射光方向L(從頂點指向光源)和物體法向量N求出:

    ?

    ?

    phong 模型渲染

    ?

    phong 光照模型的頂點著色程序?qū)崿F(xiàn)

    ?

    [cpp]?view plaincopyprint?
  • struct?VertexIn??
  • {??
  • ??float4?position?:?POSITION;?//?Vertex?in?object-space??
  • ??float4?normal?:?NORMAL;??
  • };??
  • struct?VertexScreen??
  • {??
  • ??float4?oPosition?:?POSITION;??
  • ??float4?color?:?COLOR;??
  • };??
  • void?main_v(?VertexIn?posIn,??
  • out?VertexScreen?posOut,??
  • uniform?float4x4?modelViewProj,??
  • uniform?float4x4?worldMatrix,??
  • uniform?float4x4?worldMatrix_IT,??
  • uniform?float3?globalAmbient,??
  • uniform?float3?eyePosition,??
  • uniform?float3?lightPosition,??
  • uniform?float3?lightColor,??
  • uniform?float3?Kd,??
  • uniform?float3?Ks,??
  • uniform?float?shininess)??
  • {??
  • ??posOut.oPosition?=?mul(modelViewProj,?posIn.position);??
  • ??float3?worldPos?=?mul(worldMatrix,?posIn.position).xyz;??
  • ??float3?N?=?mul(worldMatrix_IT,?posIn.normal).xyz;??
  • ??N?=?normalize(N);??
  • ??//計算入射光方向、視線方向、反射光線方向??
  • ??float3?L?=?normalize(lightPosition?-?worldPos);??
  • ??float3?V?=?normalize(eyePosition?-?worldPos);??
  • ??float3?R?=?2*max(dot(N,?L),?0)*N-L;??
  • ??R?=?normalize(R);??
  • ??//?計算漫反射分量??
  • ??float3?diffuseColor?=?Kd?*?globalAmbient+Kd*lightColor*max(dot(N,?L),?0);??
  • ??//計算鏡面反射分量??
  • ??float3?specularColor?=?Ks?*?lightColor*pow(max(dot(V,?R),?0),?shininess);??
  • ??posOut.color.xyz?=?diffuseColor?+?specularColor;??
  • ??posOut.color.w?=?1;??
  • }??
  • ??

    ?

    ?

    ?

    phong 光照模型片段著色實現(xiàn)的結(jié)構(gòu)體

    ?

    [cpp]?view plaincopyprint?
  • struct?VertexIn??
  • {??
  • ??float4?position?:?POSITION;??
  • ??float4?normal?:?NORMAL;??
  • };??
  • struct?VertexScreen??
  • {??
  • ??float4?oPosition?:?POSITION;??
  • ??float4?objectPos?:?TEXCOORD0;??
  • ??float4?objectNormal?:?TEXCOORD1;??
  • };??
  • ??

    ?

    首先將幾何頂點的模型空間坐標轉(zhuǎn)換為用于光柵化的投影坐標;然后將頂點模型坐標和法向量模型坐標賦值給綁定TEXCOORD 語義詞的變量,用于傳遞到片段著色程序中。

    ?

    phong 光照模型頂點著色程序

    ?

    [cpp]?view plaincopyprint?
  • void?main_v(VertexIn?posIn,??
  • out?VertexScreen?posOut,??
  • uniform?float4x4?modelViewProj)??
  • {??
  • ??posOut.oPosition?=?mul(modelViewProj,?posIn.position);??
  • ??posOut.objectPos?=?posIn.position;??
  • ??posOut.objectNormal?=?posIn.normal;??
  • }??
  • ??

    ?

    phong 光照模型片段著色程序

    ?

    [cpp]?view plaincopyprint?
  • void?main_f(?VertexScreen?posIn,??
  • ??out?float4?color?:?COLOR,??
  • ??uniform?float4x4?worldMatrix,??
  • ??uniform?float4x4?worldMatrix_IT,??
  • ??uniform?float3?globalAmbient,??
  • ??uniform?float3?eyePosition,??
  • ??uniform?float3?lightPosition,??
  • ??uniform?float3?lightColor,??
  • ??uniform?float3?Kd,??
  • ??uniform?float3?Ks,??
  • ??uniform?float?shininess)??
  • {??
  • ??float3?worldPos?=?mul(worldMatrix,?posIn.objectPos).xyz;??
  • ??float3?N?=?mul(worldMatrix_IT,?posIn.objectNormal).xyz;??
  • ??N?=?normalize(N);??
  • ??//計算入射光方向、視線方向、反射光線方向??
  • ??float3?L?=?normalize(lightPosition?-?worldPos);??
  • ??float3?V?=?normalize(eyePosition?-?worldPos);??
  • ??float3?R?=?2*max(dot(N,?L),?0)*N-L;??
  • ??R?=?normalize(R);??
  • ??//?計算漫反射分量??
  • ??float3?diffuseColor?=?Kd?*?globalAmbient+Kd*lightColor*max(dot(N,?L),?0);??
  • ??//計算鏡面反射分量??
  • ??float3?specularColor?=?Ks?*?lightColor*pow(max(dot(V,?R),?0),?shininess);??
  • ??color.xyz?=?diffuseColor?+?specularColor;??
  • ??color.w?=?1;??
  • }??
  • ??

    ?

    ?

    ?

    Blinn-Phong 光照模型

    ?

    phong光照模型中,必須計算V ? R的值,其中R為反射光線方向單位向量,V 為視線方向單位向量,但是在Blinn-phong光照模型中,用N ? H 的值取代了V ? R。Blinn-phong光照模型公式為:

    ?

    ?

    H 是“光入射方向L 和視點方向V 的中間向量”,通常也稱之為半角向量。

    ?

    ?

    Blinn-phong 模型片段著色程序

    ?

    [cpp]?view plaincopyprint?
  • void?main_f(VertexScreen?posIn,??
  • ??out?float4?color?:?COLOR,??
  • ??uniform?float4x4?worldMatrix,??
  • ??uniform?float4x4?worldMatrix_IT,??
  • ??uniform?float3?globalAmbient,??
  • ??uniform?float3?eyePosition,??
  • ??uniform?float3?lightPosition,??
  • ??uniform?float3?lightColor,??
  • ??uniform?float3?Kd,??
  • ??uniform?float3?Ks,??
  • ??uniform?float?shininess)??
  • {??
  • ??float3?worldPos?=?mul(worldMatrix,?posIn.objectPos).xyz;??
  • ??float3?N?=?mul(worldMatrix_IT,?posIn.objectNormal).xyz;??
  • ??N?=?normalize(N);??
  • ??//計算入射光方向/視線方向/半角向量??
  • ??float3?L?=?normalize(lightPosition?-?worldPos);??
  • ??float3?V?=?normalize(eyePosition?-?worldPos);??
  • ??float3?H?=?normalize(L?+?V);??
  • ??//?計算漫反射分量??
  • ??float3?diffuseColor?=?Kd?*?globalAmbient+Kd*lightColor*max(dot(N,?L),?0);??
  • ??//計算鏡面反射分量??
  • ??float3?specularColor?=?Ks?*?lightColor*pow(max(dot(N,?H),?0),?shininess);??
  • ??color.xyz?=?diffuseColor?+?specularColor;??
  • ??color.w?=?1;??
  • }??
  • ????

    ?

    ?

    ?

    ?

    http://blog.csdn.net/doctorsc/article/details/6287059?reload

    轉(zhuǎn)載于:https://www.cnblogs.com/aminxu/p/4274856.html

    總結(jié)

    以上是生活随笔為你收集整理的(转)光照模型及cg实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。