浅谈Unity之生成水平面的网格线

简介: RenderFeature的应用(生成水平面的网格线)

前言:每日记录自己学习unity的心得和体会,小弟才疏学浅,如有错误的地方,欢迎大佬们指正,感谢~


创建流程

创建RenderFeature模板

编写CommandBuffer生成网格方法

增加到 渲染管线资产

创建RenderFeature模板

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

简介


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);

   }

}

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

 }

}

}

相关文章
|
存储 缓存 算法
【计算机网络】数据链路层
【计算机网络】数据链路层
2224 0
【计算机网络】数据链路层
|
Java Linux
java查看CPU使用过高(linux)
java查看CPU使用过高(linux)
354 0
|
10月前
|
数据采集 API 开发者
1688商品评论API使用指南
本文介绍1688商品评论数据获取方案,基于合规爬虫技术解析商品ID(offerId)对应的买家评论信息,涵盖评论内容、评分、采购详情、多媒体及商家回复等。适用于口碑分析、质量调研等非商用学习场景,遵循平台规则与法律法规,不提供官方API外的公开接口。
|
10月前
|
机器学习/深度学习 存储 人工智能
AI 十大论文精讲(九):无损失量化革命——LLM.int8 () 破解千亿大模型内存困局
本文解读AI十大核心论文第九篇《LLM.int8()》,聚焦大模型推理中的内存瓶颈问题。该论文提出创新的混合精度量化方法,通过向量级量化与异常值分离技术,首次实现千亿参数模型无损8位量化,显著降低部署成本,提升计算效率,推动大模型在消费级硬件上的落地应用,为低比特量化研究奠定重要基础。
1019 8
|
6月前
|
人工智能 缓存 Serverless
Serverless AI部署实践:低成本构建AI应用的工程化路径
阿里云Serverless GPU方案破解AI落地难题:冷热资源分离、ComfyUI节点化封装、按量计费(单图低至0.002元),助力中小团队低成本试错。已支撑毛绒生图、语音克隆等场景,GPU利用率提升显著。(239字)
|
人工智能 NoSQL 数据可视化
n8n:16万Star超明星项目的架构解读
n8n从单体架构逐步演进为企业级集成平台,具备AI集成能力,适用于自动化场景,成为iPaaS领域的优选方案。
903 0
n8n:16万Star超明星项目的架构解读
|
9月前
|
人工智能 前端开发 JavaScript
【开源】智能简历平台,基于Vue3 + AI 大模型:我开发了一款“不像编辑器”的智能简历平台
豫唐AI简历平台是面向职高生的开源求职助手,融合Qwen大模型与职业心理学,提供智能诊断、STAR润色、模拟面试、MBTI/Holland测评及微信扫码登录。纯前端Vue3+TS实现,支持所见即所得编辑与无水印PDF导出。
1252 2
|
12月前
|
存储 自然语言处理 Java
全球语言无障碍:Unicode标准解读与技术演进史
Unicode是全球字符统一编码标准,旨在为世界上所有文字、符号及emoji分配唯一码点,解决多语言乱码问题。它兼容ASCII,支持超14万字符,覆盖现代与古文字,通过UTF-8、UTF-16等编码方案实现跨平台信息交换,是互联网、操作系统和多语言通信的基础。
1956 2
|
10月前
|
人工智能 自然语言处理 运维
解锁2025企业选型难题:十大智能客服品牌实测榜单与权威解读
智能客服市场进入“主动服务+生态协同”成熟期,企业选型面临同质化、适配难等挑战。本文基于技术实力、场景落地与未来潜力,发布2025年十大品牌实测榜单,涵盖瓴羊、智齿、轻简AI、科大讯飞等主流厂商,从核心技术、行业适配到成本效益全面解析,助力企业精准匹配需求,实现服务升级与效率跃迁。
|
存储 人工智能 JSON
AscendC从入门到精通系列(三)基于自定义算子工程开发AscendC算子
本文介绍了基于Ascend C的自定义算子开发流程,涵盖从工程创建、代码编写、编译部署到运行验证的全过程。以动态shape的AddCustom算子为例,详细描述了如何利用CANN提供的工具msOpGen生成开发工程,实现算子核函数与host侧代码,以及如何编译、部署和测试自定义算子。