浏览代码

Compress OritentedBBox storage to 48 bytes

/main
Evgenii Golubev 6 年前
当前提交
ba308dc1
共有 2 个文件被更改,包括 42 次插入28 次删除
  1. 42
      ScriptableRenderPipeline/Core/CoreRP/GeometryUtils.cs
  2. 28
      ScriptableRenderPipeline/Core/CoreRP/GeometryUtils.cs.hlsl

42
ScriptableRenderPipeline/Core/CoreRP/GeometryUtils.cs


[GenerateHLSL]
public struct OrientedBBox
{
public Vector4 center; // w is unused
public Vector4 right, up, forward; // {x, y, z} = normalized local axis, w = 1/2 * size along the axis
public Vector3 center;
public float extentX;
public Vector3 right;
public float extentY;
public Vector3 up;
public float extentZ;
obb.center = t.position;
obb.right = t.right;
obb.right.w = 0.5f * t.localScale.x;
obb.up = t.up;
obb.up.w = 0.5f * t.localScale.y;
obb.forward = t.forward;
obb.forward.w = 0.5f * t.localScale.z;
obb.center = t.position;
obb.right = t.right;
obb.up = t.up;
obb.extentX = 0.5f * t.localScale.x;
obb.extentY = 0.5f * t.localScale.y;
obb.extentZ = 0.5f * t.localScale.z;
return obb;
}

public static bool Overlap(OrientedBBox obb, Vector3 cameraRelativeOffset,
Frustum frustum, int numPlanes, int numCorners)
{
Vector3 relCenter = (Vector3)obb.center + cameraRelativeOffset;
Vector3 center = obb.center + cameraRelativeOffset;
Vector3 forward = Vector3.Cross(obb.up, obb.right);
bool overlap = true;

float d = frustum.planes[i].distance;
// Max projection of the half-diagonal onto the normal (always positive).
float maxHalfDiagProj = Mathf.Abs(Vector3.Dot(n, obb.right)) * obb.right.w
+ Mathf.Abs(Vector3.Dot(n, obb.up)) * obb.up.w
+ Mathf.Abs(Vector3.Dot(n, obb.forward)) * obb.forward.w;
float maxHalfDiagProj = obb.extentX * Mathf.Abs(Vector3.Dot(n, obb.right))
+ obb.extentY * Mathf.Abs(Vector3.Dot(n, obb.up))
+ obb.extentZ * Mathf.Abs(Vector3.Dot(n, forward));
float centerToPlaneDist = Vector3.Dot(n, relCenter) + d;
float centerToPlaneDist = Vector3.Dot(n, center) + d;
// outside = maxHalfDiagProj < -centerToPlaneDist
// outside = maxHalfDiagProj + centerToPlaneDist < 0

Plane[] planes = new Plane[3];
planes[0].normal = obb.right;
planes[0].distance = obb.right.w;
planes[0].distance = obb.extentX;
planes[1].distance = obb.up.w;
planes[2].normal = obb.forward;
planes[2].distance = obb.forward.w;
planes[1].distance = obb.extentY;
planes[2].normal = forward;
planes[2].distance = obb.extentZ;
for (int i = 0; overlap && i < 3; i++)
{

// Merge 2 loops. Continue as long as all points are outside either plane.
for (int j = 0; j < numCorners; j++)
{
float proj = Vector3.Dot(plane.normal, frustum.corners[j] - relCenter);
float proj = Vector3.Dot(plane.normal, frustum.corners[j] - center);
outsidePos = outsidePos && ( proj > plane.distance);
outsideNeg = outsideNeg && (-proj > plane.distance);
}

28
ScriptableRenderPipeline/Core/CoreRP/GeometryUtils.cs.hlsl


// PackingRules = Exact
struct OrientedBBox
{
float4 center;
float4 right;
float4 up;
float4 forward;
float3 center;
float extentX;
float3 right;
float extentY;
float3 up;
float extentZ;
float4 GetCenter(OrientedBBox value)
float3 GetCenter(OrientedBBox value)
float4 GetRight(OrientedBBox value)
float GetExtentX(OrientedBBox value)
{
return value.extentX;
}
float3 GetRight(OrientedBBox value)
float4 GetUp(OrientedBBox value)
float GetExtentY(OrientedBBox value)
{
return value.extentY;
}
float3 GetUp(OrientedBBox value)
float4 GetForward(OrientedBBox value)
float GetExtentZ(OrientedBBox value)
return value.forward;
return value.extentZ;
}
正在加载...
取消
保存