我用一个需要可视化图像层的例子来测试Three.js:
当我使用'THREE.EdgeShader'或'THREE.EdgeShader2'时,我获得了图像过滤器下一张图片显示了获得的结果:
我的问题出现了,因为场景也被修改了。所以,我只需要为图像应用滤镜。另外,我要求在应用滤镜后,所有导致黑色的像素都是透明的。你能帮帮我吗?
代码是:
<!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://www.html5rocks.com/en/tutorials/canvas/imagefilters/
/*
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>