第九章 opengl之光照(光照贴图)
创始人
2024-05-30 13:36:39
0

OpenGL

  • 光照贴图
    • 漫反射贴图
    • 镜面光贴图

光照贴图

一个物体的不同部分是不同的材质,那么会有不同的环境光和漫反射颜色表现。

漫反射贴图

原理就是:纹理。
是对同样的原理使用了不同的名字:其实都是使用一张覆盖物体的图像,让我们能够逐片段索引其独立的颜色值。是一个表现了物体所有的漫反射颜色的纹理图像。

在着色器中使用漫反射贴图的方法和纹理教程中是完全一样的。但这次我们会将纹理储存为Material结构体中的一个sampler2D。我们将之前定义的vec3漫反射颜色向量替换为漫反射贴图。
补充:sampler2D是所谓的不透明类型(Opaque Type),也就是说我们不能将它实例化,只能通过uniform来定义它。如果我们使用除uniform以外的方法(比如函数的参数)实例化这个结构体,GLSL会抛出一些奇怪的错误。这同样也适用于任何封装了不透明类型的结构体。

也需要移除环境光材质颜色向量,因为环境光颜色在几乎所有情况下都等于漫反射颜色,所以我们不需要将它们分开储存:

struct Material {sampler2D diffuse;vec3      specular;float     shininess;
}; 
...
in vec2 TexCoords;

在片段着色器中再次需要纹理坐标,所以我们声明一个额外的输入变量。接下来我们只需要从纹理中采样片段的漫反射颜色值即可:

vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));

将环境光的材质颜色设置为漫反射材质颜色同样的值:

vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));

补充:
GLSL内建的texture()函数,可以得到一个纹理颜色,第一个参数纹理采样器,第二个参数纹理坐标。

上述这就是使用漫反射贴图的全部步骤了。
下面需要使用纹理坐标更新顶点数据,将它们作为顶点属性传递到片段着色器,加载材质并绑定材质到合适的纹理单元。
更新顶点着色器来以顶点属性的形式接受纹理坐标,并将它们传递到片段着色器中:

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoords;
...
out vec2 TexCoords;void main()
{...TexCoords = aTexCoords;
}

还需要更新两个VAO的顶点属性指针来匹配新的顶点数据,并加载箱子图像为一个纹理。在绘制箱子之前,我们希望将要用的纹理单元赋值到material.diffuse这个uniform采样器,并绑定箱子的纹理到这个纹理单元:

lightingShader.setInt("material.diffuse", 0);
...
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, diffuseMap);

镜面光贴图

想要让物体的某些部分以不同的强度显示镜面高光。
可以使用一个专门用于镜面高光的纹理贴图。这也就意味着我们需要生成一个黑白的(如果你想得话也可以是彩色的)纹理,来定义物体每部分的镜面光强度:
镜面高光的强度可以通过图像每个像素的亮度来获取。镜面光贴图上的每个像素都可以由一个颜色向量来表示,比如说黑色代表颜色向量vec3(0.0),灰色代表颜色向量vec3(0.5)。在片段着色器中,我们接下来会取样对应的颜色值并将它乘以光源的镜面强度。一个像素越「白」,乘积就会越大,物体的镜面光分量就会越亮。

要保证正确地加载图像并生成一个纹理对象。由于我们正在同一个片段着色器中使用另一个纹理采样器,我们必须要对镜面光贴图使用一个不同的纹理单元,所以我们在渲染之前先把它绑定到合适的纹理单元上:

lightingShader.setInt("material.specular", 1);
...
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, specularMap);

接下来更新片段着色器的材质属性,让其接受一个sampler2D而不是vec3作为镜面光分量:

struct Material {sampler2D diffuse;sampler2D specular;float     shininess;
};

采样镜面光贴图,来获取片段所对应的镜面光强度:

vec3 ambient  = light.ambient  * vec3(texture(material.diffuse, TexCoords));
vec3 diffuse  = light.diffuse  * diff * vec3(texture(material.diffuse, TexCoords));  
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
FragColor = vec4(ambient + diffuse + specular, 1.0);

通过使用镜面光贴图我们可以可以对物体设置大量的细节,比如物体的哪些部分需要有闪闪发光的属性,我们甚至可以设置它们对应的强度。镜面光贴图能够在漫反射贴图之上给予我们更高一层的控制。

相关内容

热门资讯

张天灵安卓系统,引领智能生活新... 你知道吗?最近在手机圈里,有个名字可是火得一塌糊涂,那就是张天灵安卓系统。没错,就是那个让无数手机用...
安卓系统使用官方文档,系统架构... 你有没有想过,你的安卓手机里那些神奇的软件和功能,其实都是基于一个强大的系统——安卓系统?没错,就是...
安卓系统哪个系列最好,探索最佳... 你有没有想过,手机里的安卓系统就像是一群各具特色的英雄,每个系列都有它的独门绝技。那么,问题来了,安...
安卓修改系统时间设置,安卓系统... 你有没有发现,有时候手机上的时间总是和你心中的时间不太一样?是不是有时候你明明觉得才刚过中午,一看手...
安卓系统制裁华为,自主创新之路 你知道吗?最近安卓系统对华为下手了,这可真是让人大跌眼镜啊!华为作为我国科技界的佼佼者,一直以来都备...
安卓系统隐藏扣费,揭秘恶意应用... 你知道吗?在安卓系统的世界里,有时候会有一些小秘密,就像隐藏的宝藏一样,让人意想不到。今天,我就要来...
低安卓系统游戏推荐,盘点那些让... 手机里的游戏是不是已经玩腻了?别急,今天就来给你推荐一些适合低安卓系统运行的游戏,让你的手机焕发第二...
真我是安卓系统嘛,揭秘安卓系统... 亲爱的读者,你是否曾好奇过,自己手中的安卓手机,它的“灵魂”究竟是不是安卓系统呢?这个问题听起来可能...
安卓儿童手表换系统,轻松换新体... 你家的安卓儿童手表是不是已经陪伴了孩子好长一段时间了呢?是不是觉得它有点儿“老态龙钟”,想要给它来个...
王者安卓系统如何退钱,快速返还 你是不是在王者荣耀里花了点小钱,现在想退回来呢?别急,今天就来手把手教你如何用王者安卓系统退钱,让你...
安卓系统instagram哪里... 你有没有发现,最近你的手机里少了点什么?没错,就是那个让你每天刷到停不下来的社交神器——Instag...
安卓系统怎样用苹果系统,系统切... 你是不是也和我一样,对安卓系统和苹果系统都情有独钟呢?有时候,手头上的安卓设备用得正得心应手,突然又...
平板安卓系统价格多少,不同档次... 你有没有想过,拥有一台平板电脑,是不是就能随时随地享受大屏幕的观影体验,或者轻松处理工作上的事情呢?...
日历app推荐安卓系统,生活更... 你有没有发现,时间就像那溜走的沙子,不经意间就悄悄溜走了。想要抓住时间的尾巴,一款好用的日历app可...
山水投影删除安卓系统,基于山水... 你有没有想过,家里的电视屏幕上突然出现一幅幅流动的山水画,美得让你仿佛置身于仙境?这可不是梦,而是现...
安卓怎么换系统版本,轻松切换至... 亲爱的安卓用户们,你是否对手机系统版本升级充满了好奇和期待?想要让你的手机焕然一新,体验更流畅的性能...
安卓系统 定时锁屏,智能守护您... 你有没有发现,手机这玩意儿,简直就是现代生活的得力助手,但有时候,它也像个调皮的小家伙,时不时地给你...
小米手机安卓系统rom,功能与... 你有没有发现,最近小米手机的热度又上来了?没错,就是那个以性价比著称的小米。今天,咱们就来聊聊小米手...
安卓8.0系统自动重启,安卓8... 最近你的安卓手机是不是也遇到了一个让人头疼的问题?没错,就是那个让人抓狂的自动重启!是不是每次正在关...
安卓导航进入系统设置,解锁个性... 亲爱的手机控们,你是否曾在某个午后,手捧着你的安卓手机,突然想探索一下它的深处,看看那些隐藏在系统设...