当前位置: 首页 > news >正文

3.基础光照

从宏观上讲渲染包含了两大部分:决定一个像素的可见性,决定一个像素的光照计算

而光照模型就是用于决定在一个像素上决定怎样的渲染光照计算。

一、我们是如何看到这个世界的

1.光源

实时渲染中,我们通常把光源当成一个没有体积的点,用l来表示它的方向

辐照度:量化光的方法,一个光源发出了多少光

在计算光照模型时,我们需要知道一个物体的辐照度

对于平行光辐照度通过计算垂直于l的单位时间内穿过的能量来得到。

但物体表面往往时和l不垂直的,那么

如何计算辐照度:光源方向l和法线n之间的夹角的余弦值

注意:这里的默认方向的模都为1

辐照度和照射到物体表面时光线之间的距离\frac{d}{\cos \theta }成反比,因此辐照度与\cos \theta成正比。

\cos \theta可以使用光源方向l和表面法线n的点积得到。这也是用点积来计算辐照度的由来。

2.吸收和散射

光线由光源发射出来后,会与物体相交,相交的结果有两种:散射和吸收

散射:只改变方向,不改变颜色和密度

吸收:只改变密度和颜色,但不改变光线的方向

散射后的两种方向:

  • 1.散射到物体内部,这种现象被称为折射或投射
  • 2.散射到外部,这种现象被称为反射

对于不透明物体,折射进入物体内部的光线还会继续与内部的颗粒进行交互。其中一些光线最后会重新发射出物体表面,而另一些则被物体吸收。那些从物体表面重新发射出的光线将具有和入射光线不同的方向分布和颜色。

为了区分两种不同的散射,光照模型中用了两种不同的部分来计算:

  • 高光反射:表示物体表面是如何反射光线的
  • 漫反射:表示有多少光线会被折射、吸收和散射出表面

出射度:根据入射光线的数量和方向,计算出出射光线的数量和方向

辐照度和出射度之间是满足线性关系的,而他们之间的比值就是材质的漫反射和高光反射属性

3.着色

定义:着色(shading)是指根据材质属性(如漫反射属性等)、光源信息(如光源方向、辐照度等),使用一个等式去计算沿着某一个观察方向的出射度的过程。

我们把这个等式称为光照模型。不同的光照模型有不同的目的。

如:一些用于描述粗糙的物体表面,一些用于描述金属表面

4.BRDF光照模型

通俗的来讲,当给定入射光线的方向和辐照度后,BRDF可以给出在某个出射方向上的能量分布。

本章涉及的BRDF是对真实场景进行理想化和简化后的模型,并不能真实的反应物体与光线的交互。这写光照模型被称为经验模型。

图形学第一定律:如果它看起来是对的,那么它就是对的。

 二、标准光照模型

1975年,著名学者裴祥风提出了标准光照模型背后的基本理念。标准光照模型只关心直接光照,也就是那些直接从光源发射出来照射到物体表面后,经过物体表面的一次反射直接进入摄像机的光线。

该方法将光线分为4部分:

自发光(emissive)c_{emissive}。用于表述当给定一个方向时,一个表面本身会向该方向发射出多少辐射度。注意,如果没有使用全局光照技术,这些自发光是并不会真的照亮周围物体的,而是它本身看起来更亮了而已。

高光反射(specular)c_{specular}。用于描述当光线从光源照射到模型表面时,该表面会在完全镜面反射方向散射多少辐射量。

漫反射(diffuse)c_{diffuse}。用于描述当光线从光源照射到模型表面时,该表面会向每个方向散射多少辐射量。

环境光(ambient)c_{ambient}。用于描述其他所有间接光照。

1.环境光

间接光照是指,光线通常会在多个物体间反射,最后进入摄像机,也就是说,光线在进入摄像机前,经过了不只一次光照。

在标准光照模型中,使用了一种被称为环境光的部分来近似模拟间接光照。环境光的计算非常简单,它是一个全局变量,即场景中的所有物体都使用这个环境光。

c_{ambient}=\delta _{ambient}

2.自发光

自发光也可以直接由光源发射进摄像机,而不需要经过任何物体的反射。标准光照模型使用自发光来计算这个部分的贡献度。其计算很简答,直接使用该材质的自发光颜色

c_{emissive}=m_{emissive}

通常在实时渲染中,自发光表面并不会照亮周围表面,这个物体并不会被当成一个光源。

只有引入全局光照系统后才可以模拟这类自发光物体对周围环境的影响

3.漫反射

漫反射用于对那些被物体表面随机散射到各个方向的辐射度进行建模。

漫反射中视角不重要,入射光线角度很重要

兰伯特定律:反射光线的强度与表面法线和光源方向之间的夹角的余弦值成正比。

c_{diffuse}=(c_{light\cdot m_{diffuse}})max(0,n\cdot l)

m_{diffuse} 材质的漫反射颜色

c_{light} 光源颜色

防止物体被从后面来的光源照亮,所以将负值截去

4.高光反射

用于计算沿着完全镜面防溺水方向被反射的光线,这可以让物体看起来是有光泽的,如金属材质

需要知道的变量:法线方向、视角方向、光源方向、反射方向等

其中反射方向可以由r=2(\hat{n}\cdot I)\hat{n}-I得到

phong模型计算高光反射:c_{specular}=(c_{light}\cdot m_{specular})max (0,\hat{v}\cdot r)^{m^{gloss}}

m^{gloss}:材质的光泽度,也称反光度。用于控制高光区域的“亮点”有多宽,m^{gloss}越大,两点越小

m_{specular}:是材质的高光颜色。用于控制材质对于高光反射的强度和颜色。

c_{light}:光源颜色和强度

Blinn-Phong模型:
基本思想是为避免计算\hat{r}。因此引入一个新的矢量\hat{h},它可以通过对\hat{v}\hat{I}qupingjun后再归一化得到

Blinn-Phong模型公式:m_{specular}= (c_{light}\cdot m_{specular})max(0,\hat{n}\cdot \hat{h})^{m^{gloss}}

在硬件实现中,如果摄像机和光源距离模型足够远的话,Blinn模型会快于Phong,因为\hat{v}\hat{I}都是定值,所以\hat{h}也是一个常量。这两种模型都是经验模型,不存在谁更正确一些。

5.逐像素还是逐顶点

我们在哪里计算这些模型呢?

一般有两种选择:

  • 在片元着色器中计算,也被称为逐像素光照
  • 在顶点着色器中计算,也被称为逐顶点光照

逐像素光照:

以每一个像素为基础,得到它的法线(可以对顶点法线插值得到,也可以从法线纹理中采样得到),然后进行光照模型计算。这种在面片之间对顶点法线进行插值的技术被称为Phong着色,也被称为Phong插值或法线着色技术,与之前讲的Phong光照模型不同

逐顶点光照:
又称高洛德着色(Gouraud)。对每个顶点上进行光照,在渲染图元中进行线性插值,最后输出成像素颜色。由于顶点数目小于像素数目,因此顶点光照计算小于像素光照。但顶点光照更依赖于线性插值来得到像素光照,所以当光照模型中有非线性的计算时(如高光反射),逐顶点光照就会出错。逐顶点光照会在渲染图元内部对顶点进行插值,导致渲染图元内部颜色总处于暗于顶点处的最高颜色值,会导致产生明显的棱角现象。

6.总结

  • 标准光照模型是经验模型
  • Blinn-Phong简化了计算在某些情况下计算更快
  • Blinn-Phong无法表现很多重要的物理现象,如菲涅尔反射
  • Blinn-Phong是各向同性的,即当我们固定视角和光源方向旋转这个表现时,反射不会发生任何改变
  • 有些表面是各向异性的反射性质,如拉丝金属、毛发等

三、unity中的环境光和自发光

在标准光照模型中计算环境光和自发光

环境光:

可以在light中控制

只需要在shader中通过内置变量

UNITY_LIGHTMODEL_AMBIENT

来控制环境光的颜色和强度信息

自发光:

在片元着色器输出最后的颜色之前,把材质的自发光颜色添加到输出颜色上即可

四、在unityshader中实现漫反射光照模型

漫反射基本光照公式:c_{diffuse}=(c_{light\cdot m_{diffuse}})max(0,n\cdot l)

我们需要四个参数:

  • 入射光线颜色和强度c_{light}
  • 材质漫反射系数m_{diffuse}
  • 表面法线\hat{n}
  • 光源方向I

为了防止点积结果负值,使用max操作,CG提供了这一函数。在本例子中,使用CG的另一函数可以达到同一目的:saturate

函数:saturate()

参数:x:为用于操作的矢量或标量,可以是float、float2、float3等类型

描述:把x截取在[0,1]范围内,如果x是一个矢量,那么会对它的每一个分量进行这样的操作

1.实践:逐顶点光照

全部代码如下:

Shader "Shader/DiffuseVertexLevel"
{Properties{[HDR]_Diffuse ("Diffues", Color) = (1,1,1,1)}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{Tags{"LightMode"="ForwardBase"}//定义光照模式 只有正确定义LightMode,我们才能获得一些unity的内置变量CGPROGRAM//包围CG代码片#pragma vertex vert#pragma fragment frag//定义顶点着色器和像素着色器名字#include "UnityCG.cginc"#include "Lighting.cginc"//为了使用unity内置的一些变量,还需要包含进unity的内置文件UnityCG.cgincstruct appdata{float4 vertex : POSITION;float3 normal : NORMAL;//为了访问顶点的法线,在appdata中定义normal变量};struct v2f{float4 vertex : SV_POSITION;fixed3 color  : COLOR;//为了把顶点着色器中得到的光照颜色传递给片元着色器};fixed4 _Diffuse;//声明变量v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;fixed3 worldNormal = normalize(mul(v.normal,unity_WorldToObject));fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal, worldLight));o.color = ambient + diffuse;return o;}fixed4 frag (v2f i) : SV_Target{              return fixed4(i.color, 1.0);}ENDCG}}Fallback "Diffuse"
}

效果如下:

2.实践:逐像素光照

全部代码如下:

Shader "Shader/DiffusePixelLevel"
{Properties{[HDR]_Diffuse ("Diffues", Color) = (1,1,1,1)}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{Tags{"LightMode"="ForwardBase"}//定义光照模式 只有正确定义LightMode,我们才能获得一些unity的内置变量CGPROGRAM//包围CG代码片#pragma vertex vert#pragma fragment frag//定义顶点着色器和像素着色器名字#include "UnityCG.cginc"#include "Lighting.cginc"//为了使用unity内置的一些变量,还需要包含进unity的内置文件UnityCG.cgincstruct appdata{float4 vertex : POSITION;float3 normal : NORMAL;//为了访问顶点的法线,在appdata中定义normal变量};struct v2f{float4 pos : SV_POSITION;float3 worldNormal : TEXCOORD0;};fixed4 _Diffuse;//声明变量v2f vert (appdata v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.worldNormal = normalize(mul(v.normal,unity_WorldToObject));return o;}fixed4 frag (v2f i) : SV_Target{              fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;fixed3 worldNormal = normalize(i.worldNormal);fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal, worldLight));fixed3 color = ambient + diffuse;return fixed4(color, 1.0);}ENDCG}}Fallback "Diffuse"
}

效果如下:

 3.半兰伯特模型

c_{diffuse}=(c_{light\cdot m_{diffuse}})(0.5(n\cdot l)+0.5 )

对于模型的背光面,原兰伯特中点积结果将映射到同一个值。

而半兰伯特,则在背光面也可以有明暗变化,不同的点积结果会映射到不同的值上

半兰伯特无任何物理依据,仅仅是视觉加强技术。

五、在unityshader中实现高光反射光照模型

基本同理

 

相关文章:

3.基础光照

从宏观上讲渲染包含了两大部分:决定一个像素的可见性,决定一个像素的光照计算 而光照模型就是用于决定在一个像素上决定怎样的渲染光照计算。 一、我们是如何看到这个世界的 1.光源 实时渲染中,我们通常把光源当成一个没有体积的点&#…...

Image Search-这是你的图像搜索

Image Search-这是你的图像搜索 什么是图像搜索图像搜索开通图像搜索商品图片搜索图片搜索图片新增批量操作OSS-创建bucket上传文件创建increment.meta并上传元信息导出 体验感受 什么是图像搜索 在接触一个新的产品时,我们首先要知道这款产品是什么?那…...

对GPT-4o的评价:技术革新与未来展望

目录 引言一、GPT-4o的技术背景1.1 GPT系列的发展历程1.2 GPT-4o的技术特点 二、版本间的对比分析2.1 GPT-3与GPT-4的对比2.2 GPT-4与GPT-4o的对比 三、GPT-4o的技术能力3.1 自然语言处理3.2 多模态处理3.3 任务定制化 四、个人整体感受4.1 交互体验4.2 应用场景4.3 未来展望 五…...

【TB作品】msp430f5529单片机,dht22,烟雾传感器

功能 //硬件:msp430f5529、dht22、LCD1602、蜂鸣器、烟雾传感器、蓝牙模块。 //功能:读取温湿度、烟雾浓度显示到屏幕; //按键调节三个报警数值; //温度、湿度、烟雾浓度,任意一个大于报警数值就蜂鸣器报警&#xff1…...

uni-app全局弹窗的实现方案

背景 为了解决uni-app 任意位置出现弹窗 解决方案 一、最初方案 受限于uni-app 调用组件需要每个页面都引入注册才可以使用,此方案繁琐,每个页面都要写侵入性比较强 二、改进方案 app端:新建一个页面进行跳转,可以实现伪弹窗…...

Love-Yi情侣网站3.0存在SQL注入漏洞

目录 1. 前言 2. 网站简介 3. 寻找特征点 3.1 第一次尝试 3.2 第二次尝试 4.资产搜索 5.漏洞复现 5.1 寻找漏洞点 5.2 进行进一步测试 5.2.1 手动测试 1.寻找字段 2.寻找回显位 3.查询当前用户 5.2.2 sqlmap去跑 6.总结 1. 前言 朋友说自己建了一个情侣网站,看到…...

自然语言处理(NLP)—— 神经网络语言处理

1. 总体原则 1.1 深度神经网络(Deep Neural Network)的训练过程 下图展示了自然语言处理(NLP)领域内使用的深度神经网络(Deep Neural Network)的训练过程的简化图。 在神经网络的NLP领域: 语料…...

SHA256计算原理

标签: SHA256计算原理;SHA256;SHA-2; SHA-256计算原理 SHA-256(Secure Hash Algorithm 256-bit)是SHA-2系列中的一种哈希算法,它由美国国家安全局(NSA)设计,并由美国国家标准与技术研究院(NIST)发布。SHA-256主要用于数据完整性验证和数字签名等领域。以下是SHA-…...

Mysql | select语句导入csv后再导入excel表格

需求 从mysql数据库中导出数据到excel 解决方案 sql导出csv文件 sql SELECT col1,col2 FROM tab_01 WHERE col3 xxx INTO OUTFILE /tmp/result.csv FIELDS TERMINATED BY , ENCLOSED BY " LINES TERMINATED BY \n;csv文件导出excel文件 1、【数据】-【导入数据】 …...

SpringBoot:手动创建应用

Spring提供了在线的Spring Initialzr在线创建Spring Boot项目,为了更好的理解Spring Boot项目,这里我们选择手动创建。 1.新建Web应用 1.1 生成工程 首先要做是创建一个Java项目,这里我们选择使用Maven来支持,使用archetype:ge…...

【LeetCode】39.组合总和

组合总和 题目描述: 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个…...

用JS来控制遥控车(一行代码即可连接, 超简单!)

简介 有些时候我们想要做车辆的某一个功能,但是又不想浪费时间做整辆小车时,一般会去买一辆差不多的遥控车来改,但是那也比较麻烦,市面上好像也没有便宜的直接提供编程接口的遥控车。所以就自己做一个吧~。 主要是要实现向外提供…...

MyBatis-Plus如何优雅的配置多租户及分页

MyBatis-Plus如何优雅的配置多租户及分页 一、配置多租户1、步骤一2、步骤二3、步骤三步骤四 二、配置分页1、步骤一2、步骤二3、步骤三 一、配置多租户 TenantLineInnerInterceptor 是 MyBatis-Plus 提供的一个插件,用于实现多租户的数据隔离。通过这个插件&#…...

国产操作系统上Vim的详解01--vim基础篇 _ 统信 _ 麒麟 _ 中科方德

原文链接:国产操作系统上Vim的详解01–vim基础篇 | 统信 | 麒麟 | 中科方德 Hello,大家好啊!今天给大家带来一篇在国产操作系统上使用Vim的详解文章。Vim是一款功能强大且高度可定制的文本编辑器,广泛应用于编程和日常文本编辑中。…...

如何正确理解事件溯源架构模式?

在微服务架构盛行的当下,DDD(领域驱动设计)也得到了崭新的发展。同时,随着DDD的不断发展,也诞生了一些新的设计思想和开发模式,今天要介绍的事件溯源是其中具有代表性的一种模式。 事件溯源模式是DDD领域中…...

【漏洞复现】电信网关配置管理系统 rewrite.php 文件上传漏洞

0x01 产品简介 中国电信集团有限公司(英文名称"China Telecom”、简称“"中国电信”)成立于2000年9月,是中国特大型国有通信企业、上海世博会全球合作伙伴。电信网关配置管理系统是一个用于管理和配置电信网络中网关设备的软件系统。它可以帮助网络管理员…...

线性调整率:LINE REGULATION详解

目录 一、概述 二、 举例 一、概述 LDO(低压差线性稳压器)的LINE REGULATION(线路调整或线性调整)参数是一个衡量稳压器输出稳定性的重要指标。它反映了LDO输出电压对输入电压变化的响应程度。 当输入电压在其规定的工作范围内变…...

Workfine默认首页功能详解

一、基本介绍 Workfine V6.3推出了默认的用户首页功能,这样用户在登入系统后就可以通过默认的首页栏进行一些业务操作。第一版的用户首页功能布局了审批,制单,业务导航,便捷入口,消息和预警六大块内容,后续…...

CSAPP Lab07——Malloc Lab完成思路

等不到天黑 烟火不会太完美 回忆烧成灰 还是等不到结尾 ——她说 完整代码见:CSAPP/malloclab-handout at main SnowLegend-star/CSAPP (github.com) Malloc Lab 按照惯例,我先是上来就把mm.c编译了一番,结果产生如下报错。搜索过后看样子应…...

简单、免费、无广告的高性能多线程文件下载工具

一、简介 1、它是一款免费、无广告的高性能多线程文件下载工具。它界面简洁,简单好用,压缩包大小仅有 0.7MB,目前仅支持 Windows 平台。 2、使用方法:点击程序左上角的【】按钮,将需要的链接输入进去后点击【下载】即…...

【退役之重学 SQL】什么是笛卡尔积

一、初识笛卡尔积 概念: 笛卡尔积是指在关系型数据库中,两个表进行 join 操作时,没有指定任何条件,导致生成的结果集,是两个表中所有行的组合。 简单来说: 笛卡尔积是两个表的乘积,结果集中的每…...

Vue3禁止 H5 界面放大与缩小功能

Vue3禁止 H5 界面放大与缩小功能 一、前言1.第一步2.第二部3.总结 一、前言 当涉及到禁止 H5 界面的放大与缩小功能时&#xff0c;Vue 3 提供了一种方便的方式来处理。我们可以使用 <script setup> 语法&#xff0c;将相关代码添加到 App.vue 组件中&#xff0c;以确保在…...

上位机图像处理和嵌入式模块部署(f407 mcu中tf卡读写和fatfs挂载)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 很早之前&#xff0c;个人对tf卡并不是很重视&#xff0c;觉得它就是一个存储工具而已。后来在移植v3s芯片的时候&#xff0c;才发现很多的soc其实…...

汽车识别项目

窗口设计 这里的代码放在py文件最前面或者最后面都无所谓 # 创建主窗口 window tk.Tk() window.title("图像目标检测系统") window.geometry(1000x650) # 设置窗口大小# 创建背景画布并使用grid布局管理器 canvas_background tk.Canvas(window, width1000, height…...

【面试题-012】什么是Spring 它有哪些优势

文章目录 Spring有哪些优势有哪些优势Spring和Springboot区别在 Spring 框架中&#xff0c;什么是AOP核心概念应用场景 Spring有哪些通知类型 Spring 是一个开源的 Java 平台&#xff0c;由 Rod Johnson 创建&#xff0c;用于简化企业级 Java 应用程序的开发。它于 2003 年首次…...

ImageButton src图片会照成内存泄露吗 会使native内存增加吗?

在Android开发中&#xff0c;ImageButton 是用来显示按钮的视图组件&#xff0c;它通常用于显示图标或图片。对于ImageButton使用的src属性&#xff08;即按钮上的图片&#xff09;通常不会导致内存泄漏&#xff0c;但是有几种情况可能会导致内存问题&#xff1a; 1. **不正确…...

负载均衡与容错性:集群模式在分布式系统中的应用

本文作者:小米,一个热爱技术分享的29岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货! 大家好,我是小米,一个热爱分享技术的29岁程序员。今天我们来聊一聊分布式系统中的一个重要概念:集群(Cluster)模式。相信很多朋友在日常开发…...

【UE5.1 角色练习】09-物体抬升、抛出技能 - part1

前言 在上一篇&#xff08;【UE5.1 角色练习】08-传送技能&#xff09;的基础上继续实现控制物体抬升、抛出的功能。 效果 步骤 一、准备技能动画 1. 在项目设置中新建一个操作映射&#xff0c;这里命名为“Skill_GravityControl”&#xff0c;用按键4触发 2. 通过IK重定向…...

最大的游戏交流社区Steam服务器意外宕机 玩家服务受影响

易采游戏网6月3日消息&#xff1a;众多Steam游戏玩家报告称&#xff0c;他们无法访问Steam平台上的个人资料、好友列表和社区市场等服务。同时&#xff0c;社区的讨论功能也无法正常使用。经过第三方网站SteamDB的确认&#xff0c;&#xff0c;这一现象是由于Steam社区服务器突…...

如何手动批准内核扩展 Tuxera NTFS for mac内核扩展需要批准 内核扩展怎么打开

在了解如何手动批准内核扩展之前&#xff0c;我们应该先了解什么叫做内核扩展。内核扩展又被称为KEXT&#xff0c;通过它可以实现macOS系统与软件组件之间的交互&#xff0c;例如磁盘管理、任务管理和内存管理等等。 kext 是内核扩展&#xff08;Kernel Extension&#xff09;…...