|
@@ -78,6 +78,8 @@ var BABYLON;
|
|
defines.push("#define ALPHATEST");
|
|
defines.push("#define ALPHATEST");
|
|
if (material.opacityTexture !== undefined) {
|
|
if (material.opacityTexture !== undefined) {
|
|
defines.push("#define OPACITY");
|
|
defines.push("#define OPACITY");
|
|
|
|
+ if (material.opacityTexture.getAlphaFromRGB)
|
|
|
|
+ defines.push("#define OPACITYRGB");
|
|
if (!needUV)
|
|
if (!needUV)
|
|
defines.push("#define NEED_UV");
|
|
defines.push("#define NEED_UV");
|
|
}
|
|
}
|
|
@@ -109,7 +111,7 @@ var BABYLON;
|
|
var join = defines.join("\n");
|
|
var join = defines.join("\n");
|
|
if (this._cachedDefines !== join) {
|
|
if (this._cachedDefines !== join) {
|
|
this._cachedDefines = join;
|
|
this._cachedDefines = join;
|
|
- this._volumetricLightScatteringPass = mesh.getScene().getEngine().createEffect({ vertexElement: "depth", fragmentElement: "volumetricLightScatteringPass" }, attribs, ["world", "mBones", "viewProjection", "diffuseMatrix"], ["diffuseSampler", "opacitySampler"], join);
|
|
|
|
|
|
+ this._volumetricLightScatteringPass = mesh.getScene().getEngine().createEffect({ vertexElement: "depth", fragmentElement: "volumetricLightScatteringPass" }, attribs, ["world", "mBones", "viewProjection", "diffuseMatrix", "opacityLevel"], ["diffuseSampler", "opacitySampler"], join);
|
|
}
|
|
}
|
|
return this._volumetricLightScatteringPass.isReady();
|
|
return this._volumetricLightScatteringPass.isReady();
|
|
};
|
|
};
|
|
@@ -189,8 +191,10 @@ var BABYLON;
|
|
if (alphaTexture) {
|
|
if (alphaTexture) {
|
|
_this._volumetricLightScatteringPass.setMatrix("diffuseMatrix", alphaTexture.getTextureMatrix());
|
|
_this._volumetricLightScatteringPass.setMatrix("diffuseMatrix", alphaTexture.getTextureMatrix());
|
|
}
|
|
}
|
|
- if (material.opacityTexture !== undefined)
|
|
|
|
|
|
+ if (material.opacityTexture !== undefined) {
|
|
_this._volumetricLightScatteringPass.setTexture("opacitySampler", material.opacityTexture);
|
|
_this._volumetricLightScatteringPass.setTexture("opacitySampler", material.opacityTexture);
|
|
|
|
+ _this._volumetricLightScatteringPass.setFloat("opacityLevel", material.opacityTexture.level);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
// Bones
|
|
// Bones
|
|
if (mesh.useBones) {
|
|
if (mesh.useBones) {
|
|
@@ -202,7 +206,7 @@ var BABYLON;
|
|
};
|
|
};
|
|
// Render target texture callbacks
|
|
// Render target texture callbacks
|
|
var savedSceneClearColor;
|
|
var savedSceneClearColor;
|
|
- var sceneClearColor = new BABYLON.Color3(0.0, 0.0, 0.0);
|
|
|
|
|
|
+ var sceneClearColor = new BABYLON.Color4(0.0, 0.0, 0.0, 1.0);
|
|
this._volumetricLightScatteringRTT.onBeforeRender = function () {
|
|
this._volumetricLightScatteringRTT.onBeforeRender = function () {
|
|
savedSceneClearColor = scene.clearColor;
|
|
savedSceneClearColor = scene.clearColor;
|
|
scene.clearColor = sceneClearColor;
|
|
scene.clearColor = sceneClearColor;
|
|
@@ -211,15 +215,46 @@ var BABYLON;
|
|
scene.clearColor = savedSceneClearColor;
|
|
scene.clearColor = savedSceneClearColor;
|
|
};
|
|
};
|
|
this._volumetricLightScatteringRTT.customRenderFunction = function (opaqueSubMeshes, alphaTestSubMeshes, transparentSubMeshes) {
|
|
this._volumetricLightScatteringRTT.customRenderFunction = function (opaqueSubMeshes, alphaTestSubMeshes, transparentSubMeshes) {
|
|
|
|
+ var engine = scene.getEngine();
|
|
var index;
|
|
var index;
|
|
for (index = 0; index < opaqueSubMeshes.length; index++) {
|
|
for (index = 0; index < opaqueSubMeshes.length; index++) {
|
|
renderSubMesh(opaqueSubMeshes.data[index]);
|
|
renderSubMesh(opaqueSubMeshes.data[index]);
|
|
}
|
|
}
|
|
|
|
+ engine.setAlphaTesting(true);
|
|
for (index = 0; index < alphaTestSubMeshes.length; index++) {
|
|
for (index = 0; index < alphaTestSubMeshes.length; index++) {
|
|
renderSubMesh(alphaTestSubMeshes.data[index]);
|
|
renderSubMesh(alphaTestSubMeshes.data[index]);
|
|
}
|
|
}
|
|
- for (index = 0; index < transparentSubMeshes.length; index++) {
|
|
|
|
- renderSubMesh(transparentSubMeshes.data[index]);
|
|
|
|
|
|
+ engine.setAlphaTesting(false);
|
|
|
|
+ if (transparentSubMeshes.length) {
|
|
|
|
+ for (index = 0; index < transparentSubMeshes.length; index++) {
|
|
|
|
+ var submesh = transparentSubMeshes.data[index];
|
|
|
|
+ submesh._alphaIndex = submesh.getMesh().alphaIndex;
|
|
|
|
+ submesh._distanceToCamera = submesh.getBoundingInfo().boundingSphere.centerWorld.subtract(scene.activeCamera.position).length();
|
|
|
|
+ }
|
|
|
|
+ var sortedArray = transparentSubMeshes.data.slice(0, transparentSubMeshes.length);
|
|
|
|
+ sortedArray.sort(function (a, b) {
|
|
|
|
+ // Alpha index first
|
|
|
|
+ if (a._alphaIndex > b._alphaIndex) {
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+ if (a._alphaIndex < b._alphaIndex) {
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ // Then distance to camera
|
|
|
|
+ if (a._distanceToCamera < b._distanceToCamera) {
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+ if (a._distanceToCamera > b._distanceToCamera) {
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+ });
|
|
|
|
+ // Render sub meshes
|
|
|
|
+ engine.setAlphaMode(BABYLON.Engine.ALPHA_COMBINE);
|
|
|
|
+ for (index = 0; index < sortedArray.length; index++) {
|
|
|
|
+ renderSubMesh(sortedArray[index]);
|
|
|
|
+ }
|
|
|
|
+ engine.setAlphaMode(BABYLON.Engine.ALPHA_DISABLE);
|
|
}
|
|
}
|
|
};
|
|
};
|
|
};
|
|
};
|