I'd say using three.js for this task is a bit too much. A plain HTML <canvas>
element in conjunction with it's drawing methods will do it just right.
Nevertheless - out of the box the CanvasRenderingContext2d
does not have a built-in method to round corners. This is something that has to be done using a bit of trigonometry.
To get a better picture let's say we have a triangle with the points:
A=(50,50) ; B=(250,100) ; C=(50,350)
This is not an equilateral triangle but the concept applies to any triangle of course.
On screen this will resemble a shape like this:

If we think about it, to have a rounded corner at point B, there must be a curve going somewhere from side c, through point B to side a. But where?
Let's overlay a green circle of radius 20 at point B.

We can see that the intersection of the circle with side c and side a should be the start and respectively the end point of the curve. As the radius is 20, we need to travel 20 pixels from point B in the direction of point A and likewise 20 pixels from point B in direction of point C. The direction is given by the angle in between two particular points and can be obtained using the Math.atan2(pointB.x-pointA.x, pointB.y-pointA.y)
method.
If we calculate those two points - and repeat the process for the remaining two vertices of the triangle - and draw the curves using the bezierCurveTo()
method we finally have rounded corners.

That's it for the first part of your question.
To give the outlines of the triangle a glowing look, we can use the built-in filter effects. A blur()
filter mimics a glow just fine. The repeating pattern of the triangle in the background isn't that hard to do either. A closed shape on the canvas can be filled by a custom pattern, created using the createPattern()
method. All we need to do is draw a seamless tile with a black circle in the middle. To do this we can create a temporary <canvas>
element of equal width and height using document.createElement("canvas")
and draw a circle using the arc()
method.
Here is the complete example:
let triangle = {
a: {
x: 50,
y: 50
},
b: {
x: 250,
y: 100
},
c: {
x: 50,
y: 350
}
};
let canvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d");
let cornerRadius = 60;
let corners = [
[triangle.a, triangle.b, triangle.c],
[triangle.b, triangle.c, triangle.a],
[triangle.c, triangle.a, triangle.b]
]
function drawTriangle(offsetX = 0, offsetY = 0) {
ctx.beginPath();
let angle, corner, pA, pB;
let segments = [];
for (let a = 0; a < corners.length; a++) {
corner = corners[a];
angle = Math.atan2(corner[1].x - corner[0].x, corner[1].y - corner[0].y) + Math.PI;
pA = {
x: corner[1].x + offsetX + Math.sin(angle) * cornerRadius,
y: corner[1].y + offsetY + Math.cos(angle) * cornerRadius
}
angle = Math.atan2(corner[1].x - corner[2].x, corner[1].y - corner[2].y) + Math.PI;
pB = {
x: corner[1].x + offsetX + Math.sin(angle) * cornerRadius,
y: corner[1].y + offsetY + Math.cos(angle) * cornerRadius
};
segments.push(pA)
segments.push({
x: corner[1].x + offsetX,
y: corner[1].y + offsetY
});
segments.push(pB);
}
let temp;
ctx.moveTo(segments[0].x, segments[0].y);
for (let a = 0; a < segments.length; a += 3) {
temp = a + 3 == segments.length ? 0 : a + 3;
ctx.bezierCurveTo(segments[a + 1].x, segments[a + 1].y, segments[a + 1].x, segments[a + 1].y, segments[a + 2].x, segments[a + 2].y);
ctx.lineTo(segments[temp].x, segments[temp].y);
}
ctx.closePath();
}
function createPattern() {
let tempCanvas = document.createElement("canvas");
let tempContext = tempCanvas.getContext("2d");
let radius = 3;
tempCanvas.width = 12;
tempCanvas.height = 12;
tempContext.beginPath();
tempContext.arc(tempCanvas.width / 2, tempCanvas.height / 2, radius, 0, 2 * Math.PI);
tempContext.fill();
tempContext.closePath();
return ctx.createPattern(tempCanvas, 'repeat');
}
let rad = 0;
let radius = 25;
let fillPattern = createPattern();
function animate() {
ctx.fillStyle = "#ecebcc";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = fillPattern;
ctx.save();
ctx.translate(Math.sin(rad) * radius, Math.cos(rad) * radius);
drawTriangle();
ctx.fill();
ctx.restore();
ctx.lineWidth = 7;
ctx.strokeStyle = "#378f43"
ctx.filter = "blur(10px)";
drawTriangle();
ctx.stroke();
ctx.filter = "none";
ctx.lineWidth = 1;
drawTriangle();
ctx.stroke();
rad += Math.PI / 180;
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
<canvas id="canvas" width="400" height="400"></canvas>