目录

1. Unity的渲染路径

前向渲染路径

Unity中的前向渲染

延迟渲染

Unity的光源类型

Unity的光照衰减

Unity的阴影


1. Unity的渲染路径

Unity 5.0之前,有3种渲染路径:前向渲染路径(Forward Rendering Path)、延迟渲染路径(Deferred Rendering Path)和顶点照明渲染路径(Vertex Lit Rendering Path)。

Unity5.0之后,顶点照明渲染路径已不建议使用(但Unity依然兼容);且新的延迟渲染路径代替了原来的延迟渲染路径(老版本的延迟渲染路径在Unity中依然兼容)。

前向渲染路径

每进行一次完整的前向渲染,我们需要渲染该对象的图元,并计算两个缓冲区的信息:颜色缓冲区深度缓冲区

先根据深度缓冲来决定一个片元是否可见,如果可见再更新颜色缓冲区中的颜色值。

Pass
{for (each primitive in this model){for (each fragment covered by this primitive){if (failed in depth test){// 如果没有通过深度测试,说明该片元不可见discard;}else{// 如果该片元可见,则进行光照计算float4 color = Shading(materialInfo, pos, normal, lightDir, viewDir);// 更新帧缓冲writeFrameBuffer(fragment, color);}}}
}

每个逐像素光源都需要进行上述渲染流程。如果一个物体存在多个逐像素光源的影响,则需要执行多个Pass,每个Pass计算一个逐像素光源的光照结果,然后在帧缓冲中把这些光照结果混合,得到最终的颜色值。

Pass执行次数 = N个物体 * M个光源

限制每个物体的逐像素光照数目,以此来限制Pass执行的次数。

Unity中的前向渲染

Unity中,前向渲染有3种处理光照的方式:逐顶点处理、逐像素处理、球谐函数(Spherical Harmonics, SH)处理。

光源:取决于它的类型和渲染模式。

前向渲染中,渲染一个物体时,Unity会根据场景中各个光源的设置以及这些光源对物体的影响程度(距离远近、光照强度等)对这些光源进行重要度排序。

其中:

  • 一定数目的光源会按逐像素的方式处理;(最亮的平行光,Important

  • 最多4个光源按逐顶点的方式处理;(Not Important)

  • 剩下的光源按球谐(SH)方式处理。(Not Important)

延迟渲染

延迟渲染主要包含2个Pass。第一个Pass不进行任何光照计算,仅仅计算哪些片元可见,将可见的片元信息存储到G缓冲区。

延迟渲染适合在光源数目众多、使用前向渲染造成性能瓶颈的情况下使用,每个光源都可以按逐像素处理。

Pass 1
{// 第一个Pass不进行真正的光照计算// 仅仅把光照计算需要的信息保存到G缓冲中for (each primitive in this model){for (each fragment covered by this primitive){if (failed in depth test){// 如果没有通过深度测试,则该片元不可见discard;}else{// 如果该片元可见,把需要的信息存储到G缓冲中writeGBuffer(materialInfo, pos, normal, lightDir, viewDir);}}}
}Pass 2
{// 使用G缓冲中的信息进行真正的光照计算for (each pixel in the screen){if (the pixel is valid){// 如果该像素是有效的,读取对应G缓冲中的信息readGBuffer(pixel, materialInfo, pos, normal, lightDir, viewDir);// 根据读取到的信息进行光照计算float4 color = Shading(materialInfo, pos, normal, lightDir, viewDir);// 更新帧缓冲writeFrameBuffer(pixel, color);}}
}

缺点:

  • 不支持MSAA;

  • 不能处理半透明物体;

  • 延迟渲染只能使用一个光照模型,不支持多pass

默认的G缓冲区包含了以下几个渲染纹理(Render Texture,RT):

  • RT0 :ARGB32格式,RBG通道存储漫反射颜色,A通道未被使用。

  • RT1 :ARGB32格式,RGB通道存储高光反射颜色,A通道存储高光反射的指数部分。

  • RT2 :ARGB2101010格式,RGB通道存储法线,A通道未被使用。

  • RT3 :ARGB32格式(非HDR)或ARGBHalf(HDR),用于存储自发光 + lightmap + 反射探针

  • 深度缓冲和模板缓冲

Unity的光源类型

Unity一共支持4种光源类型:平行光点光源聚光灯面光源(area light)。面光源仅在烘焙时才有用。最常使用的光源属性有:光源的位置方向(到某点的方向)、颜色强度以及衰减(到某点的衰减,与点到光源的距离有关)。

Unity的光照衰减

Unity内部使用一张名为_LightTexture0的纹理来计算光照衰减(使用cookie的光源的衰减查找纹理是_LightTextureB0)。对_LightTexture0衰减纹理的采样基于定点在光源空间中的位置,会用到_LightMatrix0矩阵用于将定点的坐标由世界空间转到光源空间:

float3 lightCoord = mul(_LightMatrix0, float4(i.worldPosition, 1)).xyz;

然后使用这个坐标模的平方对衰减纹理进行采样,得到衰减值:

fixed atten = tex2D(_LightTexture0, dot(lightCoord, lightCoord).rr).UNITY_ATTEN_CHANNEL;float distance = length(_WorldSpaceLightPos0.xyz - i.worldPosition.xyz);
// 线性衰减
atten = 1.0 / distance;

Unity的阴影

Shadow Map技术:把相机放到与光源场合的位置,相机看不到的位置就是场景中阴影的区域。

前向渲染中,如果场景中最重要的平行光开启了阴影,Unity就会为这个光源计算它的阴影映射纹理(Shadowmap),它本质是一张深度图,记录了从光源的位置出发、能看到的场景中距离它最近的表面位置(深度信息)。为了得到映射纹理中的深度信息,需要把摄像机放到光源的位置,然后按照正常的渲染流程(调用Base Pass和Additional Pass)来更新深度信息。但是这样会造成一定的性能浪费,所以Unity使用了额外的Pass专门更新光源的阴影映射纹理,这个Pass的LightMode标签被设置为ShadowCaster

  • 传统的阴影映射纹理实现过程:

在正常渲染的Pass中把顶点位置变换到光源空间下,得到光源空间中顶点的位置,使用xy分量对阴影映射纹理进行采样得到记录的深度值,如果它小于这个顶点的z分量,则说明这个顶点在阴影中。

  • Unity 5及以后使用的屏幕空间的阴影映射技术(Screenspace Shadow Map):

调用LightMode为ShadowCaster的Pass得到光源的阴影映射纹理和相机的深度纹理,如果相机深度纹理记录的深度大于转换到光源阴影映射纹理中的深度值,则说明这个物体表面的该点处于阴影中。通过这样的方式,生成的阴影图包含了屏幕空间中所有有阴影的区域。我们只需要对这个阴影图进行采样就可以计算场景中哪些物体会呈现阴影了。

关于阴影,其实涉及投射接收两个过程。举个例子,在太阳光下物体A挡住了物体B,在物体B上产生了阴影。那么对于物体A,就是投射阴影的过程,对于物体B就是接收阴影的过程。

光源的阴影映射纹理的生成过程会计算投射物体在光源空间中的位置;

接收物体的Shader实现中会对光源的阴影映射纹理进行采样,以确认它是否会被挡住并产生阴影。

参考:《Unity Shader入门精要》笔记(十二) - 知乎

UnityShader入门精要-9相关推荐

  1. 《UnityShader入门精要》总结(1)理论篇

    紫色:大类概念或简短有力的总结 蓝色:细分概念或重要部分 红色:重要的补充注释 第二章:渲染流程与流程分工 渲染的流程分三个阶段: 应用阶段(开发者控制阶段) 由开发者全权进行管理,控制场景内摄像机位 ...

  2. UnityShader入门精要-3.3 UnityShader的结构

    一个UnityShader的基础结构如下所示: Shader "ShaderName"{Properties{//属性 } SubShader{//显卡A使用的子着色器 }SubS ...

  3. UnityShader入门精要笔记1——顶点/片元着色器结构与BRDF(基本光照模型)——实现漫反射

    文章目录 BRDF(基本光照模型) 实现漫反射 光线强度的计算 好现在开始写Shader 新建Shader 添加一个Properties语义块 添加SubShader和Pass. 使用CG/HLSL语 ...

  4. UnityShader入门精要——运动模糊

    运动模糊是真实世界中的摄像机的一种效果.如果在摄像机曝光时,拍摄场景发生了变化,就会产生模糊的画面. 运动模糊的实现有多种方法.一种实现方法是利用一块累积缓存(accumulation buffer ...

  5. UnityShader入门精要——运动模糊(2)

    本次利用速度映射图方法实现运动模糊.速度映射图中存储了每个像素的速度,然后使用这个速度来决定模糊的方向和大小. 速度缓冲生成的方法: (1)把场景中所有物体的速度渲染到一张纹理中.但这种方法的缺点在于 ...

  6. [学习笔记]UnityShader入门精要_第12章_屏幕后处理效果

    12.2 调整屏幕的亮度,饱和度和对比度 C# CheckShaderAndCreateMaterial Range OnRenderImage Material.SetFloat Graphics ...

  7. UnityShader入门精要-屏幕后处理效果 亮度饱和度对比度、边缘检测、高斯模糊、bloom效果、运动模糊

    (从这里开始可能会记录的更简略一些,时间紧张想迅速读完这本书的主要内容,可能有的部分不会自己上手做) 屏幕后处理通常指渲染完整个场景得到屏幕图像后,再对图像进行操作,抓取屏幕可以使用OnRenderI ...

  8. [UnityShader入门精要读书笔记]37.水波效果

    在这里,使用一张立方体纹理(cubemap)作为环境纹理,模拟反射.为了模拟折射效果,我们使用GrabPass来获取当前屏幕的渲染纹理,并使用切线空间下的法线方向对像素的屏幕坐标进行偏移,再使用该坐标 ...

  9. UnityShader入门精要-透明效果

    实现透明效果的方法:1.透明度测试2.透明度混合 深度缓冲Z-buffer决定了哪个物体的那些部分会被渲染在前面,而哪些部分会被遮挡(比较距照相机的距离),渲染一个片元时需要把他的深度值与已经存在在深 ...

最新文章

  1. python内置库之学习ctypes库(三)--调用Win32API
  2. hexo安装toc插件
  3. POJ3666-Making the Grade【线性dp】
  4. 关联关系、依赖关系总结
  5. 一维数组转化为二维数组(java)
  6. Android Toast小解
  7. ios 添加浮动效果_iOS 为UITableView的索引 添加浮动放大View显示
  8. 构建ai数据库_为使用AI的所有人构建更安全的互联网
  9. 工控安全PLC固件逆向二
  10. TiDB错误码与故障排除
  11. 传统项目管理 VS 敏捷项目管理
  12. 目标检测学习笔记——使用wandb
  13. 靠卖艺还债:罗永浩的冬天来了!
  14. springboot整合手机验证码
  15. 浅谈跨站脚本攻击与防御
  16. [Machine Learning] 方向导数梯度(Directional Derivative Gradient)
  17. 计算100以内的奇数之和
  18. 立体声混响效果器-Acon Digital Verberate 2.2.1 WiN-MAC
  19. 钉钉官方接口调用过程
  20. QT 鼠标形状设置问题

热门文章

  1. LevelDB初体验
  2. SAP系统管理中常见问题解答(转载)
  3. motan源码分析一:服务发布及注册
  4. 《 富爸爸与穷爸爸》
  5. 书画家点赞!基于飞桨绘制中国水墨山水画
  6. 明基PD2710QC显示器体验报告
  7. 驱动ko文件开机自动加载配置
  8. 防火墙负载均衡解决方案
  9. 计网-TCP/UDP-TCP
  10. 选择全光谱灯哪个牌子好?五款护眼台灯推荐