Skip to content

Commit af66eaf

Browse files
authored
Fixed GLSL implementations of matrix operators (#2298)
Fixed an issue with GLSL matrix multiplication and division, described in #2089 The gist of the problem is this. Taking C++ code as the basis, MaterialX uses row major matrices, with translation in the last row, so it transforms points like so `p * M`. When composing transforms `M1 * M2`, the final result is `p * M1 * M2`. However, GLSL has matrices in col-major storage, meaning that when you simply upload the CPU memory, the matrices on the GPU are transposed. That effectively means that translation is now in the last column, so transforming point works like `M * p`, and composing transforms works like `M2 * M1 * p`, to match the CPU `p * M1 * M2`. That means that matrix multiplication has to have the inputs swapped. Alternatively, we could do `transpose(transpose({{in1}}) * transpose({{in2}}))` for the same effect. The fix to division has two parts. In GLSL, only the `*` operator has special meaning (matrix multiplication), division operator `/` only does component wise division. So instead of `M1 / M2` you have to write `M1 * inverse(M2)`. And on top that, the matrix multiplication swap of arguments described above also applies, for the final form of `inverse(M2) * M1`. Again, alternatively we could transpose the arguments and then transpose the result.
1 parent 75d795f commit af66eaf

1 file changed

Lines changed: 4 additions & 4 deletions

File tree

libraries/stdlib/genglsl/stdlib_genglsl_impl.mtlx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,8 @@
237237
<implementation name="IM_multiply_vector3FA_genglsl" nodedef="ND_multiply_vector3FA" target="genglsl" sourcecode="{{in1}} * {{in2}}" />
238238
<implementation name="IM_multiply_vector4_genglsl" nodedef="ND_multiply_vector4" target="genglsl" sourcecode="{{in1}} * {{in2}}" />
239239
<implementation name="IM_multiply_vector4FA_genglsl" nodedef="ND_multiply_vector4FA" target="genglsl" sourcecode="{{in1}} * {{in2}}" />
240-
<implementation name="IM_multiply_matrix33_genglsl" nodedef="ND_multiply_matrix33" target="genglsl" sourcecode="{{in1}} * {{in2}}" />
241-
<implementation name="IM_multiply_matrix44_genglsl" nodedef="ND_multiply_matrix44" target="genglsl" sourcecode="{{in1}} * {{in2}}" />
240+
<implementation name="IM_multiply_matrix33_genglsl" nodedef="ND_multiply_matrix33" target="genglsl" sourcecode="{{in2}} * {{in1}}" />
241+
<implementation name="IM_multiply_matrix44_genglsl" nodedef="ND_multiply_matrix44" target="genglsl" sourcecode="{{in2}} * {{in1}}" />
242242

243243
<!-- <divide> -->
244244
<implementation name="IM_divide_float_genglsl" nodedef="ND_divide_float" target="genglsl" sourcecode="{{in1}} / {{in2}}" />
@@ -252,8 +252,8 @@
252252
<implementation name="IM_divide_vector3FA_genglsl" nodedef="ND_divide_vector3FA" target="genglsl" sourcecode="{{in1}} / {{in2}}" />
253253
<implementation name="IM_divide_vector4_genglsl" nodedef="ND_divide_vector4" target="genglsl" sourcecode="{{in1}} / {{in2}}" />
254254
<implementation name="IM_divide_vector4FA_genglsl" nodedef="ND_divide_vector4FA" target="genglsl" sourcecode="{{in1}} / {{in2}}" />
255-
<implementation name="IM_divide_matrix33_genglsl" nodedef="ND_divide_matrix33" target="genglsl" sourcecode="{{in1}} / {{in2}}" />
256-
<implementation name="IM_divide_matrix44_genglsl" nodedef="ND_divide_matrix44" target="genglsl" sourcecode="{{in1}} / {{in2}}" />
255+
<implementation name="IM_divide_matrix33_genglsl" nodedef="ND_divide_matrix33" target="genglsl" sourcecode="mx_inverse({{in2}}) * {{in1}}" />
256+
<implementation name="IM_divide_matrix44_genglsl" nodedef="ND_divide_matrix44" target="genglsl" sourcecode="mx_inverse({{in2}}) * {{in1}}" />
257257

258258
<!-- <modulo> -->
259259
<implementation name="IM_modulo_float_genglsl" nodedef="ND_modulo_float" target="genglsl" sourcecode="mx_mod({{in1}}, {{in2}})" />

0 commit comments

Comments
 (0)