开发者社区> 二哈卖豆腐> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

Unity3D GPU Instancing测试

简介: GPU instancing 很早就支持手机了(Android只支持Opengl ES 3.0),最近在调研这个就对它测试了一下。 如果是不动的物体勾选static静态合并批次(40-50帧率) 自定义Shader中勾选Enable GPU Instancing
+关注继续查看

GPU instancing 很早就支持手机了(Android只支持Opengl ES 3.0),最近在调研这个就对它测试了一下。

如果是不动的物体勾选static静态合并批次(40-50帧率)

自定义Shader中勾选Enable GPU Instancing

帧率竟然还不如静态合批次(帧率 30-40)

自定义Shader

Shader "SimplestInstancedShader1"

{

Properties

{

_Color ("Color", Color) = (1, 1, 1, 1)

_MainTex ("Texture", 2D) = "white" {}

}

SubShader

{

Tags { "RenderType"="Opaque" }

LOD 100

Pass

{

CGPROGRAM

pragma vertex vert

pragma fragment frag

pragma multi_compile_instancing

include "UnityCG.cginc"

struct appdata

{

float4 vertex : POSITION;

float2 uv : TEXCOORD0;

UNITY_VERTEX_INPUT_INSTANCE_ID

};

struct v2f

{

float2 uv : TEXCOORD0;

float4 vertex : SV_POSITION;

UNITY_VERTEX_INPUT_INSTANCE_ID // necessary only if you want to access instanced properties in fragment Shader.

};

UNITY_INSTANCING_BUFFER_START(Props)

UNITY_DEFINE_INSTANCED_PROP(float4, _Color)

UNITY_INSTANCING_BUFFER_END(Props)

sampler2D _MainTex;

float4 _MainTex_ST;

v2f vert(appdata v)

{

v2f o;

UNITY_SETUP_INSTANCE_ID(v);

UNITY_TRANSFER_INSTANCE_ID(v, o); // necessary only if you want to access instanced properties in the fragment Shader.

o.vertex = UnityObjectToClipPos(v.vertex);

o.uv = TRANSFORM_TEX(v.uv, _MainTex);

return o;

}

fixed4 frag(v2f i) : SV_Target

{

UNITY_SETUP_INSTANCE_ID(i); // necessary only if any instanced properties are going to be accessed in the fragment Shader.

return tex2D (_MainTex, i.uv) * UNITY_ACCESS_INSTANCED_PROP(Props, _Color);

}

ENDCG

}

}

}

所以,静态不动的物体就没必要用上面的方法了,于是我又测试了Graphics.DrawMeshInstanced()方法,终于满意了。(稳定60帧)

Graphics.DrawMeshInstanced()方法不需要游戏对象以及游戏组件的额外开销,在Update()方法中一气呵成,不过它也有限制,最多可以画1023个。

还有个方法是Graphics.DrawMeshInstancedIndirect()它没有画多少的限制,而且更加灵活,我也搞了好一会儿才在游戏中跑起来,后来才知道它不能再手机上用,只有PC上可以.

在shader中接收位置 颜色 矩阵

Shader "Instanced/InstancedIndirectSelection"

{

Properties

{

_MainTex ("Texture", 2D) = "white" {}

}

SubShader

{

Tags{ "RenderType" = "Opaque" }

LOD 100

Pass

{

CGPROGRAM

pragma vertex vert

pragma fragment frag

pragma target 4.5

include "UnityCG.cginc"

StructuredBuffer positionBuffer;

StructuredBuffer colorBuffer;

StructuredBuffer matrix4x4Buffer;

struct appdata

{

fixed4 color : COLOR;

float4 vertex : POSITION;

float4 texcoord : TEXCOORD0;

};

struct v2f

{

float4 color: COLOR;

float4 vertex : SV_POSITION;

float2 texcoord : TEXCOORD0;

};

sampler2D _MainTex;

float4 _MainTex_ST;

v2f vert(appdata v, uint instanceID : SV_InstanceID)

{

float4 data = positionBuffer[instanceID];

float4x4 materix = matrix4x4Buffer[instanceID / matrix4x4Buffer.Length];

float3 worldPosition = data.xyz + mul(materix,v.vertex.xyz * data.w);

v2f o;

o.vertex = mul(UNITY_MATRIX_VP, float4(worldPosition, 1.0f));

o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);

o.color = colorBuffer[instanceID];

return o;

}

fixed4 frag(v2f i) : SV_Target

{

return tex2D (_MainTex, i.texcoord) * i.color;

}

ENDCG

}

}

}

在代码中将位置 颜色 矩阵传进去就行了

using UnityEngine;

public class InstancedIndirectExample : MonoBehaviour

{

public int instanceCount = 100000;

public Mesh instanceMesh;

public Material instanceMaterial;

private ComputeBuffer positionBuffer;

private ComputeBuffer argsBuffer;

private ComputeBuffer colorBuffer;

private ComputeBuffer matrix4x4Buffer;

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

{

// instanceMaterial.SetBuffer("positionBuffer", positionBuffer);

Graphics.DrawMeshInstancedIndirect(instanceMesh, 0, instanceMaterial, new Bounds(Vector3.zero, new Vector3(100.0f, 100.0f, 100.0f)), argsBuffer);

}

void UpdateBuffers()

{

if ( instanceCount < 1 ) instanceCount = 1;

// Positions & Colors

if (positionBuffer != null) positionBuffer.Release();

if (colorBuffer != null) colorBuffer.Release();

if (matrix4x4Buffer != null) matrix4x4Buffer.Release();

positionBuffer = new ComputeBuffer(instanceCount, 16);

colorBuffer = new ComputeBuffer(instanceCount, 4*4);

matrix4x4Buffer = new ComputeBuffer(instanceCount,16);

Vector4[] positions = new Vector4[instanceCount];

Vector4[] colors = new Vector4[instanceCount];

Matrix4x4[] materix4X4 = new Matrix4x4[instanceCount];

for (int i=0; i < instanceCount; i++)

{

positions [i] = new Vector4 (i, 0f, 0f, 1f);

colors[i] = new Vector4( 1f, 1f, 1f, 1f );

materix4X4[i] = Matrix4x4.TRS (positions [i], Quaternion.Euler (0F, 0F, 0F), Vector3.one);

}

positionBuffer.SetData(positions);

colorBuffer.SetData(colors);

matrix4x4Buffer.SetData (materix4X4);

instanceMaterial.SetBuffer("positionBuffer", positionBuffer);

instanceMaterial.SetBuffer("colorBuffer", colorBuffer);

instanceMaterial.SetBuffer("matrix4x4Buffer", matrix4x4Buffer);

// indirect args

uint numIndices = (instanceMesh != null) ? (uint)instanceMesh.GetIndexCount(0) : 0;

args[0] = numIndices;

args[1] = (uint)instanceCount;

argsBuffer.SetData(args);

}

void OnDisable()

{

if (positionBuffer != null) positionBuffer.Release();

positionBuffer = null;

if (colorBuffer != null) colorBuffer.Release();

colorBuffer = null;

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

argsBuffer = null;

if (matrix4x4Buffer != null) matrix4x4Buffer.Release();

matrix4x4Buffer = null;

}

}

如果是发生移动的物体顶点数量在900以内会动态合并批次,如果需要支持更多的顶点GPU Instaning的优势就更明显了。 目前来看草、石头、植被、比较合适用它。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
基于Windows环境下CPU和GPU版本Tensorflow详细安装过程
基于Windows环境下CPU和GPU版本Tensorflow详细安装过程
0 0
CV:查看本地的电脑显卡是否支持GPU以及需要安装匹配的CUDA版本、tensorflow_gpu版本等
CV:查看本地的电脑显卡是否支持GPU以及需要安装匹配的CUDA版本、tensorflow_gpu版本等
0 0
GPU服务器初体验:从零搭建Pytorch GPU开发环境
如果你有一台带N卡的个人电脑的话,那么是不需要买GPU云服务器的。如果你的公司或实验室有GPU服务器这个福利或资源的话,那么玩玩GPU服务器也不错。
0 0
GPU配置太麻烦?来试试Docker一键配置GPU深度学习开发环境吧
docker环境无需安装cuda、cuDNN,docker镜像安装完毕后,就都好了,一键部署好之后,可以随意迁移,再也不用环境发愁了。
0 0
成功解决:Win系统下的Tensorflow使用CPU而不使用GPU运行加速
成功解决:Win系统下的Tensorflow使用CPU而不使用GPU运行加速
0 0
Unity全面优化
Unity的项目优化已经是老生常谈,很多人在项目完成之后,即便创意新颖,也会觉得差强人意,原因就在于没有做详细的项目优化。众所周知,Unity是一个综合性的3D开发引擎,其中包含图像渲染,逻辑处理,数据存储,发布测试等等各方面的内容。
686 0
Win10安装TensorFlow1.9-GPU版本
前言 前段时间更新自己电脑上的tf1.4到1.9,没想到踩了这么多坑。。。特意记录下来希望可以帮到大家 删除旧版本 如果你电脑上没有安装旧版本的tf,就可以忽略这一步。我是因为想要升级到最新版本,所以需要先卸载旧版本。
2265 0
win10环境下tensorflow-gpu安装
      踩了很多坑,浪费了一下午时间,在此记录一下。 pip install tensorflow-gpu   然后下载安装cuda8.0 https://developer.nvidia.
766 0
[Unity3d]DrawCall优化手记
在最近,使用U3D开发的游戏核心部分功能即将完成,中间由于各种历史原因,导致项目存在比较大的问题,这些问题在最后,恐怕只能通过一次彻底的重构来解决 现在的游戏跑起来会有接近130-170个左右的DrawCall,游戏运行起来明显感觉到卡,而经过一天的优化,Draw...
746 0
文章
问答
文章排行榜
最热
最新
相关电子书
更多
使用TensorFlow搭建智能开发系统自劢生成App UI代码
立即下载
使用TensorFlow搭建智能开发系统自动生成App UI
立即下载
低代码开发师(初级)实战教程
立即下载