OpenGL ES on iOS 光照高階

2021-09-11 12:40:19 字數 4528 閱讀 7391

本文記錄我記錄我學習 座標體系和矩陣轉換的過程,加深學習便於後續查詢,可能有些描述不夠準確,或者內容不夠充實,還請多多指正,共同學習.

在基礎光照時,學習了光照對物體的作用,也就相當於物體的材質,這次主要說 現實生活中的光源

當光源無限遠時,從其發射過來的的光可以近似的看做平行光(例如太陽);這時 光線的方向都是一致的.

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;

//光線衰弱

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));

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);

複製**

聚光源的效果就相當於 手電筒,好比朝向指定範圍的點光源~

在使用聚光源時,就需要指定 聚光朝向spotdir,和切光角ϕ. 當光源指向點的向量和spotdir的夾角大於ϕ時,則無法被光源照射到.

但是這樣的明暗邊界十分明顯,效果不夠真實

這時,我們就需要將過渡邊緣平滑,這時 我們就需要引入兩個引數, 內錐角和外錐角. 外錐角就是切光角,而內錐角以內不需要平滑效果, 內錐角和外錐角之間需要平滑過度. **如下

/(一些複雜的計算操作 應該讓cpu做,提高效率,不變的量也建議外部傳輸,避免重複計算)

float

incutoff = cos(radians(10.0f)); //內錐角cos值

float outcutoff = cos(radians(15.0f)); //外錐角cos值

vec3 spotdir = vec3(-1.2f,-1.0f,-2.0f); //聚光朝向

float theta = dot(lightdir,normalize(-spotdir)); //光源指向物體的向量 和 聚光朝向的 cos值

float epsilon = incutoff - outcutoff; //內外錐角cos差值

//clamp(a,b,c);若bfloat intensity = clamp((theta - outcutoff)/epsilon,0.0,1.0);

複製**

在現實情況中,光源發出的光線是會隨著距離的增長而衰減的, 而且也不是線性衰減的,表現為在距離光源近的這段距離衰減的較快, 在距離光源較遠的情況下衰減較慢. 通常使用這個公式來模擬光線衰減.

常數項通常保持為1.0,它的主要作用是保證分母永遠不會比1小,否則的話在某些距離上它反而會增加強度,這肯定不是我們想要的效果 一次項會與距離值相乘,以線性的方式減少強度 二次項會與距離的平方相乘,讓光源以二次遞減的方式減少強度。二次項在距離比較小的時候影響會比一次項小很多,但當距離值比較大的時候它就會比一次項更大了

float lfdistance = length(lightpo - fragpo);

float lightweakpara = 1.0/(constantpara + linearpara * lfdistance + quadraticpara * (lfdistance*lfdistance));

vec3 res = (ambient + diffuse + specular)*lightweakpara;

複製**

在一張紋理圖中,由於材質不同,所呈現的效果也會有所不同,如同下面這個箱子,金屬邊框和木頭在相同光源下所呈現的1效果肯定有所不同.

這時為了在顯示光照效果時將其區分開來,則需要引入光照貼圖的概念~ 如下圖

在該貼圖中,對應木頭部分為黑色vec3(0.0); 而在金屬邊框部分 則對應的為灰色, 這樣在計算 漫反射或者鏡面時,將其作為參考係數,則可以讓其呈現不同的效果.

vec3 spe = texture(speculartexture,outtexcoord).rgb;   //獲取鏡面光照貼圖

vec3 viewdir = normalize(viewpo - fragpo);

vec3 reflectdir = reflect(-lightdir,outnormal);

float spec = pow(max(dot(viewdir, reflectdir),0.0),spl.reflectance);

vec3 specular = point_specularstrength * spec * spe; //使用光照貼圖紋理

複製**

是可以看出箱子鐵框的鏡面效果 比 木頭的效果要強

OpenGL ES on iOS 基礎光照

本文記錄我記錄我學習 座標體系和矩陣轉換的過程,加深學習便於後續查詢,可能有些描述不夠準確,或者內容不夠充實,還請多多指正,共同學習.乙個沒有alpha通道的顏色可以用乙個3維向量來表示 例如 glm vec3 1.0,1.0,1.0 表示白色.在現實世界中,乙個物體的顏色是它反射的顏色導致的,例如...

簡單光照模型(Lambert 光照模型)

環境光是對光照現像的最簡單抽象,因而侷限性很大。它僅能描述光線在空間中無方向並均勻散布時的狀態。很多情況下,入射光是帶有方向的,比如典型的陽光。如果光照射到比較粗糙的物體表面,如粉筆,由於這些表面從各個方向等強度地反射光,因而從各個視角出發,物體表面呈現相同的亮度,所看到的物體表面某點的明暗程度不隨...

光照與渲染(二) 光照技術

廣義的來說,unity的全域性光照是 實時 或是 預先計算好 的,在某些情況下兩種方法可以結合使用,照出更逼真的場景。本節我們會針對兩種技術的差異優勢和使用時機做個簡單的描述。實時照明 realtime lighting 預設情況下,unity的燈源 直接光源,投射燈,點光源 都是實時的,代表這些燈...