1.lambert模型(漫反射)
環境光:
iambdiff = kd*ia
其中ia 表示環境光強度,kd(0
方向光:
ildiff = kd * il * cos(θ)
其中il是點光源強度,θ是入射光方向與頂點法線的夾角,稱入射角(0<=a<=90°),ildiff是漫反射體與方向光互動反射的光強,若 n為頂點單位法向量,l表示從頂點指向光源的單位向量(注意頂點指向光源),則cos(θ)等價於dot(n,l),故又有:
ildiff = kd * il * dot(n,l)
最後綜合環境光和方向光源,lambert光照模型可以寫成:
idiff = iambdiff + ildiff = kd * ia + kd * il * dot(n,l)
2.phong模型(鏡面反射)
phong模型認為鏡面反射的光強與反射光線和視線的夾角相關:
ispec = ks * il * ( dot(v,r) )^ns
其中ks 為鏡面反射係數,ns是高光指數,v表示從頂點到視點的觀察方向,r代表反射光方向。由於反射光的方向r可以通過入射光方向l(從頂點指向光源)和物體的法向量求出,
r + l = 2 * dot(n, l) * n 即 r = 2 * dot(n,l) * n - l
所以最終的計算式為:
ispec = ks * il * ( dot(v, (2 * dot(n,l) * n – l ) )^ns
3.blinn-phong光照模型(修正鏡面光)
blinn-phong是乙個基於phong模型修正的模型,其公式為:
ispec = ks * il * ( dot(n,h) )^ns
其中n是入射點的單位法向量,h是光入射方向l和視點方向v的中間向量,通常也稱之為半形向量(半形向量被廣泛用於各類光照模型,原因不但在於半形向量蘊含的資訊價值,也在於半形向量是很簡單的計算:h = (l + v) / |l + v| )。
4.rendering equation(全域性光照模型)
rendering equation 是kajia在2023年提出的,
lo(x, wo) = le(x, wo) + ∫fr(x, wi, wo) li(x, wi) dot(n, wi) dwi
其中x表示入射點,lo(x, wo)即從物體表面x點,沿方向wo反射的光強,le(x, wo)表示從物體表面x以方向wo 發射出去的光強,該值僅對自發光體有效,fr(x, wi, wo)為,入射光線方向為wi, 照射到點x上,然後從wo方向發射出去的brdf值,li(x, wi)為入射方向為wi照射到點x上的入射光強,n表示點x處的法向量,然後對入射方向進行積分(因為光線入射的方向是四面八方的,積分的意義是對每個方向進行一遍計算後相加),計算的結果就是全域性光照的輻射率。
對於單個點光源照射到不會自發光的物體上,公式可以簡化成:
lo(x, wo) = fr(x, wi, wo) li(x, wi) dot(n, wi)
這個公式非常有用,通常會將該公式分解為漫反射表示式和鏡面表示式之和。對於漫反射表面,brdf可以忽略不計,因為它總是返回某個恆定值,所以可以寫成如下形式:
lo(x, wo) = idiff + frs(x, wi, wo) li(x, wi) dot(n, wi)
其中idiff表示漫反射分量,使用公式的計算方法,frs(x, wi, wo)表示鏡面反射的brdf函式,前面的phong高光模型,其實是rendering equation在單一光源下針對理想鏡面反射的特定推導,對於phong高光而言:
frs(x, wi, wo) = ks (dot(n, h)^ns / dot(n, wi)
幾種光照模型的比較
lambert 模型能夠較好地表現粗糙表面上的光照現象,如石灰牆,紙張等等,但是在渲染金屬材質製成的物體時,則會顯得呆板,表現不出光澤,主要原因是其沒有考慮到鏡面反射效果,所以phong模型對其進行了很好的補充。由於blinn-phng光照模型混合了lambert的漫射部分和標準的高光,渲染效果有時會比 phong高光更柔和,有些人認為phong光照模型比blinn-phong更加真實,實際上也是如此,blinn-phong渲染效果要更加柔和一些,但是由於blinn-phong的光照模型省去了計算反射光線方向向量的兩個乘法運算,速度更快,因此成為許多cg軟體中預設的光找渲染方法,此外它也繼承在了大多數圖形晶元中,用以產生實時的快速渲染。在opengl和direct3d渲染管線中,blinn-phong就是預設的渲染模型。 rendering equation是基於物理光學的模型,其對於觀察方向上的輻射率進行了本質上的量化,phong模型只是其特定brdf的推導。
struct vertexscreen
float4 oposition : position;
float4 objectpos : texcoord0;
float4 objectnormal : texcoord1;
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;
Unity Shader中實現漫反射光照模型
逐頂點漫反射光照模型。頂點著色器的最基本任務就是把頂點位置從模型位置轉換到裁剪空間中。pos mul unity matrix mvp,pos2 pos為float4型別,pos2為float4型別。其中pos2要獲得模型空間座標 可在定義時 float4 pos2 position 計算漫反射光照...
57 請簡述保護類的屬性
如何保護類的屬性?1 把屬性定義為私有屬性,即在屬性名的前面加上兩個下劃線 2 新增用於設定或者獲取屬性值的兩個方法供外界呼叫。如果有乙個物件,當需要對其進行修改屬性時,有2種方法 為了更好的儲存屬性安全,即不能隨意修改,一般的處理方式為 新增乙個可以呼叫的方法,供呼叫 變數前的單下劃線表示表面上私...
請簡述以下兩個for 迴圈的優缺點
今天筆試時候遇到乙個問題,找到相似的。for i 0 i if condition else 優點 程式簡潔 缺點 多執行了n 1次邏輯判斷,並且打斷了迴圈 流水線 作業,使得編譯器不能對迴圈進行優化處理,降低了效率。優點 迴圈的效率高 缺點 程式不簡潔 看到網路上還有一種回答 前者 優點 程式簡潔...