新接到一个项目,让我做两个场景的遮罩,如下所示
可以控制参数,动态显示被遮罩的场景大小。
利用THREE.shaderPass自定义着色器写的,代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
<div id="container" style="width:100vw;height:100vh;"> <div id="three"></div> </div> <script src='http://cdnjs.cloudflare.com/ajax/libs/three.js/r80/three.min.js'></script> <script src='http://wow.techbrood.com/uploads/161101/three_post.js'></script> <script> var mainContainer = document.querySelector('#container'); var viewWidth = mainContainer.clientWidth; var viewHeight = mainContainer.clientHeight; var renderer = new THREE.WebGLRenderer({ alpha: true }); renderer.setSize(viewWidth, viewHeight); renderer.setPixelRatio(window.devicePixelRatio); renderer.setClearColor(0x3d3d38); renderer.autoClear = false; document.querySelector('#three').appendChild(renderer.domElement); //创建第一个场景 var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera(60, viewWidth / viewHeight, 1, 10000); camera.position.set(1.25, 0, 10); var box = new THREE.Mesh(new THREE.BoxGeometry(2, 2, 2)); box.position.x = 1.5; scene.add(box); var circleTexture = new THREE.TextureLoader().load("neibu.png"); var circle = new THREE.Mesh(new THREE.CircleGeometry(25, 64),new THREE.MeshBasicMaterial({map:circleTexture})); circle.position.x = 5; circle.position.z = -15; scene.add(circle); //创建第二个场景 var secondScene = new THREE.Scene(); var secondGroup = new THREE.Group(); var planeTexture = new THREE.TextureLoader().load("room.png"); var planeGeometry = new THREE.PlaneGeometry(192, 102); var planeMaterial = new THREE.MeshBasicMaterial({ map: planeTexture, side: THREE.DoubleSide, transparent: true, opacity: 1, depthTest: false }); var planeMesh = new THREE.Mesh(planeGeometry, planeMaterial); secondGroup.add(planeMesh); secondScene.add(secondGroup); secondScene.position.z = -10; var renderTargetParameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false }; secondScene.fbo = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, renderTargetParameters); scene.fbo = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, renderTargetParameters); //创建EffectComposer(效果组合器)对象,在该对象上,我们可以增加后期处理通道 var compWidth = viewWidth * window.devicePixelRatio; var compHeight = viewHeight * window.devicePixelRatio; var composer = new THREE.EffectComposer(renderer, new THREE.WebGLRenderTarget(compWidth, compHeight, { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat, stencilBuffer: false })); var renderPass = new THREE.RenderPass(scene, camera); var maskPass = new THREE.ShaderPass({ //统一值,可以向你的着色器发信息。同样的信息会发到每一个顶点和片段 uniforms: { "tDiffuse1": { value: null }, "tDiffuse2": { value: null } }, //顶点着色器,允许你修改每一个传入的顶点的位置 vertexShader: [ "varying vec2 vUv;", "void main() {", "vUv = uv;", "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" ].join("\n"), //像素着色器,定义的是每个传入的像素的颜色 fragmentShader: [ "uniform sampler2D tDiffuse1;", "uniform sampler2D tDiffuse2;", "varying vec2 vUv;", "void main() {", "vec4 texel1 = texture2D( tDiffuse1, vUv );", "vec4 texel2 = texture2D( tDiffuse2, vUv );", "if (vUv.x >0.33 && vUv.x < 0.66 && vUv.y >0.33 && vUv.y < 0.66) {", "gl_FragColor = texel1;", "} else {", "gl_FragColor = texel2;", "}", "}" ].join("\n") }); composer.addPass(renderPass); composer.addPass(maskPass); maskPass.renderToScreen = true;//将渲染结果输出到屏幕上 //给渲染器传递tDiffuse1的参数,使我们想要的纹理贴到渲染通道上面 function render() { renderer.render(scene, this.camera, scene.fbo, true); maskPass.uniforms.tDiffuse1.value = scene.fbo.texture; renderer.render(secondScene, this.camera, secondScene.fbo, true); maskPass.uniforms.tDiffuse2.value = secondScene.fbo.texture; composer.render(); } function tick() { render(); requestAnimationFrame(tick); } tick(); </script> |
欢迎转载,转载需带着文章出处链接~~