簡體   English   中英

Three.js / WebGL 如何鏡像紋理的一側

[英]Three.js / WebGL How to mirror one side of a texture

我基本上是在嘗試僅用一側實現萬花筒效果,但我正在處理很多點,所以我希望在着色器中發生這種情況。 但是,如果有一個 Threejs 技巧可以鏡像一半紋理或 Points object,那就太好了。 我試圖應用轉換矩陣,但我無法讓它工作。

我發現了一個需要使用 EffectComposer 的舊KaleidoShader ,但我想自己手動實現它(沒有 EffectComposer),我正在努力做到這一點。 我正在使用 FBO,我嘗試在我的模擬和渲染着色器中添加該着色器的代碼,但它根本沒有任何效果。 我是否必須添加另一個 FBO 紋理,或者是否可以在現有着色器之一中進行這些計算?

視覺參考https://ma-hub.imgix.net/wp-images/2019/01/23205110/premiere-pro-mirror-effect.jpg

我花了這么多時間沒有深入了解這一點,希望有人能指出我正確的方向。

謝謝

有一種紋理環繞模式可以進行鏡像。

texture.wrapS = texture.wrapT = THREE.MirroredRepeatWrapping

這有幫助嗎?

編輯:這是一個在兩個軸上顯示 mirroredrepeatwrapping 的示例:

https://glitch.com/~three-mirroredrepeatwrapping

我剛剛關注了這篇文章

從該倉庫粘貼代碼似乎有效

 body { margin: 0; } #c { width: 100vw; height: 100vh; display: block; }
 <canvas id="c"></canvas> <script type="module"> import * as THREE from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/build/three.module.js'; import {EffectComposer} from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/examples/jsm/postprocessing/EffectComposer.js'; import {RenderPass} from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/examples/jsm/postprocessing/RenderPass.js'; import {ShaderPass} from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/examples/jsm/postprocessing/ShaderPass.js'; import {GUI} from 'https://threejsfundamentals.org/threejs/../3rdparty/dat.gui.module.js'; function main() { const canvas = document.querySelector('#c'); const renderer = new THREE.WebGLRenderer({canvas}); const fov = 75; const aspect = 2; // the canvas default const near = 0.1; const far = 5; const camera = new THREE.PerspectiveCamera(fov, aspect, near, far); camera.position.z = 2; const scene = new THREE.Scene(); { const color = 0xFFFFFF; const intensity = 2; const light = new THREE.DirectionalLight(color, intensity); light.position.set(-1, 2, 4); scene.add(light); } const boxWidth = 1; const boxHeight = 1; const boxDepth = 1; const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth); function makeInstance(geometry, color, x) { const material = new THREE.MeshPhongMaterial({color}); const cube = new THREE.Mesh(geometry, material); scene.add(cube); cube.position.x = x; return cube; } const cubes = [ makeInstance(geometry, 0x44aa88, 0), makeInstance(geometry, 0x8844aa, -2), makeInstance(geometry, 0xaa8844, 2), ]; const composer = new EffectComposer(renderer); composer.addPass(new RenderPass(scene, camera)); // from: // https://github.com/mistic100/three.js-examples/blob/master/LICENSE const kaleidoscopeShader = { uniforms: { "tDiffuse": { value: null }, "sides": { value: 6.0 }, "angle": { value: 0.0 } }, vertexShader: ` varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); } `, fragmentShader: ` uniform sampler2D tDiffuse; uniform float sides; uniform float angle; varying vec2 vUv; void main() { vec2 p = vUv - 0.5; float r = length(p); float a = atan(py, px) + angle; float tau = 2. * 3.1416; a = mod(a, tau/sides); a = abs(a - tau/sides/2.); p = r * vec2(cos(a), sin(a)); vec4 color = texture2D(tDiffuse, p + 0.5); gl_FragColor = color; } ` }; const kaleidoscopePass = new ShaderPass(kaleidoscopeShader); kaleidoscopePass.renderToScreen = true; composer.addPass(kaleidoscopePass); function resizeRendererToDisplaySize(renderer) { const canvas = renderer.domElement; const width = canvas.clientWidth; const height = canvas.clientHeight; const needResize = canvas.width.== width || canvas;height.== height, if (needResize) { renderer,setSize(width; height; false); } return needResize. } const gui = new GUI(). gui.add(kaleidoscopePass,uniforms,sides, 'value'. 0; 20).name('sides'). gui.add(kaleidoscopePass,uniforms,angle, 'value'. 0, 6.28. 0;01);name('angle'). let then = 0; function render(now) { now *= 0;001; // convert to seconds const deltaTime = now - then. then = now; if (resizeRendererToDisplaySize(renderer)) { const canvas = renderer.domElement. camera.aspect = canvas;clientWidth / canvas.clientHeight; camera.updateProjectionMatrix(). composer,setSize(canvas.width; canvas.height), } cubes.forEach((cube; ndx) => { const speed = 1 + ndx *;1. const rot = now * speed. cube;rotation.x = rot. cube;rotation;y = rot. }); composer;render(deltaTime); requestAnimationFrame(render); } requestAnimationFrame(render); } main(); </script>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM