Skip to content

Commit

Permalink
Fix CCW/CW conflict with instances
Browse files Browse the repository at this point in the history
  • Loading branch information
deltakosh committed Mar 2, 2020
1 parent fa8c078 commit 8051103
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 88 deletions.
40 changes: 22 additions & 18 deletions src/Layers/effectLayer.ts
Expand Up @@ -653,47 +653,50 @@ 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;
}

// Culling
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());

Expand Down Expand Up @@ -735,39 +738,40 @@ 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;
}

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) {
engine.setAlphaMode(material.alphaMode);
}

// 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);
}

/**
Expand Down
31 changes: 18 additions & 13 deletions src/Lights/Shadows/shadowGenerator.ts
Expand Up @@ -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;
Expand All @@ -1016,15 +1019,15 @@ 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;
}

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);

Expand All @@ -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;
Expand All @@ -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);
Expand All @@ -1080,20 +1083,22 @@ 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);
}

// Observables
this.onAfterShadowMapRenderObservable.notifyObservers(this._effect);
this.onAfterShadowMapRenderMeshObservable.notifyObservers(mesh);
this.onAfterShadowMapRenderMeshObservable.notifyObservers(renderingMesh);

} else {
// Need to reset refresh rate of the shadowMap
Expand Down
4 changes: 3 additions & 1 deletion src/Materials/Textures/renderTargetTexture.ts
Expand Up @@ -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;

Expand Down
32 changes: 18 additions & 14 deletions src/PostProcesses/volumetricLightScatteringPostProcess.ts
Expand Up @@ -291,27 +291,30 @@ 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();

if (!material) {
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;
Expand All @@ -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 {
Expand All @@ -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());
Expand All @@ -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));
}
};

Expand Down
24 changes: 14 additions & 10 deletions src/Rendering/depthRenderer.ts
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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());

Expand All @@ -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));
}
};

Expand Down

0 comments on commit 8051103

Please sign in to comment.