Browse Source

REVIEWED: GPU skninning on Web, some gotchas! #4412

Ray 9 months ago
parent
commit
b0140b876b
4 changed files with 43 additions and 10 deletions
  1. 2 2
      examples/Makefile
  2. 9 2
      examples/Makefile.Web
  3. 26 4
      examples/models/resources/shaders/glsl100/skinning.vs
  4. 6 2
      src/rlgl.h

+ 2 - 2
examples/Makefile

@@ -157,8 +157,8 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
 		EMSDK_PATH         ?= C:/emsdk
 		EMSCRIPTEN_PATH    ?= $(EMSDK_PATH)/upstream/emscripten
 		CLANG_PATH          = $(EMSDK_PATH)/upstream/bin
-		PYTHON_PATH         = $(EMSDK_PATH)/python/3.9.2-1_64bit
-		NODE_PATH           = $(EMSDK_PATH)/node/14.15.5_64bit/bin
+		PYTHON_PATH         = $(EMSDK_PATH)/python/3.9.2-nuget_64bit
+		NODE_PATH           = $(EMSDK_PATH)/node/20.18.0_64bit/bin
 		export PATH         = $(EMSDK_PATH);$(EMSCRIPTEN_PATH);$(CLANG_PATH);$(NODE_PATH);$(PYTHON_PATH):$$(PATH)
     endif
 endif

+ 9 - 2
examples/Makefile.Web

@@ -110,8 +110,8 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
 		EMSDK_PATH         ?= C:/emsdk
 		EMSCRIPTEN_PATH    ?= $(EMSDK_PATH)/upstream/emscripten
 		CLANG_PATH          = $(EMSDK_PATH)/upstream/bin
-		PYTHON_PATH         = $(EMSDK_PATH)/python/3.9.2-1_64bit
-		NODE_PATH           = $(EMSDK_PATH)/node/14.15.5_64bit/bin
+		PYTHON_PATH         = $(EMSDK_PATH)/python/3.9.2-nuget_64bit
+		NODE_PATH           = $(EMSDK_PATH)/node/20.18.0_64bit/bin
 		export PATH         = $(EMSDK_PATH);$(EMSCRIPTEN_PATH);$(CLANG_PATH);$(NODE_PATH);$(PYTHON_PATH):$$(PATH)
     endif
 endif
@@ -434,6 +434,7 @@ TEXT = \
 
 MODELS = \
     models/models_animation \
+    models/models_gpu_skinning \
     models/models_billboard \
     models/models_box_collisions \
     models/models_cubicmap \
@@ -853,6 +854,12 @@ models/models_animation: models/models_animation.c
     --preload-file models/resources/models/iqm/guy.iqm@resources/models/iqm/guy.iqm \
     --preload-file models/resources/models/iqm/guytex.png@resources/models/iqm/guytex.png \
     --preload-file models/resources/models/iqm/guyanim.iqm@resources/models/iqm/guyanim.iqm
+    
+models/models_gpu_skinning: models/models_gpu_skinning.c
+	$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -sTOTAL_MEMORY=67108864 \
+    --preload-file models/resources/models/gltf/greenman.glb@resources/models/gltf/greenman.glb \
+    --preload-file models/resources/shaders/glsl100/skinning.vs@resources/shaders/glsl100/skinning.vs \
+    --preload-file models/resources/shaders/glsl100/skinning.fs@resources/shaders/glsl100/skinning.fs
 
 models/models_billboard: models/models_billboard.c
 	$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \

+ 26 - 4
examples/models/resources/shaders/glsl100/skinning.vs

@@ -24,11 +24,33 @@ void main()
     int boneIndex2 = int(vertexBoneIds.z);
     int boneIndex3 = int(vertexBoneIds.w);
     
+    // WARNING: OpenGL ES 2.0 does not support automatic matrix transposing, neither transpose() function
+    mat4 boneMatrixTransposed0 = mat4(
+        vec4(boneMatrices[boneIndex0][0].x, boneMatrices[boneIndex0][1].x, boneMatrices[boneIndex0][2].x, boneMatrices[boneIndex0][3].x),
+        vec4(boneMatrices[boneIndex0][0].y, boneMatrices[boneIndex0][1].y, boneMatrices[boneIndex0][2].y, boneMatrices[boneIndex0][3].y),
+        vec4(boneMatrices[boneIndex0][0].z, boneMatrices[boneIndex0][1].z, boneMatrices[boneIndex0][2].z, boneMatrices[boneIndex0][3].z),
+        vec4(boneMatrices[boneIndex0][0].w, boneMatrices[boneIndex0][1].w, boneMatrices[boneIndex0][2].w, boneMatrices[boneIndex0][3].w));
+    mat4 boneMatrixTransposed1 = mat4(
+        vec4(boneMatrices[boneIndex1][0].x, boneMatrices[boneIndex1][1].x, boneMatrices[boneIndex1][2].x, boneMatrices[boneIndex1][3].x),
+        vec4(boneMatrices[boneIndex1][0].y, boneMatrices[boneIndex1][1].y, boneMatrices[boneIndex1][2].y, boneMatrices[boneIndex1][3].y),
+        vec4(boneMatrices[boneIndex1][0].z, boneMatrices[boneIndex1][1].z, boneMatrices[boneIndex1][2].z, boneMatrices[boneIndex1][3].z),
+        vec4(boneMatrices[boneIndex1][0].w, boneMatrices[boneIndex1][1].w, boneMatrices[boneIndex1][2].w, boneMatrices[boneIndex1][3].w));
+    mat4 boneMatrixTransposed2 = mat4(
+        vec4(boneMatrices[boneIndex2][0].x, boneMatrices[boneIndex2][1].x, boneMatrices[boneIndex2][2].x, boneMatrices[boneIndex2][3].x),
+        vec4(boneMatrices[boneIndex2][0].y, boneMatrices[boneIndex2][1].y, boneMatrices[boneIndex2][2].y, boneMatrices[boneIndex2][3].y),
+        vec4(boneMatrices[boneIndex2][0].z, boneMatrices[boneIndex2][1].z, boneMatrices[boneIndex2][2].z, boneMatrices[boneIndex2][3].z),
+        vec4(boneMatrices[boneIndex2][0].w, boneMatrices[boneIndex2][1].w, boneMatrices[boneIndex2][2].w, boneMatrices[boneIndex2][3].w));
+    mat4 boneMatrixTransposed3 = mat4(
+        vec4(boneMatrices[boneIndex3][0].x, boneMatrices[boneIndex3][1].x, boneMatrices[boneIndex3][2].x, boneMatrices[boneIndex3][3].x),
+        vec4(boneMatrices[boneIndex3][0].y, boneMatrices[boneIndex3][1].y, boneMatrices[boneIndex3][2].y, boneMatrices[boneIndex3][3].y),
+        vec4(boneMatrices[boneIndex3][0].z, boneMatrices[boneIndex3][1].z, boneMatrices[boneIndex3][2].z, boneMatrices[boneIndex3][3].z),
+        vec4(boneMatrices[boneIndex3][0].w, boneMatrices[boneIndex3][1].w, boneMatrices[boneIndex3][2].w, boneMatrices[boneIndex3][3].w));
+    
     vec4 skinnedPosition =
-        vertexBoneWeights.x*(boneMatrices[boneIndex0]*vec4(vertexPosition, 1.0)) +
-        vertexBoneWeights.y*(boneMatrices[boneIndex1]*vec4(vertexPosition, 1.0)) + 
-        vertexBoneWeights.z*(boneMatrices[boneIndex2]*vec4(vertexPosition, 1.0)) + 
-        vertexBoneWeights.w*(boneMatrices[boneIndex3]*vec4(vertexPosition, 1.0));
+        vertexBoneWeights.x*(boneMatrixTransposed0*vec4(vertexPosition, 1.0)) +
+        vertexBoneWeights.y*(boneMatrixTransposed1*vec4(vertexPosition, 1.0)) + 
+        vertexBoneWeights.z*(boneMatrixTransposed2*vec4(vertexPosition, 1.0)) + 
+        vertexBoneWeights.w*(boneMatrixTransposed3*vec4(vertexPosition, 1.0));
     
     fragTexCoord = vertexTexCoord;
     fragColor = vertexColor;

+ 6 - 2
src/rlgl.h

@@ -4337,8 +4337,12 @@ void rlSetUniformMatrix(int locIndex, Matrix mat)
 // Set shader value uniform matrix
 void rlSetUniformMatrices(int locIndex, const Matrix *matrices, int count)
 {
-#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
-    glUniformMatrix4fv(locIndex, count, true, (const float*)matrices);
+#if defined(GRAPHICS_API_OPENGL_33)
+    glUniformMatrix4fv(locIndex, count, true, (const float *)matrices);
+#elif defined(GRAPHICS_API_OPENGL_ES2)
+    // WARNING: WebGL does not support Matrix transpose ("true" parameter)
+    // REF: https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/uniformMatrix
+    glUniformMatrix4fv(locIndex, count, true, (const float *)matrices);
 #endif
 }