unity3d 多相机分流_Unity3D+Post Processing Stack V2自定义后处理效果研究 YuanZiming

本文介绍了如何在Unity3D中结合Post Processing Stack V2自定义后处理效果,包括编写着色器、创建效果类以及操作参数。在使用官方插件时遇到的问题,以及解决纯黑纹理问题的方法,同时提供了代码示例和注意事项。
摘要由CSDN通过智能技术生成

背景

众所周知,Unity3D支持自定义后处理效果,实现过程有三步:

  1. 添加着色器,在着色器里书写后处理代码;

  2. 添加材质,把材质和着色器绑定;

  3. 给相机添加脚本,重写其OnRenderImage方法,将材质传入Graphics.Blit方法中。

但是在做最近的一个项目时,我使用了Unity3D的官方后处理插件Post Processing Stack V2(以下简称PPV2)来简化辉光、环境光遮蔽这类后处理效果的使用。但之后我又需要自定义一些后处理效果,此时就出现了问题。我发现我的OnRenderImage方法没有正常地接收到渲染帧经过插件处理后的纹理,而是接收到一个纯黑纹理,最后输出的也是纯黑,使得我的后处理效果无法正常工作,网上也找不到实际原因,可能和渲染管线的不同有关。为了解决这个问题,必须基于PPV2自定义一个效果,然后在其他代码中操作这个效果里的参数,由PPV2来执行我们的后处理效果。这个国内国外的教程都非常少,我主要参考了PPV2的官方文档,在这里给出。

代码

着色器
Shader "Hidden/Custom/Blend" {    HLSLINCLUDE        #include "Packages/com.unity.postprocessing/PostProcessing/Shaders/StdLib.hlsl"    TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);    TEXTURE2D_SAMPLER2D(_DesTex, sampler_DesTex);        float _Alpha;        float4 Frag(VaryingsDefault i) : SV_Target {      float4 col1 = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoord);      float4 col2 = SAMPLE_TEXTURE2D(_DesTex, sampler_DesTex, i.texcoord);      float4 col = lerp(col2, col1, _Alpha);      return col;        }    ENDHLSL    SubShader {        Cull Off ZWrite Off ZTest Always        Pass {            HLSLPROGRAM                #pragma vertex VertDefault                #pragma fragment Frag            ENDHLSL        }    }}

基本和文档中的一致,只是修改了片元着色器函数里的代码,实现将两张纹理进行混合的过程,另外由于这个文档比较新,实例的Shader语法好像和以前的CG语言不太一样,不知道是不是换成了HLSL。

效果自定义
using System;using UnityEngine;using UnityEngine.Rendering.PostProcessing;[Serializable][PostProcess(typeof(BlendRenderer), PostProcessEvent.AfterStack, "Custom/Blend")]public sealed class Blend : PostProcessEffectSettings {    public TextureParameter DesTex = new TextureParameter();    public FloatParameter Alpha = new FloatParameter();}public sealed class BlendRenderer : PostProcessEffectRenderer{    public override void Render(PostProcessRenderContext context) {        var sheet = context.propertySheets.Get(Shader.Find("Hidden/Custom/Blend"));        sheet.properties.SetTexture("_DesTex", settings.DesTex);        sheet.properties.SetFloat("_Alpha", settings.Alpha);        context.command.BlitFullscreenTriangle(context.source, context.destination, sheet, 0);    }}

这里定义了两个类,一个是设置类,提供了后处理效果所需的各种属性,其中支持的属性类型可以在项目下Packages/Post Processing/PostProcessing/Runtime/ParameterOverride.cs里找到,对应的基础类型有int、float、color、vector2、vector3、vector4、spline和texture。第二个类用来重写后处理方法,一般在这里指定要用的shader和给shader里的变量赋值。

修改效果参数
    void Start() {        m_Blend = ScriptableObject.CreateInstance();        m_Blend.enabled.Override(true);        m_Blend.Alpha.Override(1f);        m_Blend.DesTex.Override(Texture2D.blackTexture);        m_Volume = PostProcessManager.instance.QuickVolume(8, 100f, m_Blend);            }

这一段是初始化,先创建后处理效果,然后将其加入到后处理体积中。初始化后处理效果参数用Override方法,注意QuickVolume方法的第一个参数非常重要,它对应在PostProcessing Layer组件里填写的层的编号。

m_Blend.DesTex.value = tex; m_Blend.Alpha.value = Alpha; 

平常赋值直接修改属性名的value属性。

    private void OnDestroy() {        RuntimeUtilities.DestroyVolume(m_Volume, true, true);    }

注意在对象被销毁时要将创建的临时后处理体积销毁。如果没有这一段,更换场景时后处理会继续工作,不是我们想要的效果。

总结

Unity3D+Post Processing Stack V2自定义后处理效果其实也是只有三步,就是编写后处理着色器、编写后处理效果类、编写操作后处理参数类。主要还是国内外的教程没有与时俱进导致资料查找困难,希望更多的新教程能不断涌现,方便开发者的学习。

更新

使用已有的后处理体积

在上面的代码中,后处理体积是临时创建的,所以自定义后处理效果也是由代码生成的。如果是修改已有的后处理效果的参数,可以使用下面的代码:

m_Volume = GetComponent<PostProcessVolume>();volume.profile.TryGetSettings<Blend>(out m_Blend);

先获取脚本所在物体的后处理体积组件,然后直接获取已有的后处理效果的设置类,之后就可以修改属性了。

m_Blend.DesTex.value = tex; m_Blend.Alpha.value = Alpha; 
构建时的注意事项

由于我们在代码中引用了Hidden/Custom/Blend这个着色器文件,但是场景中并没有什么物体引用这个shader,所以构建时可能不会打包这个shader文件,导致实际运行时出现错误。我的解决方法是在场景中随意创建一个有渲染器的物体,然后创建一个引用这个shader的材质,再将材质传给这个物体,这样打包时就不会忽略了。当然可能有其他的方案有待我学习。


往期精选

Unity3D游戏开发中100+效果的实现和源码大全 - 收藏起来肯定用得着

Shader学习应该如何切入?

喵的Unity游戏开发之路 - 从入门到精通的学习线路和全教程


声明:发布此文是出于传递更多知识以供交流学习之目的。若有来源标注错误或侵犯了您的合法权益,请作者持权属证明与我们联系,我们将及时更正、删除,谢谢。

作者:YuanZiming

原文:https://www.cnblogs.com/YuanZiming/p/13299571.html


More:【微信公众号】 u3dnotes

c45924b053eb3f079309d62146ab4f7e.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值