当前位置:网站首页>UnityShader入门精要-高级光照基础
UnityShader入门精要-高级光照基础
2022-08-10 05:37:00 【hippodu】
Unity的渲染路径
渲染路径决定了光照如何应用到shader中,要和光源交互就需要为每个pass指定渲染路径,多数情况下一个项目只使用一种渲染路径,通常默认为前向。
edit-project settings-player-other settings-rendering
在pass中使用标签来指定该pass使用的渲染路径:
Pass{
Tags{"LightMode"="ForwardBase"}
}
前向渲染路径
1.前向渲染路径的原理
每进行一次完整的前向渲染,完成对对象的渲染图元渲染,需要利用深度缓冲来决定一个片元是否可见,如果可见就更新颜色缓冲中的颜色值,对于每个逐像素光影,都需要完成一个这样的完整渲染流程,如果一个物体在多个逐像素光源的影响区域内,就需要多个Pass分别计算各个逐像素光源的光照结果,并将这些结果混合得到最终的颜色值。N个物体,M个光源--N*M个pass。引擎通常会限制每个物体逐像素光源的数目。
在unity中,前向渲染路径有三种处理光照的方式:逐顶点、逐像素、球谐函数(SH)处理,选择那种处理模式取决于它的类型(光源类型是指该光源是平行光还是其他类型)和渲染模式(指该光源的模式是否设置为Important)。
最亮的平行光:逐像素
not important:逐顶点或SH处理
Important:逐像素
要得到一些正确的光照变量如光照衰减值等,需要对BassPass和Additional Pass 使用这两个编译指令。
#pragma multi_compile_fwdbase //forward base
#pragma multi_compile_fwdadd // forward add
对于前向渲染来说,一个unity shader 通常会定义一个base pass 以及一个additional pass,basepass仅执行一次,而additionnalpass会根据影响该物体的其他逐像素光源的数目被多次调用,每个逐像素光源执行一次additionalpass。
_LightColor() 该pass处理的逐像素光源的颜色
_LightMatrix(()从世界空间到光源空间的变换矩阵,可用于采样cookie和光强衰减纹理
顶点照明渲染路径
不支持逐像素才能得到的效果(如阴影、法线映射、高精度的高光反射),通常一个pass解决问题,一个顶点照明的pass最多访问到8个逐顶点光源。
unity_LightAtten 光源衰减因子
延迟渲染路径
当场景中包含大量实时光源时,前向渲染性能会下降,重叠区域造成很大的重复,延迟渲染除了颜色缓冲与深度缓冲外,利用额外的G-buffer,储存表面的其他信息如法线位置材质等。
原理:包含两个pass,第一个pass用于计算哪些片元可见(深度缓冲),当发现该片元可见时将其信息存储到G缓冲区中,然后在第二个pass中利用G缓存的信息进行计算。
缺点:不支持真正的抗锯齿,不能处理半透明物体。
默认的G缓冲区包含下面几个渲染纹理RT:RT0存储漫反射颜色,RT1存储高光反射颜色,A通道为指数部分、RT2 存储法线, RT3 存储自发光 lightmao 反射探针
Unity的光源类型
一共支持四种:平行光、点光源、聚光灯、面光源
1.平行光:几何属性只有方向,可以放在任意位置,光不会衰减
2.点光源:照亮空间有限,会衰减,衰减值可以由一个函数定义
3.聚光灯:衰减值同样由函数定义,需要判断一个点是否在锥体的范围内
attend可以编写函数用来表示衰减
fixed atten = 1.0;
return fixed4(ambient + (diffuse + specular) * atten, 1.0);
使用frame debugger 可以看出渲染的过程,以及每个渲染事件的结果,将点光源设置为not important,渲染事件将减少,不在点光源、聚光灯范围内,也将减少渲染事件。
Unity的光照衰减
unity使用一张纹理作为查找表来在片元着色器中计算逐像素光照的衰减,使其不依赖于数学公式,而这样做需要预处理得到采样纹理且纹理大小影响衰减精度,且无法用其他数学公式计算,但一定程度上可以提升性能。
用于光照衰减的纹理
unity使用一张_LightTexture0的纹理计算光源衰减,为了对该纹理采样得到给定点到该光源的衰减值,需要得到该点在光源空间中的位置,由_LightMatrix0变换矩阵得到(世界-光源)。
float3 lightCoord = mul(_LightMatrix0,float4(i.worldPostion,1)).xyz;
//得到光源空间中的相应位置
fixed atten= tex2D(_LightTexture0,dot(lightCoord,lightCoord).rr).UNITY_ATTEN_CHANNEL;
//光源空间中定点距离的平方,unity_atten_channel宏得到衰减纹理中衰减值所在的分量
边栏推荐
- LaTeX总结----在CSDN上写出数学公式
- Unity screen coordinates to world coordinates, mouse click to get 3D position
- 探究乱码问题的本源:GBK,UTF8,UTF16,UTF8BOM,ASN1之间的关联
- 剑指 Offer(第 2 版)7/12 18-20
- lua小工具-保留指定位数的小数
- 常用模块封装-csv文件操作封装
- R language cluster analysis - code analysis
- Unity中Xml简介以及通过脚本读取Xml文本中的内容
- Kernel performance analysis summary
- 通过adb devices命令在控制台显示企业级PicoNeo3设备号
猜你喜欢
浅谈游戏中3种常用阴影渲染技术(3):阴影贴图
ASP.NET连接SQL Server的步骤
Unity plug-in DOTween User Guide 2 (Brief explanation of Bezier curves)
中间件-Rocktmq
从零开始构建Google Protocol Buffer / protobuf 的helloworld工程(超级详细)
每日刷题(day01)——leetcode 53. 最大子数组和
接口自动化2.0
Easy to master Unity of eight prior to rendering
每日刷题(day03)——leetcode 899. 有序队列
LruCache与DiskLruCache结合简单实现ImageLoader
随机推荐
通过adb devices命令在控制台显示企业级PicoNeo3设备号
lua小工具-保留指定位数的小数
浅谈游戏中3种常用阴影渲染技术(3):阴影贴图
视差映射:更逼真的纹理细节表现(上):为什么要使用视差映射
电路建模的要点
Explore the origin of the garbled problem: the association between GBK, UTF8, UTF16, UTF8BOM, and ASN1
多线程与多进程(概念详细讲解)
在Unity中判断游戏物体是否在游戏屏幕范围之内
电路分析中的电容器的基本知识
自定义View的流程总结学习
如何实现网格建造系统
mkfs.minix.c之minix_super_block.s_ninodes获取解析
21天学习挑战赛--补种胡杨求最大连续胡杨数量
ASP.NET有关于文件上传、下载、全选、删除选中重要干货(亲测有效)
剑指 Offer(第 2 版)7/5 5-8
探究乱码问题的本源:GBK,UTF8,UTF16,UTF8BOM,ASN1之间的关联
解决错误 Could not find method leftShift() for arguments
mkfs.minix.c之minix_super_block.s_nzones获取解析
8个问题轻松掌握Unity前向渲染
unity3d著名项目-Dark Tree翻译