3

I should start off by saying I'm new to WebGL and the THREE library. I'm trying to achieve:

  • Add 2D shapes to a scene (squares, triangles, circles etc)
  • Shapes can have any size and position
  • Shapes should have no fill and an outline that scales depending on the shape size

I tried using wireframe:

const geometry = new THREE.BoxGeometry(40, 40, 0);

const material = new THREE.MeshBasicMaterial({
  color: 0xff0000,
  wireframe: true,
});

const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

The above renders the following:

  • A 3D box with no depth
  • A non-scalable outline with a set width of 1
  • A cross through the box

I also tried the same but plotting the points for a 2D shape:

const shapeSize = 100;
const x = -shapeSize / 2;
const y = -shapeSize / 2;

const square = new THREE.Shape();

square.moveTo(x, y);
square.lineTo(x + shapeSize, y);
square.lineTo(x + shapeSize, y + shapeSize);
square.lineTo(x, y + shapeSize);
square.lineTo(x, y);

const geometry = new THREE.ShapeGeometry(square);

const material = new THREE.MeshBasicMaterial({
  color: 0xff0000,
  wireframe: true,
});

const mesh = new THREE.Mesh(geometry, material);
this.scene.add(mesh);

The above renders:

  • A 2D box
  • A non-scalable outline with a set width of 1
  • A single diagonal line through the box

Can anyone demonstrate how to achieve the scalable outline of just the 2D shape? Do I need to use a shader?

6
  • I read this but i don't understand what you want. Could you illustrate this with an image? Commented Nov 1, 2018 at 10:00
  • @pailhead Literally just a hollow box with an outline. Or a hollow circle with an outline. Wireframe is always a width of 1, but I want an outline that corresponds to the size of the shape. I can create a graphic if it's still not clear. Commented Nov 1, 2018 at 10:05
  • Looks like he needs to combine something like this with that. Commented Nov 1, 2018 at 10:05
  • @prisoner849 Yeah potentially. Fat lines would do it. Are you able to provide an answer with an example of how this would be done? Commented Nov 1, 2018 at 10:07
  • 1
    Based on your description that you're making a 2D image and given your requirements of outlines it seems like you'd be better off using canvas 2d. Commented Nov 1, 2018 at 17:58

1 Answer 1

2

I've just used the code from the example of fat lines:

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 0, 10);
renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setClearColor(0x000000, 0.0);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

var controls = new THREE.OrbitControls(camera, renderer.domElement);

var points = [
  -5, 4, 0, 5, 4, 0, 5, -4, 0, -5, -4, 0, -5, 4, 0
]

var geometry = new THREE.LineGeometry();
geometry.setPositions(points);

matLine = new THREE.LineMaterial({

  color: 0x00ffff,
  linewidth: 5, // in pixels
  dashed: false

});

line = new THREE.Line2(geometry, matLine);
line.computeLineDistances();
line.scale.set(1, 1, 1);
scene.add(line);

render();

function render() {
  requestAnimationFrame(render);
  matLine.resolution.set(window.innerWidth, window.innerHeight);
  renderer.render(scene, camera);
}
body {
  overflow: hidden;
  margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

<script src="https://threejs.org/examples/js/WebGL.js"></script>

<script src='https://threejs.org/examples/js/lines/LineSegmentsGeometry.js'></script>
<script src='https://threejs.org/examples/js/lines/LineGeometry.js'></script>

<script src='https://threejs.org/examples/js/lines/LineMaterial.js'></script>

<script src='https://threejs.org/examples/js/lines/LineSegments2.js'></script>
<script src='https://threejs.org/examples/js/lines/Line2.js'></script>
<script src='https://threejs.org/examples/js/lines/Wireframe.js'></script>

Sign up to request clarification or add additional context in comments.

4 Comments

Really appreciate your help but as I said I'm new to WebGL and Three.js and this answer looks like it needs substantial reverse engineering for me to understand and use it since you're importing 9 external scripts. Would you be able to post a more concise example?
@Coop I haven't used this type of lines before, so I'm not an expert in it. Original example uses more than 9 external scripts :) If it is not what you're looking for, I will delete my answer.
The result is visually pretty much what I'm after. But due to the nature of this answer being split over 9 complicated external scripts, I'm unable to get this working in my scenario...
This type of lines is not a part of the core of the framework. That's why there are so many external scripts :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.