@@ -11,45 +11,19 @@ namespace UTJ.Alembic
11
11
[ ExecuteInEditMode ]
12
12
public class AlembicPointsRenderer : MonoBehaviour
13
13
{
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
-
27
14
[ SerializeField ] Mesh m_mesh ;
28
15
[ SerializeField ] Material [ ] m_materials ;
29
16
[ SerializeField ] ShadowCastingMode m_castShadows = ShadowCastingMode . Off ;
30
17
[ SerializeField ] bool m_receiveShadows = false ;
31
18
[ 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
38
19
[ Tooltip ( "Use Alembic Points IDs as shader input" ) ]
39
20
[ 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
+
44
22
float [ ] m_ids ;
45
- List < MaterialPropertyBlock > m_mpbs ;
46
- #endif
47
- #if UNITY_5_6_OR_NEWER
48
23
ComputeBuffer m_cbPoints ;
49
24
ComputeBuffer m_cbIDs ;
50
25
ComputeBuffer [ ] m_cbArgs ;
51
26
int [ ] m_args = new int [ 5 ] { 0 , 0 , 0 , 0 , 0 } ;
52
- #endif
53
27
#if UNITY_EDITOR
54
28
bool m_dirty = false ;
55
29
#endif
@@ -108,12 +82,13 @@ Material[] SetupMaterials()
108
82
{
109
83
m_materialsInternal = null ;
110
84
}
111
- else if ( m_materialsInternal == null || m_materialsInternal . Length == 0 )
85
+ else if ( m_materialsInternal == null || m_materialsInternal . Length != m_materials . Length )
112
86
{
113
87
m_materialsInternal = new Material [ m_materials . Length ] ;
114
88
for ( int i = 0 ; i < m_materials . Length ; ++ i )
115
89
{
116
- m_materialsInternal [ i ] = new Material ( m_materials [ i ] ) ;
90
+ if ( m_materials [ i ] != null )
91
+ m_materialsInternal [ i ] = new Material ( m_materials [ i ] ) ;
117
92
}
118
93
}
119
94
return m_materialsInternal ;
@@ -141,44 +116,32 @@ public void Flush()
141
116
var scale = trans . lossyScale ;
142
117
var pscale = scale * m_pointSize ;
143
118
144
- bool supportsInstancing = SystemInfo . supportsInstancing ;
145
- #if UNITY_5_6_OR_NEWER
119
+ bool supportsInstancing = SystemInfo . supportsInstancing && SystemInfo . supportsComputeShaders ;
146
120
int pidAlembicPoints = Shader . PropertyToID ( "_AlembicPoints" ) ;
147
- #endif
148
- #if UNITY_5_5_OR_NEWER
149
121
int pidAlembicIDs = Shader . PropertyToID ( "_AlembicIDs" ) ;
150
- #endif
151
122
int pidTranslate = Shader . PropertyToID ( "_Translate" ) ;
152
123
int pidRotate = Shader . PropertyToID ( "_Rotate" ) ;
153
124
int pidScale = Shader . PropertyToID ( "_Scale" ) ;
154
125
int pidPointSize = Shader . PropertyToID ( "_PointSize" ) ;
155
126
156
- if ( ! supportsInstancing && m_instancingMode != InstancingMode . NoInstancing )
127
+ if ( ! supportsInstancing )
157
128
{
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 ;
160
131
}
161
132
162
133
for ( int si = 0 ; si < num_submeshes ; ++ si )
163
134
{
164
135
var material = materials [ si ] ;
136
+ if ( material == null )
137
+ continue ;
165
138
material . SetVector ( pidTranslate , pos ) ;
166
139
material . SetVector ( pidRotate , new Vector4 ( rot . x , rot . y , rot . z , rot . w ) ) ;
167
140
material . SetVector ( pidScale , scale ) ;
168
141
material . SetFloat ( pidPointSize , m_pointSize ) ;
169
142
}
170
143
171
- #if UNITY_5_6_OR_NEWER
172
- if ( m_instancingMode == InstancingMode . Procedural && ! SystemInfo . supportsComputeShaders )
173
144
{
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
-
182
145
// update argument buffer
183
146
if ( m_cbArgs == null || m_cbArgs . Length != num_submeshes )
184
147
{
@@ -243,135 +206,25 @@ public void Flush()
243
206
args . SetData ( m_args ) ;
244
207
245
208
var material = materials [ si ] ;
246
- material . EnableKeyword ( kAlembicProceduralInstancing ) ;
209
+ if ( material == null )
210
+ continue ;
247
211
material . SetBuffer ( pidAlembicPoints , m_cbPoints ) ;
248
- if ( alembicIDsAvailable ) { material . SetBuffer ( pidAlembicIDs , m_cbIDs ) ; }
212
+ if ( alembicIDsAvailable )
213
+ material . SetBuffer ( pidAlembicIDs , m_cbIDs ) ;
249
214
Graphics . DrawMeshInstancedIndirect ( mesh , si , material ,
250
215
bounds , args , 0 , null , m_castShadows , m_receiveShadows , layer ) ;
251
216
}
252
217
}
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
- }
363
218
}
364
219
365
220
public void Release ( )
366
221
{
367
- #if UNITY_5_6_OR_NEWER
368
222
if ( m_cbArgs != null ) {
369
223
foreach ( var cb in m_cbArgs ) { cb . Release ( ) ; }
370
224
m_cbArgs = null ;
371
225
}
372
226
if ( m_cbPoints != null ) { m_cbPoints . Release ( ) ; m_cbPoints = null ; }
373
227
if ( m_cbIDs != null ) { m_cbIDs . Release ( ) ; m_cbIDs = null ; }
374
- #endif
375
228
}
376
229
377
230
@@ -388,7 +241,6 @@ void LateUpdate()
388
241
#endif
389
242
}
390
243
391
- #if UNITY_EDITOR
392
244
void OnDrawGizmos ( )
393
245
{
394
246
// force draw particles while paused.
@@ -405,6 +257,32 @@ void OnDrawGizmos()
405
257
m_materialsInternal = null ;
406
258
}
407
259
}
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
+ }
408
285
#endif
286
+ }
409
287
}
410
288
}
0 commit comments