diff --git a/js/mlj/core/Core.js b/js/mlj/core/Core.js
index f4295258..41b98a4e 100644
--- a/js/mlj/core/Core.js
+++ b/js/mlj/core/Core.js
@@ -1,39 +1,39 @@
/**
* MLJLib
* MeshLabJS Library
- *
+ *
* Copyright(C) 2015
- * Paolo Cignoni
+ * Paolo Cignoni
* Visual Computing Lab
* ISTI - CNR
- *
+ *
* All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
* version.
*
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See theGNU General Public License
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See theGNU General Public License
* (http://www.gnu.org/licenses/gpl.txt) for more details.
- *
+ *
*/
/**
- * @file Defines Emscripten Module object, MLJ.core namspace and the basic
+ * @file Defines Emscripten Module object, MLJ.core namspace and the basic
* classes used to create a Scene
* @author Stefano Gabriele
*/
/**
* @global
- * @description Module is a global JavaScript object with attributes that
+ * @description Module is a global JavaScript object with attributes that
* Emscripten-generated code calls at various points in its execution.
- * Developers can provide an implementation of Module to control
- * the execution of code. For example, to define how notification
- * messages from Emscripten are displayed, developers implement the
+ * Developers can provide an implementation of Module to control
+ * the execution of code. For example, to define how notification
+ * messages from Emscripten are displayed, developers implement the
* Module.print attribute.
* Note that parameter 'memoryInitializerPrefixURL' indicates path of file.js.mem
*/
@@ -54,45 +54,45 @@ var Module = {
MLJ.core = {
defaults: {},
- setDefaults: function(name, parameters) {
- if(MLJ.core.defaults[name] !== undefined) {
+ setDefaults: function(name, parameters) {
+ if(MLJ.core.defaults[name] !== undefined) {
console.warn("The default properties of "+name+" was overridden.");
- }
- MLJ.core.defaults[name] = parameters;
+ }
+ MLJ.core.defaults[name] = parameters;
},
- getDefaults: function(name) {
+ getDefaults: function(name) {
return MLJ.core.defaults[name];
}
};
-/**
+/**
* @class Creates a new Ambient light
* @param {THREE.Scene} scene The scene object
* @param {THREE.Camera} camera The camera object
* @param {THREE.WebGLRenderer} renderer The renderer object
* @memberOf MLJ.core
- * @author Stefano Gabriele
+ * @author Stefano Gabriele
*/
MLJ.core.AmbientLight = function (scene, camera, renderer) {
var _on = true;
//var _light = new THREE.AmbientLight("#ffffff");
var _light = new THREE.AmbientLight("#808080");
-
+
/**
* Returns true
if this ambient light is on
- * @returns {Boolean} true
if this ambient light is on,
+ * @returns {Boolean} true
if this ambient light is on,
* false
otherwise
- * @author Stefano Gabriele
+ * @author Stefano Gabriele
*/
this.isOn = function () {
return _on;
};
-
+
/**
* Sets this ambient light on/off
- * @param {Boolean} on If true
, this ambient light is enabled;
+ * @param {Boolean} on If true
, this ambient light is enabled;
* otherwise this ambient light is disabled
* @author Stefano Gabriele
*/
@@ -113,23 +113,22 @@ MLJ.core.AmbientLight = function (scene, camera, renderer) {
};
-/**
+/**
* @class Creates a new Headlight
* @param {THREE.Scene} scene The scene object
* @param {THREE.Camera} camera The camera object
* @param {THREE.WebGLRenderer} renderer The renderer object
* @memberOf MLJ.core
- * @author Stefano Gabriele
+ * @author Stefano Gabriele
*/
MLJ.core.Headlight = function (scene, camera, renderer) {
var _on = true;
- var _light = new THREE.DirectionalLight("#ffffff",0.5);
+ var _light = new THREE.DirectionalLight("#FFFF",0.5);
_light.position.set( 0, -1, 0 );
-
/**
* Sets this headlight on/off
- * @param {Boolean} on If true
, this headlight is enabled;
+ * @param {Boolean} on If true
, this headlight is enabled;
* otherwise this headlight is disabled
* @author Stefano Gabriele
*/
@@ -145,4 +144,8 @@ MLJ.core.Headlight = function (scene, camera, renderer) {
//Init
this.setOn(_on);
+ this.getPosition = () => {
+ return _light.position;
+ }
+
};
diff --git a/js/mlj/core/Scene.js b/js/mlj/core/Scene.js
index ae27155f..795ed3a3 100644
--- a/js/mlj/core/Scene.js
+++ b/js/mlj/core/Scene.js
@@ -747,6 +747,19 @@ MLJ.core.Scene = {};
* before displaying the result.
* @memberOf MLJ.core.Scene
*/
+ this._shadowMapping = false;
+ this.shadowMappingContext = null;
+
+ this.setupShadowMapping = function (context) {
+ this._shadowMapping = true;
+ this.shadowMappingContext = context;
+ }
+
+ this.disposeShadowMapping = function () {
+ context = null
+ this._shadowMapping = false;
+ }
+
this.render = function (fromReqAnimFrame) {
if (_stats.active && !fromReqAnimFrame) {
@@ -773,6 +786,9 @@ MLJ.core.Scene = {};
} else {
_renderer.render(_scene, _camera);
}
+ if (this._shadowMapping) {
+ this.shadowMappingContext.renderShadow();
+ }
// render the 2D overlays
_renderer.autoClear = false;
diff --git a/js/mlj/plugins/rendering/SM.js b/js/mlj/plugins/rendering/SM.js
index 0e0b6255..f88ae584 100644
--- a/js/mlj/plugins/rendering/SM.js
+++ b/js/mlj/plugins/rendering/SM.js
@@ -7,12 +7,11 @@
(function (plugin, core, scene) {
- let SIZE = { w : window.innerWidth, h : window.innerHeight};
-
+ let SIZE = {width: window.innerWidth, height: window.innerHeight};
+// SIZE = scene.get3DSize();
let shadowPassUniforms = {
- depthMap: { type: "t", value: null },
- positionMap: { type: "t", value: null },
- colorMap: { type: "t", value: null },
+ lightDepthMap: { type: "t", value: null },
+ eyeDepthMap: { type: "t", value: null },
lightViewProjection: { type: "m4", value: null},
};
@@ -45,19 +44,19 @@
in the render pass which draws the shadows
*/
// non posso specificare come solo depth?? su opengl mi pare si possa
- let depthMapTarget = new THREE.WebGLRenderTarget(SIZE.w, SIZE.h, {
+ let eyeDepthMapTarget = new THREE.WebGLRenderTarget(SIZE.width, SIZE.height, {
type: THREE.FloatType,
minFilter: THREE.NearestFilter,
magFilter: THREE.NearestFilter
});
- let positionMapTarget = new THREE.WebGLRenderTarget(SIZE.w, SIZE.h, {
+
+ let lightDepthMapTarget = new THREE.WebGLRenderTarget(SIZE.width, SIZE.height, {
type: THREE.FloatType,
minFilter: THREE.NearestFilter,
magFilter: THREE.NearestFilter
});
-
/*
material containing the depth pass shaders. The original scene will be
rendered using this shaders to produce a depth map
@@ -69,26 +68,19 @@
fragmentShader: plug.shaders.getByKey("SMFrag.glsl")
});
- let positionMaterial = new THREE.RawShaderMaterial({
- uniforms: {},
- side: THREE.DoubleSide,
- vertexShader: plug.shaders.getByKey("PositionVertex.glsl"),
- fragmentShader: plug.shaders.getByKey("PositionFragment.glsl")
- });
- /*
- quad che disegno per il passo di defferred rendering
- */
- let quad = new THREE.PlaneBufferGeometry(2,2, 1, 1);
- let shadowMapMesh = new THREE.Mesh(quad, new THREE.RawShaderMaterial({
+ let shadowMaterial = new THREE.RawShaderMaterial({
uniforms: shadowPassUniforms,
+ transparent: true,
+ opacity: 0.5,
+ blending: THREE["NormalBlending"],
side: THREE.DoubleSide,
vertexShader: plug.shaders.getByKey("ShadowVertex.glsl"),
fragmentShader: plug.shaders.getByKey("ShadowFrag.glsl")
- }));
+ })
+
+
- let shadowScene = new THREE.Scene();
- shadowScene.add(shadowMapMesh);
// poi costruiscilo usando bbox
let lightCamera = new THREE.OrthographicCamera(
@@ -98,54 +90,50 @@
-20,
1,
25);
+ lightCamera.position.set(0, 0, 8);
+ lightCamera.lookAt(new THREE.Vector3(0, 0, 0));
+ lightCamera.updateProjectionMatrix();
+ let projScreenMatrix = new THREE.Matrix4();
+
- lightCamera.position.set(8,0,0);
- lightCamera.lookAt(new THREE.Vector3(0,0,0));
/*
receives an input buffer in Scene.js and outputs an output buffer that will
be used as a texture for the last pass of the deferred rendering pipe.
*/
- this.pass = (inBuffer, outBuffer) => {
+ this.renderShadow = () => {
+ //TODO : light is on camera!!! (didn't notice it)..
+ // things should be easier then..
let sceneGraph = scene.getScene();
let sceneCam = scene.getCamera();
let renderer = scene.getRenderer();
- //TODO : light is on camera!!! (didn't notice it)..
- // things should be easier then..
-
- // forces the renderer to use the depth mapping shaders for the whole scene
- // lightCamera.position.set(sceneCam.position.x, sceneCam.position.y, sceneCam.position.z);
- // lightCamera.lookAt(sceneCam.getWorldDirection());
- // lightCamera.updateProjectionMatrix();
- //renderer.setClearColor(0xFFFFFF);
- let projScreenMatrix = new THREE.Matrix4();
- lightCamera.updateProjectionMatrix();
+ let dpr = renderer.getPixelRatio();
+ eyeDepthMapTarget.setSize(SIZE.width * dpr, SIZE.height * dpr);
+ lightDepthMapTarget.setSize(SIZE.width * dpr, SIZE.height * dpr);
+ // sceneGraph.overrideMaterial = new THREE.MeshDepthMaterial();
sceneGraph.overrideMaterial = depthMaterial;
- renderer.render(sceneGraph, lightCamera, depthMapTarget, true);
- //renderer.setClearColor(clearClr.getHex());
+ renderer.render(sceneGraph, sceneCam, eyeDepthMapTarget, true);
+ renderer.render(sceneGraph, lightCamera, lightDepthMapTarget, true);
- // render the position map
- sceneGraph.overrideMaterial = positionMaterial;
- renderer.render(sceneGraph, sceneCam, positionMapTarget, true);
- sceneGraph.overrideMaterial = null;
-
-
-
-
- projScreenMatrix.multiplyMatrices(lightCamera.projectionMatrix, lightCamera.matrixWorldInverse);
+ // renderer.render(sceneGraph,sceneCam);
+ projScreenMatrix.multiplyMatrices(lightCamera.projectionMatrix, lightCamera.matrixWorldInverse);
+ sceneGraph.overrideMaterial = shadowMaterial;
shadowPassUniforms.lightViewProjection.value = projScreenMatrix;
- shadowPassUniforms.depthMap.value = depthMapTarget;
- shadowPassUniforms.positionMap.value = positionMapTarget;
- shadowPassUniforms.colorMap.value = inBuffer;
+ shadowPassUniforms.lightDepthMap.value = lightDepthMapTarget;
+ shadowPassUniforms.eyeDepthMap.value = eyeDepthMapTarget.texture;
- renderer.render(shadowScene, sceneCam, outBuffer, true);
+ renderer.autoClearColor = false;
+ renderer.render(sceneGraph, sceneCam);
+ renderer.autoClearColor = true;
+ shadowPassUniforms.lightViewProjection.value = null;
+ shadowPassUniforms.lightDepthMap.value = null;
+ shadowPassUniforms.eyeDepthMap.value = null;
+ sceneGraph.overrideMaterial = null;
- shadowPassUniforms.depthMap.value = null;
- shadowPassUniforms.colorMap.value = null;
};
}
@@ -153,10 +141,10 @@
plug._applyTo = (on) => {
if (on) {
context = new SMContext();
- scene.addPostProcessPass(plug.getName(), context.pass);
+ scene.setupShadowMapping(context);
} else {
- scene.removePostProcessPass(plug.getName());
context = null;
+ scene.disposeShadowMapping();
}
};
diff --git a/js/mlj/plugins/rendering/shaders/ShadowFrag.glsl b/js/mlj/plugins/rendering/shaders/ShadowFrag.glsl
index f2fd277d..55cc9a07 100644
--- a/js/mlj/plugins/rendering/shaders/ShadowFrag.glsl
+++ b/js/mlj/plugins/rendering/shaders/ShadowFrag.glsl
@@ -1,36 +1,30 @@
precision highp float;
-uniform mat4 lightViewProjection;
-uniform mat4 modelMatrix;
-uniform sampler2D colorMap;
-uniform sampler2D positionMap;
-uniform sampler2D depthMap;
+uniform sampler2D eyeDepthMap;
+uniform sampler2D lightDepthMap;
-varying vec2 vUv;
+varying vec4 lightFragPos;
-float shadowCalc(vec2 vUv){
- vec4 position = texture2D(positionMap, vUv); //posizione mondo
- vec4 lightSpacePosition = lightViewProjection * position;
-
- lightSpacePosition.xyz /= lightSpacePosition.w;
-
- lightSpacePosition.xyz = lightSpacePosition.xyz * vec3(0.5) + vec3(0.5);
-
- float closest = texture2D(depthMap, lightSpacePosition.xy).r;
- float current = lightSpacePosition.z;
+void main(){
- float shadow = current - 0.005 > closest ? 1.0 : 0.0;
+ float eyeClosest = texture2D(eyeDepthMap, gl_FragCoord.xy).r;
- return shadow;
-}
+// if (gl_FragCoord.z > eyeClosest ) discard;
-void main(){
- vec4 color = texture2D(colorMap, vUv);
+ vec4 position = lightFragPos;
+ position.xyz /= position.w;
+ position.xyz = position.xyz * vec3(0.5) + vec3(0.5);
- if (color.a == 0.0) discard;
+ float closest = texture2D(lightDepthMap, position.xy).r;
+ float current = position.z;
- float lighting = (shadowCalc(vUv) > 0.0) ? 0.3 : 1.0;
+ //gl_FragColor.xyzw = vec4(vec3(eyeClosest), 1.0);
+ //return;
+ if (current - 0.005 > closest){
+ gl_FragColor = vec4(0, 0, 0, 0.3);
+ } else {
+ gl_FragColor = vec4(1, 0, 0, 0.002);
+ }
- gl_FragColor = vec4(color.rgb * lighting, color.a);
-}
+ }
diff --git a/js/mlj/plugins/rendering/shaders/ShadowVertex.glsl b/js/mlj/plugins/rendering/shaders/ShadowVertex.glsl
index 6587dbe4..bc68633c 100644
--- a/js/mlj/plugins/rendering/shaders/ShadowVertex.glsl
+++ b/js/mlj/plugins/rendering/shaders/ShadowVertex.glsl
@@ -2,18 +2,15 @@ precision highp float;
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
+uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
+uniform mat4 lightViewProjection;
attribute vec3 position;
-attribute vec2 uv;
-uniform sampler2D depthMap;
-uniform sampler2D positionMap;
-uniform sampler2D colorMap;
-
-varying vec2 vUv;
+varying vec4 lightFragPos;
void main(){
- gl_Position = vec4(position, 1.0);
- vUv = uv;
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
+ lightFragPos = lightViewProjection * (modelMatrix * vec4(position, 1.0));
}