当前位置: 首页 > news >正文

unity Gpu Instance

参考网址:
https://blog.csdn.net/leonwei/article/details/73274808
https://docs.unity3d.com/ScriptReference/Graphics.DrawMeshInstanced.html
https://docs.unity3d.com/ScriptReference/Graphics.DrawMeshInstancedIndirect.html
https://www.cnblogs.com/hont/p/7143626.html

draw the same mesh multiple times using GPU instancing.
similar to Graphics.DrawMesh, this function draws meshes for one frame without the overhead of creating unnecessary game objects.

use this function in situations where u want to draw the same mesh for a particular amount of times using an instanced shader. meshes are not further culled by the view frustum or baked occluders, nor sorted for transparency or z efficiency.

The transformation matrix of each instance of the mesh should be packed into the matrices array. You can specify the number of instances to draw, or by default it is the length of the matrices array. Other per-instance data, if required by the shader, should be provided by creating arrays on the MaterialPropertyBlock argument using SetFloatArray, SetVectorArray and SetMatrixArray.

To render the instances with light probes, provide the light probe data via the MaterialPropertyBlock and specify lightProbeUsage with LightProbeUsage.CustomProvided. Check LightProbes.CalculateInterpolatedLightAndOcclusionProbes for the details.

Note: You can only draw a maximum of 1023 instances at once.

InvalidOperationException will be thrown if the material doesn’t have Material.enableInstancing set to true, or the current platform doesn’t support this API (i.e. if GPU instancing is not available). See SystemInfo.supportsInstancing.

以下抄写自:https://docs.unity3d.com/ScriptReference/Graphics.DrawMeshInstancedIndirect.html
Description

Draw the same mesh multiple times using GPU instancing.
similar to Graphics.DrawMeshInstanced, this function draws many instances of the same mesh, but unlike that method, the arguments for how many instances to draw come from bufferWithArgs.

use this function in situations where u want to draw the same mesh for a particular amount of times using an instanced shader. meshes are not further culled by the view frustum or baked occluders, nor sorted for transparency or z efficiency.

buffer with arguments, bufferWithArgs, has to have five integer numbers at given argsOffset offset: index count per instance, instance count, start index location, base vertex location, start instance location.

unity only needs the submeshIndex argument if submeshes within the mesh have different topologies (e.g. Triangles and lines). otherwise, all the information about which submesh to draw comes from the bufferWithArgs argument.

Here is a script that can be used to draw many instances of the same mesh:

using UnityEngine;
using System.Collections;

public class GPUInstanceDemo : MonoBehaviour
{
    public int instanceCount = 5;
    public Mesh instanceMesh;
    public Material instanceMaterial;
    private int subMeshIndex = 0;
    private ComputeBuffer positionBuffer;
    private ComputeBuffer argsBuffer;
    private uint[] args = new uint[5] { 0, 0, 0, 0, 0 };

    void Start()
    {
        argsBuffer = new ComputeBuffer(1, args.Length * sizeof(uint), ComputeBufferType.IndirectArguments);
        UpdateBuffers();
    }

    void Update()
    {
        Graphics.DrawMeshInstancedIndirect(instanceMesh, subMeshIndex, instanceMaterial, new Bounds(Vector3.zero, new Vector3(100,100,100)), argsBuffer);
    }

    void UpdateBuffers()
    {
        if (positionBuffer != null)
            positionBuffer.Release();
        positionBuffer = new ComputeBuffer(instanceCount, 16);
        Vector4[] positions = new Vector4[instanceCount];
        for (int i = 0; i < instanceCount; i++)
        {
            float x = Random.Range(-5, 5);
            float y = Random.Range(-5, 5);
            float z = Random.Range(-5, 5);
            positions[i] = new Vector4(x, y, z);
        }
        positionBuffer.SetData(positions);
        instanceMaterial.SetBuffer("positionBuffer", positionBuffer);
    }

    void OnDisable()
    {
        if (positionBuffer != null)
            positionBuffer.Release();
        positionBuffer = null;

        if (argsBuffer != null)
            argsBuffer.Release();
        argsBuffer = null;
    }
}

shader代码:

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Instanced/InstancedShader" 
{
	SubShader
	{
		Pass 
		{

			Tags {"LightMode" = "ForwardBase"}

			CGPROGRAM

			#pragma vertex vert
			#pragma fragment frag
			#pragma multi_compile_fwdbase nolightmap nodirlightmap nodynlightmap novertexlight
			#pragma target 4.5

			#include "UnityCG.cginc"


			#if SHADER_TARGET >= 45
			StructuredBuffer<float4> positionBuffer;
			#endif

			struct v2f
			{
				float4 pos : SV_POSITION;
			};

			v2f vert(appdata_full v, uint instanceID : SV_InstanceID)
			{
				#if SHADER_TARGET >= 45
				float4 data = positionBuffer[instanceID];
				#else
				float4 data = 0;
				#endif
				v2f o;
				v.vertex += data;
				o.pos = UnityObjectToClipPos(v.vertex);
				return o;
			}

			fixed4 frag(v2f i) : SV_Target
			{
				  #if SHADER_TARGET >= 45
					fixed4 data = fixed4(1,1,0,1);
				#else
					fixed4 data = fixed4(1, 0, 0, 1);
				#endif
					return data;
			}
			ENDCG
		}
	}
}

实现效果:
在这里插入图片描述
完整的案例,见官网。
但是有一个问题:
Graphics.DrawMeshInstancedIndirect(instanceMesh, subMeshIndex, instanceMaterial, new Bounds(Vector3.zero, new Vector3(100,100,100)), argsBuffer);
最后的两个参数不知道啥意思,待续……

相关文章:

  • 通过配置JVM参数解决生成日志存在乱码问题
  • unity Graphics的一些方法介绍
  • CodeForces 1151B Dima and a Bad XOR
  • unity Stopwatch
  • unity 烘焙参数的设置
  • JS 设计模式五 -- 命令模式
  • CommandBuffer实现Distort屏幕扭曲效果
  • Anti-aliasing and Continuity with Trapezoidal Shadow Maps
  • tarjan----强连通分量
  • Trapezoidal Shadow Maps (TSM) - Recipe
  • 十天冲刺-03
  • Perspective Shadow Maps: Care and Feeding
  • 网络基础 08_NAT
  • C# AttributeUsage
  • vue组件之间的传值方式
  • 【翻译】babel对TC39装饰器草案的实现
  • 2017-08-04 前端日报
  • 345-反转字符串中的元音字母
  • Git初体验
  • k8s 面向应用开发者的基础命令
  • Linux编程学习笔记 | Linux多线程学习[2] - 线程的同步
  • Node项目之评分系统(二)- 数据库设计
  • Sass 快速入门教程
  • spring boot下thymeleaf全局静态变量配置
  • windows下如何用phpstorm同步测试服务器
  • 从0搭建SpringBoot的HelloWorld -- Java版本
  • 后端_ThinkPHP5
  • 前端每日实战:61# 视频演示如何用纯 CSS 创作一只咖啡壶
  • 如何邀请好友注册您的网站(模拟百度网盘)
  • 正则表达式
  • hi-nginx-1.3.4编译安装
  • 仓管云——企业云erp功能有哪些?
  • # Pytorch 中可以直接调用的Loss Functions总结:
  • #使用清华镜像源 安装/更新 指定版本tensorflow
  • (16)UiBot:智能化软件机器人(以头歌抓取课程数据为例)
  • (4)事件处理——(6)给.ready()回调函数传递一个参数(Passing an argument to the .ready() callback)...
  • (rabbitmq的高级特性)消息可靠性
  • (附源码)计算机毕业设计SSM疫情下的学生出入管理系统
  • (四)Tiki-taka算法(TTA)求解无人机三维路径规划研究(MATLAB)
  • (一)RocketMQ初步认识
  • (转) Android中ViewStub组件使用
  • (转)PlayerPrefs在Windows下存到哪里去了?
  • (转载)利用webkit抓取动态网页和链接
  • (转载)微软数据挖掘算法:Microsoft 时序算法(5)
  • .locked1、locked勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET core 自定义过滤器 Filter 实现webapi RestFul 统一接口数据返回格式
  • .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter
  • .Net8 Blazor 尝鲜
  • .net利用SQLBulkCopy进行数据库之间的大批量数据传递
  • .NET牛人应该知道些什么(2):中级.NET开发人员
  • .net专家(张羿专栏)
  • [.NET 即时通信SignalR] 认识SignalR (一)
  • [C++11 多线程同步] --- 条件变量的那些坑【条件变量信号丢失和条件变量虚假唤醒(spurious wakeup)】
  • [cocos2d-x]关于CC_CALLBACK
  • [CSS]浮动