Job System - Done!

This commit is contained in:
_Redstone_c_ 2021-01-31 20:51:35 +08:00
parent d7be9187e8
commit 1aa620380b
7 changed files with 116 additions and 53 deletions

View File

@ -150,7 +150,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: bef3764eec961e04db4297ce68f82391, type: 3} m_Script: {fileID: 11500000, guid: bef3764eec961e04db4297ce68f82391, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
depth: 6 depth: 8
mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0} mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
material: {fileID: 2100000, guid: 8f3914ac4291e664ba60ae208ae66460, type: 2} material: {fileID: 2100000, guid: 8f3914ac4291e664ba60ae208ae66460, type: 2}
--- !u!4 &197491476 --- !u!4 &197491476

View File

@ -1,17 +1,56 @@
using UnityEngine; using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;
using Unity.Mathematics;
using UnityEngine;
using static Unity.Mathematics.math;
using quaternion = Unity.Mathematics.quaternion;
public class Fractal : MonoBehaviour public class Fractal : MonoBehaviour
{ {
[BurstCompile(FloatPrecision.Standard, FloatMode.Fast, CompileSynchronously = true)]
private struct UpdateFractalLevelJob : IJobFor
{
public float spinAngleDelta;
public float scale;
[ReadOnly]
public NativeArray<FractalPart> parents;
public NativeArray<FractalPart> parts;
[WriteOnly]
public NativeArray<float3x4> matrices;
public void Execute(int i)
{
var parent = parents[i / 5];
var part = parts[i];
part.spinAngle += spinAngleDelta;
part.worldRotation = mul(parent.worldRotation,
mul(part.rotation, quaternion.RotateY(part.spinAngle))
);
part.worldPosition =
parent.worldPosition +
mul(parent.worldRotation, 1.5f * scale * part.direction);
parts[i] = part;
float3x3 r = float3x3(part.worldRotation) * scale;
matrices[i] = float3x4(r.c0, r.c1, r.c2, part.worldPosition);
}
}
private struct FractalPart private struct FractalPart
{ {
public Vector3 direction, worldPosition; public float3 direction, worldPosition;
public Quaternion rotation, worldRotation; public quaternion rotation, worldRotation;
public float spinAngle; public float spinAngle;
} }
FractalPart[][] parts; NativeArray<FractalPart>[] parts;
Matrix4x4[][] matrices; NativeArray<float3x4>[] matrices;
[SerializeField, Range(1, 8)] [SerializeField, Range(1, 8)]
int depth = 4; int depth = 4;
@ -22,22 +61,16 @@ public class Fractal : MonoBehaviour
[SerializeField] [SerializeField]
Material material = default; Material material = default;
static Vector3[] directions = static float3[] directions =
{ {
Vector3.up, up(), right(), left(), forward(), back()
Vector3.right,
Vector3.left,
Vector3.forward,
Vector3.back
}; };
static Quaternion[] rotations = static quaternion[] rotations =
{ {
Quaternion.identity, quaternion.identity,
Quaternion.Euler(0f, 0f, -90f), quaternion.RotateZ(-0.5f * PI), quaternion.RotateZ(0.5f * PI),
Quaternion.Euler(0f, 0f, 90f), quaternion.RotateX(0.5f * PI), quaternion.RotateX(-0.5f * PI)
Quaternion.Euler(90f, 0f, 0f),
Quaternion.Euler(-90f, 0f, 0f)
}; };
private FractalPart CreatePart(int childIndex) private FractalPart CreatePart(int childIndex)
@ -57,21 +90,21 @@ public class Fractal : MonoBehaviour
private void OnEnable() private void OnEnable()
{ {
parts = new FractalPart[depth][]; parts = new NativeArray<FractalPart>[depth];
matrices = new Matrix4x4[depth][]; matrices = new NativeArray<float3x4>[depth];
matricesBuffers = new ComputeBuffer[depth]; matricesBuffers = new ComputeBuffer[depth];
int stride = 16 * 4; int stride = 12 * 4;
for (int i = 0, length = 1; i < parts.Length; i++, length *= 5) for (int i = 0, length = 1; i < parts.Length; i++, length *= 5)
{ {
parts[i] = new FractalPart[length]; parts[i] = new NativeArray<FractalPart>(length, Allocator.Persistent);
matrices[i] = new Matrix4x4[length]; matrices[i] = new NativeArray<float3x4>(length, Allocator.Persistent);
matricesBuffers[i] = new ComputeBuffer(length, stride); matricesBuffers[i] = new ComputeBuffer(length, stride);
} }
parts[0][0] = CreatePart(0); parts[0][0] = CreatePart(0);
for (int li = 1; li < parts.Length; li++) for (int li = 1; li < parts.Length; li++)
{ {
FractalPart[] levelParts = parts[li]; NativeArray<FractalPart> levelParts = parts[li];
for (int fpi = 0; fpi < levelParts.Length; fpi += 5) for (int fpi = 0; fpi < levelParts.Length; fpi += 5)
{ {
for (int ci = 0; ci < 5; ci++) for (int ci = 0; ci < 5; ci++)
@ -92,6 +125,8 @@ public class Fractal : MonoBehaviour
for (int i = 0; i < matricesBuffers.Length; i++) for (int i = 0; i < matricesBuffers.Length; i++)
{ {
matricesBuffers[i].Release(); matricesBuffers[i].Release();
parts[i].Dispose();
matrices[i].Dispose();
} }
parts = null; parts = null;
matrices = null; matrices = null;
@ -109,45 +144,35 @@ public class Fractal : MonoBehaviour
private void Update() private void Update()
{ {
float spinAngleDelta = 22.5f * Time.deltaTime; float spinAngleDelta = 0.125f * PI * Time.deltaTime;
FractalPart rootPart = parts[0][0]; FractalPart rootPart = parts[0][0];
rootPart.spinAngle += spinAngleDelta; rootPart.spinAngle += spinAngleDelta;
rootPart.worldRotation = rootPart.worldRotation = mul(transform.rotation,
transform.rotation * mul(rootPart.rotation, quaternion.RotateY(rootPart.spinAngle))
(rootPart.rotation * Quaternion.Euler(0f, rootPart.spinAngle, 0f)); );
rootPart.worldPosition = transform.position; rootPart.worldPosition = transform.position;
parts[0][0] = rootPart; parts[0][0] = rootPart;
float objectScale = transform.lossyScale.x; float objectScale = transform.lossyScale.x;
matrices[0][0] = Matrix4x4.TRS( float3x3 r = float3x3(rootPart.worldRotation) * objectScale;
rootPart.worldPosition, rootPart.worldRotation, objectScale * Vector3.one matrices[0][0] = float3x4(r.c0, r.c1, r.c2, rootPart.worldPosition);
);
float scale = objectScale; float scale = objectScale;
JobHandle jobHandle = default;
for (int li = 1; li < parts.Length; li++) for (int li = 1; li < parts.Length; li++)
{ {
scale *= 0.5f; scale *= 0.5f;
FractalPart[] parentParts = parts[li - 1]; jobHandle = new UpdateFractalLevelJob
FractalPart[] levelParts = parts[li];
Matrix4x4[] levelMatrices = matrices[li];
for (int fpi = 0; fpi < levelParts.Length; fpi++)
{ {
var parent = parentParts[fpi / 5]; spinAngleDelta = spinAngleDelta,
var part = levelParts[fpi]; scale = scale,
part.spinAngle += spinAngleDelta; parents = parts[li - 1],
part.worldRotation = parts = parts[li],
parent.worldRotation * matrices = matrices[li]
(part.rotation * Quaternion.Euler(0f, part.spinAngle, 0f)); }.ScheduleParallel(parts[li].Length, 5, jobHandle);
part.worldPosition =
parent.worldPosition +
parent.worldRotation * (1.5f * scale * part.direction);
levelParts[fpi] = part;
levelMatrices[fpi] = Matrix4x4.TRS(
part.worldPosition, part.worldRotation, scale * Vector3.one
);
}
} }
jobHandle.Complete();
var bounds = new Bounds(rootPart.worldPosition, 3f * objectScale * Vector3.one); var bounds = new Bounds(rootPart.worldPosition, float3(3f * objectScale));
for (int i = 0; i < matricesBuffers.Length; i++) for (int i = 0; i < matricesBuffers.Length; i++)
{ {
ComputeBuffer buffer = matricesBuffers[i]; ComputeBuffer buffer = matricesBuffers[i];

View File

@ -1,10 +1,14 @@
#if defined(UNITY_PROCEDURAL_INSTANCING_ENABLED) #if defined(UNITY_PROCEDURAL_INSTANCING_ENABLED)
StructuredBuffer<float4x4> _Matrices; StructuredBuffer<float3x4> _Matrices;
#endif #endif
void ConfigureProcedural () { void ConfigureProcedural () {
#if defined(UNITY_PROCEDURAL_INSTANCING_ENABLED) #if defined(UNITY_PROCEDURAL_INSTANCING_ENABLED)
unity_ObjectToWorld = _Matrices[unity_InstanceID]; float3x4 m = _Matrices[unity_InstanceID];
unity_ObjectToWorld._m00_m01_m02_m03 = m._m00_m01_m02_m03;
unity_ObjectToWorld._m10_m11_m12_m13 = m._m10_m11_m12_m13;
unity_ObjectToWorld._m20_m21_m22_m23 = m._m20_m21_m22_m23;
unity_ObjectToWorld._m30_m31_m32_m33 = float4(0.0, 0.0, 0.0, 1.0);
#endif #endif
} }

View File

@ -1,5 +1,6 @@
{ {
"dependencies": { "dependencies": {
"com.unity.burst": "1.4.4",
"com.unity.render-pipelines.universal": "7.5.3", "com.unity.render-pipelines.universal": "7.5.3",
"com.unity.textmeshpro": "2.1.3", "com.unity.textmeshpro": "2.1.3",
"com.unity.modules.ai": "1.0.0", "com.unity.modules.ai": "1.0.0",

View File

@ -1,5 +1,21 @@
{ {
"dependencies": { "dependencies": {
"com.unity.burst": {
"version": "1.4.4",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.mathematics": "1.2.1"
},
"url": "https://packages.unity.cn"
},
"com.unity.mathematics": {
"version": "1.2.1",
"depth": 1,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.cn"
},
"com.unity.render-pipelines.core": { "com.unity.render-pipelines.core": {
"version": "7.5.3", "version": "7.5.3",
"depth": 1, "depth": 1,

View File

@ -0,0 +1,16 @@
{
"MonoBehaviour": {
"Version": 3,
"EnableBurstCompilation": true,
"EnableOptimisations": true,
"EnableSafetyChecks": false,
"EnableDebugInAllBuilds": false,
"UsePlatformSDKLinker": false,
"CpuMinTargetX32": 0,
"CpuMaxTargetX32": 0,
"CpuMinTargetX64": 0,
"CpuMaxTargetX64": 0,
"CpuTargetsX32": 6,
"CpuTargetsX64": 72
}
}

View File

@ -584,7 +584,8 @@ PlayerSettings:
webGLWasmStreaming: 0 webGLWasmStreaming: 0
scriptingDefineSymbols: {} scriptingDefineSymbols: {}
platformArchitecture: {} platformArchitecture: {}
scriptingBackend: {} scriptingBackend:
Standalone: 0
il2cppCompilerConfiguration: {} il2cppCompilerConfiguration: {}
managedStrippingLevel: {} managedStrippingLevel: {}
incrementalIl2cppBuild: {} incrementalIl2cppBuild: {}