OpenGl學習筆記(九)基本光照的使用

基本光照一般指的是馮氏光照,馮氏光照一般由三個元素組成:環境(Ambient)、漫反射(Diffuse)和鏡面(Specular)光照。
如下圖所展示的。
在這裏插入圖片描述
環境光照(Ambient Lighting):即使在黑暗的情況下,世界上也仍然有一些光亮(月亮、一個來自遠處的光),所以物體永遠不會是完全黑暗的。我們使用環境光照來模擬這種情況,也就是無論如何永遠都給物體一些顏色。
在這裏插入圖片描述
環境光照就是說一個問物體本來是什麼顏色,它就會反射什麼樣的光。
計算方式如下:
直接用環境光向量乘以模型顏色得到的它反射了多少的光。

漫反射光照(Diffuse Lighting):模擬一個發光物對物體的方向性影響(Directional Impact)。它是馮氏光照模型最顯著的組成部分。面向光源的一面比其他面會更亮。
在這裏插入圖片描述
漫反射則是說有了一個光源,照射到模型的片段上,然後光源越垂直於模型物體的片段時,該片段獲得的光照也就得到的更多,以此來模擬燈光光射的效果。
計算方式如下:
燈光向量減去片段向量得到燈光方向向量,既灰色的這條向量。
然後再通過燈光方向向量點乘法向量(黃色向量),就能夠得到這個夾角,
然後再用夾角乘以燈光,得到實際片段光照。

鏡面光照(Specular Lighting):模擬有光澤物體上面出現的亮點。鏡面光照的顏色,相比於物體的顏色更傾向於光的顏色。
在這裏插入圖片描述
鏡面反射就是需要多考慮一個相機位置,其反射向量與相機方向向量的夾角越小,鏡面光的作用越大。
計算方式如下:
先計算出燈光的反射向量,
然後是相機的方向向量,相機位置減去片段位置
之後是點乘計算夾角,然後乘以光照,得到當前片段的鏡面光作用程度。

老樣子貼代碼:
先是vertexSource.txt

#version 330 core                     
out vec3 FragPos;//輸出片段着色位置
out vec3 Normal;//輸出法向量
layout(location = 3) in vec3 aPos;	//讀入位置參數						
layout(location = 5) in vec3 normal;//讀入法向量

uniform mat4 modelMat;//模型轉換矩陣
uniform mat4 viewMat;//視角矩陣
uniform mat4 projMat;//投影矩陣

void main(){	
gl_Position = projMat*viewMat*modelMat*vec4(aPos.x, aPos.y, aPos.z, 1.0);//計算各種變換後的模型位置
FragPos=(modelMat*vec4(aPos,1.0f)).xyz;//計算片段着色位置
Normal= (modelMat*vec4(normal,0.0f)).xyz;//計算法向量
}

接着是fragmentSource.txt

#version 330 core			
out vec4 FragColor;		
in vec3 FragPos;//接受片段着色位置
in vec3 Normal;//接受法向量

uniform vec3 objColor;//模型顏色
uniform vec3 lightPos;//燈光位置
uniform vec3 lightColor;//燈光顏色
uniform vec3 CameraPos;//相機位置
void main()				
{
//環境光
vec3 ambientColor=lightColor*0.1f;//進行環境光的計算
//漫反射
vec3 norm=normalize(Normal);//對法向量進行歸一化
vec3 lightDir=normalize(lightPos-FragPos);//計算燈光相對於片段的方向
vec3 diffuse =max(dot(norm,lightDir), 0.0f) * lightColor;//點乘計算光對當前片段的影響,兩個向量的夾角越大,光就越暗,
//鏡面反射
vec3 reflectVec=reflect(-lightDir,norm);//計算出反射光
vec3 CameraVec=normalize(CameraPos-FragPos);//歸一化一定不能掉,計算相機方向向量
vec3 specularColor=pow(max(dot(reflectVec,CameraVec),0.0f),32)*lightColor;//計算當前片段鏡面光作用程度

vec3 result=(ambientColor+diffuse+specularColor)*objColor;//計算實際的光照

FragColor = vec4(result,1.0f);
}	

main.cpp中主要就是改了數據

GLfloat vertices[] = {
	   -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
		0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
		0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
		0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
	   -0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
	   -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,

	   -0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  1.0f,
		0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  1.0f,
		0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  1.0f,
		0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  1.0f,
	   -0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  1.0f,
	   -0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  1.0f,

	   -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,
	   -0.5f,  0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
	   -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
	   -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
	   -0.5f, -0.5f,  0.5f, -1.0f,  0.0f,  0.0f,
	   -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,

		0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,
		0.5f,  0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
		0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
		0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
		0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,
		0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,

	   -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,
		0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,
		0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
		0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
	   -0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
	   -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,

	   -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,
		0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,
		0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
		0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
	   -0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
	   -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f
};

跟着改了對應vertexSource的值

glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);//從vao裏面在0號索引位上拿取三個值
	glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));

	glEnableVertexAttribArray(3);//啓用屬性0,因爲默認是禁用的
	glEnableVertexAttribArray(5);//啓用屬性0,因爲默認是禁用的

然後在將幾個uniform的值給投進去

glUniform3f(glGetUniformLocation(myShader->ID, "objColor"), 1.0f, 0.5f, 0.31f);
glUniform3f(glGetUniformLocation(myShader->ID, "lightColor"), 1.0f, 1.0f, 1.0f);
glUniform3f(glGetUniformLocation(myShader->ID, "lightPos"), 1.2f, 1.0f, 2.0f);
glUniform3f(glGetUniformLocation(myShader->ID, "CameraPos"), myCamera->Position.x, myCamera->Position.y, myCamera->Position.z);

然後效果如下:
在這裏插入圖片描述
注意事項:那些normalize該加的一定要加,否則這個效果啊,會很怪。
兩個normalize卡了我一天。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章