상세 컨텐츠

본문 제목

[WebGL] Three.js - Vignette Shader

WEB/WebGL

by AlrepondTech 2017. 11. 1. 19:28

본문

반응형

 

 

 

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

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

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

 

 

 

 

 

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

[WebGL] Vignette Shader

 

이번 예제는 Vignette Shader 구현에 관한 것이다.Vignette Shader에 대한 자세한 내용은 다음을 참고하도록 한다:
https://github.com/mattdesl/lwjgl-basics/wiki/ShaderLesson3
또한 Shader Code는 Alfred Qualia에게 저작권이 있음을 알려둔다:Visit Alfred Qualia's Web Page.
[Download Project]

14-02-shader-vignette.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 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 ); // 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); // 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; 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 = { vignetteOffset: 1.5, vignetteDarkness: 1.6, useShaderNone: function() { setupShaderNone(); }, useShaderVignette: function() { setupShaderVignette(); } }; gui.add( parameters, 'useShaderNone' ).name("Display Original Scene"); var folderVignette = gui.addFolder('Vignette'); var vignetteOffsetGUI = folderVignette.add( parameters, 'vignetteOffset' ).min(0).max(3).step(0.01).name("Offset").listen(); vignetteOffsetGUI.onChange( function(value) { setupShaderVignette(); } ); var vignetteDarknessGUI = folderVignette.add( parameters, 'vignetteDarkness' ).min(0).max(3).step(0.01).name("Darkness").listen(); vignetteDarknessGUI.onChange( function(value) { setupShaderVignette(); } ); folderVignette.add( parameters, 'useShaderVignette' ).name("Use Vignette Shader"); folderVignette.open(); setupShaderNone(); } function setupShaderNone() { shaderActive = "none"; } function setupShaderVignette() { composer = new THREE.EffectComposer( renderer ); composer.addPass( new THREE.RenderPass( scene, camera ) ); var shaderVignette = THREE.VignetteShader; var effectVignette = new THREE.ShaderPass( shaderVignette ); // larger values = darker closer to center // darkness < 1 => lighter edges effectVignette.uniforms[ "offset" ].value = parameters.vignetteOffset; effectVignette.uniforms[ "darkness" ].value = parameters.vignetteDarkness; effectVignette.renderToScreen = true; composer.addPass(effectVignette); shaderActive = "vignette"; } 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(); }
[VignetteShader.js

]

 

/** * @author alteredq / http://alteredqualia.com/ * * Vignette shader * based on PaintEffect postprocess from ro.me * http://code.google.com/p/3-dreams-of-black/source/browse/deploy/js/effects/PaintEffect.js */ THREE.VignetteShader = { uniforms: { "tDiffuse": { type: "t", value: null }, "offset": { type: "f", value: 1.0 }, "darkness": { type: "f", value: 1.0 } }, vertexShader: [ "varying vec2 vUv;", "void main() {", "vUv = uv;", "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" ].join("\n"), fragmentShader: [ "uniform float offset;", "uniform float darkness;", "uniform sampler2D tDiffuse;", "varying vec2 vUv;", "void main() {", // Eskil's vignette "vec4 texel = texture2D( tDiffuse, vUv );", "vec2 uv = ( vUv - vec2( 0.5 ) ) * vec2( offset );", "gl_FragColor = vec4( mix( texel.rgb, vec3( 1.0 - darkness ), dot( uv, uv ) ), texel.a );", /* // alternative version from glfx.js // this one makes more "dusty" look (as opposed to "burned") "vec4 color = texture2D( tDiffuse, vUv );", "float dist = distance( vUv, vec2( 0.5 ) );", "color.rgb *= smoothstep( 0.8, offset * 0.799, dist *( darkness + offset ) );", "gl_FragColor = color;", */ "}" ].join("\n") };

 

 

 

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

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

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

 

 

 

반응형


관련글 더보기

댓글 영역