-- glslfx version 0.1 // // Copyright 2016 Pixar // // Licensed under the Apache License, Version 2.0 (the "Apache License") // with the following modification; you may not use this file except in // compliance with the Apache License and the following modification to it: // Section 6. Trademarks. is deleted and replaced with: // // 6. Trademarks. This License does not grant permission to use the trade // names, trademarks, service marks, or product names of the Licensor // and its affiliates, except as required to comply with Section 4(c) of // the License and to reproduce the content of the NOTICE file. // // You may obtain a copy of the Apache License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the Apache License with the above modification is // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the Apache License for the specific // language governing permissions and limitations under the Apache License. // --- This is what an import might look like. --- #import $TOOLS/hdSt/shaders/instancing.glslfx --- -------------------------------------------------------------------------- -- glsl Instancing.Transform // quaternion to matrix. x=real, yzw=imaginary MAT4 GetRotationMatrix(vec4 q) { MAT4 r; r[0].xyzw = vec4(1 - 2 * (q.z * q.z + q.w * q.w), 2 * (q.y * q.z + q.w * q.x), 2 * (q.y * q.w - q.z * q.x), 0); r[1].xyzw = vec4( 2 * (q.y * q.z - q.w * q.x), 1 - 2 * (q.y * q.y + q.w * q.w), 2 * (q.z * q.w + q.y * q.x), 0); r[2].xyzw = vec4( 2 * (q.y * q.w + q.z * q.x), 2 * (q.z * q.w - q.y * q.x), 1 - 2 * (q.y * q.y + q.z * q.z), 0); r[3] = vec4(0, 0, 0, 1); return r; } // --------------------------------------------------------------------------- MAT4 GetInstanceTransform(int level) { MAT4 m = MAT4(1); #ifdef HD_HAS_INSTANCE_instanceTransform m = HdGetInstance_instanceTransform(level, MAT4(1)) * m; #endif // instance transform elements are applied: // scale then rotate then translate // i.e. (T * R * S) * position #ifdef HD_HAS_INSTANCE_scale vec3 s = HdGetInstance_scale(level, /*default=*/vec3(1)); m = MAT4(s.x, 0, 0, 0, 0, s.y, 0, 0, 0, 0, s.z, 0, 0, 0, 0, 1) * m; #endif #ifdef HD_HAS_INSTANCE_rotate // GfQuaternion(real, ix, iy, iz) vec4 q = HdGetInstance_rotate(level, /*default=*/vec4(0)); m = GetRotationMatrix(q) * m; #endif #ifdef HD_HAS_INSTANCE_translate vec3 t = HdGetInstance_translate(level, /*default=*/vec3(0)); m = MAT4( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, t.x, t.y, t.z, 1) * m; #endif return m; } MAT4 GetInstanceTransformInverse(int level) { MAT4 m = MAT4(1); #ifdef HD_HAS_INSTANCE_instanceTransform m = inverse(HdGetInstance_instanceTransform(level, MAT4(1))) * m; #endif #ifdef HD_HAS_INSTANCE_translate vec3 it = -HdGetInstance_translate(level, /*default=*/vec3(0)); // negate m = MAT4( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, it.x, it.y, it.z, 1) * m; #endif #ifdef HD_HAS_INSTANCE_rotate vec4 q = HdGetInstance_rotate(level, /*default=*/vec4(0)); q.yzw = -q.yzw; // inverse rotataion axis m = GetRotationMatrix(q) * m; #endif #ifdef HD_HAS_INSTANCE_scale vec3 is = 1.0/HdGetInstance_scale(level, /*default=*/vec3(1)); // inverse scale m = MAT4(is.x, 0, 0, 0, 0, is.y, 0, 0, 0, 0, is.z, 0, 0, 0, 0, 1) * m; #endif return m; } // --------------------------------------------------------------------------- MAT4 GetInstanceTransform() { MAT4 m = MAT4(1); #ifdef HD_INSTANCER_NUM_LEVELS for (int i = 0; i < HD_INSTANCER_NUM_LEVELS; ++i) { m = GetInstanceTransform(i) * m; #ifdef HD_HAS_instancerTransform m = HdGet_instancerTransform(i) * m; #endif } #endif return m; } MAT4 GetInstanceTransformInverse() { MAT4 m = MAT4(1); #ifdef HD_INSTANCER_NUM_LEVELS for (int i = 0; i < HD_INSTANCER_NUM_LEVELS; ++i) { m = m * GetInstanceTransformInverse(i); #ifdef HD_HAS_instancerTransformInverse m = m * HdGet_instancerTransformInverse(i); #endif } #endif return m; } // --------------------------------------------------------------------------- MAT4 ApplyInstanceTransform(MAT4 m) { return GetInstanceTransform() * m; } MAT4 ApplyInstanceTransformInverse(MAT4 m) { return m * GetInstanceTransformInverse(); } bool IsFlipped() { #if defined(HD_HAS_isFlipped) bool flip = (HdGet_isFlipped() != 0); #elif defined(HD_HAS_transform) // The sign of the determinant indicates whether m flips handedness bool flip = (determinant(HdGet_transform()) < 0.0); #else bool flip = false; #endif #ifdef HD_HAS_INSTANCE_scale for (int i = 0; i < HD_INSTANCER_NUM_LEVELS; ++i) { vec3 scale = HdGetInstance_scale(i, /*default=*/vec3(1)); flip = flip ^^ ((sign(scale.x) * sign(scale.y) * sign(scale.z)) < 0); } #endif #ifdef HD_HAS_INSTANCE_instanceTransform for (int i = 0; i < HD_INSTANCER_NUM_LEVELS; ++i) { MAT4 m = HdGetInstance_instanceTransform(i, MAT4(1)); flip = flip ^^ (determinant(m) < 0.0); } #endif return flip; }