WEB/WebGL

[WebGL] Three.js - Blur Shader

AlrepondTech 2017. 11. 1. 19:34
반응형

 

 

 

 

 

 

=================================

=================================

=================================

 

 

 

 

 

 

 

출처: http://cinema4dr12.tistory.com/795

[WebGL] Blur Shader

 

이번 예제는 Blur Shader 구현에 관한 것이다.또한 Shader Code는 zz85에게 저작권이 있음을 알려둔다:Visit zz85's Web Page.
[Download Project]

14-05-shader-blur.zip
다운로드

 

FULL SCREEN

 

 

[Operations]

Mouse Left Button Click & Drag: Camera Rotating

Mouse Wheel: Camera Zoom In & Out

Mouse Right Button Click & Drag: Camera Panning


[main.js]

// standard global variables var container, scene, camera, renderer, controls, stats; var keyboard = new THREEx.KeyboardState(); var clock = new THREE.Clock(); // custom global variables var cube, gui; var shaderActive = "none"; // variables for shader var composer, finalPass; init(); animate(); // FUNCTIONS function init() { // SCENE scene = new THREE.Scene(); // CAMERA var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight; var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000; camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR); scene.add(camera); camera.position.set(0,150,400); camera.lookAt(scene.position); // RENDERER if ( Detector.webgl ) renderer = new THREE.WebGLRenderer( {antialias:true} ); else renderer = new THREE.CanvasRenderer(); renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); container = document.getElementById( 'ThreeJS' ); container.appendChild( renderer.domElement ); renderer.shadowMapEnabled = true; renderer.shadowMapSoft = true; // EVENTS THREEx.WindowResize(renderer, camera); THREEx.FullScreen.bindKey({ charCode : 'f'.charCodeAt(0) }); // CONTROLS controls = new THREE.OrbitControls( camera, renderer.domElement ); // STATS stats = new Stats(); stats.domElement.style.position = 'absolute'; stats.domElement.style.bottom = '0px'; stats.domElement.style.zIndex = 100; container.appendChild( stats.domElement ); // LIGHT var light = new THREE.PointLight(0xffffff); light.position.set(0,250,0); scene.add(light); var dirLight = new THREE.DirectionalLight(0xffc051); dirLight.position.set(-250,500,-150); dirLight.shadowDarkness = 0.95; dirLight.intensity = 2; dirLight.castShadow = true; // enable shadow casting ability for the light scene.add(dirLight); // FLOOR var floorTexture = new THREE.ImageUtils.loadTexture( 'img/Wood_floor.jpg' ); 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.PlaneGeometry(1000, 1000, 10, 10); var floor = new THREE.Mesh(floorGeometry, floorMaterial); floor.position.y = -0.5; floor.rotation.x = Math.PI / 2; floor.receiveShadow = true; scene.add(floor); // SKYBOX/FOG var materialArray = []; materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'img/px.jpg' ) })); materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'img/nx.jpg' ) })); materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'img/py.jpg' ) })); materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'img/ny.jpg' ) })); materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'img/pz.jpg' ) })); materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'img/nz.jpg' ) })); for (var i = 0; i < 6; i++) materialArray[i].side = THREE.BackSide; var skyboxMaterial = new THREE.MeshFaceMaterial( materialArray ); var skyboxGeom = new THREE.CubeGeometry( 5000, 5000, 5000, 1, 1, 1 ); var skybox = new THREE.Mesh( skyboxGeom, skyboxMaterial ); scene.add( skybox ); //////////// // CUSTOM // //////////// var cubeGeometry = new THREE.CubeGeometry( 50, 50, 50 ); var cubeTexture = new THREE.ImageUtils.loadTexture( 'img/0.png' ); var cubeMaterial = new THREE.MeshBasicMaterial( { map: cubeTexture } ); var cube = new THREE.Mesh( cubeGeometry, cubeMaterial ); cube.position.set(-50,25,0); cube.castShadow = true; scene.add(cube); var cubeGeometry1 = new THREE.CubeGeometry( 50, 50, 50 ); var cubeTexture1 = new THREE.ImageUtils.loadTexture( 'img/4.png' ); var cubeMaterial1 = new THREE.MeshBasicMaterial( { map: cubeTexture1 } ); var cube1 = new THREE.Mesh( cubeGeometry1, cubeMaterial1 ); cube1.position.set(-150,25,0); cube1.castShadow = true; scene.add(cube1); var cubeGeometry2 = new THREE.CubeGeometry( 50, 50, 50 ); var cubeTexture2 = new THREE.ImageUtils.loadTexture( 'img/9.png' ); var cubeMaterial2 = new THREE.MeshBasicMaterial( { map: cubeTexture2 } ); var cube2 = new THREE.Mesh( cubeGeometry2, cubeMaterial2 ); cube2.position.set(150,25,0); cube2.castShadow = true; scene.add(cube2); var sphereGeometry = new THREE.SphereGeometry( 50, 32, 16 ); var sphereTexture = new THREE.ImageUtils.loadTexture( 'img/8.png' ); var sphereMaterial = new THREE.MeshBasicMaterial( { map: sphereTexture } ); var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); sphere.position.set(50, 50, -50); sphere.castShadow = true; scene.add(sphere); ///////////////////// // POST-PROCESSING // ///////////////////// // GUI setup gui = new dat.GUI(); parameters = { horizBlur: 1.25, vertiBlur: 1.25, useShaderNone: function() { setupShaderNone(); }, useShaderBlur: function() { setupShaderBlur(); } }; gui.add( parameters, 'useShaderNone' ).name("Display Original Scene"); var folderBlur = gui.addFolder('Blur'); var horizBlurGUI = folderBlur.add( parameters, 'horizBlur' ).min(0.0).max(3.0).step(0.01).name("Horizontal Blur").listen(); horizBlurGUI.onChange( function(value) { setupShaderBlur(); } ); var vertiBlurGUI = folderBlur.add( parameters, 'vertiBlur' ).min(0.0).max(3.0).step(0.01).name("Vertical Blur").listen(); vertiBlurGUI.onChange( function(value) { setupShaderBlur(); } ); folderBlur.add( parameters, 'useShaderBlur' ).name("Use Blur Shader"); folderBlur.open(); setupShaderNone(); } function setupShaderNone() { shaderActive = "none"; } function setupShaderBlur() { composer = new THREE.EffectComposer( renderer ); composer.addPass( new THREE.RenderPass( scene, camera ) ); // http://devmaster.net/posts/3100/shader-effects-glow-bloom // http://www.neilblevins.com/cg_education/specular_bloom/specular_bloom.htm var effectHorizBlur = new THREE.ShaderPass( THREE.HorizontalBlurShader ); var effectVertiBlur = new THREE.ShaderPass( THREE.VerticalBlurShader ); effectHorizBlur.uniforms[ "h" ].value = parameters.horizBlur / window.innerWidth; effectVertiBlur.uniforms[ "v" ].value = parameters.vertiBlur / window.innerHeight; effectVertiBlur.renderToScreen = true; composer.addPass( effectHorizBlur ); composer.addPass( effectVertiBlur ); shaderActive = "blur"; } function animate() { requestAnimationFrame( animate ); render(); update(); } function update() { if ( keyboard.pressed("z") ) { // do something } controls.update(); stats.update(); } function render() { if ( shaderActive == "none" ) renderer.render( scene, camera ); else composer.render(); }

 

[HorizontalBlurShader.js]

/** * @author zz85 / http://www.lab4games.net/zz85/blog * * Two pass Gaussian blur filter (horizontal and vertical blur shaders) * - described in http://www.gamerendering.com/2008/10/11/gaussian-blur-filter-shader/ * and used in http://www.cake23.de/traveling-wavefronts-lit-up.html * * - 9 samples per pass * - standard deviation 2.7 * - "h" and "v" parameters should be set to "1 / width" and "1 / height" */ THREE.HorizontalBlurShader = { uniforms: { "tDiffuse": { type: "t", value: null }, "h": { type: "f", value: 1.0 / 512.0 } }, vertexShader: [ "varying vec2 vUv;", "void main() {", "vUv = uv;", "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" ].join("\n"), fragmentShader: [ "uniform sampler2D tDiffuse;", "uniform float h;", "varying vec2 vUv;", "void main() {", "vec4 sum = vec4( 0.0 );", "sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * h, vUv.y ) ) * 0.051;", "sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * h, vUv.y ) ) * 0.0918;", "sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * h, vUv.y ) ) * 0.12245;", "sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * h, vUv.y ) ) * 0.1531;", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;", "sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * h, vUv.y ) ) * 0.1531;", "sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * h, vUv.y ) ) * 0.12245;", "sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * h, vUv.y ) ) * 0.0918;", "sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * h, vUv.y ) ) * 0.051;", "gl_FragColor = sum;", "}" ].join("\n") };

 

[VerticalBlurShader.js]

/** * @author zz85 / http://www.lab4games.net/zz85/blog * * Two pass Gaussian blur filter (horizontal and vertical blur shaders) * - described in http://www.gamerendering.com/2008/10/11/gaussian-blur-filter-shader/ * and used in http://www.cake23.de/traveling-wavefronts-lit-up.html * * - 9 samples per pass * - standard deviation 2.7 * - "h" and "v" parameters should be set to "1 / width" and "1 / height" */ THREE.VerticalBlurShader = { uniforms: { "tDiffuse": { type: "t", value: null }, "v": { type: "f", value: 1.0 / 512.0 } }, vertexShader: [ "varying vec2 vUv;", "void main() {", "vUv = uv;", "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" ].join("\n"), fragmentShader: [ "uniform sampler2D tDiffuse;", "uniform float v;", "varying vec2 vUv;", "void main() {", "vec4 sum = vec4( 0.0 );", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * v ) ) * 0.051;", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * v ) ) * 0.0918;", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * v ) ) * 0.12245;", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * v ) ) * 0.1531;", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * v ) ) * 0.1531;", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * v ) ) * 0.12245;", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * v ) ) * 0.0918;", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * v ) ) * 0.051;", "gl_FragColor = sum;", "}" ].join("\n") };

 

 

 

=================================

=================================

=================================

 

 

 

반응형

'WEB > WebGL' 카테고리의 다른 글

[WebGL] Three.js - COLLADA(dae) Loader  (0) 2017.11.01
[WebGL] Three.js - Path Tracing  (0) 2017.11.01
[WebGL] Three.js - Bloom Shader  (0) 2017.11.01
[WebGL] Three.js - Dot-Screen Shader  (0) 2017.11.01
[WebGL] Three.js - Vignette Shader  (0) 2017.11.01