소스 검색

Add GlowLayer alpha support

sebavan 6 년 전
부모
커밋
d41bd2ab28
5개의 변경된 파일148개의 추가작업 그리고 26개의 파일을 삭제
  1. 1 0
      dist/preview release/what's new.md
  2. 72 18
      src/Layers/effectLayer.ts
  3. 11 1
      src/Layers/glowLayer.ts
  4. 39 5
      src/Shaders/glowMapGeneration.fragment.fx
  5. 25 2
      src/Shaders/glowMapGeneration.vertex.fx

+ 1 - 0
dist/preview release/what's new.md

@@ -88,6 +88,7 @@
 - Enable dragging in boundingBoxGizmo without needing a parent ([TrevorDev](https://github.com/TrevorDev))
 - Added per mesh culling strategy ([jerome](https://github.com/jbousquie))
 - Added per solid particle culling possibility : `solidParticle.isInFrustum()`  ([jerome](https://github.com/jbousquie))
+- Added transparency support to `GlowLayer` ([Sebavan](https://github.com/Sebavan))
 
 ### OBJ Loader
 - Add color vertex support (not part of standard) ([brianzinn](https://github.com/brianzinn))

+ 72 - 18
src/Layers/effectLayer.ts

@@ -383,13 +383,18 @@ import "../Shaders/glowMapGeneration.vertex";
             var uv1 = false;
             var uv2 = false;
 
-            // Alpha test
-            if (material && material.needAlphaTesting()) {
-                var alphaTexture = material.getAlphaTestTexture();
-                if (alphaTexture) {
-                    defines.push("#define ALPHATEST");
+            // Diffuse
+            if (material) {
+                const needAlphaTest = material.needAlphaTesting();
+
+                const diffuseTexture = material.getAlphaTestTexture();
+                const needAlphaBlendFromDiffuse = diffuseTexture && diffuseTexture.hasAlpha &&
+                    ((material as any).useAlphaFromDiffuseTexture || (material as any)._useAlphaFromAlbedoTexture);
+
+                if (diffuseTexture && (needAlphaTest || needAlphaBlendFromDiffuse)) {
+                    defines.push("#define DIFFUSE");
                     if (mesh.isVerticesDataPresent(VertexBuffer.UV2Kind) &&
-                        alphaTexture.coordinatesIndex === 1) {
+                        diffuseTexture.coordinatesIndex === 1) {
                         defines.push("#define DIFFUSEUV2");
                         uv2 = true;
                     }
@@ -397,6 +402,25 @@ import "../Shaders/glowMapGeneration.vertex";
                         defines.push("#define DIFFUSEUV1");
                         uv1 = true;
                     }
+
+                    if (needAlphaTest) {
+                        defines.push("#define ALPHATEST");
+                        defines.push("#define ALPHATESTVALUE 0.4");
+                    }
+                }
+
+                var opacityTexture = (material as any).opacityTexture;
+                if (opacityTexture) {
+                    defines.push("#define OPACITY");
+                    if (mesh.isVerticesDataPresent(VertexBuffer.UV2Kind) &&
+                        opacityTexture.coordinatesIndex === 1) {
+                        defines.push("#define OPACITYUV2");
+                        uv2 = true;
+                    }
+                    else if (mesh.isVerticesDataPresent(VertexBuffer.UVKind)) {
+                        defines.push("#define OPACITYUV1");
+                        uv1 = true;
+                    }
                 }
             }
 
@@ -414,6 +438,12 @@ import "../Shaders/glowMapGeneration.vertex";
                 }
             }
 
+            // Vertex
+            if (mesh.isVerticesDataPresent(VertexBuffer.ColorKind) && mesh.hasVertexAlpha) {
+                attribs.push(VertexBuffer.ColorKind);
+                defines.push("#define VERTEXALPHA");
+            }
+
             if (uv1) {
                 attribs.push(VertexBuffer.UVKind);
                 defines.push("#define UV1");
@@ -464,8 +494,10 @@ import "../Shaders/glowMapGeneration.vertex";
                 this._cachedDefines = join;
                 this._effectLayerMapGenerationEffect = this._scene.getEngine().createEffect("glowMapGeneration",
                     attribs,
-                    ["world", "mBones", "viewProjection", "diffuseMatrix", "color", "emissiveMatrix", "morphTargetInfluences"],
-                    ["diffuseSampler", "emissiveSampler"], join,
+                    ["world", "mBones", "viewProjection",
+                    "color", "morphTargetInfluences",
+                    "diffuseMatrix", "emissiveMatrix", "opacityMatrix", "opacityIntensity"],
+                    ["diffuseSampler", "emissiveSampler", "opacitySampler"], join,
                     undefined, undefined, undefined, { maxSimultaneousMorphTargets: morphInfluencers });
             }
 
@@ -556,6 +588,16 @@ import "../Shaders/glowMapGeneration.vertex";
         }
 
         /**
+         * Returns true if the mesh can be rendered, otherwise false.
+         * @param mesh The mesh to render
+         * @param material The material used on the mesh
+         * @returns true if it can be rendered otherwise false
+         */
+        protected _canRenderMesh(mesh: AbstractMesh, material: Material): boolean {
+            return material.needAlphaBlendingForMesh(mesh);
+        }
+
+        /**
          * Returns true if the mesh should render, otherwise false.
          * @param mesh The mesh to render
          * @returns true if it should render otherwise false
@@ -582,7 +624,7 @@ import "../Shaders/glowMapGeneration.vertex";
             }
 
             // Do not block in blend mode.
-            if (material.needAlphaBlendingForMesh(mesh)) {
+            if (this._canRenderMesh(mesh, material)) {
                 return;
             }
 
@@ -616,16 +658,28 @@ import "../Shaders/glowMapGeneration.vertex";
                     this._emissiveTextureAndColor.color.b,
                     this._emissiveTextureAndColor.color.a);
 
-                // Alpha test
-                if (material && material.needAlphaTesting()) {
-                    var alphaTexture = material.getAlphaTestTexture();
-                    if (alphaTexture) {
-                        this._effectLayerMapGenerationEffect.setTexture("diffuseSampler", alphaTexture);
-                        let textureMatrix = alphaTexture.getTextureMatrix();
+                const needAlphaTest = material.needAlphaTesting();
+
+                const diffuseTexture = material.getAlphaTestTexture();
+                const needAlphaBlendFromDiffuse = diffuseTexture && diffuseTexture.hasAlpha &&
+                    ((material as any).useAlphaFromDiffuseTexture || (material as any)._useAlphaFromAlbedoTexture);
+
+                if (diffuseTexture && (needAlphaTest || needAlphaBlendFromDiffuse)) {
+                    this._effectLayerMapGenerationEffect.setTexture("diffuseSampler", diffuseTexture);
+                    const textureMatrix = diffuseTexture.getTextureMatrix();
+
+                    if (textureMatrix) {
+                        this._effectLayerMapGenerationEffect.setMatrix("diffuseMatrix", textureMatrix);
+                    }
+                }
 
-                        if (textureMatrix) {
-                            this._effectLayerMapGenerationEffect.setMatrix("diffuseMatrix", textureMatrix);
-                        }
+                const opacityTexture = (material as any).opacityTexture;
+                if (opacityTexture) {
+                    this._effectLayerMapGenerationEffect.setTexture("opacitySampler", opacityTexture);
+                    this._effectLayerMapGenerationEffect.setFloat("opacityIntensity", opacityTexture.level);
+                    const textureMatrix = opacityTexture.getTextureMatrix();
+                    if (textureMatrix) {
+                        this._effectLayerMapGenerationEffect.setMatrix("opacityMatrix", textureMatrix);
                     }
                 }
 

+ 11 - 1
src/Layers/glowLayer.ts

@@ -355,6 +355,16 @@ declare module "../abstractScene" {
         }
 
         /**
+         * Returns true if the mesh can be rendered, otherwise false.
+         * @param mesh The mesh to render
+         * @param material The material used on the mesh
+         * @returns true if it can be rendered otherwise false
+         */
+        protected _canRenderMesh(mesh: AbstractMesh, material: Material): boolean {
+            return true;
+        }
+
+        /**
          * Implementation specific of rendering the generating effect on the main canvas.
          * @param effect The effect used to render through
          */
@@ -405,7 +415,7 @@ declare module "../abstractScene" {
                         (<any>material).emissiveColor.r * textureLevel,
                         (<any>material).emissiveColor.g * textureLevel,
                         (<any>material).emissiveColor.b * textureLevel,
-                        1.0);
+                        material.alpha);
                 }
                 else {
                     this._emissiveTextureAndColor.color.set(

+ 39 - 5
src/Shaders/glowMapGeneration.fragment.fx

@@ -1,8 +1,14 @@
-#ifdef ALPHATEST
+#ifdef DIFFUSE
 varying vec2 vUVDiffuse;
 uniform sampler2D diffuseSampler;
 #endif
 
+#ifdef OPACITY
+varying vec2 vUVOpacity;
+uniform sampler2D opacitySampler;
+uniform float opacityIntensity;
+#endif
+
 #ifdef EMISSIVE
 varying vec2 vUVEmissive;
 uniform sampler2D emissiveSampler;
@@ -12,14 +18,42 @@ uniform vec4 color;
 
 void main(void)
 {
+
+vec4 finalColor = color;
+
+// _____________________________ Alpha Information _______________________________
+#ifdef DIFFUSE
+    vec4 albedoTexture = texture2D(diffuseSampler, vUVDiffuse);
+    finalColor.a *= albedoTexture.a;
+#endif
+
+#ifdef OPACITY
+    vec4 opacityMap = texture2D(opacitySampler, vUVOpacity);
+
+    #ifdef OPACITYRGB
+        finalColor.a *= getLuminance(opacityMap.rgb);
+    #else
+        finalColor.a *= opacityMap.a;
+    #endif
+
+    finalColor.a *= opacityIntensity;
+#endif
+
+#ifdef VERTEXALPHA
+    finalColor.a *= vColor.a;
+#endif
+
 #ifdef ALPHATEST
-	if (texture2D(diffuseSampler, vUVDiffuse).a < 0.4)
-		discard;
+    if (finalColor.a < ALPHATESTVALUE)
+        discard;
 #endif
 
 #ifdef EMISSIVE
-	gl_FragColor = texture2D(emissiveSampler, vUVEmissive) * color;
+    gl_FragColor = texture2D(emissiveSampler, vUVEmissive) * finalColor;
 #else
-	gl_FragColor = color;
+    gl_FragColor = finalColor;
 #endif
+
+    gl_FragColor.rgb *= gl_FragColor.a;
+    gl_FragColor.a = 1.0;
 }

+ 25 - 2
src/Shaders/glowMapGeneration.vertex.fx

@@ -21,16 +21,26 @@ attribute vec2 uv;
 attribute vec2 uv2;
 #endif
 
-#ifdef ALPHATEST
+#ifdef DIFFUSE
 	varying vec2 vUVDiffuse;
 	uniform mat4 diffuseMatrix;
 #endif
 
+#ifdef OPACITY
+	varying vec2 vUVOpacity;
+	uniform mat4 opacityMatrix;
+#endif
+
 #ifdef EMISSIVE
 	varying vec2 vUVEmissive;
 	uniform mat4 emissiveMatrix;
 #endif
 
+#ifdef VERTEXALPHA
+	attribute vec4 color;
+	varying vec4 vColor;
+#endif
+
 void main(void)
 {
 	vec3 positionUpdated = position;
@@ -47,7 +57,7 @@ void main(void)
 	gl_Position = vPosition;
 #endif
 
-#ifdef ALPHATEST
+#ifdef DIFFUSE
 	#ifdef DIFFUSEUV1
 		vUVDiffuse = vec2(diffuseMatrix * vec4(uv, 1.0, 0.0));
 	#endif
@@ -56,6 +66,15 @@ void main(void)
 	#endif
 #endif
 
+#ifdef OPACITY
+	#ifdef OPACITYUV1
+		vUVOpacity = vec2(opacityMatrix * vec4(uv, 1.0, 0.0));
+	#endif
+	#ifdef OPACITYUV2
+		vUVOpacity = vec2(opacityMatrix * vec4(uv2, 1.0, 0.0));
+	#endif
+#endif
+
 #ifdef EMISSIVE
 	#ifdef EMISSIVEUV1
 		vUVEmissive = vec2(emissiveMatrix * vec4(uv, 1.0, 0.0));
@@ -64,4 +83,8 @@ void main(void)
 		vUVEmissive = vec2(emissiveMatrix * vec4(uv2, 1.0, 0.0));
 	#endif
 #endif
+
+#ifdef VERTEXALPHA
+    vColor = color;
+#endif
 }