Skip to content

Commit

Permalink
cleanup AlembicPointsRenderer
Browse files Browse the repository at this point in the history
  • Loading branch information
i-saint committed Jan 19, 2018
1 parent 3039d9d commit 5ed38e6
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 212 deletions.
Expand Up @@ -11,45 +11,19 @@ namespace UTJ.Alembic
[ExecuteInEditMode]
public class AlembicPointsRenderer : MonoBehaviour
{
public enum InstancingMode
{
NoInstancing,
#if UNITY_5_5_OR_NEWER
Instancing,
#endif
#if UNITY_5_6_OR_NEWER
Procedural,
#endif
}

public const int MaxInstancesParDraw = 1023;

[SerializeField] Mesh m_mesh;
[SerializeField] Material[] m_materials;
[SerializeField] ShadowCastingMode m_castShadows = ShadowCastingMode.Off;
[SerializeField] bool m_receiveShadows = false;
[SerializeField] float m_pointSize = 0.2f;
[SerializeField] InstancingMode m_instancingMode =
#if UNITY_5_5_OR_NEWER
InstancingMode.Instancing;
#else
InstancingMode.NoInstancing;
#endif
[Tooltip("Use Alembic Points IDs as shader input")]
[SerializeField] bool m_useAlembicIDs = false;

#if UNITY_5_5_OR_NEWER
const string kAlembicProceduralInstancing = "ALEMBIC_PROCEDURAL_INSTANCING_ENABLED";
Matrix4x4[] m_matrices;

float[] m_ids;
List<MaterialPropertyBlock> m_mpbs;
#endif
#if UNITY_5_6_OR_NEWER
ComputeBuffer m_cbPoints;
ComputeBuffer m_cbIDs;
ComputeBuffer[] m_cbArgs;
int[] m_args = new int[5] { 0, 0, 0, 0, 0 };
#endif
#if UNITY_EDITOR
bool m_dirty = false;
#endif
Expand Down Expand Up @@ -108,12 +82,13 @@ Material[] SetupMaterials()
{
m_materialsInternal = null;
}
else if (m_materialsInternal == null || m_materialsInternal.Length == 0)
else if (m_materialsInternal == null || m_materialsInternal.Length != m_materials.Length)
{
m_materialsInternal = new Material[m_materials.Length];
for (int i = 0; i < m_materials.Length; ++i)
{
m_materialsInternal[i] = new Material(m_materials[i]);
if (m_materials[i] != null)
m_materialsInternal[i] = new Material(m_materials[i]);
}
}
return m_materialsInternal;
Expand Down Expand Up @@ -141,44 +116,32 @@ public void Flush()
var scale = trans.lossyScale;
var pscale = scale * m_pointSize;

bool supportsInstancing = SystemInfo.supportsInstancing;
#if UNITY_5_6_OR_NEWER
bool supportsInstancing = SystemInfo.supportsInstancing && SystemInfo.supportsComputeShaders;
int pidAlembicPoints = Shader.PropertyToID("_AlembicPoints");
#endif
#if UNITY_5_5_OR_NEWER
int pidAlembicIDs = Shader.PropertyToID("_AlembicIDs");
#endif
int pidTranslate = Shader.PropertyToID("_Translate");
int pidRotate = Shader.PropertyToID("_Rotate");
int pidScale = Shader.PropertyToID("_Scale");
int pidPointSize = Shader.PropertyToID("_PointSize");

if (!supportsInstancing && m_instancingMode != InstancingMode.NoInstancing)
if (!supportsInstancing)
{
Debug.LogWarning("AlembicPointsRenderer: Instancing is not supported on this system. fallback to InstancingMode.NoInstancing.");
m_instancingMode = InstancingMode.NoInstancing;
Debug.LogWarning("AlembicPointsRenderer: Instancing is not supported on this system.");
return;
}

for (int si = 0; si < num_submeshes; ++si)
{
var material = materials[si];
if (material == null)
continue;
material.SetVector(pidTranslate, pos);
material.SetVector(pidRotate, new Vector4(rot.x, rot.y, rot.z, rot.w));
material.SetVector(pidScale, scale);
material.SetFloat(pidPointSize, m_pointSize);
}

#if UNITY_5_6_OR_NEWER
if (m_instancingMode == InstancingMode.Procedural && !SystemInfo.supportsComputeShaders)
{
Debug.LogWarning("AlembicPointsRenderer: InstancingMode.Procedural is not supported on this system. fallback to InstancingMode.Instancing.");
m_instancingMode = InstancingMode.Instancing;
}

if (supportsInstancing && m_instancingMode == InstancingMode.Procedural)
{
// Graphics.DrawMeshInstancedIndirect() route

// update argument buffer
if (m_cbArgs == null || m_cbArgs.Length != num_submeshes)
{
Expand Down Expand Up @@ -243,135 +206,25 @@ public void Flush()
args.SetData(m_args);

var material = materials[si];
material.EnableKeyword(kAlembicProceduralInstancing);
if (material == null)
continue;
material.SetBuffer(pidAlembicPoints, m_cbPoints);
if (alembicIDsAvailable) { material.SetBuffer(pidAlembicIDs, m_cbIDs); }
if (alembicIDsAvailable)
material.SetBuffer(pidAlembicIDs, m_cbIDs);
Graphics.DrawMeshInstancedIndirect(mesh, si, material,
bounds, args, 0, null, m_castShadows, m_receiveShadows, layer);
}
}
else
#endif
#if UNITY_5_5_OR_NEWER
if (supportsInstancing && m_instancingMode == InstancingMode.Instancing)
{
// Graphics.DrawMeshInstanced() route
// Graphics.DrawMeshInstanced() can draw only up to 1023 instances.
// multiple drawcalls maybe required.

int num_batches = (num_instances + MaxInstancesParDraw - 1) / MaxInstancesParDraw;

if (m_matrices == null || m_matrices.Length != MaxInstancesParDraw)
{
m_matrices = new Matrix4x4[MaxInstancesParDraw];
for (int i = 0; i < MaxInstancesParDraw; ++i) { m_matrices[i] = Matrix4x4.identity; }
}

for (int si = 0; si < num_submeshes; ++si)
{
var material = materials[si];
if (material.IsKeywordEnabled(kAlembicProceduralInstancing))
{
material.DisableKeyword(kAlembicProceduralInstancing);
}
}

// setup alembic point IDs
bool alembicIDsAvailable = false;
ulong[] ids = null;
if (m_useAlembicIDs)
{
ids = apc.abcIDs;
alembicIDsAvailable = ids != null && ids.Length == num_instances;
if (alembicIDsAvailable)
{
if (m_ids == null || m_ids.Length != MaxInstancesParDraw)
{
m_ids = new float[MaxInstancesParDraw];
}
if (m_mpbs == null)
{
m_mpbs = new List<MaterialPropertyBlock>();
}
while (m_mpbs.Count < num_batches)
{
m_mpbs.Add(new MaterialPropertyBlock());
}
}
}

for (int ib = 0; ib < num_batches; ++ib)
{
int ibegin = ib * MaxInstancesParDraw;
int iend = System.Math.Min(ibegin + MaxInstancesParDraw, num_instances);
int n = iend - ibegin;

// build matrices
for (int ii = 0; ii < n; ++ii)
{
var ppos = points[ibegin + ii];
ppos.x *= scale.x;
ppos.y *= scale.y;
ppos.z *= scale.z;
ppos = (rot * ppos) + pos;
m_matrices[ii].SetTRS(ppos, rot, pscale);
}

MaterialPropertyBlock mpb = null;
if (alembicIDsAvailable)
{
for (int ii = 0; ii < n; ++ii)
{
m_ids[ii] = ids[ibegin + ii];
}
mpb = m_mpbs[ib];
mpb.SetFloatArray(pidAlembicIDs, m_ids);
}

// issue drawcalls
for (int si = 0; si < num_submeshes; ++si)
{
var material = materials[si];
Graphics.DrawMeshInstanced(mesh, si, material, m_matrices, n, mpb, m_castShadows, m_receiveShadows, layer);
}
}
}
else
#endif
{
// Graphics.DrawMesh() route
// not use IDs in this case because it's too expensive...

var matrix = Matrix4x4.identity;
for (int ii = 0; ii < num_instances; ++ii)
{
var ppos = points[ii];
ppos.x *= scale.x;
ppos.y *= scale.y;
ppos.z *= scale.z;
ppos = (rot * ppos) + pos;
matrix.SetTRS(ppos, rot, pscale);

// issue drawcalls
for (int si = 0; si < num_submeshes; ++si)
{
var material = materials[si];
Graphics.DrawMesh(mesh, matrix, material, layer, null, si, null, m_castShadows, m_receiveShadows);
}
}
}
}

public void Release()
{
#if UNITY_5_6_OR_NEWER
if (m_cbArgs != null) {
foreach(var cb in m_cbArgs) { cb.Release(); }
m_cbArgs = null;
}
if (m_cbPoints != null) { m_cbPoints.Release(); m_cbPoints = null; }
if (m_cbIDs != null) { m_cbIDs.Release(); m_cbIDs = null; }
#endif
}


Expand All @@ -388,7 +241,6 @@ void LateUpdate()
#endif
}

#if UNITY_EDITOR
void OnDrawGizmos()
{
// force draw particles while paused.
Expand All @@ -405,6 +257,32 @@ void OnDrawGizmos()
m_materialsInternal = null;
}
}

private void Start()
{
#if UNITY_EDITOR
if (m_mesh == null)
{
var cubeGO = GameObject.CreatePrimitive(PrimitiveType.Cube);
m_mesh = cubeGO.GetComponent<MeshFilter>().sharedMesh;
DestroyImmediate(cubeGO);
}
if (m_materials != null)
{
bool allNull = true;
foreach (var m in m_materials)
if (m_materials != null)
allNull = false;
if (allNull)
m_materials = null;
}
if (m_materials == null)
{
var mat = new Material(AssetDatabase.LoadAssetAtPath<Shader>("Assets/UTJ/Alembic/Shaders/StandardInstanced.shader"));
mat.name = "Default Alembic Points";
m_materials = new Material[] { mat };
}
#endif
}
}
}
58 changes: 13 additions & 45 deletions AlembicImporter/Assets/UTJ/Alembic/Shaders/PointRenderer.cginc
@@ -1,44 +1,12 @@
// Upgrade NOTE: upgraded instancing buffer 'A' to new syntax.
// Upgrade NOTE: upgraded instancing buffer 'Props' to new syntax.

#include "UnityCG.cginc"

#if defined(UNITY_SUPPORT_INSTANCING) && !defined(UNITY_INSTANCING_ENABLED) && !defined(UNITY_PROCEDURAL_INSTANCING_ENABLED) && (SHADER_TARGET >= 45 && defined(ALEMBIC_PROCEDURAL_INSTANCING_ENABLED))
#define UNITY_SUPPORT_INSTANCING
#define UNITY_PROCEDURAL_INSTANCING_ENABLED

uint unity_InstanceID;
#define UNITY_VERTEX_INPUT_INSTANCE_ID uint instanceID : SV_InstanceID;
#define UNITY_SETUP_INSTANCE_ID(v) unity_InstanceID = v.instanceID;
#endif


float3 _Translate;
float4 _Rotate;
float3 _Scale;
float _PointSize;
float _AlembicID;

#ifdef UNITY_SUPPORT_INSTANCING
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
StructuredBuffer<float3> _AlembicPoints;
StructuredBuffer<float> _AlembicIDs;
#else
UNITY_INSTANCING_BUFFER_START (Props)
UNITY_DEFINE_INSTANCED_PROP (float, _AlembicIDs)
#define _AlembicIDs_arr Props
UNITY_INSTANCING_BUFFER_END(Props)
#endif
#elif !defined(UNITY_VERTEX_INPUT_INSTANCE_ID)
// for pre-5.5
#define UNITY_VERTEX_INPUT_INSTANCE_ID
#define UNITY_INSTANCING_BUFFER_START(A, B)
#define UNITY_DEFINE_INSTANCED_PROP(A, B)
#define B_arr A
#define UNITY_ACCESS_INSTANCED_PROP(A_arr, A)
#define UNITY_INSTANCING_BUFFER_END(A)
#define UNITY_SETUP_INSTANCE_ID(A)
#define UNITY_TRANSFER_INSTANCE_ID(A, B)
StructuredBuffer<float3> _AlembicPoints;
StructuredBuffer<float> _AlembicIDs;
#endif

float GetPointSize()
Expand Down Expand Up @@ -100,30 +68,30 @@ float3 Rotate(float4 q, float3 p)
return p + (a * q.w + b) * 2.0;
}

float3 GetAlembicPoint()
float3 GetAlembicPoint(int iid)
{
return
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
Rotate(_Rotate, _AlembicPoints[unity_InstanceID] * _Scale) + _Translate;
#ifdef UNITY_SUPPORT_INSTANCING
Rotate(_Rotate, _AlembicPoints[iid] * _Scale) + _Translate;
#else
float3(unity_ObjectToWorld[0][3], unity_ObjectToWorld[1][3], unity_ObjectToWorld[2][3]);
float3(0,0,0);
#endif
}

float GetAlembicID()
float GetAlembicID(int iid)
{
return
#if defined(UNITY_INSTANCING_ENABLED) || defined(UNITY_PROCEDURAL_INSTANCING_ENABLED)
_AlembicIDs[unity_InstanceID];
#ifdef UNITY_SUPPORT_INSTANCING
_AlembicIDs[iid];
#else
_AlembicID;
0;
#endif
}

float4x4 GetPointMatrix()
float4x4 GetPointMatrix(int iid)
{
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
float3 ppos = GetAlembicPoint();
#ifdef UNITY_SUPPORT_INSTANCING
float3 ppos = GetAlembicPoint(iid);
float4 prot = _Rotate;
float3 pscale = _Scale * _PointSize;
return mul(mul(Translate44(ppos), Rotate44(prot)), Scale44(pscale));
Expand Down

21 comments on commit 5ed38e6

@davoodkharmanzar
Copy link

@davoodkharmanzar davoodkharmanzar commented on 5ed38e6 Jan 19, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for your dev ...

i'm trying to install this package on raw and empty project ...
but the importer does not working completely on 2017.3.0f3 :/
and the exporter crashed at the end of capturing!!

Alembic for unity 20180119

@i-saint
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry about that, but please remember: we can't fix the problem we can't reproduce. if you really want to solve the problem, you should send us enough information. Editor.log with minimum reproducible project is ideal.

@davoodkharmanzar
Copy link

@davoodkharmanzar davoodkharmanzar commented on 5ed38e6 Jan 19, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so, does it need to install prerequistics before installing the alembic package?
i'm just using the raw installer of unity 2017.3.0f3 , without ant preintergrated shaders or standard assets ...

@davoodkharmanzar
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and here is my problem ...
empty project ... just drop package to unity and import it ...

untitled-1

@i-saint
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

read the document (it was updated).

@davoodkharmanzar
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i followed the doc . and after install the package i tried to import an .abc file but nothing happened :/

@i-saint
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davoodkharmanzar
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here is dump file after crashing!!
crash.zip

@i-saint
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

send me your .abc file

@i-saint
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, no data, no fix.

@davoodkharmanzar
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well ... file is big ... 50% sent now :/
after completed i'v insert download link :]

@i-saint
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, sorry, I'm too pessimistic as many people just scream "it doesn't work" without any useful information and then disappear. you are different. I will do as much as I can after I receive data.

@davoodkharmanzar
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@i-saint
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks. I got data and reproduced the problem. I will look into it..

@davoodkharmanzar
Copy link

@davoodkharmanzar davoodkharmanzar commented on 5ed38e6 Jan 19, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks alot ... i hope to see the fix version of alembic soon ...
really powerful tool to creating animations :]

@i-saint
Copy link
Contributor Author

@i-saint i-saint commented on 5ed38e6 Jan 19, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/unity3d-jp/AlembicImporter/releases/download/20180119/AlembicForUnity.unitypackage
I secretly updated package. I think it works. (I'm not sure this is correct fix, but I confirmed it can play your data both on windows and mac)
btw, can you tell me what tool did you use to create this? your data seems bit strange and I want to investigate more.

bb

@davoodkharmanzar
Copy link

@davoodkharmanzar davoodkharmanzar commented on 5ed38e6 Jan 19, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good job :]
i'm using neuron mocap inside iClone and directly export alembic ... this character needs motion cleanup :P
does this plugin fully support timeline?

@i-saint
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, that's interesting.
you can control time parameter in AlembicStreamPlayer with Timeline. just drag the prefab into Timeline.

@davoodkharmanzar
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wow ... wow ... nice ... i tested it ... everything is ok :]

@davoodkharmanzar
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now ... i hate UNREAL ENGINE :D

@i-saint
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

glad to hear your problem solved!

Please sign in to comment.