【Overload游戏引擎细节分析】Lambert材质Shader分析

一、经典光照模型:Phong模型

现实世界的光照是极其复杂的,而且会受到诸多因素的影响,这是以目前我们所拥有的处理能力无法模拟的。经典光照模型冯氏光照模型(Phong Lighting Model)通过单独计算光源成分得到综合光照效果,然后添加到材质表面特定的点。冯光照模型的主要由3个部分组成:环境(Ambient)、漫反射(Diffuse)和镜面(Specular)光照。

  1. 环境光照(Ambient Lighting): 即使在黑暗的情况下,世界上也仍然有一些光亮,所以物体永远不会是完全黑暗的。我们使用环境光照来模拟这种情况,也就是无论如何永远都给物体一些颜色。计算这个光照并不涉及任何关于光的方向或人眼观察场景方向。
  2. 漫反射光照(Diffuse Lighting):模拟一个发光物对物体的方向性影响(Directional Impact)。它是冯氏光照模型最显著的组成部分。面向光源的一面比其他面会更亮。Lambert方程是计算漫反射的一种方式。
  3. 镜面光照(Specular Lighting):也成高光项,模拟有光泽物体上面出现的亮点。镜面光照的颜色,相比于物体的颜色更倾向于光的颜色。
    在这里插入图片描述

二、Lambert漫反射模型

兰伯特光照模型是经验模型,主要用于计算漫反射光照。漫反射有以下特点:

  1. 反射强度与观察者的角度没有关系,向任何方向的反射都是一样的;
  2. 反射强度与光线的入射角度有关系,当入射光垂直于物体表面时,光照最强,随着光线与法线夹角变大反射强度逐渐变小。
    在这里插入图片描述

兰伯特定律(Lambert’s law):反射光线的强度与表面法线和光源方向之间夹角的余弦值成正比,夹角越大,受到的光线照射量越少,当夹角大于90度,光线照射物体背面,此时认为光照强度为0。
在这里插入图片描述
在这里插入图片描述
计算公式:
B d = C I c o s ( θ ) = C I ( L ⋅ N ) B_{d}=\mathbf{C} \mathbf{I}cos(\theta) = \mathbf{C} \mathbf{I}(\mathbf{L}\cdot\mathbf{N}) Bd=CIcos(θ)=CI(LN)
其中:
            C—光的颜色
            I —光照强度
            L—光源方向,入射光的反方向,默认已单位化
            N—物体的法向,默认已单位化

三、Overloal创建材料

Overload中在左下角Assert菜单上右键,可以找到创建材料的入口。其提供了Lambert材质,创建完成后,会在Material Editor面板找到其可配置参数。
在这里插入图片描述
Material Setting是渲染管线的配置,比较通用。Shader Setting是其使用的Shader入参,可以看到其可以设置一个漫反射贴图,还可设置漫反射的光颜色。所谓材料就是Shader+unform参数+贴图,其中Shader是其核心计算逻辑。下面就分析一下其使用的Shader。

四、shader分析

Lambert材质使用的Shader在Lambert.glsl文件中,其前半部分是Vertex Shader,后半部分是Fragment Shader,源码如下:

#shader vertex
#version 430 corelayout (location = 0) in vec3 geo_Pos; // 顶点坐标
layout (location = 1) in vec2 geo_TexCoords; // 顶点纹理坐标
layout (location = 2) in vec3 geo_Normal; // 顶点法线layout (std140) uniform EngineUBO // UBO方式传入MVP矩阵
{mat4    ubo_Model;mat4    ubo_View;mat4    ubo_Projection;vec3    ubo_ViewPos;float   ubo_Time;
};out VS_OUT    // 顶点着色器输出
{vec3 FragPos; // 顶点世界坐标系下的坐标vec3 Normal;  // 顶点法线vec2 TexCoords; // 顶点纹理
} vs_out;void main()
{vs_out.FragPos      = vec3(ubo_Model * vec4(geo_Pos, 1.0)); // 使用模型矩阵计算全局坐标系下的坐标vs_out.Normal       = normalize(mat3(transpose(inverse(ubo_Model))) * geo_Normal); // 计算全局坐标系下的法线vs_out.TexCoords    = geo_TexCoords; // 纹理坐标不用变gl_Position = ubo_Projection * ubo_View * vec4(vs_out.FragPos, 1.0); // 计算NDC坐标
}#shader fragment
#version 430 coreout vec4 FRAGMENT_COLOR;in VS_OUT
{vec3 FragPos;vec3 Normal;vec2 TexCoords;
} fs_in;uniform vec4        u_Diffuse = vec4(1.0, 1.0, 1.0, 1.0); // 漫反射光颜色
uniform sampler2D   u_DiffuseMap;   // 漫反射贴图
uniform vec2        u_TextureTiling = vec2(1.0, 1.0); 
uniform vec2        u_TextureOffset = vec2(0.0, 0.0);const vec3 c_lightPosition    = vec3(-9000.0, 10000.0, 11000.0); // 光源位置
const vec3 c_lightDiffuse     = vec3(1.0, 1.0, 1.0);  // 光源强度
const vec3 c_lightAmbient     = vec3(0.3, 0.3, 0.3); // 环境光强度vec3 Lambert(vec3 p_fragPos, vec3 p_normal)
{const float diffuse = max(dot(p_normal, normalize(c_lightPosition - p_fragPos)), 0.0); // L点乘Nreturn clamp(c_lightDiffuse * diffuse + c_lightAmbient, 0.0, 1.0); // 漫反射与环境光叠加
}void main()
{const vec4 diffuse = texture(u_DiffuseMap, u_TextureOffset + vec2(mod(fs_in.TexCoords.x * u_TextureTiling.x, 1), mod(fs_in.TexCoords.y * u_TextureTiling.y, 1))) * u_Diffuse; // 获取贴图颜色FRAGMENT_COLOR = vec4(Lambert(fs_in.FragPos, fs_in.Normal) * diffuse.rgb, diffuse.a);
}

Vertex Shader的入参有顶点坐标、纹理坐标、法线、模型视图投影矩阵。其逻辑很简单,没有特殊操作,计算法线、NDC坐标完事。
Fragment Shader中,先从纹理中获取片元颜色并与设置的环境光颜色相乘,这是最强的光颜色。如果贴图没有设置,那么texture函数返回的是1.0,至于原因前面的文章中分析过。函数Lambert是核心计算逻辑,包含了Lambert计算公式,其先计算L,在与法线点乘,最终结果就是 c o s ( θ ) cos(\theta) cos(θ)。漫反射的光强度与环境光强度都是写死的。两者累计,用clamp保证最终结果在0到1之间,修正了 c o s ( θ ) < 0 cos(\theta) <0 cos(θ)<0的情况。可见这种材质没有高光成分。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

08-React扩展

08-React扩展 1. setState的2种写法 案例&#xff1a; export default class Demo extends Component {state {count: 0}add () > {// 获取当前的值const { count } this.state// 更新状态this.setState({ count: count 1 })console.log(count);}render() {const { coun…

JavaScript从入门到精通系列第二十二篇:JavaScript中的toString方法和JavaScript中的垃圾回收

文章目录 一&#xff1a;toString方法 1&#xff1a;怪异的返回值[object Object] 2&#xff1a;打印对象成为一个JSON 二&#xff1a;垃圾回收&#xff08;GC&#xff09; 1&#xff1a;垃圾回收概念 2&#xff1a;JS当中的垃圾回收机制 3&#xff1a;JS中的垃圾回收算…

基于厨师优化的BP神经网络(分类应用) - 附代码

基于厨师优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于厨师优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.厨师优化BP神经网络3.1 BP神经网络参数设置3.2 厨师算法应用 4.测试结果&#xff1a;5.M…

基于ssm的旅游管理系统

功能如下图所示 摘要 基于SSM框架的旅游管理系统代表了信息技术在旅行业中的崭新机遇&#xff0c;为旅行企业提供了强大的工具&#xff0c;以应对现代旅游市场的复杂挑战。这个系统的研发和实施具有广泛的研究意义&#xff0c;它深刻影响了旅游业的发展&#xff0c;具体表现如下…

自然语言处理---Transformer机制详解之GPT模型介绍

1 GPT介绍 GPT是OpenAI公司提出的一种语言预训练模型.OpenAI在论文<< Improving Language Understanding by Generative Pre-Training >>中提出GPT模型.OpenAI后续又在论文<< Language Models are Unsupervised Multitask Learners >>中提出GPT2模型.…

【LeetCode刷题(数据结构与算法)】:数据结构中的常用排序实现数组的升序排列

现在我先将各大排序的动图和思路以及代码呈现给大家 插入排序 直接插入排序是一种简单的插入排序法&#xff0c;其基本思想是&#xff1a; 把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中&#xff0c;直到所有的记录插入完为 止&#xff0c;得到一个…

基于协作搜索优化的BP神经网络(分类应用) - 附代码

基于协作搜索优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于协作搜索优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.协作搜索优化BP神经网络3.1 BP神经网络参数设置3.2 协作搜索算法应用 4.测试结果…

图论04-【无权无向】-图的广度优先遍历

文章目录 1. 代码仓库2. 广度优先遍历图解3.主要代码4. 完整代码 1. 代码仓库 https://github.com/Chufeng-Jiang/Graph-Theory 2. 广度优先遍历图解 3.主要代码 原点入队列原点出队列的同时&#xff0c;将与其相邻的顶点全部入队列下一个顶点出队列出队列的同时&#xff0c;将…

2023-10-19 LeetCode每日一题(同积元组)

2023-10-19每日一题 一、题目编号 1726. 同积元组二、题目链接 点击跳转到题目位置 三、题目描述 给你一个由 不同 正整数组成的数组 nums &#xff0c;请你返回满足 a * b c * d 的元组 (a, b, c, d) 的数量。其中 a、b、c 和 d 都是 nums 中的元素&#xff0c;且 a ! b…

前端工作方式要换了?HTMX简介:无需JavaScript的动态HTML

HTMX允许你使用扩展的HTML语法代替 JavaScript 来实现交互性。HTMX 在标记中直接为你提供HTTP 交互&#xff0c;并支持许多其他交互需求&#xff0c;无需求助于 JavaScript。这是一个有趣的想法&#xff0c;可能最终会影响到web前端的工作方式。让我们看看如何使用HTMX以及它的…

Studio One 6.5新版本功能讲解及一键安装下载教程

Studio One 6.5 发布&#xff1a;整合 Dolby Atmos 全景声&#xff0c;跟 Bitwig 联合推出开放的 DAWproject 格式&#xff0c;支持 Linux&#xff01; PreSonus 的“.5”更新通常都有比较大的变化&#xff0c;这次也不例外。Studio One 6.5 增加了一种全新的工作方式&#xff…

SpringMVC的工作流程

1、SpringMVC的定义 Spring MVC是基于Java的开源Web框架&#xff0c;它是Spring框架的一部分&#xff0c;用于构建MVC&#xff08;Model-View-Controller&#xff09;模式的Web应用程序。它提供了一种灵活且强大的方式来开发Web应用程序&#xff0c;并将应用程序的不同层进行解…

Hadoop3教程(二十八):(生产调优篇)NN、DN的多目录配置及磁盘间数据均衡

文章目录 &#xff08;148&#xff09;NN多目录配置&#xff08;149&#xff09;DataNode多目录配置及磁盘间数据平衡磁盘间数据均衡 参考文献 &#xff08;148&#xff09;NN多目录配置 NN多目录的意思是&#xff0c;本地目录可以配置成多个&#xff0c;且每个目录存放内容相…

Tmux:终端复用器的基本使用(二)

相关阅读 Tmuxhttps://blog.csdn.net/weixin_45791458/category_12472796.html?spm1001.2014.3001.5482 上一篇文章列举了一些关于tmux中会话的基本使用方法&#xff0c;但会话并非是tmux的最强大的功能&#xff0c;tmux还能在一个会话中创建多个窗口(windows)&#xff0c;并…

如何为 Elasticsearch 创建自定义连接器

了解如何为 Elasticsearch 创建自定义连接器以简化数据摄取过程。 作者&#xff1a;JEDR BLASZYK Elasticsearch 拥有一个摄取工具库&#xff0c;可以从多个来源获取数据。 但是&#xff0c;有时你的数据源可能与 Elastic 现有的提取工具不兼容。 在这种情况下&#xff0c;你可…

文件列表创建工具 Nifty File Lists mac中文版功能特色

Nifty File Lists mac是一款文件列表创建工具&#xff0c;全面的元数据支持&#xff0c;涵盖了从基本文件信息&#xff0c;如文件名、路径、大小、创建和修改日期等等内容。 Nifty File Lists mac功能特色 全面的 元数据支持强大的多线程元数据提取系统涵盖了从基本文件信息&a…

elasticsearch的docker安装与使用

安装 docker network create elasticdocker pull docker.elastic.co/elasticsearch/elasticsearch:8.10.4# 增加虚拟内存&#xff0c; 此处适用于linux vim /etc/sysctl.conf # 添加 vm.max_map_count262144 # 重新启动 sysctl vm.max_map_countdocker run --name es01 --net …

Spring定时任务@Scheduled

在 Spring 框架中&#xff0c;可以使用定时任务来执行周期性或延迟执行的任务。Spring 提供了多种方式来配置和管理定时任务。有Java自带的java.util.Timer类&#xff0c;也有强大的调度器Quartz&#xff0c;还有SpringBoot自带的Scheduled。 在实际应用中&#xff0c;如果没有…

聊聊分布式架构09——分布式中的一致性协议

目录 01从集中式到分布式 系统特点 集中式特点 分布式特点 事务处理差异 02一致性协议与Paxos算法 2PC&#xff08;Two-Phase Commit&#xff09; 阶段一&#xff1a;提交事务请求 阶段二&#xff1a;执行事务提交 优缺点 3PC&#xff08;Three-Phase Commit&#x…

实际项目中最常用的设计模式

在软件开发领域,设计模式是一种经过验证的通用解决方案,用于解决各种常见问题。它们有助于提高代码的可维护性、可扩展性和可重用性。虽然有许多不同的设计模式,但以下是实际项目中最常用的一些: 1. 单例模式 (Singleton Pattern) 单例模式确保一个类只有一个实例,并提供…