Skip to content

Commit 5ed38e6

Browse files
committed
cleanup AlembicPointsRenderer
1 parent 3039d9d commit 5ed38e6

File tree

4 files changed

+61
-212
lines changed

4 files changed

+61
-212
lines changed

AlembicImporter/Assets/UTJ/Alembic/Scripts/Importer/AlembicPointsRenderer.cs

Lines changed: 40 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -11,45 +11,19 @@ namespace UTJ.Alembic
1111
[ExecuteInEditMode]
1212
public class AlembicPointsRenderer : MonoBehaviour
1313
{
14-
public enum InstancingMode
15-
{
16-
NoInstancing,
17-
#if UNITY_5_5_OR_NEWER
18-
Instancing,
19-
#endif
20-
#if UNITY_5_6_OR_NEWER
21-
Procedural,
22-
#endif
23-
}
24-
25-
public const int MaxInstancesParDraw = 1023;
26-
2714
[SerializeField] Mesh m_mesh;
2815
[SerializeField] Material[] m_materials;
2916
[SerializeField] ShadowCastingMode m_castShadows = ShadowCastingMode.Off;
3017
[SerializeField] bool m_receiveShadows = false;
3118
[SerializeField] float m_pointSize = 0.2f;
32-
[SerializeField] InstancingMode m_instancingMode =
33-
#if UNITY_5_5_OR_NEWER
34-
InstancingMode.Instancing;
35-
#else
36-
InstancingMode.NoInstancing;
37-
#endif
3819
[Tooltip("Use Alembic Points IDs as shader input")]
3920
[SerializeField] bool m_useAlembicIDs = false;
40-
41-
#if UNITY_5_5_OR_NEWER
42-
const string kAlembicProceduralInstancing = "ALEMBIC_PROCEDURAL_INSTANCING_ENABLED";
43-
Matrix4x4[] m_matrices;
21+
4422
float[] m_ids;
45-
List<MaterialPropertyBlock> m_mpbs;
46-
#endif
47-
#if UNITY_5_6_OR_NEWER
4823
ComputeBuffer m_cbPoints;
4924
ComputeBuffer m_cbIDs;
5025
ComputeBuffer[] m_cbArgs;
5126
int[] m_args = new int[5] { 0, 0, 0, 0, 0 };
52-
#endif
5327
#if UNITY_EDITOR
5428
bool m_dirty = false;
5529
#endif
@@ -108,12 +82,13 @@ Material[] SetupMaterials()
10882
{
10983
m_materialsInternal = null;
11084
}
111-
else if (m_materialsInternal == null || m_materialsInternal.Length == 0)
85+
else if (m_materialsInternal == null || m_materialsInternal.Length != m_materials.Length)
11286
{
11387
m_materialsInternal = new Material[m_materials.Length];
11488
for (int i = 0; i < m_materials.Length; ++i)
11589
{
116-
m_materialsInternal[i] = new Material(m_materials[i]);
90+
if (m_materials[i] != null)
91+
m_materialsInternal[i] = new Material(m_materials[i]);
11792
}
11893
}
11994
return m_materialsInternal;
@@ -141,44 +116,32 @@ public void Flush()
141116
var scale = trans.lossyScale;
142117
var pscale = scale * m_pointSize;
143118

144-
bool supportsInstancing = SystemInfo.supportsInstancing;
145-
#if UNITY_5_6_OR_NEWER
119+
bool supportsInstancing = SystemInfo.supportsInstancing && SystemInfo.supportsComputeShaders;
146120
int pidAlembicPoints = Shader.PropertyToID("_AlembicPoints");
147-
#endif
148-
#if UNITY_5_5_OR_NEWER
149121
int pidAlembicIDs = Shader.PropertyToID("_AlembicIDs");
150-
#endif
151122
int pidTranslate = Shader.PropertyToID("_Translate");
152123
int pidRotate = Shader.PropertyToID("_Rotate");
153124
int pidScale = Shader.PropertyToID("_Scale");
154125
int pidPointSize = Shader.PropertyToID("_PointSize");
155126

156-
if (!supportsInstancing && m_instancingMode != InstancingMode.NoInstancing)
127+
if (!supportsInstancing)
157128
{
158-
Debug.LogWarning("AlembicPointsRenderer: Instancing is not supported on this system. fallback to InstancingMode.NoInstancing.");
159-
m_instancingMode = InstancingMode.NoInstancing;
129+
Debug.LogWarning("AlembicPointsRenderer: Instancing is not supported on this system.");
130+
return;
160131
}
161132

162133
for (int si = 0; si < num_submeshes; ++si)
163134
{
164135
var material = materials[si];
136+
if (material == null)
137+
continue;
165138
material.SetVector(pidTranslate, pos);
166139
material.SetVector(pidRotate, new Vector4(rot.x, rot.y, rot.z, rot.w));
167140
material.SetVector(pidScale, scale);
168141
material.SetFloat(pidPointSize, m_pointSize);
169142
}
170143

171-
#if UNITY_5_6_OR_NEWER
172-
if (m_instancingMode == InstancingMode.Procedural && !SystemInfo.supportsComputeShaders)
173144
{
174-
Debug.LogWarning("AlembicPointsRenderer: InstancingMode.Procedural is not supported on this system. fallback to InstancingMode.Instancing.");
175-
m_instancingMode = InstancingMode.Instancing;
176-
}
177-
178-
if (supportsInstancing && m_instancingMode == InstancingMode.Procedural)
179-
{
180-
// Graphics.DrawMeshInstancedIndirect() route
181-
182145
// update argument buffer
183146
if (m_cbArgs == null || m_cbArgs.Length != num_submeshes)
184147
{
@@ -243,135 +206,25 @@ public void Flush()
243206
args.SetData(m_args);
244207

245208
var material = materials[si];
246-
material.EnableKeyword(kAlembicProceduralInstancing);
209+
if (material == null)
210+
continue;
247211
material.SetBuffer(pidAlembicPoints, m_cbPoints);
248-
if (alembicIDsAvailable) { material.SetBuffer(pidAlembicIDs, m_cbIDs); }
212+
if (alembicIDsAvailable)
213+
material.SetBuffer(pidAlembicIDs, m_cbIDs);
249214
Graphics.DrawMeshInstancedIndirect(mesh, si, material,
250215
bounds, args, 0, null, m_castShadows, m_receiveShadows, layer);
251216
}
252217
}
253-
else
254-
#endif
255-
#if UNITY_5_5_OR_NEWER
256-
if (supportsInstancing && m_instancingMode == InstancingMode.Instancing)
257-
{
258-
// Graphics.DrawMeshInstanced() route
259-
// Graphics.DrawMeshInstanced() can draw only up to 1023 instances.
260-
// multiple drawcalls maybe required.
261-
262-
int num_batches = (num_instances + MaxInstancesParDraw - 1) / MaxInstancesParDraw;
263-
264-
if (m_matrices == null || m_matrices.Length != MaxInstancesParDraw)
265-
{
266-
m_matrices = new Matrix4x4[MaxInstancesParDraw];
267-
for (int i = 0; i < MaxInstancesParDraw; ++i) { m_matrices[i] = Matrix4x4.identity; }
268-
}
269-
270-
for (int si = 0; si < num_submeshes; ++si)
271-
{
272-
var material = materials[si];
273-
if (material.IsKeywordEnabled(kAlembicProceduralInstancing))
274-
{
275-
material.DisableKeyword(kAlembicProceduralInstancing);
276-
}
277-
}
278-
279-
// setup alembic point IDs
280-
bool alembicIDsAvailable = false;
281-
ulong[] ids = null;
282-
if (m_useAlembicIDs)
283-
{
284-
ids = apc.abcIDs;
285-
alembicIDsAvailable = ids != null && ids.Length == num_instances;
286-
if (alembicIDsAvailable)
287-
{
288-
if (m_ids == null || m_ids.Length != MaxInstancesParDraw)
289-
{
290-
m_ids = new float[MaxInstancesParDraw];
291-
}
292-
if (m_mpbs == null)
293-
{
294-
m_mpbs = new List<MaterialPropertyBlock>();
295-
}
296-
while (m_mpbs.Count < num_batches)
297-
{
298-
m_mpbs.Add(new MaterialPropertyBlock());
299-
}
300-
}
301-
}
302-
303-
for (int ib = 0; ib < num_batches; ++ib)
304-
{
305-
int ibegin = ib * MaxInstancesParDraw;
306-
int iend = System.Math.Min(ibegin + MaxInstancesParDraw, num_instances);
307-
int n = iend - ibegin;
308-
309-
// build matrices
310-
for (int ii = 0; ii < n; ++ii)
311-
{
312-
var ppos = points[ibegin + ii];
313-
ppos.x *= scale.x;
314-
ppos.y *= scale.y;
315-
ppos.z *= scale.z;
316-
ppos = (rot * ppos) + pos;
317-
m_matrices[ii].SetTRS(ppos, rot, pscale);
318-
}
319-
320-
MaterialPropertyBlock mpb = null;
321-
if (alembicIDsAvailable)
322-
{
323-
for (int ii = 0; ii < n; ++ii)
324-
{
325-
m_ids[ii] = ids[ibegin + ii];
326-
}
327-
mpb = m_mpbs[ib];
328-
mpb.SetFloatArray(pidAlembicIDs, m_ids);
329-
}
330-
331-
// issue drawcalls
332-
for (int si = 0; si < num_submeshes; ++si)
333-
{
334-
var material = materials[si];
335-
Graphics.DrawMeshInstanced(mesh, si, material, m_matrices, n, mpb, m_castShadows, m_receiveShadows, layer);
336-
}
337-
}
338-
}
339-
else
340-
#endif
341-
{
342-
// Graphics.DrawMesh() route
343-
// not use IDs in this case because it's too expensive...
344-
345-
var matrix = Matrix4x4.identity;
346-
for (int ii = 0; ii < num_instances; ++ii)
347-
{
348-
var ppos = points[ii];
349-
ppos.x *= scale.x;
350-
ppos.y *= scale.y;
351-
ppos.z *= scale.z;
352-
ppos = (rot * ppos) + pos;
353-
matrix.SetTRS(ppos, rot, pscale);
354-
355-
// issue drawcalls
356-
for (int si = 0; si < num_submeshes; ++si)
357-
{
358-
var material = materials[si];
359-
Graphics.DrawMesh(mesh, matrix, material, layer, null, si, null, m_castShadows, m_receiveShadows);
360-
}
361-
}
362-
}
363218
}
364219

365220
public void Release()
366221
{
367-
#if UNITY_5_6_OR_NEWER
368222
if (m_cbArgs != null) {
369223
foreach(var cb in m_cbArgs) { cb.Release(); }
370224
m_cbArgs = null;
371225
}
372226
if (m_cbPoints != null) { m_cbPoints.Release(); m_cbPoints = null; }
373227
if (m_cbIDs != null) { m_cbIDs.Release(); m_cbIDs = null; }
374-
#endif
375228
}
376229

377230

@@ -388,7 +241,6 @@ void LateUpdate()
388241
#endif
389242
}
390243

391-
#if UNITY_EDITOR
392244
void OnDrawGizmos()
393245
{
394246
// force draw particles while paused.
@@ -405,6 +257,32 @@ void OnDrawGizmos()
405257
m_materialsInternal = null;
406258
}
407259
}
260+
261+
private void Start()
262+
{
263+
#if UNITY_EDITOR
264+
if (m_mesh == null)
265+
{
266+
var cubeGO = GameObject.CreatePrimitive(PrimitiveType.Cube);
267+
m_mesh = cubeGO.GetComponent<MeshFilter>().sharedMesh;
268+
DestroyImmediate(cubeGO);
269+
}
270+
if (m_materials != null)
271+
{
272+
bool allNull = true;
273+
foreach (var m in m_materials)
274+
if (m_materials != null)
275+
allNull = false;
276+
if (allNull)
277+
m_materials = null;
278+
}
279+
if (m_materials == null)
280+
{
281+
var mat = new Material(AssetDatabase.LoadAssetAtPath<Shader>("Assets/UTJ/Alembic/Shaders/StandardInstanced.shader"));
282+
mat.name = "Default Alembic Points";
283+
m_materials = new Material[] { mat };
284+
}
408285
#endif
286+
}
409287
}
410288
}

AlembicImporter/Assets/UTJ/Alembic/Shaders/PointRenderer.cginc

Lines changed: 13 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,12 @@
1-
// Upgrade NOTE: upgraded instancing buffer 'A' to new syntax.
2-
// Upgrade NOTE: upgraded instancing buffer 'Props' to new syntax.
3-
41
#include "UnityCG.cginc"
52

6-
#if defined(UNITY_SUPPORT_INSTANCING) && !defined(UNITY_INSTANCING_ENABLED) && !defined(UNITY_PROCEDURAL_INSTANCING_ENABLED) && (SHADER_TARGET >= 45 && defined(ALEMBIC_PROCEDURAL_INSTANCING_ENABLED))
7-
#define UNITY_SUPPORT_INSTANCING
8-
#define UNITY_PROCEDURAL_INSTANCING_ENABLED
9-
10-
uint unity_InstanceID;
11-
#define UNITY_VERTEX_INPUT_INSTANCE_ID uint instanceID : SV_InstanceID;
12-
#define UNITY_SETUP_INSTANCE_ID(v) unity_InstanceID = v.instanceID;
13-
#endif
14-
15-
163
float3 _Translate;
174
float4 _Rotate;
185
float3 _Scale;
196
float _PointSize;
20-
float _AlembicID;
21-
227
#ifdef UNITY_SUPPORT_INSTANCING
23-
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
24-
StructuredBuffer<float3> _AlembicPoints;
25-
StructuredBuffer<float> _AlembicIDs;
26-
#else
27-
UNITY_INSTANCING_BUFFER_START (Props)
28-
UNITY_DEFINE_INSTANCED_PROP (float, _AlembicIDs)
29-
#define _AlembicIDs_arr Props
30-
UNITY_INSTANCING_BUFFER_END(Props)
31-
#endif
32-
#elif !defined(UNITY_VERTEX_INPUT_INSTANCE_ID)
33-
// for pre-5.5
34-
#define UNITY_VERTEX_INPUT_INSTANCE_ID
35-
#define UNITY_INSTANCING_BUFFER_START(A, B)
36-
#define UNITY_DEFINE_INSTANCED_PROP(A, B)
37-
#define B_arr A
38-
#define UNITY_ACCESS_INSTANCED_PROP(A_arr, A)
39-
#define UNITY_INSTANCING_BUFFER_END(A)
40-
#define UNITY_SETUP_INSTANCE_ID(A)
41-
#define UNITY_TRANSFER_INSTANCE_ID(A, B)
8+
StructuredBuffer<float3> _AlembicPoints;
9+
StructuredBuffer<float> _AlembicIDs;
4210
#endif
4311

4412
float GetPointSize()
@@ -100,30 +68,30 @@ float3 Rotate(float4 q, float3 p)
10068
return p + (a * q.w + b) * 2.0;
10169
}
10270

103-
float3 GetAlembicPoint()
71+
float3 GetAlembicPoint(int iid)
10472
{
10573
return
106-
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
107-
Rotate(_Rotate, _AlembicPoints[unity_InstanceID] * _Scale) + _Translate;
74+
#ifdef UNITY_SUPPORT_INSTANCING
75+
Rotate(_Rotate, _AlembicPoints[iid] * _Scale) + _Translate;
10876
#else
109-
float3(unity_ObjectToWorld[0][3], unity_ObjectToWorld[1][3], unity_ObjectToWorld[2][3]);
77+
float3(0,0,0);
11078
#endif
11179
}
11280

113-
float GetAlembicID()
81+
float GetAlembicID(int iid)
11482
{
11583
return
116-
#if defined(UNITY_INSTANCING_ENABLED) || defined(UNITY_PROCEDURAL_INSTANCING_ENABLED)
117-
_AlembicIDs[unity_InstanceID];
84+
#ifdef UNITY_SUPPORT_INSTANCING
85+
_AlembicIDs[iid];
11886
#else
119-
_AlembicID;
87+
0;
12088
#endif
12189
}
12290

123-
float4x4 GetPointMatrix()
91+
float4x4 GetPointMatrix(int iid)
12492
{
125-
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
126-
float3 ppos = GetAlembicPoint();
93+
#ifdef UNITY_SUPPORT_INSTANCING
94+
float3 ppos = GetAlembicPoint(iid);
12795
float4 prot = _Rotate;
12896
float3 pscale = _Scale * _PointSize;
12997
return mul(mul(Translate44(ppos), Rotate44(prot)), Scale44(pscale));

0 commit comments

Comments
 (0)