Skip to content

Commit

Permalink
AlembicPointsRenderer: handling TRS
Browse files Browse the repository at this point in the history
  • Loading branch information
i-saint committed Apr 26, 2017
1 parent c3fabcd commit 26af568
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 28 deletions.
Expand Up @@ -143,22 +143,31 @@ public void Flush()

bool supportsInstancing = SystemInfo.supportsInstancing;
#if UNITY_5_6_OR_NEWER
int pidPointSize = Shader.PropertyToID("_PointSize");
int pidTranslate = Shader.PropertyToID("_Translate");
int pidRotate = Shader.PropertyToID("_Rotate");
int pidScale = Shader.PropertyToID("_Scale");
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)
{
Debug.LogWarning("AlembicPointsRenderer: Instancing is not supported on this system. fallback to InstancingMode.NoInstancing.");
m_instancingMode = InstancingMode.NoInstancing;
}

for (int si = 0; si < num_submeshes; ++si)
{
var material = materials[si];
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)
{
Expand Down Expand Up @@ -235,7 +244,6 @@ public void Flush()

var material = materials[si];
material.EnableKeyword(kAlembicProceduralInstancing);
material.SetFloat(pidPointSize, m_pointSize);
material.SetBuffer(pidAlembicPoints, m_cbPoints);
if (alembicIDsAvailable) { material.SetBuffer(pidAlembicIDs, m_cbIDs); }
Graphics.DrawMeshInstancedIndirect(mesh, si, material,
Expand Down
81 changes: 68 additions & 13 deletions AlembicImporter/Assets/UTJ/Alembic/Shaders/PointRenderer.cginc
Expand Up @@ -10,6 +10,9 @@
#endif


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

Expand All @@ -35,19 +38,68 @@ float _AlembicID;

float GetPointSize()
{
return
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
_PointSize;
#else
unity_ObjectToWorld[0][0];
#endif
return _PointSize;
}

float3x3 ToF33(float4x4 v)
{
// (float3x3)v don't compile on some platforms
return float3x3(
v[0][0], v[0][1], v[0][2],
v[1][0], v[1][1], v[1][2],
v[2][0], v[2][1], v[2][2]);
}


float4x4 Translate44(float3 t)
{
return float4x4(
1.0, 0.0, 0.0, t.x,
0.0, 1.0, 0.0, t.y,
0.0, 0.0, 1.0, t.z,
0.0, 0.0, 0.0, 1.0);
}

float4x4 Scale44(float3 s)
{
return float4x4(
s.x, 0.0, 0.0, 0.0,
0.0, s.y, 0.0, 0.0,
0.0, 0.0, s.x, 0.0,
0.0, 0.0, 0.0, 1.0);
}

// q: quaternion
float4x4 Rotate44(float4 q)
{
return float4x4(
1.0-2.0*q.y*q.y - 2.0*q.z*q.z, 2.0*q.x*q.y - 2.0*q.z*q.w, 2.0*q.x*q.z + 2.0*q.y*q.w, 0.0,
2.0*q.x*q.y + 2.0*q.z*q.w, 1.0 - 2.0*q.x*q.x - 2.0*q.z*q.z, 2.0*q.y*q.z - 2.0*q.x*q.w, 0.0,
2.0*q.x*q.z - 2.0*q.y*q.w, 2.0*q.y*q.z + 2.0*q.x*q.w, 1.0 - 2.0*q.x*q.x - 2.0*q.y*q.y, 0.0,
0.0, 0.0, 0.0, 1.0 );
}

float3 Cross(float3 l, float3 r)
{
return float3(
l.y * r.z - l.z * r.y,
l.z * r.x - l.x * r.z,
l.x * r.y - l.y * r.x);
}

// q: quaternion
float3 Rotate(float4 q, float3 p)
{
float3 a = cross(q.xyz, p);
float3 b = cross(q.xyz, a);
return p + (a * q.w + b) * 2.0;
}

float3 GetAlembicPoint()
{
return
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
_AlembicPoints[unity_InstanceID];
Rotate(_Rotate, _AlembicPoints[unity_InstanceID] * _Scale) + _Translate;
#else
float3(unity_ObjectToWorld[0][3], unity_ObjectToWorld[1][3], unity_ObjectToWorld[2][3]);
#endif
Expand All @@ -63,11 +115,14 @@ float GetAlembicID()
#endif
}

float3x3 ToF33(float4x4 v)
float4x4 GetPointMatrix()
{
// (float3x3)v don't compile on some platforms
return float3x3(
v[0][0], v[0][1], v[0][2],
v[1][0], v[1][1], v[1][2],
v[2][0], v[2][1], v[2][2]);
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
float3 ppos = GetAlembicPoint();
float4 prot = _Rotate;
float3 pscale = _Scale * _PointSize;
return mul(mul(Translate44(ppos), Rotate44(prot)), Scale44(pscale));
#else
return unity_ObjectToWorld;
#endif
}
Expand Up @@ -30,13 +30,7 @@
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
void setup()
{
float size = GetPointSize();
float3 pos = GetAlembicPoint();

unity_ObjectToWorld._11_21_31_41 = float4(size, 0, 0, 0);
unity_ObjectToWorld._12_22_32_42 = float4(0, size, 0, 0);
unity_ObjectToWorld._13_23_33_43 = float4(0, 0, size, 0);
unity_ObjectToWorld._14_24_34_44 = float4(pos, 1);
unity_ObjectToWorld = GetPointMatrix();
unity_WorldToObject = unity_ObjectToWorld;
unity_WorldToObject._14_24_34 *= -1;
unity_WorldToObject._11_22_33 = 1.0f / unity_WorldToObject._11_22_33;
Expand Down
Expand Up @@ -51,9 +51,7 @@
UNITY_SETUP_INSTANCE_ID(v);

float4 vertex = v.vertex;
vertex.xyz *= GetPointSize();
vertex.xyz += GetAlembicPoint();
vertex = mul(UNITY_MATRIX_VP, vertex);
vertex = mul(mul(UNITY_MATRIX_VP, GetPointMatrix()), vertex);

v2f o;
o.vertex = vertex;
Expand Down

0 comments on commit 26af568

Please sign in to comment.