[英]How can I get a Clamp-To-Border effect on an Image-Loaded Texture in THREE.js?
我的場景中有一個平面,圖像加載到紋理上,據我所知,紋理沒有 Clamp-To-Border 選項,只有 Clamp-To-Edge、Repeat Wrapping 和 Mirrored Wrapping。
這是具有默認 ClampToEdge 效果的圖像。
這是我想要實現的目標。
我能想到的一個解決方案是為圖像添加一個白色邊框,這將使整個部分變白,但我不知道如何拍攝圖像並為其應用白色邊框。
圖像是通過 base64 字符串加載的,也許有辦法為該字符串添加白色邊框?
非常感謝任何建議,謝謝!
最明顯的解決方案是將您的圖像加載到圖像編輯器中,將其在每個方向上擴大 1 個像素並添加邊框顏色,將其保存回原處,使用帶有邊框的新圖像。
第二個最明顯的解決方案是將圖像繪制到寬度和高度分別為 2 像素的畫布中。
const img = new Image();
img.onload = () => {
const canvas = document.createElement('canvas');
canvas.width = img.width + 2;
canvas.height = img.height + 2;
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'white'; // border color
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 1, 1);
// now make a texture using `new THREE.CanvasTexture(canvas)`
};
img.src = urlForImage;
例子:
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 boxWidth = 1; const boxHeight = 1; const boxDepth = 1; const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth); const cubes = []; // just an array we can use to rotate the cubes // create a usable texture to start. We'll update it when the image loads const imgCanvas = document.createElement('canvas'); const texture = new THREE.CanvasTexture(imgCanvas); texture.minFilter = THREE.LinearFilter; texture.wrapS = THREE.ClampToEdgeWrapping; texture.wrapT = THREE.ClampToEdgeWrapping; texture.offset.set(-0.5, -0.5); texture.repeat.set(2, 2); const img = new Image(); img.onload = () => { imgCanvas.width = img.width + 2; imgCanvas.height = img.height + 2; const ctx = imgCanvas.getContext('2d'); ctx.fillStyle = 'white'; // border color ctx.fillRect(0, 0, imgCanvas.width, imgCanvas.height); ctx.drawImage(img, 1, 1); texture.needsUpdate = true; }; img.crossOrigin = 'anonymous'; // only needed if image is from another origin img.src = 'https://threejsfundamentals.org/threejs/resources/images/wall.jpg'; const material = new THREE.MeshBasicMaterial({ map: texture, }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); cubes.push(cube); // add to our list of cubes to rotate 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; } function render(time) { time *= 0.001; if (resizeRendererToDisplaySize(renderer)) { const canvas = renderer.domElement; camera.aspect = canvas.clientWidth / canvas.clientHeight; camera.updateProjectionMatrix(); } cubes.forEach((cube, ndx) => { const speed = .2 + ndx * .1; const rot = time * speed; cube.rotation.x = rot; cube.rotation.y = rot; }); renderer.render(scene, camera); requestAnimationFrame(render); } requestAnimationFrame(render); } main();
body { margin: 0; } #c { width: 100vw; height: 100vh; display: block; }
<script src="https://threejsfundamentals.org/threejs/resources/threejs/r112/build/three.min.js"></script><canvas id="c"></canvas>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.