(自用)learnOpenGL学习总结-光照-Color And Basic Lighting

从光照开始,我都会把每一次的学习内容都记录下来,不然的话,太久了真的会容易忘记的>_<


Color

这一章简单定义了在OpenGL中颜色是如何mix的,现在有个例子,一个太阳光打在一个红色的物体上,那么我们会看到物体是红色的(废话)。一个物体是红色的,是因为他会吸收除了红色之外的颜色,剩下的光再到我们的眼睛中时就是红色的了。

太阳光vec3(1.0f ,1.0f ,1.0f)*红色物体 vec3(1.0f ,0.0f ,0.0f)=(1.0f ,  0.0f, 0.0f )

很合理对吧,

这也就是之后的基础了,一个光打在物体上,反射的颜色是 光颜色和物体颜色的乘。

#version 330 core
out vec4 FragColor;

uniform vec3 objectColor;
uniform vec3 ambientColor;

void main()
{
    FragColor = vec4(ambientColor * objectColor, 1.0);
}

这里给了个简单的fragmentshader,里面定义了uniform的物体颜色和光颜色,相乘就行。

			glUniform3f(glGetUniformLocation(testShader->ID, "objColor"), 1.0f, 0.5f, 0.31f);
			glUniform3f(glGetUniformLocation(testShader->ID, "ambientColor"), 1.0f, 1.0f, 1.0f);

然后在主程序中修改uniform后看看结果

然后把材质也加上

FragColor = vec4(objColor * ambientColor , 1.0f)*mix(texture(ourTexture,TexCoord),texture(ourFace,TexCoord),mixValue);

得到


Basic Lighting

ok,首先最最重要的就是phong模型,这是一种经验模型,但是非常常用而且实用。

phong Model中包含3部分,环境光ambient,漫反射diffuse,高光specular

环境光ambient的处理最简单,直接把ambientColor与objColor相乘就好。

漫反射diffuse 需要两个参数,1.法向量,2.光线的方向,然后将这两个点乘就好,但是需要注意的是点乘之前一定要normalize!!!

那么,点乘得到的是一个标量,用这个标量与光颜色相乘就能得到漫反射颜色。

	vec3 lightDir = normalize( lightPos - FragPos );
	vec3 diffuse = max(dot(lightDir,Normal),0) * lightColor ;//漫反射量
	FragColor = vec4(  ambientColor*objColor + diffuse *objColor, 1.0f);

ok,可以注意到的是这里有个max。可以想象一个画面,一束光如果和平面法向量夹角大于90度,那么就代表没有打到这个平面,也就是这个时候光的作用为0.max的目的就是这个,如果两个向量角度大于90度,点乘得到的是负数,那么就消除它。

镜面反射/高光反射 specular

我们经常会看到一个在灯下的物体上有一块圆型的光斑,这个就是高光。那么,我们什么时候,又或者说什么角度可以看到高光。上面这幅图可以告诉我们,当我们人眼与灯的那个夹角的中位线刚刚好就是法向量的时候,我们就能看到高光,偏了就会减弱。(可以自己想象一下)

所以,我们计算高光项就是基于此,一般来说,判断法向量是中位线 会比 判断人眼方向是反射方向 要好判断的多。 (因为 我有 lightDir 和 eyeDir,直接把两个向量相加然后除以2就可以了),之后的偏离多少就交给dot点乘就好了。

这里的代码还是跟着教程来,可以通过reflect()函数得到橘色向量,然后dot就好。

这里可以看到出现了pow(),后面的32表示的是反光度,反光度越高,就代表高光点越集中。

	vec3 reflectVec = reflect( -lightDir,Normal);
	vec3 cameraDir = normalize(cameraPos - FragPos );
	vec3 specular = pow(max(dot(reflectVec,cameraDir),0),32)*lightColor;

一个比较重要的事情

zzai在vertexShader中,我们有两个参数需要传递给fragmentShader,一个是顶点位置,一个是法向量。

顶点位置需要乘上Model变换转变成世界空间中的位置,但是法向量不能直接乘。

只需要进行处理才可以。

这里看到存在求逆的过程,这个过程是在计算机中尽量避免的。所以在后面会通过法线矩阵来实现。


练习

1.尝试使用sin或cos函数让光源在场景中来回移动。观察光照随时间的改变能让你更容易理解冯氏光照模型。

glUniform3f(glGetUniformLocation(testShader->ID, "lightPos"), 20.0f * cos(glfwGetTime()), 10.0f, 20.0f * sin(glfwGetTime()));

把main中的lightPos中x,z改了就行。这样就是一个高度10,半径20的一个轨迹在运动的光。

2.在观察空间(而不是世界空间)中计算冯氏光照

3.尝试实现一个Gouraud着色(而不是冯氏着色)

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值