百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

Unity|体积光散射(上)

bigegpt 2024-08-20 10:55 2 浏览

本篇主要通过向小型动画场景添加一些体积光散射,了解如何使用 Unity 的通用渲染管线创建你自己的自定义渲染功能。首先上效果图

(甩锅声明:本教程默认你已经熟练使用unity,c#和shader。有向量代数的知识很有帮助,但是没有的话你也可以学到很多。)

1立方体顶点坐标

文末下载源文件,然后解压项目并在unity中打开,项目中查看到的应该是这样子的

下面是每个文件夹包含的内容的快速细分:

  • Animations:玩家角色的动画。
  • Materials:用于玩家和场景的材料。
  • Models:场景和玩家的模型。
  • Scenes:工作的示例场景。
  • Scripts:示例项目的一堆脚本。
  • Settings:通用渲染管线设置的资产。
  • Shaders : 一个空的文件夹,你的着色器将放在其中。
  • Textures:用于播放器和调试的纹理贴图。

现在,在RW/Scenes中打开Sunset God Rays场景。查看场景视图,点击Play试玩:

你将看到游戏关卡的概览。使用A和D键左右移动播放器。按空格键跳跃。

你在本教程中的目标是学习如何使用一些很酷的体积效果来改善游戏的视觉效果,使其更加有趣。你的第一步是了解什么是体积光照以及如何实现它。

2体积光散射

在现实世界中,光不会在真空中传播,在真空中,你和你正在看的物体之间不存在任何东西,除非你在太空中。

在实时渲染中,这被称为参与媒体对光传输的影响。最常见的现象是雾。

当空气中的粒子密度足够高时,部分遮挡光源的物体将以光束或射线的形式在这些粒子上投射阴影。

在游戏设计中,这些被称为God Rays或Light shafts。此效果可让你增强场景的真实感和润色,让一切看起来都非常漂亮。

接下来,你将了解如何在 Unity 游戏中实现此效果。

3使用屏幕空间

虽然在物理上并不准确,但屏幕空间方法非常简单。首先,渲染光源颜色,然后将场景中的所有对象涂成黑色。你可以在occluders map的屏幕外纹理中执行此操作。它看起来像这样:

之后,你在后期处理中对图像应用径向模糊。从光源中心开始,你沿着从光源到你正在评估的当前像素的向量采集多个颜色样本。你将此像素的最终颜色设置为这些样本的加权和。


最后,将此图像叠加在原始彩色图像之上。

了解了这个过程之后,你将看到如何将这个概念应用到你自己的游戏中。

4创建自定义shader

Universal Render Pipeline 提供了一个脚本模板来创建特征。现在,你将创建自己的自定义渲染器功能。

在RW/Scripts中,选择Create ? Rendering ? Universal Render Pipeline ? Renderer Feature并将其命名为VolumetricLightScattering。

接下来,双击VolumetricLightScattering.cs以启动代码编辑器。你将看到以下内容:

这是你渲染器的类。它派生自基本抽象类 ,ScriptableRendererFeature它使你能够将渲染传递注入渲染器并在不同的事件上执行它们。

ScriptableRendererFeatures由一个或多个组成ScriptableRenderPasses。默认情况下,Unity 为你提供一个名为CustomRenderPass. 当你编写自定义pass时,你会了解这个class的详细信息。目前,先看VolumetricLightScattering.

Unity 在脚本运行时以预定的顺序调用一些方法:

  • Create():在函数首次加载时调用。你将使用它来创建和配置所有ScriptableRenderPass实例。
  • AddRenderPasses():每帧调用一次,每个摄像机调用一次。你将使用它将你的ScriptableRenderPass实例注入到ScriptableRenderer.

首先,你将定义一些设置来配置此功能。首先在上面添加以下类VolumetricLightScattering:

VolumetricLightScatteringSettings包含以下参数:

  • resolutionScale:屏幕配置外的大小。
  • Intensity:设置light的强度。
  • blurWidth:组合像素颜色时使用的模糊半径。

注意:System.Serializable在类的顶部添加以使属性可通过检查器进行编辑。

接下来,通过在上面添加以下行来声明设置的实例Create():

这就是使用自定义渲染器功能所需的全部内容。保存你的脚本并切换到 Unity。

5将渲染功能添加到ForwardRenderer

现在你有了一个renderer feature,你需要将它添加到ForwardRenderer中。

为此,在 Project 窗口中找到RW/Settings并选择ForwardRenderer。

在 Inspector 窗口中,选择Add Renderer Feature ? Volumetric Light Scattering。

渲染器现在使用你创建的renderer feature。单击设置以显示你刚刚定义的属性。

然后,单击“播放”,然后……你会发现没有任何变化。这是因为该功能的渲染通道还没有做任何事情。

注意:如果你在检查器中看不到设置,请尝试重新加载VolumetricLightScattering.cs。右键单击脚本并选择Reimport。回到ForwardRenderer——现在应该可以看到设置了。

6实现custom render pass

首先回到VolumetricLightScattering.cs。寻找CustomRenderPass,你会看到:

CustomRenderPass派生自基本抽象类 ,ScriptableRenderPass它提供了实现逻辑渲染过程的方法。

与 一样ScriptableRendererFeature,Unity 在脚本运行时调用一些方法。以下是本文需要了解的内容:

  • OnCameraSetup():在渲染相机以配置渲染目标之前,调用它。
  • Execute():调用每一帧来运行渲染逻辑。
  • OnCameraCleanup():在这个渲染过程执行后,调用它来清理所有分配的资源——通常是渲染目标。
  • 你还可以用更多方法,但不会在本文中使用,包括:Configure():在执行渲染过程以配置渲染目标之前,你可以调用此函数,它会在之后执行OnCameraSetup()
  • OnFinishCameraStackRendering():此函数在渲染相机堆栈中的最后一个相机后调用一次。一旦堆栈中的所有相机完成渲染,你就可以使用它来清理任何分配的资源。


7设置Ligt Scattering Pass

重命名CustomRenderPass为LightScatteringPass. 使用代码编辑器的重命名功能,因为这个出现在多个位置。然后,在上面声明以下变量OnCameraSetup():

  • occluders:需要一个RenderTargetHandle来创建纹理。
  • resolutionScale:分辨率比例。
  • intensity:效果强度。
  • blurWidth:径向模糊宽度。

在设置中定义resolutionScale,intensity和blurWidth

下一步是声明一个构造函数来初始化这些变量。通过在刚刚添加的变量下方添加以下代码来执行此操作:

这里,LightScatteringPass是renderpass构造函数。

第一步是resolutionScale根据设置进行初始化。然后你需要occluders通过调用Init()纹理名称来进行初始化。

接下来,将Create()替换VolumetricLightScattering为以下内容:

这里表示,你调用 pass 构造函数并将setting作为参数。你还可以配置输入render pass的位置。在这种情况下,你就是在后处理效果之前设置的它。

8配置遮挡贴图occlusion map

现在,你将创建一个屏幕外纹理来存储所有遮挡光源的对象的轮廓。你将在OnCameraSetup(). 具体代码如下:

这里有几件重要的问题:

1.首先,你会获得当前相机的RenderTextureDescriptor. 此描述符包含创建新纹理所需的所有信息。

2.然后,禁用深度缓冲区,因为你不会使用它。

3.将纹理尺寸缩放resolutionScale.

4.要创建新纹理,请用GetTemporaryRT()图形命令。第一个参数是的ID occluders。第二个参数是你从创建的描述符中获取的纹理配置,第三个参数是纹理过滤模式。

5.最后,调用ConfigureTarget()纹理RenderTargetIdentifier来完成配置。

保存脚本并返回编辑器。

9实现occluders shader

接下来,你需要创建自己的无光照着色器。为什么要编写自己的而不是使用默认的无光照着色器?

默认着色器将雾设置考虑在内,在渲染远处对象时使用它们来影响远处对象的颜色。这对最终图像很好,但不适用于此纹理贴图。这就是为什么你创建一个自定义的无光照着色器并在SubShader中Fog {Mode Off}.

在RW/Shaders中,选择Create ? Shader ? Unlit Shader并将其命名为UnlitColor。双击UnlitColor.shader启动编辑器,然后将所有行替换为:

这里,你创建一个着色器,该着色器采用名为的颜色属性_Color并将其传递给Color着色器命令。这就是用黑色绘制对象所需的全部内容。

保存着色器代码并切换到编辑器进行编译。

10执行render pass

首先,你需要使用着色器创建材质。返回VolumetricLightScattering.cs并在LightScatteringPass构造函数上方添加以下行:

然后,在构造函数中添加这一行:

这会使用UnlitColor着色器创建一个新的材质实例。你可以使用Shader.Find()着色器名称获取对着色器的引用。

要执行渲染逻辑,请找到Execute()并将其替换为以下内容:

上面代码的功能是:

1.如果缺少材质,会停止传递渲染。

2.通过命令缓冲区发出图形命令。CommandBufferPool只是准备好使用的预先创建的命令缓冲区的集合。你可以使用Get().

3.将图形命令包装在 aProfilingScope中,以确保FrameDebugger可以分析代码。

4.将所有命令添加到 后CommandBuffer,你就可以安排它执行并释放它。

相关推荐

悠悠万事,吃饭为大(悠悠万事吃饭为大,什么意思)

新媒体编辑:杜岷赵蕾初审:程秀娟审核:汤小俊审签:周星...

高铁扒门事件升级版!婚宴上‘冲喜’老人团:我们抢的是社会资源

凌晨两点改方案时,突然收到婚庆团队发来的视频——胶东某酒店宴会厅,三个穿大红棉袄的中年妇女跟敢死队似的往前冲,眼瞅着就要扑到新娘的高额钻石项链上。要不是门口小伙及时阻拦,这婚礼造型团队熬了三个月的方案...

微服务架构实战:商家管理后台与sso设计,SSO客户端设计

SSO客户端设计下面通过模块merchant-security对SSO客户端安全认证部分的实现进行封装,以便各个接入SSO的客户端应用进行引用。安全认证的项目管理配置SSO客户端安全认证的项目管理使...

还在为 Spring Boot 配置类加载机制困惑?一文为你彻底解惑

在当今微服务架构盛行、项目复杂度不断攀升的开发环境下,SpringBoot作为Java后端开发的主流框架,无疑是我们手中的得力武器。然而,当我们在享受其自动配置带来的便捷时,是否曾被配置类加载...

Seata源码—6.Seata AT模式的数据源代理二

大纲1.Seata的Resource资源接口源码2.Seata数据源连接池代理的实现源码3.Client向Server发起注册RM的源码4.Client向Server注册RM时的交互源码5.数据源连接...

30分钟了解K8S(30分钟了解微积分)

微服务演进方向o面向分布式设计(Distribution):容器、微服务、API驱动的开发;o面向配置设计(Configuration):一个镜像,多个环境配置;o面向韧性设计(Resista...

SpringBoot条件化配置(@Conditional)全面解析与实战指南

一、条件化配置基础概念1.1什么是条件化配置条件化配置是Spring框架提供的一种基于特定条件来决定是否注册Bean或加载配置的机制。在SpringBoot中,这一机制通过@Conditional...

一招解决所有依赖冲突(克服依赖)

背景介绍最近遇到了这样一个问题,我们有一个jar包common-tool,作为基础工具包,被各个项目在引用。突然某一天发现日志很多报错。一看是NoSuchMethodError,意思是Dis...

你读过Mybatis的源码?说说它用到了几种设计模式

学习设计模式时,很多人都有类似的困扰——明明概念背得滚瓜烂熟,一到写代码就完全想不起来怎么用。就像学了一堆游泳技巧,却从没下过水实践,很难真正掌握。其实理解一个知识点,就像看立体模型,单角度观察总...

golang对接阿里云私有Bucket上传图片、授权访问图片

1、为什么要设置私有bucket公共读写:互联网上任何用户都可以对该Bucket内的文件进行访问,并且向该Bucket写入数据。这有可能造成您数据的外泄以及费用激增,若被人恶意写入违法信息还可...

spring中的资源的加载(spring加载原理)

最近在网上看到有人问@ContextConfiguration("classpath:/bean.xml")中除了classpath这种还有其他的写法么,看他的意思是想从本地文件...

Android资源使用(android资源文件)

Android资源管理机制在Android的开发中,需要使用到各式各样的资源,这些资源往往是一些静态资源,比如位图,颜色,布局定义,用户界面使用到的字符串,动画等。这些资源统统放在项目的res/独立子...

如何深度理解mybatis?(如何深度理解康乐服务质量管理的5个维度)

深度自定义mybatis回顾mybatis的操作的核心步骤编写核心类SqlSessionFacotryBuild进行解析配置文件深度分析解析SqlSessionFacotryBuild干的核心工作编写...

@Autowired与@Resource原理知识点详解

springIOCAOP的不多做赘述了,说下IOC:SpringIOC解决的是对象管理和对象依赖的问题,IOC容器可以理解为一个对象工厂,我们都把该对象交给工厂,工厂管理这些对象的创建以及依赖关系...

java的redis连接工具篇(java redis client)

在Java里,有不少用于连接Redis的工具,下面为你介绍一些主流的工具及其特点:JedisJedis是Redis官方推荐的Java连接工具,它提供了全面的Redis命令支持,且...