Browse Source

Fix CCW/CW conflict with instances

David Catuhe 5 years ago
parent
commit
80511032e7

+ 22 - 18
src/Layers/effectLayer.ts

@@ -653,18 +653,21 @@ export abstract class EffectLayer {
         }
 
         var material = subMesh.getMaterial();
-        var mesh = subMesh.getRenderingMesh();
+        var ownerMesh = subMesh.getMesh();  
+        var replacementMesh = ownerMesh._internalAbstractMeshDataInfo._actAsRegularMesh ? ownerMesh: null;
+        var renderingMesh = subMesh.getRenderingMesh();        
+        var effectiveMesh = replacementMesh ? replacementMesh : renderingMesh;
         var scene = this._scene;
         var engine = scene.getEngine();
 
-        mesh._internalAbstractMeshDataInfo._isActiveIntermediate = false;
+        effectiveMesh._internalAbstractMeshDataInfo._isActiveIntermediate = false;
 
         if (!material) {
             return;
         }
 
         // Do not block in blend mode.
-        if (!this._canRenderMesh(mesh, material)) {
+        if (!this._canRenderMesh(renderingMesh, material)) {
             return;
         }
 
@@ -672,28 +675,28 @@ export abstract class EffectLayer {
         engine.setState(material.backFaceCulling);
 
         // Managing instances
-        var batch = mesh._getInstancesRenderList(subMesh._id);
+        var batch = renderingMesh._getInstancesRenderList(subMesh._id, !!replacementMesh);
         if (batch.mustReturn) {
             return;
         }
 
         // Early Exit per mesh
-        if (!this._shouldRenderMesh(mesh)) {
+        if (!this._shouldRenderMesh(renderingMesh)) {
             return;
         }
 
         var hardwareInstancedRendering = batch.hardwareInstancedRendering[subMesh._id];
 
-        this._setEmissiveTextureAndColor(mesh, subMesh, material);
+        this._setEmissiveTextureAndColor(renderingMesh, subMesh, material);
 
-        this.onBeforeRenderMeshToEffect.notifyObservers(mesh);
+        this.onBeforeRenderMeshToEffect.notifyObservers(ownerMesh);
 
-        if (this._useMeshMaterial(mesh)) {
-            mesh.render(subMesh, hardwareInstancedRendering);
+        if (this._useMeshMaterial(renderingMesh)) {
+            renderingMesh.render(subMesh, hardwareInstancedRendering, replacementMesh || undefined);
         }
         else if (this._isReady(subMesh, hardwareInstancedRendering, this._emissiveTextureAndColor.texture)) {
             engine.enableEffect(this._effectLayerMapGenerationEffect);
-            mesh._bind(subMesh, this._effectLayerMapGenerationEffect, Material.TriangleFillMode);
+            renderingMesh._bind(subMesh, this._effectLayerMapGenerationEffect, Material.TriangleFillMode);
 
             this._effectLayerMapGenerationEffect.setMatrix("viewProjection", scene.getTransformMatrix());
 
@@ -735,11 +738,11 @@ export abstract class EffectLayer {
             }
 
             // Bones
-            if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
-                const skeleton = mesh.skeleton;
+            if (renderingMesh.useBones && renderingMesh.computeBonesUsingShaders && renderingMesh.skeleton) {
+                const skeleton = renderingMesh.skeleton;
 
                 if (skeleton.isUsingTextureForMatrices) {
-                    const boneTexture = skeleton.getTransformMatrixTexture(mesh);
+                    const boneTexture = skeleton.getTransformMatrixTexture(renderingMesh);
                     if (!boneTexture) {
                         return;
                     }
@@ -747,12 +750,12 @@ export abstract class EffectLayer {
                     this._effectLayerMapGenerationEffect.setTexture("boneSampler", boneTexture);
                     this._effectLayerMapGenerationEffect.setFloat("boneTextureWidth", 4.0 * (skeleton.bones.length + 1));
                 } else {
-                    this._effectLayerMapGenerationEffect.setMatrices("mBones", skeleton.getTransformMatrices((mesh)));
+                    this._effectLayerMapGenerationEffect.setMatrices("mBones", skeleton.getTransformMatrices((renderingMesh)));
                 }
             }
 
             // Morph targets
-            MaterialHelper.BindMorphTargetParameters(mesh, this._effectLayerMapGenerationEffect);
+            MaterialHelper.BindMorphTargetParameters(renderingMesh, this._effectLayerMapGenerationEffect);
 
             // Alpha mode
             if (enableAlphaMode) {
@@ -760,14 +763,15 @@ export abstract class EffectLayer {
             }
 
             // Draw
-            mesh._processRendering(subMesh, this._effectLayerMapGenerationEffect, material.fillMode, batch, hardwareInstancedRendering,
-                (isInstance, world) => this._effectLayerMapGenerationEffect.setMatrix("world", world));
+            var world = effectiveMesh.getWorldMatrix();
+            renderingMesh._processRendering(subMesh, this._effectLayerMapGenerationEffect, material.fillMode, batch, hardwareInstancedRendering,
+                (isInstance, w) => this._effectLayerMapGenerationEffect.setMatrix("world", world));
         } else {
             // Need to reset refresh rate of the main map
             this._mainTexture.resetRefreshCounter();
         }
 
-        this.onAfterRenderMeshToEffect.notifyObservers(mesh);
+        this.onAfterRenderMeshToEffect.notifyObservers(ownerMesh);
     }
 
     /**

+ 18 - 13
src/Lights/Shadows/shadowGenerator.ts

@@ -1001,12 +1001,15 @@ export class ShadowGenerator implements IShadowGenerator {
     }
 
     protected _renderSubMeshForShadowMap(subMesh: SubMesh): void {
-        var mesh = subMesh.getRenderingMesh();
+        var ownerMesh = subMesh.getMesh();  
+        var replacementMesh = ownerMesh._internalAbstractMeshDataInfo._actAsRegularMesh ? ownerMesh: null;
+        var renderingMesh = subMesh.getRenderingMesh();        
+        var effectiveMesh = replacementMesh ? replacementMesh : renderingMesh;
         var scene = this._scene;
         var engine = scene.getEngine();
         let material = subMesh.getMaterial();
 
-        mesh._internalAbstractMeshDataInfo._isActiveIntermediate = false;
+        effectiveMesh._internalAbstractMeshDataInfo._isActiveIntermediate = false;
 
         if (!material || subMesh.verticesCount === 0) {
             return;
@@ -1016,7 +1019,7 @@ export class ShadowGenerator implements IShadowGenerator {
         engine.setState(material.backFaceCulling);
 
         // Managing instances
-        var batch = mesh._getInstancesRenderList(subMesh._id);
+        var batch = renderingMesh._getInstancesRenderList(subMesh._id, !!replacementMesh);
         if (batch.mustReturn) {
             return;
         }
@@ -1024,7 +1027,7 @@ export class ShadowGenerator implements IShadowGenerator {
         var hardwareInstancedRendering = (engine.getCaps().instancedArrays) && (batch.visibleInstances[subMesh._id] !== null) && (batch.visibleInstances[subMesh._id] !== undefined);
         if (this.isReady(subMesh, hardwareInstancedRendering)) {
             engine.enableEffect(this._effect);
-            mesh._bind(subMesh, this._effect, material.fillMode);
+            renderingMesh._bind(subMesh, this._effect, material.fillMode);
 
             this._effect.setFloat3("biasAndScale", this.bias, this.normalBias, this.depthScale);
 
@@ -1050,11 +1053,11 @@ export class ShadowGenerator implements IShadowGenerator {
             }
 
             // Bones
-            if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
-                const skeleton = mesh.skeleton;
+            if (renderingMesh.useBones && renderingMesh.computeBonesUsingShaders && renderingMesh.skeleton) {
+                const skeleton = renderingMesh.skeleton;
 
                 if (skeleton.isUsingTextureForMatrices) {
-                    const boneTexture = skeleton.getTransformMatrixTexture(mesh);
+                    const boneTexture = skeleton.getTransformMatrixTexture(renderingMesh);
 
                     if (!boneTexture) {
                         return;
@@ -1063,12 +1066,12 @@ export class ShadowGenerator implements IShadowGenerator {
                     this._effect.setTexture("boneSampler", boneTexture);
                     this._effect.setFloat("boneTextureWidth", 4.0 * (skeleton.bones.length + 1));
                 } else {
-                    this._effect.setMatrices("mBones", skeleton.getTransformMatrices((mesh)));
+                    this._effect.setMatrices("mBones", skeleton.getTransformMatrices((renderingMesh)));
                 }
             }
 
             // Morph targets
-            MaterialHelper.BindMorphTargetParameters(mesh, this._effect);
+            MaterialHelper.BindMorphTargetParameters(renderingMesh, this._effect);
 
             // Clip planes
             MaterialHelper.BindClipPlane(this._effect, scene);
@@ -1080,12 +1083,14 @@ export class ShadowGenerator implements IShadowGenerator {
             }
 
             // Observables
-            this.onBeforeShadowMapRenderMeshObservable.notifyObservers(mesh);
+            this.onBeforeShadowMapRenderMeshObservable.notifyObservers(renderingMesh);
             this.onBeforeShadowMapRenderObservable.notifyObservers(this._effect);
 
             // Draw
-            mesh._processRendering(subMesh, this._effect, material.fillMode, batch, hardwareInstancedRendering,
-                (isInstance, world) => this._effect.setMatrix("world", world));
+            
+            var world = effectiveMesh.getWorldMatrix();
+            renderingMesh._processRendering(subMesh, this._effect, material.fillMode, batch, hardwareInstancedRendering,
+                (isInstance, w) => this._effect.setMatrix("world", world));
 
             if (this.forceBackFacesOnly) {
                 engine.setState(true, 0, false, false);
@@ -1093,7 +1098,7 @@ export class ShadowGenerator implements IShadowGenerator {
 
             // Observables
             this.onAfterShadowMapRenderObservable.notifyObservers(this._effect);
-            this.onAfterShadowMapRenderMeshObservable.notifyObservers(mesh);
+            this.onAfterShadowMapRenderMeshObservable.notifyObservers(renderingMesh);
 
         } else {
             // Need to reset refresh rate of the shadowMap

+ 3 - 1
src/Materials/Textures/renderTargetTexture.ts

@@ -764,7 +764,9 @@ export class RenderTargetTexture extends Texture {
                         if (!mesh.isAnInstance) {
                             mesh._internalAbstractMeshDataInfo._onlyForInstancesIntermediate = false;
                         } else {
-                            mesh = (mesh as InstancedMesh).sourceMesh;
+                            if (!mesh._internalAbstractMeshDataInfo._actAsRegularMesh) {
+                                mesh = (mesh as InstancedMesh).sourceMesh;
+                            }
                         }
                         mesh._internalAbstractMeshDataInfo._isActiveIntermediate = true;
 

+ 18 - 14
src/PostProcesses/volumetricLightScatteringPostProcess.ts

@@ -291,12 +291,15 @@ export class VolumetricLightScatteringPostProcess extends PostProcess {
 
         // Custom render function for submeshes
         var renderSubMesh = (subMesh: SubMesh): void => {
-            var mesh = subMesh.getRenderingMesh();
-            if (this._meshExcluded(mesh)) {
+            var ownerMesh = subMesh.getMesh();  
+            var replacementMesh = ownerMesh._internalAbstractMeshDataInfo._actAsRegularMesh ? ownerMesh: null;
+            var renderingMesh = subMesh.getRenderingMesh();        
+            var effectiveMesh = replacementMesh ? replacementMesh : renderingMesh;
+            if (this._meshExcluded(renderingMesh)) {
                 return;
             }
 
-            mesh._internalAbstractMeshDataInfo._isActiveIntermediate = false;
+            effectiveMesh._internalAbstractMeshDataInfo._isActiveIntermediate = false;
 
             let material = subMesh.getMaterial();
 
@@ -304,14 +307,14 @@ export class VolumetricLightScatteringPostProcess extends PostProcess {
                 return;
             }
 
-            var scene = mesh.getScene();
+            var scene = renderingMesh.getScene();
             var engine = scene.getEngine();
 
             // Culling
             engine.setState(material.backFaceCulling);
 
             // Managing instances
-            var batch = mesh._getInstancesRenderList(subMesh._id);
+            var batch = renderingMesh._getInstancesRenderList(subMesh._id, !!replacementMesh);
 
             if (batch.mustReturn) {
                 return;
@@ -321,7 +324,7 @@ export class VolumetricLightScatteringPostProcess extends PostProcess {
 
             if (this._isReady(subMesh, hardwareInstancedRendering)) {
                 var effect: Effect = this._volumetricLightScatteringPass;
-                if (mesh === this.mesh) {
+                if (renderingMesh === this.mesh) {
                     if (subMesh.effect) {
                         effect = subMesh.effect;
                     } else {
@@ -330,10 +333,10 @@ export class VolumetricLightScatteringPostProcess extends PostProcess {
                 }
 
                 engine.enableEffect(effect);
-                mesh._bind(subMesh, effect, material.fillMode);
+                renderingMesh._bind(subMesh, effect, material.fillMode);
 
-                if (mesh === this.mesh) {
-                    material.bind(mesh.getWorldMatrix(), mesh);
+                if (renderingMesh === this.mesh) {
+                    material.bind(effectiveMesh.getWorldMatrix(), renderingMesh);
                 }
                 else {
                     this._volumetricLightScatteringPass.setMatrix("viewProjection", scene.getTransformMatrix());
@@ -350,14 +353,15 @@ export class VolumetricLightScatteringPostProcess extends PostProcess {
                     }
 
                     // Bones
-                    if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
-                        this._volumetricLightScatteringPass.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
+                    if (renderingMesh.useBones && renderingMesh.computeBonesUsingShaders && renderingMesh.skeleton) {
+                        this._volumetricLightScatteringPass.setMatrices("mBones", renderingMesh.skeleton.getTransformMatrices(renderingMesh));
                     }
                 }
 
-                // Draw
-                mesh._processRendering(subMesh, this._volumetricLightScatteringPass, Material.TriangleFillMode, batch, hardwareInstancedRendering,
-                    (isInstance, world) => effect.setMatrix("world", world));
+                // Draw                
+                var world = effectiveMesh.getWorldMatrix();
+                renderingMesh._processRendering(subMesh, this._volumetricLightScatteringPass, Material.TriangleFillMode, batch, hardwareInstancedRendering,
+                    (isInstance, w) => effect.setMatrix("world", world));
             }
         };
 

+ 14 - 10
src/Rendering/depthRenderer.ts

@@ -94,12 +94,15 @@ export class DepthRenderer {
 
         // Custom render function
         var renderSubMesh = (subMesh: SubMesh): void => {
-            var mesh = subMesh.getRenderingMesh();
+            var ownerMesh = subMesh.getMesh();  
+            var replacementMesh = ownerMesh._internalAbstractMeshDataInfo._actAsRegularMesh ? ownerMesh: null;
+            var renderingMesh = subMesh.getRenderingMesh();        
+            var effectiveMesh = replacementMesh ? replacementMesh : renderingMesh;
             var scene = this._scene;
             var engine = scene.getEngine();
             let material = subMesh.getMaterial();
 
-            mesh._internalAbstractMeshDataInfo._isActiveIntermediate = false;
+            effectiveMesh._internalAbstractMeshDataInfo._isActiveIntermediate = false;
 
             if (!material) {
                 return;
@@ -109,7 +112,7 @@ export class DepthRenderer {
             engine.setState(material.backFaceCulling, 0, false, scene.useRightHandedSystem);
 
             // Managing instances
-            var batch = mesh._getInstancesRenderList(subMesh._id);
+            var batch = renderingMesh._getInstancesRenderList(subMesh._id, !!replacementMesh);
 
             if (batch.mustReturn) {
                 return;
@@ -120,7 +123,7 @@ export class DepthRenderer {
             var camera = this._camera || scene.activeCamera;
             if (this.isReady(subMesh, hardwareInstancedRendering) && camera) {
                 engine.enableEffect(this._effect);
-                mesh._bind(subMesh, this._effect, material.fillMode);
+                renderingMesh._bind(subMesh, this._effect, material.fillMode);
 
                 this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
 
@@ -137,16 +140,17 @@ export class DepthRenderer {
                 }
 
                 // Bones
-                if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
-                    this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
+                if (renderingMesh.useBones && renderingMesh.computeBonesUsingShaders && renderingMesh.skeleton) {
+                    this._effect.setMatrices("mBones", renderingMesh.skeleton.getTransformMatrices(renderingMesh));
                 }
 
                 // Morph targets
-                MaterialHelper.BindMorphTargetParameters(mesh, this._effect);
+                MaterialHelper.BindMorphTargetParameters(renderingMesh, this._effect);
 
-                // Draw
-                mesh._processRendering(subMesh, this._effect, material.fillMode, batch, hardwareInstancedRendering,
-                    (isInstance, world) => this._effect.setMatrix("world", world));
+                // Draw                
+                var world = effectiveMesh.getWorldMatrix();
+                renderingMesh._processRendering(subMesh, this._effect, material.fillMode, batch, hardwareInstancedRendering,
+                    (isInstance, w) => this._effect.setMatrix("world", world));
             }
         };
 

+ 26 - 22
src/Rendering/geometryBufferRenderer.ts

@@ -390,7 +390,10 @@ export class GeometryBufferRenderer {
 
         // Custom render function
         var renderSubMesh = (subMesh: SubMesh): void => {
-            var mesh = subMesh.getRenderingMesh();
+            var ownerMesh = subMesh.getMesh();  
+            var replacementMesh = ownerMesh._internalAbstractMeshDataInfo._actAsRegularMesh ? ownerMesh: null;
+            var renderingMesh = subMesh.getRenderingMesh();        
+            var effectiveMesh = replacementMesh ? replacementMesh : renderingMesh;
             var scene = this._scene;
             var engine = scene.getEngine();
             let material = <any> subMesh.getMaterial();
@@ -399,18 +402,18 @@ export class GeometryBufferRenderer {
                 return;
             }
 
-            mesh._internalAbstractMeshDataInfo._isActiveIntermediate = false;
+            effectiveMesh._internalAbstractMeshDataInfo._isActiveIntermediate = false;
 
             // Velocity
-            if (this._enableVelocity && !this._previousTransformationMatrices[mesh.uniqueId]) {
-                this._previousTransformationMatrices[mesh.uniqueId] = {
+            if (this._enableVelocity && !this._previousTransformationMatrices[effectiveMesh.uniqueId]) {
+                this._previousTransformationMatrices[effectiveMesh.uniqueId] = {
                     world: Matrix.Identity(),
                     viewProjection: scene.getTransformMatrix()
                 };
 
-                if (mesh.skeleton) {
-                    const bonesTransformations = mesh.skeleton.getTransformMatrices(mesh);
-                    this._previousBonesTransformationMatrices[mesh.uniqueId] = this._copyBonesTransformationMatrices(bonesTransformations, new Float32Array(bonesTransformations.length));
+                if (renderingMesh.skeleton) {
+                    const bonesTransformations = renderingMesh.skeleton.getTransformMatrices(renderingMesh);
+                    this._previousBonesTransformationMatrices[renderingMesh.uniqueId] = this._copyBonesTransformationMatrices(bonesTransformations, new Float32Array(bonesTransformations.length));
                 }
             }
 
@@ -418,17 +421,18 @@ export class GeometryBufferRenderer {
             engine.setState(material.backFaceCulling, 0, false, scene.useRightHandedSystem);
 
             // Managing instances
-            var batch = mesh._getInstancesRenderList(subMesh._id);
+            var batch = renderingMesh._getInstancesRenderList(subMesh._id, !!replacementMesh);
 
             if (batch.mustReturn) {
                 return;
             }
 
             var hardwareInstancedRendering = (engine.getCaps().instancedArrays) && (batch.visibleInstances[subMesh._id] !== null);
-
+            var world = effectiveMesh.getWorldMatrix();
+            
             if (this.isReady(subMesh, hardwareInstancedRendering)) {
                 engine.enableEffect(this._effect);
-                mesh._bind(subMesh, this._effect, material.fillMode);
+                renderingMesh._bind(subMesh, this._effect, material.fillMode);
 
                 this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
                 this._effect.setMatrix("view", scene.getViewMatrix());
@@ -464,33 +468,33 @@ export class GeometryBufferRenderer {
                 }
 
                 // Bones
-                if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
-                    this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
+                if (renderingMesh.useBones && renderingMesh.computeBonesUsingShaders && renderingMesh.skeleton) {
+                    this._effect.setMatrices("mBones", renderingMesh.skeleton.getTransformMatrices(renderingMesh));
                     if (this._enableVelocity) {
-                        this._effect.setMatrices("mPreviousBones", this._previousBonesTransformationMatrices[mesh.uniqueId]);
+                        this._effect.setMatrices("mPreviousBones", this._previousBonesTransformationMatrices[renderingMesh.uniqueId]);
                     }
                 }
 
                 // Morph targets
-                MaterialHelper.BindMorphTargetParameters(mesh, this._effect);
+                MaterialHelper.BindMorphTargetParameters(renderingMesh, this._effect);
 
                 // Velocity
                 if (this._enableVelocity) {
-                    this._effect.setMatrix("previousWorld", this._previousTransformationMatrices[mesh.uniqueId].world);
-                    this._effect.setMatrix("previousViewProjection", this._previousTransformationMatrices[mesh.uniqueId].viewProjection);
+                    this._effect.setMatrix("previousWorld", this._previousTransformationMatrices[effectiveMesh.uniqueId].world);
+                    this._effect.setMatrix("previousViewProjection", this._previousTransformationMatrices[effectiveMesh.uniqueId].viewProjection);
                 }
 
                 // Draw
-                mesh._processRendering(subMesh, this._effect, material.fillMode, batch, hardwareInstancedRendering,
-                    (isInstance, world) => this._effect.setMatrix("world", world));
+                renderingMesh._processRendering(subMesh, this._effect, material.fillMode, batch, hardwareInstancedRendering,
+                    (isInstance, w) => this._effect.setMatrix("world", world));
             }
 
             // Velocity
             if (this._enableVelocity) {
-                this._previousTransformationMatrices[mesh.uniqueId].world = mesh.getWorldMatrix().clone();
-                this._previousTransformationMatrices[mesh.uniqueId].viewProjection = this._scene.getTransformMatrix().clone();
-                if (mesh.skeleton) {
-                    this._copyBonesTransformationMatrices(mesh.skeleton.getTransformMatrices(mesh), this._previousBonesTransformationMatrices[mesh.uniqueId]);
+                this._previousTransformationMatrices[effectiveMesh.uniqueId].world = world.clone();
+                this._previousTransformationMatrices[effectiveMesh.uniqueId].viewProjection = this._scene.getTransformMatrix().clone();
+                if (renderingMesh.skeleton) {
+                    this._copyBonesTransformationMatrices(renderingMesh.skeleton.getTransformMatrices(renderingMesh), this._previousBonesTransformationMatrices[effectiveMesh.uniqueId]);
                 }
             }
         };

+ 13 - 10
src/Rendering/outlineRenderer.ts

@@ -163,7 +163,10 @@ export class OutlineRenderer implements ISceneComponent {
             return;
         }
 
-        var mesh = subMesh.getRenderingMesh();
+        var ownerMesh = subMesh.getMesh();  
+        var replacementMesh = ownerMesh._internalAbstractMeshDataInfo._actAsRegularMesh ? ownerMesh: null;
+        var renderingMesh = subMesh.getRenderingMesh();        
+        var effectiveMesh = replacementMesh ? replacementMesh : renderingMesh;
         var material = subMesh.getMaterial();
 
         if (!material || !scene.activeCamera) {
@@ -177,19 +180,19 @@ export class OutlineRenderer implements ISceneComponent {
             this._effect.setFloat("logarithmicDepthConstant", 2.0 / (Math.log(scene.activeCamera.maxZ + 1.0) / Math.LN2));
         }
 
-        this._effect.setFloat("offset", useOverlay ? 0 : mesh.outlineWidth);
-        this._effect.setColor4("color", useOverlay ? mesh.overlayColor : mesh.outlineColor, useOverlay ? mesh.overlayAlpha : material.alpha);
+        this._effect.setFloat("offset", useOverlay ? 0 : renderingMesh.outlineWidth);
+        this._effect.setColor4("color", useOverlay ? renderingMesh.overlayColor : renderingMesh.outlineColor, useOverlay ? renderingMesh.overlayAlpha : material.alpha);
         this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
 
         // Bones
-        if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
-            this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
+        if (renderingMesh.useBones && renderingMesh.computeBonesUsingShaders && renderingMesh.skeleton) {
+            this._effect.setMatrices("mBones", renderingMesh.skeleton.getTransformMatrices(renderingMesh));
         }
 
         // Morph targets
-        MaterialHelper.BindMorphTargetParameters(mesh, this._effect);
+        MaterialHelper.BindMorphTargetParameters(renderingMesh, this._effect);
 
-        mesh._bind(subMesh, this._effect, material.fillMode);
+        renderingMesh._bind(subMesh, this._effect, material.fillMode);
 
         // Alpha test
         if (material && material.needAlphaTesting()) {
@@ -201,9 +204,9 @@ export class OutlineRenderer implements ISceneComponent {
         }
 
         engine.setZOffset(-this.zOffset);
-
-        mesh._processRendering(subMesh, this._effect, material.fillMode, batch, hardwareInstancedRendering,
-            (isInstance, world) => { this._effect.setMatrix("world", world); });
+        var world = effectiveMesh.getWorldMatrix();
+        renderingMesh._processRendering(subMesh, this._effect, material.fillMode, batch, hardwareInstancedRendering,
+            (isInstance, w) => { this._effect.setMatrix("world", world); });
 
         engine.setZOffset(0);
     }