【OpenGL学习】光照贴图

news2025/1/17 4:12:28

光照贴图

上节中我们给物体添加了材质,使得物体能够对光照做出不同的反应,但是有个问题就是,使用该种材质的物体,只能够表现出我们所定义的一种性质,而实际生活中我们的一个物体往往具有多种材质,因此本节中我们使用漫反射贴图和镜面反射贴图对物体的漫反射分量和镜面反射分量有着更为精确的控制。

一、漫反射贴图

漫反射贴图允许我们对物体的每个点单独指定漫反射颜色。比如我们想让之前的立方体表面看起来像一个木箱子,就可以用下面这张帖图:
在这里插入图片描述

可以通过纹理采样来获得该点所对应的漫反射颜色,首先在material 结构体中创建一个采样器 sampler2D 来替换之前创建的 vec3 变量 diffuse:

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

同时由于环境光照的颜色和漫反射颜色相同,所以我们移去了环境光照分量。此外,我们还需要获得每一个片元对应的纹理坐标,因此在修改顶点数组之后,重新指定GPU内存布局:

layout(location = 0) in vec3 a_position;
layout(location = 1) in vec3 a_normal;
layout(location = 2) in vec2 a_texcoord;

out vec3 v_normal;
out vec3 v_world_pos;
out vec2 v_texcoord;

记得去更新两个VAO的顶点属性指针来匹配新的顶点数据,然后可以将原来 diffuse 变量位置的内容替换为 :

vec3 ambient_color = light.ambient * texture(material.diffuse, v_texcoord).rgb;
vec3 diffuse_color = light.diffuse * max(0.0, dot(normal, light_dir)) * texture(material.diffuse, v_texcoord).rgb;

还需要做的一件事就是给当前的纹理绑定纹理单元,然后赋值到 material.diffuse 采样器:

box_shader.set_int("material.diffuse", 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, diffuse_map);

稍稍运行看一下结果:

在这里插入图片描述

此时我们的立方体看上去就像一个木箱子了,这是因为漫反射贴图就像是一张画布一样贴在了立方体的表面。

二、镜面光贴图

镜面光贴图就是能够对物体表面的高光部分进行精准控制的贴图,就比如上面的立方体箱子当中,我们希望木头的部分没有镜面反射,金属的部分有镜面反射,我们就可以利用下面这张帖图:

img

和之前的操作一样,我们也对镜面高光贴图进行采样,因此修改之前 shader 中的 specular 变量为 samper2D:

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

设置全局变量并绑定纹理单元:

		box_shader.set_int("material.specular", 1);	
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, specular_map);

重新计算镜面高光部分:

	vec3 view_dir = normalize(view_pos - v_world_pos);
	vec3 reflect_dir = reflect(-light_dir, normal);
	vec3 specular_color = light.specular * pow(max(dot(view_dir, reflect_dir), 0.0), material.shininess) * texture(material.specular, v_texcoord).rgb;
	

运行结果是这样的:

在这里插入图片描述

这次镜面高光只在金属部分出现了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/197963.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一文了解jquery

簡述本文主要介紹jquery的重要語法功能,如選擇器,dom操作,事件等處理操作什麼jquery?jquery由美国人John Resig(约翰莱西格)于2006年创建 ,是目前最流行的JavaScript程序库。以輕量,代碼簡潔&am…

windows快速切换jdk版本号

前言 因为老项目和新项目的需要,在电脑上需要切换jdk1.8和jdk17(其它版本jdk同样可以切换)。网上有修改配置文件的方式,但是感觉比较繁琐,后来找到了通过bat文件和环境变量来快速切换jdk环境的方法。这里记录分享出出…

rclone挂载webdav详细步骤(含脚本)

挂载说明 文章目录挂载说明文件下载地址:文件夹及文件说明windows安装、配置和挂载操作步骤安装新建连接配置挂载开机自启linux安装、配置和挂载操作步骤安装新建连接配置,见 [链接新建连接配置](#新建连接配置)挂载linux开机自启文件下载地址: 文件下载…

如何实现前端全屏

前言 最近有个需求是要求免登录自动打开看板,然后全屏并播放视频。当然最后自动全屏并播放视频没有实现,写这篇文章是为了记录一下踩的坑。 全屏 网上有挺多现成的组件的,这里就不介绍了,可以自行百度。这里只说通过原生的方法…

手机更换电池-小米8se操作步骤

目录 准备工具: 步骤: 注意事项: 准备工具: 需要更换电池的手机电池背胶(左上蓝色)缠胶棍(手机左边)小螺丝刀新电池卡针后盖拆卸片(右上三角)吸盘后盖背胶 …

Cesium 点位聚合

实现效果 实现方式 通过 new Cesium.EntityCluster(options) 接口对象实现而 new Cesium.DataSource() 有成员变量 clusteringclustering 类型是 EntityCluster代码实现,基于 vue 前端框架 这里使用的是 cesium 沙盒演示中自带的数据进行实现 加载数据 getKMLDTSource() {let o…

cnetsdk:.NET OCR SDK-支持中文-Crack

产品概览 .NET OCR SDK 许可证和价格 OCR SDK 兼容性 CnetSDK .NET OCR Scanner SDK兼容.NET Framework 4.0及以上版本。此 OCR 库软件可用于在任何 CPU 上进行 .NET OCR Windows 和基于服务器的应用程序开发。我们为 x86 和 x64 系统提供 OCR 库解决方案。 OCR 图像格式 这个 …

[学习笔记]黑马程序员-Hadoop入门视频教程

文章目录参考资料大数据导论企业数据分析方向数据分析基本流程步骤明确分析的目的和思路数据收集数据处理数据分析数据展现报告攥写大数据时代大数据定义大数据的5V特征参考资料 黑马程序员大数据Hadoop入门视频教程,适合零基础自学的大数据Hadoop教程 目录 大数据…

C++ 面试题-设计模式类问题(万余字总结)

C 面试题-设计模式类问题1 、说说什么是单例设计模式,如何实现2、 简述一下单例设计模式的懒汉式和饿汉式,如何保证线程安全3、 请说说工厂设计模式,如何实现,以及它的优点4 、请说说装饰器计模式,以及它的优缺点5 、请…

数据挖掘,计算机网络、操作系统刷题笔记40

数据挖掘,计算机网络、操作系统刷题笔记40 2022找工作是学历、能力和运气的超强结合体,遇到寒冬,大厂不招人,可能很多算法学生都得去找开发,测开 测开的话,你就得学数据库,sql,orac…

TCP协议面试灵魂12 问(三)

等待2MSL的意义 如果不等待会怎样? 如果不等待,客户端直接跑路,当服务端还有很多数据包要给客户端发,且还在路上的时候,若客户端的端口此时刚好被新的应用占用,那么就接收到了无用数据包,造成…

C++高级教程——C++ 异常处理

C 异常处理C 异常处理抛出异常捕获异常C 标准的异常定义新的异常C 异常处理 异常是程序在执行期间产生的问题。C 异常是指在程序运行时发生的特殊情况,比如尝试除以零的操作。 异常提供了一种转移程序控制权的方式。C 异常处理涉及到三个关键字:try、c…

【Linux】gdb的使用

文章目录🎪 Linux下gdb的使用🚀1.gdb调试准备🚀2.gdb指令集🚀3.gdb指令演示⭐3.1 展示源文件代码⭐3.2 断点与多步调试操作⭐3.3 常用操作指令🎪 Linux下gdb的使用 GDB 全称“GNU symbolic debugger”,是一…

dp(十)* 0-1背包与完全背包的组合数问题 搞清组合数与排列数

目录 兑换零钱(二)_牛客题霸_牛客网(完全背包) 494. 目标和(0-1背包) 分割等和子集_牛客题霸_牛客网 兑换零钱(二)_牛客题霸_牛客网(完全背包) 描述 给定一个整数数组 nums 表示不同数额的硬币和一个正…

拉伯证券|社会消费复苏将是2023年主旋律

安排指出,兔年新年黄金周社会消费平稳复苏。全国范围看,依据国家税务总局增值税发票数据,2023年新年黄金周(1月21日-27日,阴历岁除至正月初六),全国消费相关工作销售收入同比2022年新年假日添加…

Qt 进程(基本用法)

进程的使用情况: 运行的当前的应用中调用外部程序来实现功时调使用到进程。 比如:在你的运行程序中,开启迅雷或开启其他程序QProcess类用来 启动一个外部程序并与之通信QProcess类 常用一些函数: start()…

Pycharm 中Torch安装方法

1.使用自带工具安装依次打开菜单:File->Setting点击号,搜索torch选择1.13.0版本安装安装错误:具体包含很长一段错误记录,如下:Collecting torch1.13.0Downloading https://files.pythonhosted.org/packages/ec/5e/8…

网络协议栈简单设计(tcp)

网络协议栈简单设计(tcp) 接着这篇文章写的 TCP相对于Udp,分为两个部分:连接(三次握手、四次挥手)、交互(数据传输) 三次握手 tcp包结构体定义 依照tcp包头字段定义就行: 注意,…

jenkins配置

ssh配置 选择Manager Jenkins 选择Configure System,进入页面一直拉到底 Remote Directory:是你需要从jenkins服务拷贝到远程应用服务指定的目录 高级:可以配置ssh密码 配置maven,git,jdk 选择 Global Tool Configur…

dpdk无锁队列rte_ring实现分析

1. 概述 rte_ring(以下简称ring)是一个高效率的无锁环形队列,它具有以下特点: FIFO队列长度是固定的,所有指针存放在数组中无锁实现(lockless)多消费者或单消费者出队多生产者或单消费者入队批量(bulk)出队 - 出队N个对象,否则失…