3

I made a rounded corner plane by merging circle and plane geometries.

The rendered version with a flat color works well, but the textured gets chopped up.

http://jsfiddle.net/28usyw12/

I suspect I have to somehow add some hinting or define how the texture should be rendered, but I don't really know how.

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()
genpfault
  • 51,148
  • 11
  • 85
  • 139
Koen Bok
  • 3,234
  • 3
  • 29
  • 42

1 Answers1

5

You'll need to fix the UV coordinates of each face in the mesh. UV Coordinates are what tells GL how to map the image onto the face. The top left corner should have UV Coordinate (0,0) and the bottom right should have (1,1).

One solution is to just iterate through each face and give it the normalized UV coordinates based on it's position in space, which could work for a simple example like yours. You basically calculate the bounding box of your shape to normalize the vertex coordinates, then create 3 UV Coordinates for each face (since each face is a triangle).

Try this: 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

based off the code found THREE.js generate UV coordinate

If you're familiar at all with blender or other 3d software, you can also create and map the mesh there then import it and not deal with this.

Community
  • 1
  • 1
msfeldstein
  • 1,080
  • 1
  • 9
  • 18