生活随笔
收集整理的這篇文章主要介紹了
(转)光照模型及cg实现
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
?
經(jīng)典光照模型(illumination model)
物體表面光照顏色由入射光、物體材質(zhì),以及材質(zhì)和光的交互規(guī)律共同決定。
由于環(huán)境光給予物體各個點(diǎn)的光照強(qiáng)度相同,且沒有方向之分,所以在只有環(huán)境光的情況下,同一物體各點(diǎn)的明暗程度均一樣。
?
環(huán)境光是對光照現(xiàn)象的最簡單抽象,局限性很大。它僅能描述光線在空間中無方向并均勻散布時的狀態(tài)。
?
還有一種是平行光,即光線都從同一個方向照射。通過模擬方向光和物體表面的交互模式,可以渲染出具有高真實(shí)感(明暗變化、鏡面反射等)的三維場景。
?
漫反射與Lambert 模型
?
粗糙的物體表面向各個方向等強(qiáng)度地反射光,這種等同地向各個方向散射的現(xiàn)象稱為光的漫反射(diffuse reflection)
?
對于僅暴露在環(huán)境光下的朗伯反射體,可以用公式(9-1)表示某點(diǎn)處漫反射的光強(qiáng):?
?
其中Ia表示環(huán)境光強(qiáng)度(簡稱光強(qiáng)),dk(0<dk<1)為材質(zhì)對環(huán)境光的反射系數(shù),Iam是漫反射體與環(huán)境光交互反射的光強(qiáng)。
?
當(dāng)方向光照射到朗伯反射體上時,漫反射光的光強(qiáng)與入射光的方向和入射點(diǎn)表面法向夾角的余弦成正比,這稱之為Lambert 定律,并由此構(gòu)造出Lambert漫反射模型:
?
?
I是點(diǎn)光源強(qiáng)度,θ是入射光方向與頂點(diǎn)法線的夾角,稱為入射(0≤θ ≤90°)
?
若N 為頂點(diǎn)單位法向量,L 表示從頂點(diǎn)指向光源的單位向量(注意,是由頂點(diǎn)指向光源,不要弄反了),則cosθ 等價于N 與L 的點(diǎn)積。所以公式(9-2)可以表示為公式(9-3):
?
?
綜合考慮環(huán)境光和方向來,Lambert 光照模型可寫為:
?
?
漫反射渲染
?
漫反射光照模型頂點(diǎn)著色程序(使用結(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);??????float3?ambientColor?=?Kd*globalAmbient;????posOut.color.xyz?=?diffuseColor+ambientColor;????posOut.color.w?=?1;??}?? ??
?
鏡面反射與Phong 模型
Lambert 模型較好地表現(xiàn)了粗糙表面上的光照現(xiàn)象,但表現(xiàn)不出光澤,主要原因是該模型沒有考慮這些表面的鏡面反射效果。
?
?
Phong Bui Tuong 提出一個計算鏡面反射光強(qiáng)的經(jīng)驗(yàn)?zāi)P?#xff0c;稱為phong模型,認(rèn)為鏡面反射的光強(qiáng)與反射光線和視線的夾角相關(guān),其數(shù)學(xué)表達(dá)如公式(9-5)所示:
?
?
k 為材質(zhì)的鏡面反射系數(shù), Ns是高光指數(shù),V表示從頂點(diǎn)到視點(diǎn)的觀察方向, R代表反射光方向。
?
高光指數(shù)反映了物體表面的光澤程度。Ns越大,反射光越集中,當(dāng)偏離反射方向時,光線衰減的越厲害,只有當(dāng)視線方向與反射光線方向非常接近時才能看到鏡面反射的高光現(xiàn)象,此時,鏡面反射光將會在反射方向附近形成亮且小的光斑; Ns越小,表示物體越粗糙,反射光分散,觀察到的光斑區(qū)域小,強(qiáng)度弱。
?
反射光的方向R 可以通過入射光方向L(從頂點(diǎn)指向光源)和物體法向量N求出:
?
?
phong 模型渲染
?
phong 光照模型的頂點(diǎn)著色程序?qū)崿F(xiàn)
?
[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?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 光照模型片段著色實(shí)現(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;??};?? ??
?
首先將幾何頂點(diǎn)的模型空間坐標(biāo)轉(zhuǎn)換為用于光柵化的投影坐標(biāo);然后將頂點(diǎn)模型坐標(biāo)和法向量模型坐標(biāo)賦值給綁定TEXCOORD 語義詞的變量,用于傳遞到片段著色程序中。
?
phong 光照模型頂點(diǎn)著色程序
?
[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 和視點(diǎn)方向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)容還不錯,歡迎將生活随笔推薦給好友。