Procedural Drawing
This commit is contained in:
parent
1d3d62dd31
commit
d7be9187e8
8
Assets/Fractal.meta
Normal file
8
Assets/Fractal.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5c5c09c79ba995b4cbb07fc6eecd341b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -8,14 +8,14 @@ Material:
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Fractal URP
|
||||
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
|
||||
m_Shader: {fileID: -6465566751694194690, guid: 2ccc118ffa0f0574ba86592258e86a9e,
|
||||
type: 3}
|
||||
m_ShaderKeywords:
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: 2000
|
||||
stringTagMap:
|
||||
RenderType: Opaque
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
@ -49,6 +49,7 @@ Material:
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
- Vector1_8EEC20FB: 0.5
|
||||
- _AlphaClip: 0
|
||||
- _Blend: 0
|
||||
- _BumpScale: 1
|
||||
@ -71,6 +72,7 @@ Material:
|
||||
- _WorkflowMode: 1
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- Vector3_32FB817D: {r: 1, g: 1, b: 0, a: 0}
|
||||
- _BaseColor: {r: 1, g: 1, b: 0, a: 1}
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
98
Assets/Fractal/Fractal URP.shadergraph
Normal file
98
Assets/Fractal/Fractal URP.shadergraph
Normal file
File diff suppressed because one or more lines are too long
10
Assets/Fractal/Fractal URP.shadergraph.meta
Normal file
10
Assets/Fractal/Fractal URP.shadergraph.meta
Normal file
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2ccc118ffa0f0574ba86592258e86a9e
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3}
|
@ -4,13 +4,15 @@ public class Fractal : MonoBehaviour
|
||||
{
|
||||
private struct FractalPart
|
||||
{
|
||||
public Vector3 direction;
|
||||
public Quaternion rotation;
|
||||
public Transform transform;
|
||||
public Vector3 direction, worldPosition;
|
||||
public Quaternion rotation, worldRotation;
|
||||
public float spinAngle;
|
||||
}
|
||||
|
||||
FractalPart[][] parts;
|
||||
|
||||
Matrix4x4[][] matrices;
|
||||
|
||||
[SerializeField, Range(1, 8)]
|
||||
int depth = 4;
|
||||
|
||||
@ -38,72 +40,120 @@ public class Fractal : MonoBehaviour
|
||||
Quaternion.Euler(-90f, 0f, 0f)
|
||||
};
|
||||
|
||||
private FractalPart CreatePart(int levelIndex, int childIndex, float scale)
|
||||
private FractalPart CreatePart(int childIndex)
|
||||
{
|
||||
var go = new GameObject("Fractal Part L" + levelIndex + " C" + childIndex);
|
||||
go.transform.localScale = scale * Vector3.one;
|
||||
go.transform.SetParent(transform, false);
|
||||
go.AddComponent<MeshFilter>().mesh = mesh;
|
||||
go.AddComponent<MeshRenderer>().material = material;
|
||||
|
||||
return new FractalPart()
|
||||
{
|
||||
direction = directions[childIndex],
|
||||
rotation = rotations[childIndex],
|
||||
transform = go.transform
|
||||
rotation = rotations[childIndex]
|
||||
};
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
ComputeBuffer[] matricesBuffers;
|
||||
|
||||
static readonly int matricesId = Shader.PropertyToID("_Matrices");
|
||||
|
||||
static MaterialPropertyBlock propertyBlock;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
parts = new FractalPart[depth][];
|
||||
matrices = new Matrix4x4[depth][];
|
||||
matricesBuffers = new ComputeBuffer[depth];
|
||||
int stride = 16 * 4;
|
||||
for (int i = 0, length = 1; i < parts.Length; i++, length *= 5)
|
||||
{
|
||||
parts[i] = new FractalPart[length];
|
||||
matrices[i] = new Matrix4x4[length];
|
||||
matricesBuffers[i] = new ComputeBuffer(length, stride);
|
||||
}
|
||||
|
||||
var scale = 1f;
|
||||
parts[0][0] = CreatePart(0, 0, scale);
|
||||
parts[0][0] = CreatePart(0);
|
||||
for (int li = 1; li < parts.Length; li++)
|
||||
{
|
||||
scale *= 0.5f;
|
||||
FractalPart[] levelParts = parts[li];
|
||||
for (int fpi = 0; fpi < levelParts.Length; fpi += 5)
|
||||
{
|
||||
for (int ci = 0; ci < 5; ci++)
|
||||
{
|
||||
levelParts[fpi + ci] = CreatePart(li, ci, scale);
|
||||
levelParts[fpi + ci] = CreatePart(ci);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (propertyBlock == null)
|
||||
{
|
||||
propertyBlock = new MaterialPropertyBlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
for (int i = 0; i < matricesBuffers.Length; i++)
|
||||
{
|
||||
matricesBuffers[i].Release();
|
||||
}
|
||||
parts = null;
|
||||
matrices = null;
|
||||
matricesBuffers = null;
|
||||
}
|
||||
|
||||
void OnValidate()
|
||||
{
|
||||
if (parts != null && enabled)
|
||||
{
|
||||
OnDisable();
|
||||
OnEnable();
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
Quaternion deltaRotation = Quaternion.Euler(0f, 22.5f * Time.deltaTime, 0f);
|
||||
|
||||
float spinAngleDelta = 22.5f * Time.deltaTime;
|
||||
FractalPart rootPart = parts[0][0];
|
||||
rootPart.rotation *= deltaRotation;
|
||||
rootPart.transform.localRotation = rootPart.rotation;
|
||||
rootPart.spinAngle += spinAngleDelta;
|
||||
rootPart.worldRotation =
|
||||
transform.rotation *
|
||||
(rootPart.rotation * Quaternion.Euler(0f, rootPart.spinAngle, 0f));
|
||||
rootPart.worldPosition = transform.position;
|
||||
parts[0][0] = rootPart;
|
||||
float objectScale = transform.lossyScale.x;
|
||||
matrices[0][0] = Matrix4x4.TRS(
|
||||
rootPart.worldPosition, rootPart.worldRotation, objectScale * Vector3.one
|
||||
);
|
||||
|
||||
float scale = objectScale;
|
||||
for (int li = 1; li < parts.Length; li++)
|
||||
{
|
||||
scale *= 0.5f;
|
||||
FractalPart[] parentParts = parts[li - 1];
|
||||
FractalPart[] levelParts = parts[li];
|
||||
Matrix4x4[] levelMatrices = matrices[li];
|
||||
for (int fpi = 0; fpi < levelParts.Length; fpi++)
|
||||
{
|
||||
var parentTransform = parentParts[fpi / 5].transform;
|
||||
var parent = parentParts[fpi / 5];
|
||||
var part = levelParts[fpi];
|
||||
part.rotation *= deltaRotation;
|
||||
part.transform.rotation =
|
||||
parentTransform.localRotation * part.rotation;
|
||||
part.transform.localPosition =
|
||||
parentTransform.localPosition +
|
||||
parentTransform.localRotation *
|
||||
(1.5f * part.transform.localScale.x * part.direction);
|
||||
part.spinAngle += spinAngleDelta;
|
||||
part.worldRotation =
|
||||
parent.worldRotation *
|
||||
(part.rotation * Quaternion.Euler(0f, part.spinAngle, 0f));
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var bounds = new Bounds(rootPart.worldPosition, 3f * objectScale * Vector3.one);
|
||||
for (int i = 0; i < matricesBuffers.Length; i++)
|
||||
{
|
||||
ComputeBuffer buffer = matricesBuffers[i];
|
||||
buffer.SetData(matrices[i]);
|
||||
propertyBlock.SetBuffer(matricesId, buffer);
|
||||
Graphics.DrawMeshInstancedProcedural(mesh, 0, material, bounds, buffer.count, propertyBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
17
Assets/Script/PartGPU.hlsl
Normal file
17
Assets/Script/PartGPU.hlsl
Normal file
@ -0,0 +1,17 @@
|
||||
#if defined(UNITY_PROCEDURAL_INSTANCING_ENABLED)
|
||||
StructuredBuffer<float4x4> _Matrices;
|
||||
#endif
|
||||
|
||||
void ConfigureProcedural () {
|
||||
#if defined(UNITY_PROCEDURAL_INSTANCING_ENABLED)
|
||||
unity_ObjectToWorld = _Matrices[unity_InstanceID];
|
||||
#endif
|
||||
}
|
||||
|
||||
void ShaderGraphFunction_float (float3 In, out float3 Out) {
|
||||
Out = In;
|
||||
}
|
||||
|
||||
void ShaderGraphFunction_half (half3 In, out half3 Out) {
|
||||
Out = In;
|
||||
}
|
9
Assets/Script/PartGPU.hlsl.meta
Normal file
9
Assets/Script/PartGPU.hlsl.meta
Normal file
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ed85852d1001bf44b1fef32640df23b
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user