【unity】RenderFeature的应用(生成水平面的网格线)

这篇具有很好参考价值的文章主要介绍了【unity】RenderFeature的应用(生成水平面的网格线)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【unity】RenderFeature的应用(生成水平面的网格线)

在URP里RenderFeature是用于后处理效果上的,也还可以实现一些特殊的效果,比如生成网格线。我们可以使用 CommandBuffer来创建地面网格,这样的话可以通过调整 CommandBuffer的参数来控制地面网格的密度。

实现效果

【unity】RenderFeature的应用(生成水平面的网格线),unity,游戏引擎

创建流程

  1. 创建RenderFeature模板
  2. 编写CommandBuffer生成网格方法
  3. 增加到 渲染管线资产

创建RenderFeature模板

  • 在Project面板Create→Rendering→URP Renderer Feature,默认命名为CustomRenderPassFeature

【unity】RenderFeature的应用(生成水平面的网格线),unity,游戏引擎

简介

URP Renderer Feature模板继承ScriptableRendererFeature

ScriptableRendererFeature由两个类 CustomRenderPassFeature 与 CustomRenderPass 组成,CustomRenderPass继承ScriptableRenderPass

ScriptableRendererFeature

Create:是用来初始化这个 Feature 的资源

AddRenderPasses:在 Renderer 中插入一个或多个 ScriptableRenderPass

ScriptableRenderPass

Configure :在执行渲染过程之前,Renderer 将调用此方法

Execute:是这个类的核心方法,定义我们的执行规则 ,实现渲染逻辑

FrameCleanup:可用于释放通过此过程创建的分配资源

编写CommandBuffer生成网格方法

在创建的RenderFeature模板中编写脚本如下:

using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

public class CustomRenderPassFeature : ScriptableRendererFeature
{
  
    public float lineCount; 
  
    class CustomRenderPass : ScriptableRenderPass
    {
        public float lineCount;
        public   bool isRender = false;
        public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
        {
             if (!Application.isPlaying|| !isRender) return;
            ProfilingSampler mProfilingSampler = new ProfilingSampler("Test1");
            CommandBuffer cmd = CommandBufferPool.Get("Test1 Cmd");
            Material cmdMat1 = new Material(Shader.Find("Models/LineShader"));
            using (new ProfilingScope(cmd, mProfilingSampler))
            {
                Mesh meshRenderer = CreateGridMesh(Color.green, lineCount);
                cmd.DrawMesh(meshRenderer, Matrix4x4.identity, cmdMat1);
                context.ExecuteCommandBuffer(cmd);
                CommandBufferPool.Release(cmd);
            }
        }

      /// <summary>
      /// 创建网格
      /// </summary>
      /// <param name="color"></param>
      /// <param name="spacing"></param>
      /// <param name="linesCount"></param>
      /// <returns></returns>
        public Mesh CreateGridMesh(Color color, float spacing, int linesCount = 150)
        {
            int count = linesCount / 2;
            Mesh mesh = new Mesh();
            mesh.name = "Grid " + spacing;
            int index = 0;
            int[] indices = new int[count * 8];
            Vector3[] vertices = new Vector3[count * 8];
            Color[] colors = new Color[count * 8];
            for (int i = -count; i < count; ++i)
            {
                vertices[index] = new Vector3(i * spacing, 0, -count * spacing);
                vertices[index + 1] = new Vector3(i * spacing, 0, count * spacing);

                vertices[index + 2] = new Vector3(-count * spacing, 0, i * spacing);
                vertices[index + 3] = new Vector3(count * spacing, 0, i * spacing);

                indices[index] = index;
                indices[index + 1] = index + 1;
                indices[index + 2] = index + 2;
                indices[index + 3] = index + 3;
                colors[index] = colors[index + 1] = colors[index + 2] = colors[index + 3] = color;
                index += 4;
            }
            Debug.Log(vertices.Length);
            mesh.vertices = vertices;
            mesh.SetIndices(indices, MeshTopology.Lines, 0);
            return mesh;
        }
    }
    CustomRenderPass m_ScriptablePass;

    /// <inheritdoc/>
    public override void Create()
    {
        m_ScriptablePass = new CustomRenderPass();
        m_ScriptablePass.lineCount = lineCount;
        m_ScriptablePass.renderPassEvent = RenderPassEvent.AfterRenderingOpaques;
    }
    /// <summary>
    /// 用于修改参数
    /// </summary>
    public void SetParam()
    {
        m_ScriptablePass.isRender = true;
        m_ScriptablePass.lineCount = lineCount;
    }

    public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    {
        renderer.EnqueuePass(m_ScriptablePass);
    }
}

增加到渲染管线资产(RenderPipelineAsset)

  • 找到URP Asset(位置: Edit→ProjectSetting→Quality→Rendering→RenderPipelineAsset)
  • 找到URP Universal Renderer(位置:URP Asset→Rendering→RendererList)
  • 增加Renderer Feature,点击URP Universal Renderer的Add Renderer Feature添加之前创建的Renderer Feature模板

补充

RenderFeature模板自定义参数调整方法

方法一:

    CustomRenderPassFeature custom=renderData.rendererFeatures.OfType<CustomRenderPassFeature>().FirstOrDefault();
     custom.lineCount =200;
     custom.SetParam();

方法二:文章来源地址https://www.toymoban.com/news/detail-517937.html

    [SerializeField]    
    UniversalRendererData renderData;
    List<ScriptableRendererFeature> rendererFeatures;
    Dictionary<string, ScriptableRendererFeature> innerFeatures = new Dictionary<string, ScriptableRendererFeature>();
    CustomRenderPassFeature custom;

     void Start()
    {
        rendererFeatures = renderData.rendererFeatures;
        for (int i = 0; i < rendererFeatures.Count; i++)
        {
            var feature = rendererFeatures[i];
            innerFeatures[feature.name] = feature;
        }
        ScriptableRendererFeature rendererFeature;
        innerFeatures.TryGetValue("CustomRenderPassFeature", out rendererFeature);
         custom = rendererFeature as CustomRenderPassFeature;
    }
void SetParam()
{
            custom.lineCount = 200;
            custom.SetParam();    
}
void Clear()
    {
        custom.Clear();
    }
内置渲染管线使用 CommandBuffer来创建地面网格
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;

public class CommandBufferTest : MonoBehaviour
{
    CommandBuffer cmdBuffer;
    public Material cmdMat1;
    public Camera mainCamera;
    public float m_alpha = 1.0f;
    bool m_zTest = false;
    Mesh m_grid0Mesh;
    private void Start()
    {
        cmdBuffer = new CommandBuffer() { name = "CameraCmdBuffer" };
        mainCamera.AddCommandBuffer(CameraEvent.AfterForwardOpaque, cmdBuffer);
        m_zTest = true;
        DrawMesh();
    }
    //关机调用
    void OnDestroy()
    {
        Cleanup();
    }
    //卸载调用
    void OnDisable()
    {
        Cleanup();
    }
    //载入调用
    void OnEnable()
    {
        if (m_zTest)
        
        DrawMesh();
    }
    public void DrawMesh()
    {
        cmdBuffer.Clear();
        m_grid0Mesh = CreateGridMesh(Color.green, 10);
        cmdBuffer.DrawMesh(m_grid0Mesh, Matrix4x4.identity, cmdMat1);
    }

    public Mesh CreateGridMesh(Color color, float spacing, int linesCount = 150)
    {
        int count = linesCount / 2;

        Mesh mesh = new Mesh();
        mesh.name = "Grid " + spacing;

        int index = 0;
        int[] indices = new int[count * 8];
        Vector3[] vertices = new Vector3[count * 8];
        Color[] colors = new Color[count * 8];

        for (int i = -count; i < count; ++i)
        {
            vertices[index] = new Vector3(i * spacing, 0, -count * spacing);
            vertices[index + 1] = new Vector3(i * spacing, 0, count * spacing);

            vertices[index + 2] = new Vector3(-count * spacing, 0, i * spacing);
            vertices[index + 3] = new Vector3(count * spacing, 0, i * spacing);

            indices[index] = index;
            indices[index + 1] = index + 1;
            indices[index + 2] = index + 2;
            indices[index + 3] = index + 3;

            colors[index] = colors[index + 1] = colors[index + 2] = colors[index + 3] = color;

            index += 4;
        }
        mesh.vertices = vertices;
        mesh.SetIndices(indices, MeshTopology.Lines, 0);
        return mesh;
    }
    private void Cleanup()
    {
        if (m_grid0Mesh != null)
        {
            Destroy(m_grid0Mesh);
        }
    }
}

LineShader
Shader "Models/LineShader"
{
	Properties
	{
		_Color("Color", Color) = (1, 1, 1, 1) 
		[Enum(Off,0,On,1)]_ZWrite("ZWrite", Float) = 1.0
	}

	SubShader
	{
		Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" }
		LOD 100
	
		Pass
		{ 
			ZWrite[_ZWrite]
			Blend SrcAlpha OneMinusSrcAlpha
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			// make fog work
			#pragma multi_compile_fog

			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
			};

			struct v2f
			{
				float4 vertex : SV_POSITION;
			};

			fixed4 _Color;

			v2f vert(appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				return o;
			}

			fixed4 frag(v2f i) : SV_Target
			{
				return _Color;
			}
			ENDCG
		}
	}
}

到了这里,关于【unity】RenderFeature的应用(生成水平面的网格线)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【用unity实现100个游戏之4】手搓一个网格放置功能,及装修建造种植功能(2d3d通用,附源码)

    参考原视频链接 【视频】:https://www.youtube.com/watch?v=l0emsAHIBjU 注意 :本文为学习笔记记录,推荐支持原作者,去看原视频自己手敲代码理解更加深入

    2024年02月13日
    浏览(29)
  • Unity--随机生成游戏对象

    在脚本中声明数组 RandomObjects 用于保存生成对象的类型,在project文件中拖入对象。 先将脚本拖到一个对象上,然后点击检查器-覆盖-应用到全部,这样将使所有预制件都拥有该属性。

    2024年02月15日
    浏览(31)
  • Unity游戏嵌入Android应用(融合为一个应用)

    嵌入项目的AndroidStudio版本和Unity版本 Unity2019 AndroidStudio2021 01 新建一个新的安卓项目 项目里新建一个button 实现button的点击事件进入游戏 unity导出android工程 导出的工程文件夹放入原生的安卓项目 放入如下代码 放入如下代码 放入如下代码 项目里添加UnityGameActivity.java 需要配置

    2023年04月08日
    浏览(26)
  • 【实现100个unity游戏之20】制作一个2d开放世界游戏,TileMap+柏林噪声生成随机地图(附源码)

    我的上一篇文章介绍了TileMap的使用,主要是为我这篇做一个铺垫,看过上一篇文章的人,应该已经很好的理解TileMap的使用了,这里我就不需要过多的解释一些繁琐而基础的知识了,省去很多时间。所有没看过上一篇文章的小伙伴我强烈建议先去看看:

    2024年01月20日
    浏览(36)
  • 【Unity】AI实战应用——Unity接入GPT和对游戏开发实际应用的展望

    GPT for unity插件地址: GitHub - sunsvip/ChatGPTForUnity: ChatGPT for unity 用法: 打开Unity PackageManager界面. Add package from git URL 粘贴插件地址添加 https://github.com/sunsvip/ChatGPTForUnity.git ———————————————————————————————————— 几个资本大佬花钱让一群

    2024年02月08日
    浏览(34)
  • 【Unity】AI实战应用——Unity接入ChatGPT和对游戏开发实际应用的展望

    GPT for unity插件地址: GitHub - sunsvip/ChatGPTForUnity: ChatGPT for unity 用法: 打开Unity PackageManager界面. Add package from git URL 粘贴插件地址添加 https://github.com/sunsvip/ChatGPTForUnity.git ———————————————————————————————————— 几个资本大佬花钱让一群

    2023年04月08日
    浏览(36)
  • 【用unity实现100个游戏之16】Unity中程序化生成的2D地牢5(附项目源码,完结)

    【视频】:https://www.youtube.com/watch?app=desktopv=-QOCX6SVFsklist=PLcRSafycjWFenI87z7uZHFv6cUG2Tzu9vindex=1 注意 :本文为学习笔记记录,推荐支持原作者,去看原视频自己手敲代码理解更加深入

    2024年02月03日
    浏览(36)
  • [游戏开发][Unity] Xlua生成wrap文件报错、打AB包Wrap报错

     Xlua生成wrap文件,自带添加了ref字段报错 例如Material生成MaterialWrap时,EnableKeyword(in LocalKeyword keyword);带着in,所以在Wrap文件中会自动在参数前生成ref导致编译不过 解决办法: 换Xlua版本就好了,也不知道我xlua当时从哪个版本copy过来的,换了xlua-master里的Xlua源码

    2024年02月04日
    浏览(42)
  • Unity学习笔记--如何优雅简便地利用对象池生成游戏对象(进阶版)LRU + 对象池

    之前写过一篇关于对象池的文章,现在来看写的并不是很好,所以来考虑优化下。 现在来看一年前写的代码,越看越不能入目hhh Unity学习笔记–如何优雅简便地利用对象池生成游戏对象 Unity学习笔记–使用 C# 开发一个 LRU PoolManager.cs BaseFactory.cs 创建 Factory 创建 object 创建 Bu

    2024年02月13日
    浏览(31)
  • CGAL笔记之网格生成——3D 表面网格生成

    这个包提供了一个函数模板来计算一个近似于表面的三角形网格。 网格划分算法需要仅通过 oracle 了解要划分网格的表面,该 oracle 能够判断给定线段、线或射线是否与表面相交,并计算交点(如果有)。此功能使包足够通用,可以应用于各种情况。例如,它可用于对描述为

    2024年02月10日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包