mercredi 28 janvier 2015

How applicate Sobel filter or Frei-Chen Filter only on the images?

I testing Three.js with an example that need to visualize layer of images like this:


enter image description here


When i use 'THREE.EdgeShader' or 'THREE.EdgeShader2' i obtain the filter of images The next image show the results obtained:


enter image description here


My problem arises because the scene is also modified. So, I need apply the filter only for the images. Additionally, I require that after applying the filter, all pixels resulting in black be transparent. Could you help me ?


The code is :



<!DOCTYPE html>
<html lang="en">
<head>
<title>Webgl - postprocessing</title>
<meta charset="utf-8">
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<meta name="viewport" content="width=device-width, height=device-height, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link rel=stylesheet href="css/base.css"/>
</head>
<body>

<script src="js/three.min.js"></script>
<script src="js/Detector.js"></script>
<script src="js/OrbitControls.js"></script>
<script src="js/THREEx.FullScreen.js"></script>
<script src="js/THREEx.KeyboardState.js"></script>
<script src="js/THREEx.WindowResize.js"></script>

<script src="js/libs/stats.min.js"></script>
<script type='text/javascript' src='js/libs/dat.gui.min.js'></script>

<script src="js/postprocessing/EffectComposer.js"></script>
<script src="js/shaders/CopyShader.js"></script>
<script src="js/postprocessing/RenderPass.js"></script>
<script src="js/postprocessing/MaskPass.js"></script>
<script src="js/postprocessing/ShaderPass.js"></script>

<script src="js/shaders/EdgeShader.js"></script>
<script src="js/shaders/EdgeShader2.js"></script>

<script src="js/shaders/BokehShader2.js"></script>

<script id="vertexShader" type="x-shader/x-vertex">
uniform vec3 viewVector;
uniform float c;
uniform float p;
varying float intensity;
void main()
{
vec3 vNormal = normalize( normalMatrix * normal );
vec3 vNormel = normalize( normalMatrix * viewVector );
intensity = pow( c - dot(vNormal, vNormel), p );

gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
</script>

<!-- fragment shader a.k.a. pixel shader -->
<script id="fragmentShader" type="x-shader/x-vertex">
uniform vec3 glowColor;
varying float intensity;
void main()
{
vec3 glow = glowColor * intensity;
gl_FragColor = vec4( glow, 1.0 );
}
</script>

<div id="Test3D" style="position: absolute; left:0px; top:0px"></div>

<script>

var myImage;
var container, scene, camera, renderer, controls, stats;
var composer, object, light, View_Angle;
var keyboard = new THREEx.KeyboardState();
var clock = new THREE.Clock();
var Screen_Width, Screen_Height;

var edgeEffect, edgeEffect2;

var gui, parameters;

initScene();
animateScene();

function setScene() {
// Create the scene
scene = new THREE.Scene();
}

function setContainer(renderer) {
container = document.getElementById( 'Test3D' ).appendChild( renderer.domElement );
}

function renderer() {
if ( Detector.webgl )
renderer = new THREE.WebGLRenderer( ); //{antialias:true} );
else
renderer = new THREE.CanvasRenderer();

renderer.setSize(Screen_Width, Screen_Height);
setContainer(renderer);
}

function setCamera(x, y, z) {
// Get the size of the inner window (content area) to create a full size renderer
Screen_Width = window.innerWidth, Screen_Height = window.innerHeight;
View_Angle = 45, ASPECT = Screen_Width / Screen_Height, NEAR = 0.1, FAR = 20000;

// Create the camera
camera = new THREE.PerspectiveCamera( View_Angle, ASPECT, NEAR, FAR);
camera.position.set(x,y,z);
scene.add(camera);
camera.lookAt(scene.position);
}

function setEvents() {
THREEx.WindowResize(renderer, camera);
THREEx.FullScreen.bindKey({ charCode : 'm'.charCodeAt(0) });
}

function setOrbitControls() {
controls = new THREE.OrbitControls( camera, renderer.domElement );
}

function setStats() {
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.bottom = '0px';
stats.domElement.style.zIndex = 100;
container.appendChild( stats.domElement );
}

function setFloor(image) {
var floorTexture = new THREE.ImageUtils.loadTexture( image );
floorTexture.wrapS = floorTexture.wrapT = THREE.RepeatWrapping;
floorTexture.repeat.set( 1, 1 );
var floorMaterial = new THREE.MeshBasicMaterial( { map: floorTexture, side: THREE.DoubleSide } );
var floorGeometry = new THREE.PlaneBufferGeometry(1000, 1000, 10, 10);
var floor = new THREE.Mesh(floorGeometry, floorMaterial);
floor.position.y = 5;
floor.rotation.x = Math.PI / 2;
scene.add(floor);
}

function setSkyBox_FOG(isFog, color) {
var skyBoxGeometry = new THREE.BoxGeometry( 10000, 10000, 10000 );
var skyBoxMaterial = new THREE.MeshBasicMaterial( { color: color, side: THREE.BackSide } );
var skyBox = new THREE.Mesh( skyBoxGeometry, skyBoxMaterial );
scene.add(skyBox);
if (isFog) {
scene.fog = new THREE.FogExp2( color, 0.00025 );
}
}

function setAmbientLight(color) {
light = new THREE.AmbientLight( color );
scene.add( light );
}

function initScene() {
setScene() //scene = new THREE.Scene();
setCamera(500, 0, 600);
renderer();
setEvents();
setOrbitControls();
setStats() // STATS
setSkyBox_FOG(false, 0xB0C4DE); // SKYBOX/FOG

CreateImages();
PostProcessing();
setAmbientLight(0xeeeeee);

initGUI(); // GUI
}

function createMaterial() {
/*
var materialCameraPosition = camera.position.clone();
var material = new THREE.ShaderMaterial(
{
uniforms: {
"c": { type: "f", value: 128.0 },
"p": { type: "f", value: 3 },
glowColor: { type: "c", value: new THREE.Color(0x84ccff) },
viewVector: { type: "v3", value: materialCameraPosition }
},
vertexShader: document.getElementById('vertexShader').textContent,
fragmentShader: document.getElementById('fragmentShader').textContent,
//shading: THREE.FlatShading,
//side: THREE.FrontSide,
side: THREE.DoubleSide,
blending: THREE.AdditiveBlending,
transparent: true,
//opacity: 0.5,
depthWrite: false
});
*/

var material = new THREE.MeshPhongMaterial({
shading: THREE.FlatShading,
side: THREE.DoubleSide
});
return material;
}

function createImage(x, y, imageName, posX) {
var material = createMaterial();
var geometry = new THREE.PlaneBufferGeometry( x, y );
material.map = THREE.ImageUtils.loadTexture(imageName);

var mesh = new THREE.Mesh( geometry, material );
mesh.position.z = posX;

scene.add( mesh );
return mesh;
}

function CreateImages() {
for ( var i = 0; i < 5; i ++ ) {
createImage(512,246, 'beach.jpg', i*30 + 100);
}
}

function PostProcessing() {

// basic renderer that renders the scene, and uses the
// effectCopy shader to output the image to the defined
// rendertarget.
composer = new THREE.EffectComposer( renderer );
composer.addPass( new THREE.RenderPass(scene, camera) );

edgeEffect = new THREE.ShaderPass( THREE.EdgeShader );
edgeEffect.uniforms[ 'aspect' ].value.set(window.innerWidth, window.innerHeight);
composer.addPass( edgeEffect );

edgeEffect2 = new THREE.ShaderPass( THREE.EdgeShader2 );
edgeEffect2.uniforms[ 'aspect' ].value.set(window.innerWidth, window.innerHeight);
composer.addPass( edgeEffect2 );

var effectCopy = new THREE.ShaderPass( THREE.CopyShader);
effectCopy.renderToScreen = true;
composer.addPass( effectCopy );

window.addEventListener( 'resize', onWindowResize, false );

initializeParameters(false, false, false, false);


//http://ift.tt/H17FYE

/*
Filters.threshold = function(pixels, threshold) {
var d = pixels.data;
for (var i=0; i<d.length; i+=4) {
var r = d[i];
var g = d[i+1];
var b = d[i+2];
var v = (0.2126*r + 0.7152*g + 0.0722*b >= threshold) ? 255 : 0;
d[i] = d[i+1] = d[i+2] = v
}
return pixels;
};


var grayscale = Filters.filterImage(Filter.grayscale, image);
// Note that ImageData values are clamped between 0 and 255, so we need
// to use a Float32Array for the gradient values because they
// range between -255 and 255.
var vertical = Filters.convoluteFloat32(grayscale,
[ -1, 0, 1,
-2, 0, 2,
-1, 0, 1 ]);
var horizontal = Filters.convoluteFloat32(grayscale,
[ -1, -2, -1,
0, 0, 0,
1, 2, 1 ]);
var final_image = Filters.createImageData(vertical.width, vertical.height);
for (var i=0; i<final_image.data.length; i+=4) {
// make the vertical gradient red
var v = Math.abs(vertical.data[i]);
final_image.data[i] = v;
// make the horizontal gradient green
var h = Math.abs(horizontal.data[i]);
final_image.data[i+1] = h;
// and mix in some blue for aesthetics
final_image.data[i+2] = (v+h)/4;
final_image.data[i+3] = 255; // opaque alpha
}
*/

}


function initializeParameters(EdgeDetection, EdgeDetection2) {
edgeEffect.enabled = EdgeDetection;
edgeEffect2.enabled = EdgeDetection2;
}

function initGUI() {

gui = new dat.GUI({
height : 5 * 32 - 1
});

parameters = {
EdgeDetection: false, // Edge Detection (Frei-Chen Filter)
EdgeDetection2: false, // Edge Detection (Sobel Filter)
EdgeAspect: 512,
Threshold: 0.5,
reset: function() {
parameters.EdgeDetection = false;
parameters.EdgeDetection2 = false;
parameters.EdgeAspect = 512;
parameters.Threshold = 0.5;
initializeParameters(false, false, false, false);
}
};

var filters = gui.addFolder('Filters');
filters.add( parameters, 'EdgeDetection').name('Frei-Chen Filter').listen().onChange(
function(value) {
edgeEffect.enabled = value;
});
filters.add( parameters, 'EdgeDetection2').name('Sobel Filter').listen().onChange(
function(value) {
edgeEffect2.enabled = value;
});
filters.open();

var edgeAspect = gui.add( parameters, "EdgeAspect", 128, 2048 ).listen().onChange(
function(value) {
//
edgeEffect.uniforms.aspect.value = new THREE.Vector2(value, value);
});
var threshold = gui.add( parameters, "Threshold", 0, 1, 0.001 ).listen().onChange(
function(value) {
//
});

gui.add( parameters, 'reset' ).name("Reset Parameters");

gui.open();
}

function onWindowResize() {

camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();

renderer.setSize( window.innerWidth, window.innerHeight );

edgeEffect.uniforms[ 'aspect' ].value.set(window.innerWidth, window.innerHeight);
edgeEffect2.uniforms[ 'aspect' ].value.set(window.innerWidth, window.innerHeight);
}

function update() {
controls.update();
stats.update();
}

function animateScene() {
// render using requestAnimationFrame
requestAnimationFrame( animateScene );
renderer.autoClear = false;
renderer.clear();
composer.render();
update();
}

</script>
</body>
</html>

Aucun commentaire:

Enregistrer un commentaire