Javascript 如何仅在图像上应用Sobel过滤器或Frei Chen过滤器?
我用一个需要可视化图像层的示例测试Three.js,如下所示: 当我使用“THREE.EdgeShader”或“THREE.EdgeShader 2”时,我获得图像的过滤器,下一幅图像显示获得的结果: 我的问题出现了,因为场景也被修改了。所以,我只需要对图像应用过滤器。此外,我要求在应用过滤器后,所有产生黑色的像素都是透明的。你能帮我吗 代码是:Javascript 如何仅在图像上应用Sobel过滤器或Frei Chen过滤器?,javascript,filter,three.js,post-processing,sobel,Javascript,Filter,Three.js,Post Processing,Sobel,我用一个需要可视化图像层的示例测试Three.js,如下所示: 当我使用“THREE.EdgeShader”或“THREE.EdgeShader 2”时,我获得图像的过滤器,下一幅图像显示获得的结果: 我的问题出现了,因为场景也被修改了。所以,我只需要对图像应用过滤器。此外,我要求在应用过滤器后,所有产生黑色的像素都是透明的。你能帮我吗 代码是: <!DOCTYPE html> <html lang="en"> <head> <
<!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>
Webgl-后处理
均匀vec3视向量;
均匀浮点数c;
均匀浮动p;
浮动强度变化;
void main()
{
vec3 vNormal=规格化(normalMatrix*normal);
vec3 vNormel=规格化(normalMatrix*viewVector);
强度=功率(c-点(vNormal,vNormal),p);
gl_位置=projectionMatrix*modelViewMatrix*vec4(位置,1.0);
}
颜色均匀;
浮动强度变化;
void main()
{
vec3发光=发光颜色*强度;
gl_FragColor=vec4(辉光,1.0);
}
var-myImage;
var容器、场景、摄影机、渲染器、控件、统计信息;
变量生成器、对象、灯光、视角;
var keyboard=new THREEx.KeyboardState();
var clock=新的三个时钟();
可变屏幕宽度、屏幕高度;
var edgeEffect,edgeEffect2;
var-gui,参数;
初始化场景();
animateScene();
函数setScene(){
//创建场景
场景=新的三个。场景();
}
函数集合容器(渲染器){
container=document.getElementById('Test3D').appendChild(renderer.doElement);
}
函数渲染器(){
if(Detector.webgl)
renderer=new THREE.WebGLRenderer();//{antialas:true});
其他的
renderer=new THREE.CanvasRenderer();
设置大小(屏幕宽度、屏幕高度);
setContainer(渲染器);
}
功能设置摄像头(x、y、z){
//获取内部窗口(内容区域)的大小以创建全尺寸渲染器
屏幕宽度=window.innerWidth,屏幕高度=window.innerHeight;
视角=45,纵横比=屏幕宽度/屏幕高度,近距离=0.1,远距离=20000;
//创建摄影机
摄像机=新的三个透视摄像机(视角、方向、近距离、远距离);
摄像机位置设置(x,y,z);
场景。添加(摄影机);
摄像机。注视(场景。位置);
}
函数setEvents(){
三倍。窗口大小调整(渲染器、相机);
THREEx.FullScreen.bindKey({charCode:'m'.charCodeAt(0)});
}
函数setOrbitControls(){
控件=新的三个.轨道控件(摄影机、渲染器.doElement);
}
函数setStats(){
统计数据=新统计数据();
stats.domElement.style.position='绝对';
stats.domeElement.style.bottom='0px';
stats.domElement.style.zIndex=100;
container.appendChild(stats.domeElement);
}
功能设置楼层(图像){
var floorTexture=new THREE.ImageUtils.loadTexture(图像);
floorTexture.wrapps=floorTexture.wrapT=THREE.RepeatWrapping;
地板结构。重复。设置(1,1);
var floorMaterial=新的三个.MeshBasicMaterial({map:floorTexture,side:THREE.DoubleSide});
var地板测量法=新的三个平面几何(1000,1000,10,10);
var地板=新的三层网格(地板测量、地板材料);
楼层位置y=5;
floor.rotation.x=Math.PI/2;
场景。添加(楼层);
}
功能设置SkyBox_FOG(isFog,彩色){
var skyBoxGeometry=新的三个.BoxGeometry(10000、10000、10000);
var skyBoxMaterial=new THREE.MeshBasicMaterial({color:color,side:THREE.BackSide});
var skyBox=new THREE.Mesh(skyBoxGeometry,skyBoxMaterial);
场景.添加(skyBox);
如果(isFog){
scene.fog=新的三个.fogep2(颜色,0.00025);
}
}
功能设置环境光(颜色){
光=新的三个。环境光(颜色);
场景。添加(灯光);
}
函数initScene(){
setScene()//scene=new THREE.scene();
设置摄像机(500、0600);
渲染器();
setEvents();
setOrbitControls();
setStats()//STATS
setSkyBox_FOG(false,0xB0C4DE);//SKYBOX/FOG
CreateImages();
后处理();
设置环境光(0xEEEE);
initGUI();//GUI
}
函数createMaterial(){
/*
var materialCameraPosition=camera.position.clone();
var material=新的3.ShaderMaterial(
{
制服:{
“c”:{类型:“f”,值:128.0},
“p”:{类型:“f”,值:3},