Compare commits
No commits in common. "d635eeadd2140fb143514161a9d119735bcef39e" and "4d861c50dd3ba45ee1ff257a8a286d2cc670a757" have entirely different histories.
d635eeadd2
...
4d861c50dd
File diff suppressed because one or more lines are too long
@ -152,70 +152,7 @@ MonoBehaviour:
|
|||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
depth: 8
|
depth: 8
|
||||||
mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
|
mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
|
||||||
leafMesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
|
|
||||||
material: {fileID: 2100000, guid: 8f3914ac4291e664ba60ae208ae66460, type: 2}
|
material: {fileID: 2100000, guid: 8f3914ac4291e664ba60ae208ae66460, type: 2}
|
||||||
gradientA:
|
|
||||||
serializedVersion: 2
|
|
||||||
key0: {r: 0.764151, g: 0.18413278, b: 0, a: 0.3137255}
|
|
||||||
key1: {r: 1, g: 1, b: 0, a: 0.3529412}
|
|
||||||
key2: {r: 0, g: 0, b: 0, a: 0}
|
|
||||||
key3: {r: 0, g: 0, b: 0, a: 0}
|
|
||||||
key4: {r: 0, g: 0, b: 0, a: 0}
|
|
||||||
key5: {r: 0, g: 0, b: 0, a: 0}
|
|
||||||
key6: {r: 0, g: 0, b: 0, a: 0}
|
|
||||||
key7: {r: 0, g: 0, b: 0, a: 0}
|
|
||||||
ctime0: 0
|
|
||||||
ctime1: 65535
|
|
||||||
ctime2: 65535
|
|
||||||
ctime3: 0
|
|
||||||
ctime4: 0
|
|
||||||
ctime5: 0
|
|
||||||
ctime6: 0
|
|
||||||
ctime7: 0
|
|
||||||
atime0: 0
|
|
||||||
atime1: 65535
|
|
||||||
atime2: 0
|
|
||||||
atime3: 0
|
|
||||||
atime4: 0
|
|
||||||
atime5: 0
|
|
||||||
atime6: 0
|
|
||||||
atime7: 0
|
|
||||||
m_Mode: 0
|
|
||||||
m_NumColorKeys: 2
|
|
||||||
m_NumAlphaKeys: 2
|
|
||||||
gradientB:
|
|
||||||
serializedVersion: 2
|
|
||||||
key0: {r: 0.40392157, g: 0.14109339, b: 0, a: 0.54901963}
|
|
||||||
key1: {r: 0, g: 0.6320754, b: 0, a: 0.627451}
|
|
||||||
key2: {r: 1, g: 1, b: 0, a: 0}
|
|
||||||
key3: {r: 0, g: 0, b: 0, a: 0}
|
|
||||||
key4: {r: 0, g: 0, b: 0, a: 0}
|
|
||||||
key5: {r: 0, g: 0, b: 0, a: 0}
|
|
||||||
key6: {r: 0, g: 0, b: 0, a: 0}
|
|
||||||
key7: {r: 0, g: 0, b: 0, a: 0}
|
|
||||||
ctime0: 0
|
|
||||||
ctime1: 65535
|
|
||||||
ctime2: 65535
|
|
||||||
ctime3: 0
|
|
||||||
ctime4: 0
|
|
||||||
ctime5: 0
|
|
||||||
ctime6: 0
|
|
||||||
ctime7: 0
|
|
||||||
atime0: 0
|
|
||||||
atime1: 65535
|
|
||||||
atime2: 0
|
|
||||||
atime3: 0
|
|
||||||
atime4: 0
|
|
||||||
atime5: 0
|
|
||||||
atime6: 0
|
|
||||||
atime7: 0
|
|
||||||
m_Mode: 0
|
|
||||||
m_NumColorKeys: 2
|
|
||||||
m_NumAlphaKeys: 2
|
|
||||||
leafColorA: {r: 0.45882356, g: 0.97647065, b: 0.29803923, a: 0.49803922}
|
|
||||||
leafColorB: {r: 0.21568629, g: 0.4901961, b: 0.13333334, a: 0.9019608}
|
|
||||||
maxSagAngleA: 15
|
|
||||||
maxSagAngleB: 25
|
|
||||||
--- !u!4 &197491476
|
--- !u!4 &197491476
|
||||||
Transform:
|
Transform:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@ -223,13 +160,13 @@ Transform:
|
|||||||
m_PrefabInstance: {fileID: 0}
|
m_PrefabInstance: {fileID: 0}
|
||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_GameObject: {fileID: 197491472}
|
m_GameObject: {fileID: 197491472}
|
||||||
m_LocalRotation: {x: 0, y: 0, z: 0.17364816, w: 0.9848078}
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
m_Children: []
|
m_Children: []
|
||||||
m_Father: {fileID: 0}
|
m_Father: {fileID: 0}
|
||||||
m_RootOrder: 4
|
m_RootOrder: 4
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 20}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
--- !u!1 &705507993
|
--- !u!1 &705507993
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
@ -3,7 +3,6 @@ using Unity.Collections;
|
|||||||
using Unity.Jobs;
|
using Unity.Jobs;
|
||||||
using Unity.Mathematics;
|
using Unity.Mathematics;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Random = UnityEngine.Random;
|
|
||||||
|
|
||||||
using static Unity.Mathematics.math;
|
using static Unity.Mathematics.math;
|
||||||
using quaternion = Unity.Mathematics.quaternion;
|
using quaternion = Unity.Mathematics.quaternion;
|
||||||
@ -13,8 +12,8 @@ public class Fractal : MonoBehaviour
|
|||||||
[BurstCompile(FloatPrecision.Standard, FloatMode.Fast, CompileSynchronously = true)]
|
[BurstCompile(FloatPrecision.Standard, FloatMode.Fast, CompileSynchronously = true)]
|
||||||
private struct UpdateFractalLevelJob : IJobFor
|
private struct UpdateFractalLevelJob : IJobFor
|
||||||
{
|
{
|
||||||
|
public float spinAngleDelta;
|
||||||
public float scale;
|
public float scale;
|
||||||
public float deltaTime;
|
|
||||||
|
|
||||||
[ReadOnly]
|
[ReadOnly]
|
||||||
public NativeArray<FractalPart> parents;
|
public NativeArray<FractalPart> parents;
|
||||||
@ -28,34 +27,13 @@ public class Fractal : MonoBehaviour
|
|||||||
{
|
{
|
||||||
var parent = parents[i / 5];
|
var parent = parents[i / 5];
|
||||||
var part = parts[i];
|
var part = parts[i];
|
||||||
part.spinAngle += part.spinVelocity * deltaTime;
|
part.spinAngle += spinAngleDelta;
|
||||||
|
part.worldRotation = mul(parent.worldRotation,
|
||||||
|
|
||||||
float3 upAxis =
|
|
||||||
mul(mul(parent.worldRotation, part.rotation), up());
|
|
||||||
float3 sagAxis = cross(up(), upAxis);
|
|
||||||
|
|
||||||
float sagMagnitude = length(sagAxis);
|
|
||||||
quaternion baseRotation;
|
|
||||||
if (sagMagnitude > 0f)
|
|
||||||
{
|
|
||||||
sagAxis /= sagMagnitude;
|
|
||||||
quaternion sagRotation =
|
|
||||||
quaternion.AxisAngle(sagAxis, part.maxSagAngle * sagMagnitude);
|
|
||||||
baseRotation = mul(sagRotation, parent.worldRotation);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
baseRotation = parent.worldRotation;
|
|
||||||
}
|
|
||||||
|
|
||||||
part.worldRotation = mul(baseRotation,
|
|
||||||
mul(part.rotation, quaternion.RotateY(part.spinAngle))
|
mul(part.rotation, quaternion.RotateY(part.spinAngle))
|
||||||
);
|
);
|
||||||
|
|
||||||
part.worldPosition =
|
part.worldPosition =
|
||||||
parent.worldPosition +
|
parent.worldPosition +
|
||||||
mul(part.worldRotation, float3(0f, 1.5f * scale, 0f));
|
mul(parent.worldRotation, 1.5f * scale * part.direction);
|
||||||
parts[i] = part;
|
parts[i] = part;
|
||||||
|
|
||||||
float3x3 r = float3x3(part.worldRotation) * scale;
|
float3x3 r = float3x3(part.worldRotation) * scale;
|
||||||
@ -65,39 +43,24 @@ public class Fractal : MonoBehaviour
|
|||||||
|
|
||||||
private struct FractalPart
|
private struct FractalPart
|
||||||
{
|
{
|
||||||
public float3 worldPosition;
|
public float3 direction, worldPosition;
|
||||||
public quaternion rotation, worldRotation;
|
public quaternion rotation, worldRotation;
|
||||||
public float maxSagAngle, spinAngle, spinVelocity;
|
public float spinAngle;
|
||||||
}
|
}
|
||||||
|
|
||||||
NativeArray<FractalPart>[] parts;
|
NativeArray<FractalPart>[] parts;
|
||||||
|
|
||||||
NativeArray<float3x4>[] matrices;
|
NativeArray<float3x4>[] matrices;
|
||||||
|
|
||||||
[SerializeField, Range(3, 8)]
|
[SerializeField, Range(1, 8)]
|
||||||
int depth = 4;
|
int depth = 4;
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
Mesh mesh = default, leafMesh = default;
|
Mesh mesh = default;
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
Material material = default;
|
Material material = default;
|
||||||
|
|
||||||
[SerializeField]
|
|
||||||
Gradient gradientA = default, gradientB = default;
|
|
||||||
|
|
||||||
[SerializeField]
|
|
||||||
Color leafColorA = default, leafColorB = default;
|
|
||||||
|
|
||||||
[SerializeField, Range(0f, 90f)]
|
|
||||||
float maxSagAngleA = 15f, maxSagAngleB = 25f;
|
|
||||||
|
|
||||||
[SerializeField, Range(0f, 90f)]
|
|
||||||
float spinSpeedA = 20f, spinSpeedB = 25f;
|
|
||||||
|
|
||||||
[SerializeField, Range(0f, 1f)]
|
|
||||||
float reverseSpinChance = 0.25f;
|
|
||||||
|
|
||||||
static float3[] directions =
|
static float3[] directions =
|
||||||
{
|
{
|
||||||
up(), right(), left(), forward(), back()
|
up(), right(), left(), forward(), back()
|
||||||
@ -114,22 +77,14 @@ public class Fractal : MonoBehaviour
|
|||||||
{
|
{
|
||||||
return new FractalPart()
|
return new FractalPart()
|
||||||
{
|
{
|
||||||
maxSagAngle = radians(Random.Range(maxSagAngleA, maxSagAngleB)),
|
direction = directions[childIndex],
|
||||||
rotation = rotations[childIndex],
|
rotation = rotations[childIndex]
|
||||||
spinVelocity =
|
|
||||||
(Random.value < reverseSpinChance ? -1f : 1f) *
|
|
||||||
radians(Random.Range(spinSpeedA, spinSpeedB))
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
ComputeBuffer[] matricesBuffers;
|
ComputeBuffer[] matricesBuffers;
|
||||||
|
|
||||||
Vector4[] sequenceNumbers;
|
|
||||||
|
|
||||||
static readonly int colorAId = Shader.PropertyToID("_ColorA");
|
|
||||||
static readonly int colorBId = Shader.PropertyToID("_ColorB");
|
|
||||||
static readonly int matricesId = Shader.PropertyToID("_Matrices");
|
static readonly int matricesId = Shader.PropertyToID("_Matrices");
|
||||||
static readonly int sequenceNumbersId = Shader.PropertyToID("_SequenceNumbers");
|
|
||||||
|
|
||||||
static MaterialPropertyBlock propertyBlock;
|
static MaterialPropertyBlock propertyBlock;
|
||||||
|
|
||||||
@ -138,14 +93,12 @@ public class Fractal : MonoBehaviour
|
|||||||
parts = new NativeArray<FractalPart>[depth];
|
parts = new NativeArray<FractalPart>[depth];
|
||||||
matrices = new NativeArray<float3x4>[depth];
|
matrices = new NativeArray<float3x4>[depth];
|
||||||
matricesBuffers = new ComputeBuffer[depth];
|
matricesBuffers = new ComputeBuffer[depth];
|
||||||
sequenceNumbers = new Vector4[depth];
|
|
||||||
int stride = 12 * 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 NativeArray<FractalPart>(length, Allocator.Persistent);
|
parts[i] = new NativeArray<FractalPart>(length, Allocator.Persistent);
|
||||||
matrices[i] = new NativeArray<float3x4>(length, Allocator.Persistent);
|
matrices[i] = new NativeArray<float3x4>(length, Allocator.Persistent);
|
||||||
matricesBuffers[i] = new ComputeBuffer(length, stride);
|
matricesBuffers[i] = new ComputeBuffer(length, stride);
|
||||||
sequenceNumbers[i] = new Vector4(Random.value, Random.value, Random.value, Random.value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parts[0][0] = CreatePart(0);
|
parts[0][0] = CreatePart(0);
|
||||||
@ -178,7 +131,6 @@ public class Fractal : MonoBehaviour
|
|||||||
parts = null;
|
parts = null;
|
||||||
matrices = null;
|
matrices = null;
|
||||||
matricesBuffers = null;
|
matricesBuffers = null;
|
||||||
sequenceNumbers = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnValidate()
|
void OnValidate()
|
||||||
@ -192,9 +144,9 @@ public class Fractal : MonoBehaviour
|
|||||||
|
|
||||||
private void Update()
|
private void Update()
|
||||||
{
|
{
|
||||||
float deltaTime = Time.deltaTime;
|
float spinAngleDelta = 0.125f * PI * Time.deltaTime;
|
||||||
FractalPart rootPart = parts[0][0];
|
FractalPart rootPart = parts[0][0];
|
||||||
rootPart.spinAngle += rootPart.spinVelocity * deltaTime;
|
rootPart.spinAngle += spinAngleDelta;
|
||||||
rootPart.worldRotation = mul(transform.rotation,
|
rootPart.worldRotation = mul(transform.rotation,
|
||||||
mul(rootPart.rotation, quaternion.RotateY(rootPart.spinAngle))
|
mul(rootPart.rotation, quaternion.RotateY(rootPart.spinAngle))
|
||||||
);
|
);
|
||||||
@ -211,7 +163,7 @@ public class Fractal : MonoBehaviour
|
|||||||
scale *= 0.5f;
|
scale *= 0.5f;
|
||||||
jobHandle = new UpdateFractalLevelJob
|
jobHandle = new UpdateFractalLevelJob
|
||||||
{
|
{
|
||||||
deltaTime = deltaTime,
|
spinAngleDelta = spinAngleDelta,
|
||||||
scale = scale,
|
scale = scale,
|
||||||
parents = parts[li - 1],
|
parents = parts[li - 1],
|
||||||
parts = parts[li],
|
parts = parts[li],
|
||||||
@ -221,33 +173,12 @@ public class Fractal : MonoBehaviour
|
|||||||
jobHandle.Complete();
|
jobHandle.Complete();
|
||||||
|
|
||||||
var bounds = new Bounds(rootPart.worldPosition, float3(3f * objectScale));
|
var bounds = new Bounds(rootPart.worldPosition, float3(3f * objectScale));
|
||||||
int leafIndex = matricesBuffers.Length - 1;
|
|
||||||
for (int i = 0; i < matricesBuffers.Length; i++)
|
for (int i = 0; i < matricesBuffers.Length; i++)
|
||||||
{
|
{
|
||||||
Mesh instanceMesh;
|
|
||||||
Color colorA, colorB;
|
|
||||||
if (i == leafIndex)
|
|
||||||
{
|
|
||||||
colorA = leafColorA;
|
|
||||||
colorB = leafColorB;
|
|
||||||
instanceMesh = leafMesh;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
colorA = gradientA.Evaluate(i / (matricesBuffers.Length - 2f));
|
|
||||||
colorB = gradientB.Evaluate(i / (matricesBuffers.Length - 2f));
|
|
||||||
instanceMesh = mesh;
|
|
||||||
}
|
|
||||||
propertyBlock.SetColor(colorAId, colorA);
|
|
||||||
propertyBlock.SetColor(colorBId, colorB);
|
|
||||||
ComputeBuffer buffer = matricesBuffers[i];
|
ComputeBuffer buffer = matricesBuffers[i];
|
||||||
buffer.SetData(matrices[i]);
|
buffer.SetData(matrices[i]);
|
||||||
float gradientInterpolator = i / (matricesBuffers.Length - 1f);
|
|
||||||
propertyBlock.SetColor(colorAId, gradientA.Evaluate(gradientInterpolator));
|
|
||||||
propertyBlock.SetColor(colorBId, gradientB.Evaluate(gradientInterpolator));
|
|
||||||
propertyBlock.SetBuffer(matricesId, buffer);
|
propertyBlock.SetBuffer(matricesId, buffer);
|
||||||
propertyBlock.SetVector(sequenceNumbersId, sequenceNumbers[i]);
|
Graphics.DrawMeshInstancedProcedural(mesh, 0, material, bounds, buffer.count, propertyBlock);
|
||||||
Graphics.DrawMeshInstancedProcedural(instanceMesh, 0, material, bounds, buffer.count, propertyBlock);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,27 +2,6 @@
|
|||||||
StructuredBuffer<float3x4> _Matrices;
|
StructuredBuffer<float3x4> _Matrices;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
float4 _ColorA, _ColorB;
|
|
||||||
|
|
||||||
float4 _SequenceNumbers;
|
|
||||||
|
|
||||||
float4 GetFractalColor () {
|
|
||||||
#if defined(UNITY_PROCEDURAL_INSTANCING_ENABLED)
|
|
||||||
float4 color;
|
|
||||||
color.rgb = lerp(
|
|
||||||
_ColorA.rgb, _ColorB.rgb,
|
|
||||||
frac(unity_InstanceID * _SequenceNumbers.x + _SequenceNumbers.y)
|
|
||||||
);
|
|
||||||
color.a = lerp(
|
|
||||||
_ColorA.a, _ColorB.a,
|
|
||||||
frac(unity_InstanceID * _SequenceNumbers.z + _SequenceNumbers.w)
|
|
||||||
);
|
|
||||||
return color;
|
|
||||||
#else
|
|
||||||
return _ColorA;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigureProcedural () {
|
void ConfigureProcedural () {
|
||||||
#if defined(UNITY_PROCEDURAL_INSTANCING_ENABLED)
|
#if defined(UNITY_PROCEDURAL_INSTANCING_ENABLED)
|
||||||
float3x4 m = _Matrices[unity_InstanceID];
|
float3x4 m = _Matrices[unity_InstanceID];
|
||||||
@ -33,12 +12,10 @@ void ConfigureProcedural () {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderGraphFunction_float (float3 In, out float3 Out, out float4 FractalColor) {
|
void ShaderGraphFunction_float (float3 In, out float3 Out) {
|
||||||
Out = In;
|
Out = In;
|
||||||
FractalColor = GetFractalColor();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderGraphFunction_half (half3 In, out half3 Out, out half4 FractalColor) {
|
void ShaderGraphFunction_half (half3 In, out half3 Out) {
|
||||||
Out = In;
|
Out = In;
|
||||||
FractalColor = GetFractalColor();
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user