2017-04-15 212 views

回答

5

它看起來像你可以調整紋理的UV膠印

texture.offset.x = someAnimatedValue; 
texture.offset.y = someAnimatedValue; 

,作爲使管道本身,幾乎任何3D建模軟件包(攪拌機,瑪雅,3D工作室最大等...)會讓你extrude a line along a path。所以要讓管子做一個圓,然後沿着路徑擠壓它。同樣,您可以沿同一曲線向下擠壓一條線,從而將牆/柵欄放在管道的中心。默認的UV座標對於滾動是正確的。

const scene = new THREE.Scene(); 
 
const camera = new THREE.PerspectiveCamera(75, 1, 0.1, 1000); 
 

 
const renderer = new THREE.WebGLRenderer(); 
 
document.body.appendChild(renderer.domElement); 
 

 
// make a texture with an arrow 
 
const ctx = document.createElement("canvas").getContext("2d"); 
 
ctx.canvas.width = 64; 
 
ctx.canvas.height = 64; 
 

 
ctx.fillStyle = "rgba(0,0,255,0.5)"; 
 
ctx.fillRect(0, 0, 64, 64); 
 

 
ctx.translate(32, 32); 
 
ctx.rotate(Math.PI * .5); 
 
ctx.fillStyle = "rgb(0,255,255)"; 
 
ctx.textAlign = "center"; 
 
ctx.textBaseline = "middle"; 
 
ctx.font = "48px sans-serif"; 
 
ctx.fillText("➡︎", 0, 0); 
 

 
const texture = new THREE.CanvasTexture(ctx.canvas); 
 
texture.wrapS = THREE.RepeatWrapping; 
 
texture.wrapT = THREE.RepeatWrapping; 
 
texture.repeat.x = 4; 
 
texture.repeat.y = 9; 
 

 
const radiusTop = 1; 
 
const radiusBottom = 1; 
 
const height = 5; 
 
const radiusSegments = 20; 
 
const heightSegments = 2; 
 
const openEnded = true; 
 
const geometry = new THREE.CylinderBufferGeometry( 
 
    radiusTop, radiusBottom, height, radiusSegments, heightSegments, openEnded); 
 
const material = new THREE.MeshBasicMaterial({ 
 
    map: texture, 
 
    side: THREE.DoubleSide, 
 
    depthWrite: false, 
 
    depthTest: false, 
 
    transparent: true, 
 
}); 
 
const mesh = new THREE.Mesh(geometry, material); 
 
scene.add(mesh); 
 
mesh.rotation.z = Math.PI * .5; 
 

 
function render(time) { 
 
    time *= 0.001; 
 
    
 
    resize(); 
 
    
 
    const cameraSpeed = time * 0.3; 
 
    const cameraRadius = 5; 
 
    camera.position.x = Math.cos(cameraSpeed) * cameraRadius; 
 
    camera.position.y = 1; 
 
    camera.position.z = Math.sin(cameraSpeed) * cameraRadius; 
 
    camera.lookAt(mesh.position); 
 
\t 
 
    texture.offset.y = (time * 3 % 1); 
 
    
 
    renderer.render(scene, camera); 
 
\t requestAnimationFrame(render); 
 
} 
 
requestAnimationFrame(render); 
 

 
function resize() { 
 
    const canvas = renderer.domElement; 
 
    const width = canvas.clientWidth; 
 
    const height = canvas.clientHeight; 
 
    if (canvas.width !== width || canvas.height !== height) { 
 
    renderer.setSize(width, height, false); 
 
    camera.aspect = width/height; 
 
    camera.updateProjectionMatrix(); 
 
    } 
 
}
body { margin: 0; } 
 
canvas { width: 100vw; height: 100vh; display: block; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/84/three.min.js"></script>

PS:我懶得對付排序問題,但處理這應該是一個獨立的quesiton