2014-09-21 91 views
2

我通過合併圓和平面幾何來製作圓角落地平面。如何在three.js中修復圓角落地平面上的紋理

具有平坦顏色的渲染版本效果很好,但紋理被切碎。

http://jsfiddle.net/28usyw12/

我懷疑我必須以某種方式加入一些提示或定義紋理應該如何呈現,但我真的不知道怎麼辦。

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

WIDTH = HEIGHT = 500 

renderer = new THREE.WebGLRenderer({ antialias: true }); 
renderer.setClearColor(0xffffff); 
renderer.setSize(WIDTH, HEIGHT); 

light = new THREE.PointLight(0xffffff); 
light.position.set(0,0,100); 
scene.add(light); 

# 628 × 697 


camera.position.z = 5; 

document.body.appendChild(renderer.domElement); 


meshA = new THREE.Mesh() 


makeRoundedCornerPlane = (offset=2, radius=2, smooth=16) -> 

    geometry = new THREE.Geometry() 

    offset = (offset - radius)/2 
    radius = radius/4 
    smooth = 16 

    cornerA = new THREE.CircleGeometry(radius, smooth, (Math.PI * 2/4) * 1, Math.PI * 2/4); 
    matrixA = new THREE.Matrix4(); 
    matrixA.makeTranslation(0-offset, 0+offset, 0) 
    geometry.merge(cornerA, matrixA) 

    cornerB = new THREE.CircleGeometry(radius, smooth, (Math.PI * 2/4) * 0, Math.PI * 2/4); 
    matrixB = new THREE.Matrix4(); 
    matrixB.makeTranslation(0+offset, 0+offset, 0) 
    geometry.merge(cornerB, matrixB) 

    cornerC = new THREE.CircleGeometry(radius, smooth, (Math.PI * 2/4) * 3, Math.PI * 2/4); 
    matrixC = new THREE.Matrix4(); 
    matrixC.makeTranslation(0+offset, 0-offset, 0) 
    geometry.merge(cornerC, matrixC) 

    cornerD = new THREE.CircleGeometry(radius, smooth, (Math.PI * 2/4) * 2, Math.PI * 2/4); 
    matrixD = new THREE.Matrix4(); 
    matrixD.makeTranslation(0-offset, 0-offset, 0) 
    geometry.merge(cornerD, matrixD) 

    planeA = new THREE.PlaneGeometry((offset+radius) * 2, offset * 2) 
    geometry.merge(planeA) 

    planeB = new THREE.PlaneGeometry(offset * 2, (offset+radius) * 2) 
    geometry.merge(planeB) 

    return geometry 

meshA.geometry = makeRoundedCornerPlane(2, 0.5) 

meshA.material = new THREE.MeshBasicMaterial 
    side:THREE.DoubleSide 
    color: new THREE.Color("rgb(255,0,0)") 
    #wireframe: true 

meshB = new THREE.Mesh() 
meshB.geometry = makeRoundedCornerPlane(2, 0.5) 

meshB.material = new THREE.MeshBasicMaterial 
    side:THREE.DoubleSide 
    color: new THREE.Color("rgb(255,0,0)") 
    #wireframe: true 

texture = new THREE.ImageUtils.loadTexture("/img/initializing.png"); 
texture.wrapS = texture.wrapT = THREE.RepeatWrapping; 
meshB.material.map = texture 
meshB.material.color = new THREE.Color(0xffffff) 

meshB.position.x = -1 
meshB.position.y = -1 

scene.add(meshA) 
scene.add(meshB) 

update = -> 
    # meshA.scale.x += 0.001 
    # meshA.scale.y += 0.001 
    meshA.rotation.z += 0.002 
    meshA.rotation.y += 0.002 
    meshB.rotation.z += 0.002 
    meshB.rotation.y += 0.002 

render = -> 
    renderer.render(scene, camera) 

tick = -> 
    window.requestAnimationFrame(tick) 
    update() 
    render() 

tick() 

回答

3

您需要修復網格中每個面的UV座標。 UV座標告訴GL如何將圖像映射到臉上。左上角應該有UV座標(0,0),右下角應該有(1,1)。

一個解決方案是迭代通過每個面,並根據它在空間中的位置給它規範化的UV座標,這可以用於像您這樣的簡單示例。你基本上計算你的形狀的邊界框來規範頂點座標,然後爲每個面創建3個UV座標(因爲每個面都是一個三角形)。

試試這個:http://jsfiddle.net/MacroMeez/e84y9bbq/1/

remapUVs = (geo) -> 
geo.computeBoundingBox() 
min = geo.boundingBox.min 
max = geo.boundingBox.max 
offset = new THREE.Vector2(0 - min.x, 0 - min.y) 
size = new THREE.Vector2(max.x - min.x, max.y - min.y) 
# Remove the old UVs that were incorrect 
geo.faceVertexUvs[0] = [] 
for face, i in geo.faces 
    v1 = geo.vertices[face.a] 
    v2 = geo.vertices[face.b] 
    v3 = geo.vertices[face.c] 
    # Push on a new UV based on its position inside the shape 
    geo.faceVertexUvs[0].push [ 
     new THREE.Vector2((v1.x + offset.x)/size.x, (v1.y + offset.y)/size.y), 
     new THREE.Vector2((v2.x + offset.x)/size.x, (v2.y + offset.y)/size.y), 
     new THREE.Vector2((v3.x + offset.x)/size.x, (v3.y + offset.y)/size.y) 
    ] 
geo.uvsNeedUpdate = true 

基於關閉代碼中發現THREE.js generate UV coordinate

如果你熟悉在所有攪拌器或其它3D軟件,你也可以創建和映射網有那麼進口它並沒有處理這一點。