主要的核心代码:
var renderPass = new THREE.RenderPass(scene, camera);//renderPass 通道:它只会渲染场景,但不会把结果输出到场景上 var effectFilm = new THREE.FilmPass(0.8, 0.325, 256, false);//FilmPass通道:它可以把结果输出到场景上 effectFilm.renderToScreen = true;//设置是否渲染到场景中 /*创建一个Three.EffectComposer() 它是一个组合器*/ var composer = new THREE.EffectComposer(webGLRenderer); /*每个通道都会按照其加入EffectComposer的顺序执行。 * 第一个加入的通道是RenderPass下面这个通道会渲染场景,但不会将渲染结果输出到平面上 * * FilmPass可以将其结果输出到屏幕上。这个通道是在RenderPass后面添加 * */ composer.addPass(renderPass); composer.addPass(effectFilm);
然后:
composer.render(delta);//替代webGLRenderer.render(),渲染时,就会调用EffectComposer 中的render()进行渲染
EffectComposer 是一个组合器, 渲染通道:
BloomPass 该通道会使得明亮区域参入较暗的区域。模拟相机照到过多亮光的情形 DotScreenPass 将一层黑点贴到代表原始图片的屏幕上 FilmPass 通过扫描线和失真模拟电视屏幕 MaskPass 在当前图片上贴一层掩膜,后续通道只会影响被贴的区域 RenderPass 该通道在指定的场景和相机的基础上渲染出一个新的场景 SavePass 执行该通道时,它会将当前渲染步骤的结果复制一份,方便后面使用。这个通道实际应用中作用不大; ShaderPass 使用该通道你可以传入一个自定义的着色器,用来生成高级的、自定义的后期处理通道 TexturePass 该通道可以将效果组合器的当前状态保存为一个纹理,然后可以在其他EffectCoposer对象中将该纹理作为输入参数
<!DOCTYPE html> <html> <head> <title>Example 11.01 - Effect composings</title> <script type="text/javascript" src="../js/three.js"></script> <script type="text/javascript" src="../js/stats.js"></script> <script type="text/javascript" src="../js/dat.gui.js"></script> <script type="text/javascript" src="../js/OrbitControls.js"></script> <script type="text/javascript" src="../js/postprocessing/ShaderPass.js"></script> <script type="text/javascript" src="../js/shaders/CopyShader.js"></script> <!--添加后期处理的步骤--> <script type="text/javascript" src="../js/postprocessing/EffectComposer.js"></script> <!-- MaskPass.js、ShaderPass.js、CopyShader.js 是EffectComposer内部使用的文件,--> <script type="text/javascript" src="../js/postprocessing/MaskPass.js"></script> <script type="text/javascript" src="../js/postprocessing/FilmPass.js"></script> <script type="text/javascript" src="../js/shaders/FilmShader.js"></script> <!--RenderPass.js 可以用来在EffectComposer对象上添加渲染通道--> <script type="text/javascript" src="../js/postprocessing/RenderPass.js"></script> <style> body { /* set margin to 0 and overflow to hidden, to go fullscreen */ margin: 0; overflow: hidden; } </style> </head> <body> <!-- BloomPass 该通道会使得明亮区域参入较暗的区域。模拟相机照到过多亮光的情形 DotScreenPass 将一层黑点贴到代表原始图片的屏幕上 FilmPass 通过扫描线和失真模拟电视屏幕 MaskPass 在当前图片上贴一层掩膜,后续通道只会影响被贴的区域 RenderPass 该通道在指定的场景和相机的基础上渲染出一个新的场景 SavePass 执行该通道时,它会将当前渲染步骤的结果复制一份,方便后面使用。这个通道实际应用中作用不大; ShaderPass 使用该通道你可以传入一个自定义的着色器,用来生成高级的、自定义的后期处理通道 TexturePass 该通道可以将效果组合器的当前状态保存为一个纹理,然后可以在其他EffectCoposer对象中将该纹理作为输入参数 --> <div id="Stats-output"> </div> <!-- Div which will hold the Output --> <div id="WebGL-output"> </div> <!-- Javascript code that runs our Three.js examples --> <script type="text/javascript"> // once everything is loaded, we run our Three.js stuff. function init() { var stats = initStats(); // create a scene, that will hold all our elements such as objects, cameras and lights. var scene = new THREE.Scene(); // create a camera, which defines where we're looking at. var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); // create a render and set the size var webGLRenderer = new THREE.WebGLRenderer(); webGLRenderer.setClearColor(new THREE.Color(0x000, 1.0)); webGLRenderer.setSize(window.innerWidth, window.innerHeight); webGLRenderer.shadowMapEnabled = true; var sphere = createMesh(new THREE.SphereGeometry(10, 40, 40)); // add the sphere to the scene scene.add(sphere); // position and point the camera to the center of the scene camera.position.x = -10; camera.position.y = 15; camera.position.z = 25; camera.lookAt(new THREE.Vector3(0, 0, 0)); var orbitControls = new THREE.OrbitControls(camera); orbitControls.autoRotate = false; var clock = new THREE.Clock(); var ambi = new THREE.AmbientLight(0x181818); scene.add(ambi); var spotLight = new THREE.DirectionalLight(0xffffff); spotLight.position.set(550, 100, 550); spotLight.intensity = 0.6; scene.add(spotLight); // add the output of the renderer to the html element document.getElementById("WebGL-output").appendChild(webGLRenderer.domElement); /*------------------------后期处理----------------------------------*/ var renderPass = new THREE.RenderPass(scene, camera);//renderPass 通道:它只会渲染场景,但不会把结果输出到场景上 var effectFilm = new THREE.FilmPass(0.8, 0.325, 256, false);//FilmPass通道:它可以把结果输出到场景上 effectFilm.renderToScreen = true;//设置是否渲染到场景中 /*创建一个Three.EffectComposer() 它是一个组合器*/ var composer = new THREE.EffectComposer(webGLRenderer); /*每个通道都会按照其加入EffectComposer的顺序执行。 * 第一个加入的通道是RenderPass下面这个通道会渲染场景,但不会将渲染结果输出到平面上 * * FilmPass可以将其结果输出到屏幕上。这个通道是在RenderPass后面添加 * */ composer.addPass(renderPass); composer.addPass(effectFilm); /*----------------------------------------------------------*/ // setup the control gui var controls = new function () { this.scanlinesCount = 256; this.grayscale = false; this.scanlinesIntensity = 0.3; this.noiseIntensity = 0.8; this.updateEffectFilm = function () { effectFilm.uniforms.grayscale.value = controls.grayscale; effectFilm.uniforms.nIntensity.value = controls.noiseIntensity; effectFilm.uniforms.sIntensity.value = controls.scanlinesIntensity; effectFilm.uniforms.sCount.value = controls.scanlinesCount; }; }; var gui = new dat.GUI(); gui.add(controls, "scanlinesIntensity", 0, 1).onChange(controls.updateEffectFilm); gui.add(controls, "noiseIntensity", 0, 3).onChange(controls.updateEffectFilm); gui.add(controls, "grayscale").onChange(controls.updateEffectFilm); gui.add(controls, "scanlinesCount", 0, 2048).step(1).onChange(controls.updateEffectFilm); // call the render function var step = 0; render(); function createMesh(geom) { var planetTexture = THREE.ImageUtils.loadTexture("../../img/textures/planets/Earth.png"); var specularTexture = THREE.ImageUtils.loadTexture("../../img/textures/planets/EarthSpec.png"); var normalTexture = THREE.ImageUtils.loadTexture("../../img/textures/planets/EarthNormal.png"); var planetMaterial = new THREE.MeshPhongMaterial(); planetMaterial.specularMap = specularTexture; planetMaterial.specular = new THREE.Color(0x4444aa); planetMaterial.normalMap = normalTexture; planetMaterial.map = planetTexture; // planetMaterial.shininess = 150; // create a multimaterial var mesh = THREE.SceneUtils.createMultiMaterialObject(geom, [planetMaterial]); return mesh; } function render() { stats.update(); //sphere.rotation.y=step+=0.04; var delta = clock.getDelta(); orbitControls.update(delta); sphere.rotation.y += 0.002; // render using requestAnimationFrame requestAnimationFrame(render); // webGLRenderer.render(scene, camera); composer.render(delta);//替代webGLRenderer.render(),渲染时,就会调用EffectComposer 中的render()进行渲染 } function initStats() { var stats = new Stats(); stats.setMode(0); // 0: fps, 1: ms // Align top-left stats.domElement.style.position = 'absolute'; stats.domElement.style.left = '0px'; stats.domElement.style.top = '0px'; document.getElementById("Stats-output").appendChild(stats.domElement); return stats; } } window.onload = init; </script> </body> </html>