Unity中无GC Alloc的CalculateFrustumPlanes
如果你需要在逻辑层做一些预先的剔除操作,可能需要从MainCamera构建视锥体,然后进行简易相交测试,这时候在unity里面用到的函数接口是CalculateFrustumPlanes:
namespace UnityEngine
{
// 摘要:
// Utility class for common geometric functions.
public sealed class GeometryUtility
{
public GeometryUtility(); // 摘要:
// Calculates frustum planes.
public static Plane[] CalculateFrustumPlanes(Camera camera);
//
// 摘要:
// Calculates frustum planes.
public static Plane[] CalculateFrustumPlanes(Matrix4x4 worldToProjectionMatrix);
//
// 摘要:
// Returns true if bounds are inside the plane array.
public static bool TestPlanesAABB(Plane[] planes, Bounds bounds);
}
}
然而它的主要问题是有gc alloc,每次调用都会自己new一个Plane数组,这很明显是不科学的,然而unity迟迟未修复此问题。
下面提供的函数在C#层中重新实现了这个接口,同时没有gcalloc,然而由于在C#中实现的原因,其效率比引擎提供的C++版本慢一倍。C#版本实测一次调用在0.01毫秒左右。所以使用哪一个版本,根据实际需求来是最好的。
C#版本的实现:
public static class GeometryUtilityUser
{
/**
* @warning OutPlanes must be new Plane[6]
* Plane Position :
* Left
* Right
* Bottom
* Top
* Near
* Far
*/
enum EPlaneSide
{
Left,
Right,
Bottom,
Top,
Near,
Far
} static float[] RootVector = new float[];
static float[] ComVector = new float[]; public static void CalculateFrustumPlanes(Camera InCamera, ref Plane[] OutPlanes)
{
Matrix4x4 projectionMatrix = InCamera.projectionMatrix;
Matrix4x4 worldToCameraMatrix = InCamera.worldToCameraMatrix;
Matrix4x4 worldToProjectionMatrix = projectionMatrix * worldToCameraMatrix; RootVector[] = worldToProjectionMatrix[, ];
RootVector[] = worldToProjectionMatrix[, ];
RootVector[] = worldToProjectionMatrix[, ];
RootVector[] = worldToProjectionMatrix[, ]; ComVector[] = worldToProjectionMatrix[, ];
ComVector[] = worldToProjectionMatrix[, ];
ComVector[] = worldToProjectionMatrix[, ];
ComVector[] = worldToProjectionMatrix[, ]; CalcPlane(ref OutPlanes[(int)EPlaneSide.Left], ComVector[] + RootVector[], ComVector[] + RootVector[], ComVector[] + RootVector[], ComVector[] + RootVector[]);
CalcPlane(ref OutPlanes[(int)EPlaneSide.Right], -ComVector[] + RootVector[], -ComVector[] + RootVector[], -ComVector[] + RootVector[], -ComVector[] + RootVector[]); ComVector[] = worldToProjectionMatrix[, ];
ComVector[] = worldToProjectionMatrix[, ];
ComVector[] = worldToProjectionMatrix[, ];
ComVector[] = worldToProjectionMatrix[, ]; CalcPlane(ref OutPlanes[(int)EPlaneSide.Bottom], ComVector[] + RootVector[], ComVector[] + RootVector[], ComVector[] + RootVector[], ComVector[] + RootVector[]);
CalcPlane(ref OutPlanes[(int)EPlaneSide.Top], -ComVector[] + RootVector[], -ComVector[] + RootVector[], -ComVector[] + RootVector[], -ComVector[] + RootVector[]); ComVector[] = worldToProjectionMatrix[, ];
ComVector[] = worldToProjectionMatrix[, ];
ComVector[] = worldToProjectionMatrix[, ];
ComVector[] = worldToProjectionMatrix[, ]; CalcPlane(ref OutPlanes[(int)EPlaneSide.Near], ComVector[] + RootVector[], ComVector[] + RootVector[], ComVector[] + RootVector[], ComVector[] + RootVector[]);
CalcPlane(ref OutPlanes[(int)EPlaneSide.Far], -ComVector[] + RootVector[], -ComVector[] + RootVector[], -ComVector[] + RootVector[], -ComVector[] + RootVector[]); } static void CalcPlane(ref Plane InPlane, float InA, float InB, float InC, float InDistance)
{
Vector3 Normal = new Vector3(InA, InB, InC); float InverseMagnitude = 1.0f / (float)System.Math.Sqrt(Normal.x * Normal.x + Normal.y * Normal.y + Normal.z * Normal.z); InPlane.normal = new Vector3(Normal.x * InverseMagnitude, Normal.y * InverseMagnitude, Normal.z * InverseMagnitude); InPlane.distance = InDistance * InverseMagnitude;
}
}
下面的代码可用于验证其正确性:
private Plane[] CalcFrustum(Camera InCamera)
{
GeometryUtilityUser.CalculateFrustumPlanes(InCamera, ref CachedPlanes);
#if UNITY_EDITOR && false
Plane[] SysPlanes = GeometryUtility.CalculateFrustumPlanes(InCamera);
for (int i = ; i < SysPlanes.Length; ++i )
{
if( !IsEqual(SysPlanes[i], CachedPlanes[i]) )
{
DebugHelper.Assert(false, "Internal error in CalcFrustum");
}
}
#endif
return CachedPlanes;
}
private static bool IsEqual(Plane InFirst, Plane InSecond)
{
return IsEqual(InFirst.normal, InSecond.normal) &&
IsEqual(InFirst.distance, InSecond.distance);
}
private static bool IsEqual(Vector3 InFirst, Vector3 InSecond)
{
return IsEqual(InFirst.x, InSecond.x) &&
IsEqual(InFirst.y, InSecond.y) &&
IsEqual(InFirst.y, InSecond.y);
}
private static bool IsEqual(float InFirst, float InSecond)
{
return System.Math.Abs(InFirst - InSecond) < 0.001f;
}
private Plane[] CachedPlanes = new Plane[];
Unity中无GC Alloc的CalculateFrustumPlanes的更多相关文章
- Unity中的GC以及优化
[简介] 常见的 Unity GC 知识点总结出来的思维导图 Unity 官方文档,正巧在博客园发现了已经有位大神(zblade)把原文翻译出来了,而且质量很高~,译文地址 在这里.下面我就可耻地把译 ...
- 浅谈Unity中的GC以及优化
介绍: 在游戏运行的时候,数据主要存储在内存中,当游戏的数据不在需要的时候,存储当前数据的内存就可以被回收再次使用.内存垃圾是指当前废弃数据所占用的内存,垃圾回收(GC)是指将废弃的内存重新回收再次使 ...
- 如何查看子线程中的GC Alloc
1)如何查看子线程中的GC Alloc2)Build时,提示安卓NDK异常3)如何获得ParticleSystem产生的三角形数量4)关于图片通道的问题5)GPUSkinning导致模型动画不平滑 M ...
- UNITY 的GC ALLOC到底是什么
U3D的Profiler中的GC ALLOC 项让人很麻烦,一直搞不清楚它是什么,因为 GC 是垃圾回收,而alloc是内存分配,那么 GC ALLOC 是 垃圾回收内存分配? 这个名字起的太TM烂了 ...
- Unity优化之GC——合理优化Unity的GC
转载请标明出处http://www.cnblogs.com/zblade/ 最近有点繁忙,白天干活晚上抽空写点翻译,还要运动,所以翻译工作进行的有点缓慢 =.= PS: 最近重新回来更新了一遍,文 ...
- Unity减少GC Alloc之 使用for替换foreach
Unity中foreach会增加GC unity中for效率比foreach高? 在unity中使用foreach遍历集合会增加gc alloc,参考的话题:作为Unity3D的脚本而言,c#中for ...
- C#可空类型的速度和GC Alloc测试
在Unity中进行速度和GC Alloc的测试 测试脚本: using UnityEngine; using System; using System.Collections; using Syste ...
- Unity3D游戏GC优化总结---protobuf-net无GC版本优化实践
protobuf-net优化效果图 protobuf-net是Unity3D游戏开发中被广泛使用的Google Protocol Buffer库的c#版本,之所以c#版本被广泛使用,是因为c++版本的 ...
- Unity中的内存泄漏
在对内存泄漏有一个基本印象之后,我们再来看一下在特定环境——Unity下的内存泄漏.大家都知道,游戏程序由代码和资源两部分组成,Unity下的内存泄漏也主要分为代码侧的泄漏和资源侧的泄漏,当然,资源侧 ...
随机推荐
- LibreOffice去重复数据
菜单:数据--更多筛选---标准筛选 点开“选项”,勾上“无重复值”. 然后还可以把结果复制到其它单元格.
- java日期工具类
public class UtilDate { /** 年月日时分秒(无下划线) yyyyMMddHHmmss */ public static final String dtLong = " ...
- 关于JavaScript初级的知识点一(持续更新 )
自己刚开始接触JS这是自己一个多月以来的一些总结和回顾. 一.什么是js? js是一种弱类型的脚本语言,是HTML的3大组成部分之一.HTML标签 CSS样式 JS脚本. 二.js的5种基本数据类型 ...
- 百度地图多点路径加载以及调整页面js
$(document).ready(function () { /*用正则表达式获取url传递的地址参数,split后获得地址数组*/ bmap = new BMap.Map('mapcontaine ...
- [BZOJ1552][Cerc2007]robotic sort
[BZOJ1552][Cerc2007]robotic sort 试题描述 输入 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000.第二行为N个用空格隔开的正整数 ...
- word20161224
V.34 V.90 validation / 验证 value entry / 值项 variable / 变量 variable bit rate, VBR / 可变传输率 VBR, variabl ...
- bzoj4398:福慧双修
学习了一下最短路的姿势,这个建图方法好妙啊,虽然不会证明正确性…… #include <bits/stdc++.h> #define N 220000 #define INF 100000 ...
- Maximal Rectangle
很不好想的一道题,参考:http://blog.csdn.net/doc_sgl/article/details/11832965 分为两步:把原矩阵转为直方图,再用largest rectangle ...
- 9个基于Java的搜索引擎框架
在这个信息相当繁杂的互联网时代,我们已经学会了如何利用搜索引擎这个强大的利器来找寻目标信息,比如你会在Google上搜索情人节如何讨女朋友欢心,你也会在百度上寻找正规的整容医疗机构(尽管有很大一部分广 ...
- visual studio installer 打包123
下载安装visual studio installer