【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.mzph.cn/news/118336.shtml

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

相关文章

城市正视图(Urban Elevations, ACM/ICPC World Finals 1992, UVa221)rust解法

如图5-4所示&#xff0c;有n&#xff08;n≤100&#xff09;个建筑物。左侧是俯视图&#xff08;左上角为建筑物编号&#xff0c;右下角为高度&#xff09;&#xff0c;右侧是从南向北看的正视图。 输入每个建筑物左下角坐标&#xff08;即x、y坐标的最小值&#xff09;、宽度…

React之diff原理

一、是什么 跟Vue一致&#xff0c;React通过引入Virtual DOM的概念&#xff0c;极大地避免无效的Dom操作&#xff0c;使我们的页面的构建效率提到了极大的提升 而diff算法就是更高效地通过对比新旧Virtual DOM来找出真正的Dom变化之处 传统diff算法通过循环递归对节点进行依…

嵌入式中的MCU、ARM、DSP、FPGA

目录 “角色扮演” MCU ARM 特点 DSP 特点 FPGA 特点 应用 “角色扮演” MCU&#xff08;Microcontroller Unit&#xff09;、ARM&#xff08;Advanced RISC Machine&#xff09;、DSP&#xff08;Digital Signal Processor&#xff09;和FPGA&#xff08;Field-Progr…

PHP 危险函数2-代码执行语句

代码执行语句 eval() 不是函数&#xff0c;不能被动态调用&#xff0c;并且需要以 ;结束 直接输出&#xff0c;不执行 <?php$code"phpinfo();";echo $code;?>eval() 语句执行 <?php$code"phpinfo();";eval($code); // eval 不是函数&am…

【TGRS 2023】RingMo: A Remote Sensing Foundation ModelWith Masked Image Modeling

RingMo: A Remote Sensing Foundation Model With Masked Image Modeling, TGRS 2023 论文&#xff1a;https://ieeexplore.ieee.org/stamp/stamp.jsp?tp&arnumber9844015 代码&#xff1a;https://github.com/comeony/RingMo MindSpore/RingMo-Framework (gitee.com) …

软件测试之【单元测试、系统测试、集成测试】

一、单元测试的概念 单元测试&#xff08;Unit Testing&#xff09;是对软件基本组成单元进行的测试&#xff0c;如函数&#xff08;function或procedure&#xff09;或一个类的方法&#xff08;method&#xff09;。当然这里的基本单元不仅仅指的是一个函数或者方法&#xff…

Python:实现日历功能

背景 日常生活中&#xff0c;每天都要用到日历&#xff0c;日历成为我们生活中的必需品&#xff0c;那么如何制作日历呢&#xff0c;其实方法有很多&#xff0c;可以直接在excel中制作&#xff0c;也可以手画等等。 学习过编程的朋友&#xff0c;能否想到用Python编写一…

【Pytorch】Pytorch学习笔记02 - 单变量时间序列 LSTM

目录 说明简单神经网络LSTM原理Pytorch LSTM生成数据初始化前向传播方法训练模型自动化模型构建 总结参考文献 说明 这篇文章主要介绍如何使用PyTorch的API构建一个单变量时间序列 LSTM。文章首先介绍了LSTM&#xff0c;解释了它们在时间序列数据中的简单性和有效性。然后&…

智慧垃圾站:AI视频智能识别技术助力智慧环保项目,以“智”替人强监管

一、背景分析 建设“技术先进、架构合理、开放智能、安全可靠”的智慧环保平台&#xff0c;整合环境相关的数据&#xff0c;对接已建业务系统&#xff0c;将环境相关数据进行统一管理&#xff0c;结合GIS技术进行监测、监控信息的展现和挖掘分析&#xff0c;实现业务数据的快速…

每日一练——快速合并2个有序数组

每日一练来喽~~~ 今天up主为大家分享一个&#xff0c;快速合并2个有序数组的法子&#xff0c;注意听哟&#xff01; 题目&#xff1a; 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数…

[Docker]二.Docker 镜像,仓库,容器介绍以及详解

一.Docker 镜像,容器,仓库的简单介绍 通俗来讲:镜像相当于VM虚拟机中的ios文件,容器相当于虚拟机系统,仓库相当于系统中的进程或者执行文件,容器是通过镜像创建的 1.镜像 Docker 镜像就是一个 Linux 的文件系统&#xff08; Root FileSystem &#xff09;&#xff0c;这个文…

万宾科技智能井盖传感器怎么使用?

时代在进步&#xff0c;科技在更新&#xff0c;人们身边的万事万物都在随着时代的脚步不断的前进。各种各样高科技技术在城市基础设施建设的过程中得到应用&#xff0c;很多智能产品不仅施工方便&#xff0c;而且可以向政府部门提供精准的数据&#xff0c;提高了相关管理人员的…

一、PHP环境搭建[phpstorm]

一、安装 1.php编写工具 地址&#xff1a;https://www.jetbrains.com/phpstorm/download/#sectionwindows 图示&#xff1a; 2.php环境 解释&#xff1a;建议使用phpstudy进行安装&#xff0c;安装较为简单 链接&#xff1a;https://www.xp.cn/ 图示&#xff1a; 二、第…

yyds,Elasticsearch Template自动化管理新索引创建

一、什么是Elasticsearch Template&#xff1f; Elasticsearch Template是一种将预定义模板应用于新索引的功能。在索引创建时&#xff0c;它可以自动为新索引应用已定义的模板。Template功能可用于定义索引的映射、设置和别名等。它是一种自动化管理索引创建的方式&#xff0…

Elasticsearch:使用 Open AI 和 Langchain 的 RAG - Retrieval Augmented Generation (四)

这篇博客是之前文章&#xff1a; Elasticsearch&#xff1a;使用 Open AI 和 Langchain 的 RAG - Retrieval Augmented Generation &#xff08;一&#xff09;Elasticsearch&#xff1a;使用 Open AI 和 Langchain 的 RAG - Retrieval Augmented Generation &#xff08;二&a…

vue3 elementPlus 表格实现行列拖拽及列检索功能

1、安装vuedraggable npm i -S vuedraggablenext 2、完整代码 <template> <div classcontainer><div class"dragbox"><el-table row-key"id" :data"tableData" :border"true"><el-table-columnv-for"…

ChatGPT和Copilot协助Vue火速搭建博客网站

AI 对于开发人员的核心价值 网上会看到很多 AI 的应用介绍或者教程 使用 AI 聊天&#xff0c;咨询问题 —— 代替搜索引擎使用 AI 写各种的电商文案&#xff08;淘宝、小红书&#xff09;使用 AI 做一个聊天机器人 —— 这最多算猎奇、业余爱好、或者搞个套壳产品来收费 以上…

AWS Lambda 操作 RDS 示例

实现目标 创建一个 Lambda 接收调用时传入的数据, 写入 RDS 数据库 Post 表存储文章信息. 表结构如下: idtitlecontentcreate_date1我是标题我是正文内容2023-10-21 15:20:00 AWS 资源准备 RDS 控制台创建 MySQL 实例, 不允许 Public access (后面 Lambda 需要通过 VPC 访问…

AI的Prompt是什么

一.AI的Prompt的作用 在人工智能&#xff08;AI&#xff09;中&#xff0c;"Prompt"通常指的是向AI系统提供的输入或指令&#xff0c;用于引导AI进行特定的操作或生成特定的输出。例如&#xff0c;在一个对话型AI系统中&#xff0c;用户输入的问题就是一个prompt&…

【vue】使用less报错:显示this.getOptions is not a function

在vue-cli中使用 lang“less” 时报错&#xff1a; Module build failed: TypeError: this.getOptions is not a function at Object.lessLoader 原因&#xff1a;版本过高所致&#xff0c;所用版本为 解决&#xff1a;降低版本&#xff1a;npm install less-loader4.1.0 --s…