From 26af5681b9416153d7b07ae5ed4c2139402417bf Mon Sep 17 00:00:00 2001 From: i-saint Date: Wed, 26 Apr 2017 20:03:19 +0900 Subject: [PATCH] AlembicPointsRenderer: handling TRS --- .../Scripts/Importer/AlembicPointsRenderer.cs | 18 +++-- .../UTJ/Alembic/Shaders/PointRenderer.cginc | 81 ++++++++++++++++--- .../Alembic/Shaders/StandardInstanced.shader | 8 +- .../Shaders/TransparentInstanced.shader | 4 +- 4 files changed, 83 insertions(+), 28 deletions(-) diff --git a/AlembicImporter/Assets/UTJ/Alembic/Scripts/Importer/AlembicPointsRenderer.cs b/AlembicImporter/Assets/UTJ/Alembic/Scripts/Importer/AlembicPointsRenderer.cs index 8cc092914..147b3b0fc 100644 --- a/AlembicImporter/Assets/UTJ/Alembic/Scripts/Importer/AlembicPointsRenderer.cs +++ b/AlembicImporter/Assets/UTJ/Alembic/Scripts/Importer/AlembicPointsRenderer.cs @@ -143,15 +143,15 @@ 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) { @@ -159,6 +159,15 @@ public void Flush() 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) { @@ -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, diff --git a/AlembicImporter/Assets/UTJ/Alembic/Shaders/PointRenderer.cginc b/AlembicImporter/Assets/UTJ/Alembic/Shaders/PointRenderer.cginc index 00592e6d6..33ef510a9 100644 --- a/AlembicImporter/Assets/UTJ/Alembic/Shaders/PointRenderer.cginc +++ b/AlembicImporter/Assets/UTJ/Alembic/Shaders/PointRenderer.cginc @@ -10,6 +10,9 @@ #endif +float3 _Translate; +float4 _Rotate; +float3 _Scale; float _PointSize; float _AlembicID; @@ -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 @@ -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 } diff --git a/AlembicImporter/Assets/UTJ/Alembic/Shaders/StandardInstanced.shader b/AlembicImporter/Assets/UTJ/Alembic/Shaders/StandardInstanced.shader index 3d09d4ff8..2c6c0aaa2 100644 --- a/AlembicImporter/Assets/UTJ/Alembic/Shaders/StandardInstanced.shader +++ b/AlembicImporter/Assets/UTJ/Alembic/Shaders/StandardInstanced.shader @@ -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; diff --git a/AlembicImporter/Assets/UTJ/Alembic/Shaders/TransparentInstanced.shader b/AlembicImporter/Assets/UTJ/Alembic/Shaders/TransparentInstanced.shader index fdad70385..f0c92ea44 100644 --- a/AlembicImporter/Assets/UTJ/Alembic/Shaders/TransparentInstanced.shader +++ b/AlembicImporter/Assets/UTJ/Alembic/Shaders/TransparentInstanced.shader @@ -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;