如何通过代码在Unity设置URP通用渲染管线资源的画质选项、后处理效果、渲染分辨率、抗锯齿效果、Renderer Features等效果并制作一个可以设置它们的UI

   Hello喔 这里是没有鱼的猫先生,本期文章的主题佬们有看到标题了 QWQ

   当使用Urp管道项目时,我们需要在一个Urp通用管线资源的项目中修改它的各种效果以玩家自己设置不同的画质需求,那下面这个通用脚本便诞生了,它也许并不适用于所有的场景,但是相信应用过它后可以给初学Urp渲染管线资源的您提供如何去修改画质选项等功能的新思路。

(⁠*⁠´⁠ω⁠`⁠*⁠)

                                   

    通常情况下在使用Urp通用管线资源的项目中的源代码脚本挂上物体并赋值必须赋值的变量后成功运行效果如上。  😀     

在了解到脚本的内容之后,你可以将其中UI部分删除,并整合到你的代码当中去,以给你的项目提供基于Urp通用管线资源的画质选项用户界面。

在给脚本赋值之前 你需要先确保你的渲染管线为Universal Render Pipeline ,在Bing中可以搜索到如何创建一个Urp通用管线资源或将你的项目转化为Urp通用管线资源喔。

在Unity创建一个新的脚本 名为HowSetting,并将代码复制到其中

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using System;
using UnityEngine.UI;
using UnityEngine.Experimental.Rendering.Universal;
using UnityEditor.Rendering.Universal;

public class HowSetting : MonoBehaviour
{
    [Header("如何设置URP管道的画质项目")]
    [Header("必须赋值的变量")]

    [Tooltip("至少需要添加一个 通用渲染数据 ")]
    public UniversalRendererData[] URD;
    [Tooltip("至少需要添加一个 通用渲染管线资产 ")]
    public UniversalRenderPipelineAsset[] URPA;
    [Tooltip("至少需要添加一个 体积")]
    public Volume volume;

    [Header("选择赋值的变量")]
    [Tooltip("指定 主摄像机,你可以不用赋值此变量")]
    public Camera MainCamera;
    [Tooltip("指定 Bloom后处理效果,你可以不用赋值此变量")]
    public Bloom BM;
    [Tooltip("指定 Motionblur后处理效果,你可以不用赋值此变量")]
    public MotionBlur MB;
    [Tooltip("指定 DepthOfField后处理效果,你可以不用赋值此变量")]
    public DepthOfField DF;

    [Header("状态")]
    [Tooltip("视野")]
    public float VisualField;
    [Tooltip("画质选项")]
    public int QualitySetting = 0;
    [Tooltip("后处理抗锯齿 0=null 1=FXAA 2=SMAA低质量 3=SMAA中质量 4=SMAA高质量")]
    public int Setting_AntiAliasing_Set = 0;
    [Tooltip("MSAA抗锯齿")]
    public int MSAA =0;
    [Tooltip("渲染分辨率")]
    public float SSAA = 1;
    [Tooltip("屏幕空间环境光遮蔽")]
    public bool AmbientOcclusions =false;
    [Tooltip("Bloom")]
    public bool BMactive = false;
    [Tooltip("MotionBlur")]
    public bool MBactive = false;
    [Tooltip("DepthOfField")]
    public bool DFactive = false;




    void Start()
    {
        
        if (MainCamera == null)
        {
            MainCamera = Camera.main;
        }
        MainCamera.GetComponent<UniversalAdditionalCameraData>().renderPostProcessing = true; //打开后处理
        if (volume != null)
        {
            if(!volume.profile.Has<Bloom>())                                                  //如果Volume不存在Bloom后处理效果则添加并赋值初始值
            {
                volume.profile.Add<Bloom>();
                volume.profile.TryGet<Bloom>(out BM);
                BM.active = true;
                BM.intensity.value = 2f;
                BM.intensity.overrideState = true;           
                BM.clamp.value = 0.9f;
                BM.clamp.overrideState = true;

            }
            if (!volume.profile.Has<MotionBlur>())                                           //如果Volume不存在MotionBlur后处理效果则添加并赋值初始值
            {
                volume.profile.Add<MotionBlur>();
                volume.profile.TryGet<MotionBlur>(out MB);
                MB.active=true;
                MB.quality.value = MotionBlurQuality.High;
                MB.quality.overrideState = true;
                MB.intensity.value = 1;
                MB.intensity.overrideState = true;
                MB.clamp.value = 0.05f;
                MB.clamp.overrideState = true;
            }
            if (!volume.profile.Has<DepthOfField>())                                          //如果Volume不存在DepthOfField后处理效果则添加并赋值初始值
            {
                volume.profile.Add<DepthOfField>();
                volume.profile.TryGet<DepthOfField>(out DF);
                DF.active = true;
                DF.mode.value = DepthOfFieldMode.Bokeh;
                DF.mode.overrideState = true;
                DF.focusDistance.value = 40;
                DF.focusDistance.overrideState = true;
                DF.focalLength.value = 300;
                DF.focalLength.overrideState = true;
                DF.aperture.value = 10f;
                DF.aperture.overrideState = true;
                DF.bladeRotation.value = 40f;
                DF.bladeRotation.overrideState = true;

            }
            volume.profile.TryGet<Bloom>(out BM);
            volume.profile.TryGet<MotionBlur>(out MB);
            volume.profile.TryGet<DepthOfField>(out DF);

            foreach (var child in URD)                                                                                      //遍历所有的渲染数据
            {                
                
                if (child.rendererFeatures.Find(ss => ss.name == "ScreenSpaceAmbientOcclusion"))                              //如果环境光遮蔽存在则执行
                {
                    child.rendererFeatures.Find(ss => ss.name == "ScreenSpaceAmbientOcclusion").SetActive(AmbientOcclusions);
                }
                else
                {
                 //   RenderObjects rendererFeatrues = ScriptableObject.CreateInstance<RenderObjects>();                    
                 //   rendererFeatrues.name = "ScreenSpaceAmbientOcclusion";
                 //   child.rendererFeatures.Add(rendererFeatrues);
                }
                
            }
        }
        SSAA = 1;
        VisualField = MainCamera.fieldOfView;
    }


    void OnGUI()
    {
        VisualField = GUI.HorizontalSlider(new Rect(30, 170, 100, 30), VisualField, 60, 110);
        GUI.Label(new Rect(5, 170, 40, 30), VisualField.ToString());
        GUI.Label(new Rect(130, 170, 80, 30), "视野");

      //  QualitySetting = (int)GUI.HorizontalSlider(new Rect(30, 210, 100, 30), QualitySetting, 0, 2);
     //   GUI.Label(new Rect(5, 210, 40, 30), QualitySetting.ToString());
     //   GUI.Label(new Rect(130, 210, 80, 30), "无");

        Setting_AntiAliasing_Set =(int)GUI.HorizontalSlider(new Rect(30, 250, 100, 30), Setting_AntiAliasing_Set, 0, 4);
        GUI.Label(new Rect(5, 250, 40, 30), Setting_AntiAliasing_Set.ToString());
        GUI.Label(new Rect(130, 250, 150, 30), "SMAA和FXAA抗锯齿");

        MSAA = (int)GUI.HorizontalSlider(new Rect(30, 290, 100, 30), MSAA, 0, 3);
        GUI.Label(new Rect(5, 290, 40, 30), MSAA.ToString());
        GUI.Label(new Rect(130, 290, 80, 30), "MSAA抗锯齿");

        SSAA = GUI.HorizontalSlider(new Rect(30, 340, 100, 30), SSAA, 0.5f, 2f);
        GUI.Label(new Rect(5, 340, 40, 30), SSAA.ToString());
        GUI.Label(new Rect(130, 340, 80, 30), "渲染分辨率");

        int aa = 0;
        
        foreach(var child in URD)
        {
            if (GUI.Button(new Rect(130, 10+(aa*30), 100, 30), "第"+aa+"个画质选项"))
            {
                QualitySetting = aa;
                QualitySettings.SetQualityLevel(aa, true);
                child.rendererFeatures.Find(ss => ss.name == "ScreenSpaceAmbientOcclusion").SetActive(false);
                MainCamera.GetComponent<UniversalAdditionalCameraData>().renderPostProcessing = true;
                if(aa<=0)
                {  BM.active = true;}
                else
                { BM.active = false; }
                if (aa <= 1)
                { MB.active = true; }
                else
                { MB.active = false; }
                if (aa <= 2)
                { DF.active = true; }
                else
                { DF.active = false; }
            }
                aa++;
        }
        aa = 0;
        BMactive=GUI.Toggle(new Rect(30, 100, 100, 20), BMactive, "泛光");
        MBactive = GUI.Toggle(new Rect(30, 120, 100, 20), MBactive, "动态模糊");
        DFactive = GUI.Toggle(new Rect(30, 140, 100, 20), DFactive, "景深");
        AmbientOcclusions = GUI.Toggle(new Rect(180, 100, 100, 20), AmbientOcclusions, "环境光渲染");
        

        #region 画质修改
        if (GUI.changed)
        {
           
            MainCamera.fieldOfView = VisualField;
            #region 修改抗锯齿
            if (Setting_AntiAliasing_Set == 0)
            {
                MainCamera.GetComponent<UniversalAdditionalCameraData>().antialiasing = UnityEngine.Rendering.Universal.AntialiasingMode.None;
            }
            else if (Setting_AntiAliasing_Set == 1)
            {
                MainCamera.GetComponent<UniversalAdditionalCameraData>().antialiasing = UnityEngine.Rendering.Universal.AntialiasingMode.FastApproximateAntialiasing;
            }
            else if (Setting_AntiAliasing_Set == 2)
            {
                MainCamera.GetComponent<UniversalAdditionalCameraData>().antialiasing = UnityEngine.Rendering.Universal.AntialiasingMode.SubpixelMorphologicalAntiAliasing;
                MainCamera.GetComponent<UniversalAdditionalCameraData>().antialiasingQuality = UnityEngine.Rendering.Universal.AntialiasingQuality.Low;
            }
            else if (Setting_AntiAliasing_Set == 3)
            {
                MainCamera.GetComponent<UniversalAdditionalCameraData>().antialiasing = UnityEngine.Rendering.Universal.AntialiasingMode.SubpixelMorphologicalAntiAliasing;
                MainCamera.GetComponent<UniversalAdditionalCameraData>().antialiasingQuality = UnityEngine.Rendering.Universal.AntialiasingQuality.Medium;
            }
            else if (Setting_AntiAliasing_Set == 4)
            {
                MainCamera.GetComponent<UniversalAdditionalCameraData>().antialiasing = UnityEngine.Rendering.Universal.AntialiasingMode.SubpixelMorphologicalAntiAliasing;
                MainCamera.GetComponent<UniversalAdditionalCameraData>().antialiasingQuality = UnityEngine.Rendering.Universal.AntialiasingQuality.High;
            }
            #endregion
            #region 修改MSAA
            if (MSAA == 0)
            {
                foreach (var child in URPA)
                {
                    child.msaaSampleCount = 1;
                }
            }
            else if (MSAA == 1)
            {
                foreach (var child in URPA)
                {
                    child.msaaSampleCount = 2;
                }
            }
            else if (MSAA == 2)
            {
                foreach (var child in URPA)
                {
                    child.msaaSampleCount = 4;
                }
            }
            else if (MSAA == 3)
            {
                foreach (var child in URPA)
                {
                    child.msaaSampleCount = 8;
                }
            }
            #endregion
            #region 修改SSAA
            foreach (var child in URPA)
            {
                child.renderScale = SSAA;
            }
            #endregion
            #region 修改AmbientOcclusion
            foreach (var child in URD)
            {
                Debug.Log(child.rendererFeatures.Find(ss => ss.name == "ScreenSpaceAmbientOcclusion"));
                child.rendererFeatures.Find(ss => ss.name == "ScreenSpaceAmbientOcclusion").SetActive(AmbientOcclusions);
            }
            #endregion
            #region 打开或关闭泛光
            BM.active = BMactive;
            #endregion
            #region 打开或关闭动态模糊
            MB.active=MBactive;
            #endregion
            #region 打开或关闭景深
            DF.active = DFactive;
            #endregion
        }
        #endregion

    }
}

 在Edit-ProjectSettings的质量中查看我们有几个质量级别,在一个新的使用URP管道资源的项目中,你会获得三个质量级别选项,这些质量级别的通用渲染管线资源和所对应的通用渲染数据通常会存储在Asset/Setting。(如下图)

 

 你可以将此脚本挂在项目的摄像机上 此时你可以看到以下内容

 你可以不用给 选择赋值的变量 下的变量赋值,不过如果赋值了它便不会自动添加所对应的值

你需要给必须赋值的选项赋值 分别为URD(通用渲染数据)、URPA(通用渲染管线资源)和Volume(这里翻译为了音量,它其实是体积组件,通常情况创建一个新的Urp管线资源项目下会自动获得一个挂有Volume的组件,volume组件像下图这样) 

URD(通用渲染数据)、URPA(通用渲染管线资源)通常在Asset/Setting中,你可以把项目所拥有的所有URD和URPA添加到变量中 通常分别有三个 在添加完成内容后 它将会是这样   

                                     

可以不用给Volume添加眩光、动态模糊、景深等效果喔,通常情况它将会由脚本完成添加值

在完成这些之后 此脚本就能够正常运行并可以修改大部分的内容了 但是它无法修改环境光遮蔽效果 环境光遮蔽是独立于Volume后处理之外的后处理效果 它需要在  URD(通用渲染数据)中手动点击Add Renderer Feature添加

 

 点击添加Screen Space Ambient Occlusion之后 你便能够添加屏幕空间环境光遮蔽效果了 你需要在所有的URD(通用渲染数据)中都添加屏幕空间环境光遮蔽效果 此时脚本会遍历RendererFeature 列表找到屏幕空间环境光遮蔽效果并进行打开或关闭操作了喔(⁠。⁠•̀⁠ᴗ⁠-⁠)⁠✧

在进行完成这些设置之后 我们便可以设置项目选择的画质级别等内容了 我们也可以修改这个脚本的UI 或者添加更多的Urp渲染管道后处理效果 ᕙ⁠(⁠@⁠°⁠▽⁠°⁠@⁠)⁠ᕗ

那教程就就到这里了喔 如对此脚本有疑问请在bilibili中联系同名作者 猫先生不是鱼先生 喔 😀

或在QQ频道搜索 Unity社区 (7083) 与 加入QQ社群 Unity新手村(425)来询问更多Unity大佬

Unity新手村 QQ社群:524745718

(⁠≧⁠▽⁠≦⁠)
 

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>