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 123 124 125 126 127 128 129 130 131
| const transitionParams = { transition: 0, texture: undefined, useTexture: false, transitionSpeed: 0.03, animate: false, };
const sceneTransition = new THREE.Scene(); const materialTransition = new THREE.ShaderMaterial({ uniforms: { tDiffuse1: { value: null, }, tDiffuse2: { value: null, }, mixRatio: { value: 0.0, }, threshold: { value: 0.1, }, useTexture: { value: false, }, tMixTexture: { value: transitionParams.texture, }, }, vertexShader: ` varying vec2 vUv; void main() { vUv = vec2( uv.x, uv.y ); gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); } `, fragmentShader: ` uniform float mixRatio; uniform sampler2D tDiffuse1; uniform sampler2D tDiffuse2; uniform sampler2D tMixTexture; uniform bool useTexture; uniform float threshold; varying vec2 vUv; void main() { vec4 texel1 = texture2D( tDiffuse1, vUv ); vec4 texel2 = texture2D( tDiffuse2, vUv ); if (useTexture==true) { vec4 transitionTexel = texture2D( tMixTexture, vUv ); float r = mixRatio * (1.0 + threshold * 2.0) - threshold; float mixf=clamp((transitionTexel.r - r)*(1.0/threshold), 0.0, 1.0); gl_FragColor = mix( texel1, texel2, mixf ); } else { gl_FragColor = mix( texel2, texel1, mixRatio ); } } `, }) const finalMesh = new THREE.Mesh(new THREE.PlaneGeometry(1, 1), materialTransition); sceneTransition.add(finalMesh);
let frustumSize = 1; const cameraTransition = new THREE.OrthographicCamera(frustumSize / -2, frustumSize / 2, frustumSize / 2, frustumSize / -2, -1000, 1000);
const render3 = () => { requestAnimationFrame(render3) if (transitionParams.transition === 0) { if (currentScene === 'first') render(); if (currentScene === 'second') render2(); } else if (transitionParams.transition >= 1) { currentScene = currentScene === 'first' ? 'second' : 'first' document.getElementById('button').innerHTML = currentScene === 'first' ? '进入户型2' : '进入户型1' setTimeout(() => { transitionParams.animate = false; transitionParams.transition = 0; }, 10); currentScene === 'first' && render(); currentScene === 'second' && render2(); } else { render('trans'); render2('trans') renderer.setRenderTarget(null); renderer.clear(); renderer.render(sceneTransition, cameraTransition); } if (transitionParams.animate && transitionParams.transition <= 1) { transitionParams.transition = transitionParams.transition + transitionParams.transitionSpeed; materialTransition.uniforms.mixRatio.value = transitionParams.transition; } } render3()
const update = (params, f1, f2) => { console.log('fbo2.texture', fbo2.texture) console.log('fbo.texture', fbo.texture) if (transitionParams.animate) return false; const { transitionSpeed = 0.03, texture, useTexture = false } = params; transitionParams.texture = texture; transitionParams.useTexture = useTexture;
transitionParams.transition = 0; transitionParams.transitionSpeed = transitionSpeed; transitionParams.animate = true; materialTransition.uniforms.tDiffuse1.value = f1.texture; materialTransition.uniforms.tDiffuse2.value = f2.texture; materialTransition.uniforms.threshold.value = 0.1; materialTransition.uniforms.mixRatio.value = 0.0; materialTransition.uniforms.tMixTexture.value = texture; materialTransition.uniforms.useTexture.value = useTexture; return true; }
document.getElementById('button').onclick = function() { if (currentScene === 'first') update(transitionParams, fbo2, fbo); else update(transitionParams, fbo, fbo2); }
|