2017-04-15 90 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