How can I create a cube with complete beveling using Three.js?

I'm struggling to create a beveled cube in my project. I have come across the THREE.ExtrudeGeometry snippet in the documentation here. However, when I tried it out, I only managed to achieve beveled sides on the top and bottom faces like this:

https://i.sstatic.net/b6Bpk.png

What I really want is something like this instead:

https://i.sstatic.net/yW3QZ.png

This is my current code:

        var bevelShape = new THREE.Shape();
        bevelShape.moveTo(0, unitSize - 0.2);
        bevelShape.lineTo(0, unitSize - 0.2);
        bevelShape.lineTo(unitSize - 0.2, unitSize - 0.2);
        bevelShape.lineTo(unitSize - 0.2, 0);
        bevelShape.lineTo(0, 0);

        var extrudeSettings = {
            steps: 20,
            depth: unitSize - 0.2,
            bevelEnabled: true,
            bevelThickness: 0.1,
            bevelSize: 0.1,
            bevelOffset: 0,
            bevelSegments: 1
        };

        var blockGeometry = new THREE.ExtrudeGeometry(bevelShape, extrudeSettings);
        var blockMaterial = new THREE.MeshStandardMaterial({color: color, roughness: 1, metalness: -1});
        var block = new THREE.Mesh(blockGeometry, blockMaterial);
        scene.add(block);

How can I modify this to achieve the desired look?

Any help would be greatly appreciated!

Answer №1

If you're feeling creative, why not try your hand at creating your own geometric shapes?

Alternatively, browse through the forum for a plethora of helpful and fascinating resources.

Here's an example to get you started:

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, 1, 1, 1000);
camera.position.set(15, 10, 20).setLength(130);
var renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setClearColor(0x404040);
//renderer.setPixelRatio(0.5);
var canvas = renderer.domElement;
document.body.appendChild(canvas);

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

var light = new THREE.DirectionalLight(0xffffff, 0.5);
light.position.set(1, 2, 1);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, 0.5));

for (let i = 0; i < 11; i++) {
  let r = 10;
  let posX = (-5 + i) * 12.5;
  let wireGeom = facetedBox(r, r, r, i * 0.5, true);
  let wire = new THREE.LineSegments(
    wireGeom,
    new THREE.LineBasicMaterial({ color: Math.random() * 0x808080 + 0x808080 })
  );
  wire.position.x = posX;
  scene.add(wire);

  let geom = facetedBox(r, r, r, i * 0.5, false);
  let mesh = new THREE.Mesh(
    geom,
    new THREE.MeshStandardMaterial({
      color: Math.random() * 0x808080 + 0x808080,
      flatShading: true
    })
  );
  mesh.position.x = posX;
  scene.add(mesh);
}

var clock = new THREE.Clock();

renderer.setAnimationLoop(() => {
  if (resize(renderer)) {
    camera.aspect = canvas.clientWidth / canvas.clientHeight;
    camera.updateProjectionMatrix();
  }

  renderer.render(scene, camera);
});

function resize(renderer) {
  const canvas = renderer.domElement;
  const width = canvas.clientWidth;
  const height = canvas.clientHeight;
  const needResize = canvas.width !== width || canvas.height !== height;
  if (needResize) {
    renderer.setSize(width, height, false);
  }
  return needResize;
}
html, body {
  height: 100%;
  margin: 0;
  overflow: hidden;
}
canvas {
  width: 100%;
  height: 100%;
  display; block;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script>
  function facetedBox(w, h, d, f, isWireframed){
    let hw = w * 0.5, hh = h * 0.5, hd = d * 0.5;
    let vertices = [
      // px
      hw, hh - f, -hd + f,   // 0
      hw, -hh + f, -hd + f,  // 1
      hw, -hh + f, hd - f,   // 2
      hw, hh - f, hd - f,    // 3
      
      // pz
      hw - f, hh - f, hd,    // 4
      hw - f, -hh + f, hd,   // 5
      -hw + f, -hh + f, hd,  // 6
      -hw + f, hh - f, hd,   // 7
      
      // nx
      -hw, hh - f, hd - f,   // 8
      -hw, -hh + f, hd - f,  // 9
      -hw, -hh + f, -hd + f, // 10
      -hw, hh - f, -hd + f,  // 11
      
      // nz
      -hw + f, hh - f, -hd,  // 12
      -hw + f, -hh + f, -hd, // 13
      hw - f, -hh + f, -hd,  // 14
      hw - f, hh - f, -hd,   // 15
      
      // py
      hw - f, hh, -hd + f,   // 16
      hw - f, hh, hd - f,    // 17
      -hw + f, hh, hd - f,   // 18
      -hw + f, hh, -hd + f,  // 19
      
      // ny
      hw - f, -hh, -hd + f,  // 20
      hw - f, -hh, hd - f,   // 21
      -hw + f, -hh, hd - f,  // 22
      -hw + f, -hh, -hd + f  // 23
    ];
    
    let indices = [
      0, 2, 1, 3, 2, 0,
      4, 6, 5, 7, 6, 4,
      8, 10, 9, 11, 10, 8,
      12, 14, 13, 15, 14, 12,
      16, 18, 17, 19, 18, 16,
      20, 21, 22, 23, 20, 22,
      
      // link the sides
      3, 5, 2, 4, 5, 3,
      7, 9, 6, 8, 9, 7,
      11, 13, 10, 12, 13, 11,
      15, 1, 14, 0, 1, 15,
      
      // link the lids
      // top
      16, 3, 0, 17, 3, 16,
      17, 7, 4, 18, 7, 17,
      18, 11, 8, 19, 11, 18,
      19, 15, 12, 16, 15, 19,
      // bottom
      1, 21, 20, 2, 21, 1,
      5, 22, 21, 6, 22, 5,
      9, 23, 22, 10, 23, 9,
      13, 20, 23, 14, 20, 13,
      
      // corners
      // top
      3, 17, 4,
      7, 18, 8,
      11, 19, 12,
      15, 16, 0,
      // bottom
      2, 5, 21,
      6, 9, 22,
      10, 13, 23,
      14, 1, 20
    ];
    
    let indicesWire = [
      0, 1, 1, 2, 2, 3, 3, 0,
      4, 5, 5, 6, 6, 7, 7, 4,
      8, 9, 9, 10, 10, 11, 11, 8,
      12, 13, 13, 14, 14, 15, 15, 12,
      16, 17, 17, 18, 18, 19, 19, 16,
      20, 21, 21, 22, 22, 23, 23, 20,
      // link the sides
      2, 5, 3, 4,     //px - pz
      6, 9, 7, 8,     // pz - nx
      10, 13, 11, 12, // nx - nz
      15, 0, 14, 1,   // nz - px
      
      // link the lids
      // top
      16, 0, 17, 3,   // px
      17, 4, 18, 7,   // pz
      18, 8, 19, 11,  // nx
      19, 12, 16, 15,  // nz
      // bottom
      20, 1, 21, 2,
      21, 5, 22, 6,
      22, 9, 23, 10,
      23, 13, 20, 14
    ];
    
    let geom = new THREE.BufferGeometry();
    geom.setAttribute("position", new THREE.BufferAttribute(new Float32Array(vertices), 3));
    geom.setIndex(isWireframed ? indicesWire : indices);
    if (!isWireframed) geom.computeVertexNormals();
    return geom;
  }
</script>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Angular foreach method encounters a syntax issue

When I use the getTotal.getValues() function to make a server call that returns values like "one", "two", "three" up to "nine", I am able to print them using console.log(res). However, I am facing an issue where I cannot push these returned values into t ...

Problem Installing Express Sharp using Docker

When deploying via Docker, I encountered an error with sharp, even though it works fine on my workspace. I followed all the steps but still faced issues. Error: 'linux-x64' binaries cannot be used on the 'linuxmusl-x64' platform. P ...

Vuex has reserved this keyword

I am working on a Laravel application with the following code in app.js: require('./bootstrap'); window.Vue = require('vue'); import { store } from './store/store' import Sidebar from './Sidebar' Vue.component(& ...

Filtering incoming data from a Firestore database: A step-by-step guide

I'm facing a challenge while trying to incorporate this filtering mechanism into my code. FILTERING An issue arises when I attempt to implement the following lines of code: function search(text: string, pipe: PipeTransform): Country[] { return CO ...

What is the best way to locate the Vue component I need to share data with?

Seeking guidance on structuring my Vue app. It features an interactive map where users can click on items, triggering a side panel to display related information. The side panel is enclosed in a new Vue(...) instance (perhaps referred to as a Vue component ...

Troubleshooting React/Jest issues with updating values in Select elements on onChange event

I am currently testing the Select element's value after it has been changed with the following code: it("changes value after selecting another field", () => { doSetupWork(); let field = screen.getByLabelText("MySelectField") ...

Creating a PDF document using html2pdf: A step-by-step guide

Currently, I am immersed in a project using React. The main goal right now is to dynamically generate a PDF file (invoice) and then securely upload it to Google Drive. In the snippet of code provided below, you can see how I attempted to create the PDF f ...

Failure to execute the success function

My current issue involves making an AJAX call to retrieve a record from the database. Despite console logs showing that the record is successfully returned, the success function fails to execute. function ajaxForParent() { var search = document.getEle ...

Is there a way to display "not found" if the code's output is blank?

Incorporating an "ajax select" and "while scrolling load data" script has been successful for me. However, I'm struggling with displaying a "not found data" message in div.status when the output variable on animals.php is empty. index.html <!DOCT ...

Determining html column values using a related column and user input

Is there a way to populate an HTML table column (using Javascript or jQuery) based on the values in another column and an input field? For instance, if I input the number 115 into the field, then the advance column should display a value of 1 for each ath ...

Updating documents in a mongoDB collection can be done by simply

I require an update to my database that will modify existing data, as illustrated below: existing data => [{_id:"abnc214124",name:"mustafa",age:12,etc...}, {_id:"abnc21412432",name:"mustafa1",age:32,etc...}, {_id ...

Issues with Node.js routes on the express server aren't functioning as expected

I used to have a node.js express server up and running on my previous server. However, after migrating to a new server, the code seems to have stopped functioning. Let me share the setup of my server: var fs = require('fs'); var express = requi ...

Is there a way to save a base64 image to an excel file?

I need assistance with exporting Excel Charts from NVd3 using Angularjs. Here is the code I have been trying: (jsfiddle) <button id="myButtonControlID">Export Table data into Excel</button> <div id="divTableDataHolder"> <table> ...

Is it more advantageous in Vue to pre-process and save data directly to the data property, or to utilize computed properties?

I am interested in hearing diverse perspectives on this topic. When working with Vue (and possibly other frameworks), is it more beneficial to prepare non-reactive data through a method and store it in the data for use in the template, or is it preferable ...

Making modifications to the database will trigger real-time updates in the web interface. How is it possible to achieve this seamlessly?

Can someone please help me understand how to automatically insert news or new events from a Facebook page as an event in a webpage? I am a programmer and currently, the data is retrieved from the database using AJAX without reloading the page. However, I ...

Tips for handling datetime in angular

Currently, I am working with Angular (v5) and facing an issue related to Datetime manipulation. I am trying to retrieve the current time and store it in a variable. After that, I need to subtract a specified number of hours (either 8 hours or just 1 hour) ...

Using the jQuery.grep() method to sort through data

I have been attempting to filter data that is stored in a .js file using the jQuery.grep() method, but unfortunately, the data is not loading as expected. Data var myData = { "type": "FeatureCollection", "crs": { "type": "name", "properties": {"name": ur ...

What is the best way to retrieve an ID from a select multiple using Element?

I am working on a select element for assigning persons to a project. My goal is to send the ID of the selected person object to a specific function. Here is what I have tried so far: <el-form-item label="Assign to:" prop="person"> & ...

Ways to integrate npm dependencies into your Cordova plugin

Currently working on implementing a Cordova plugin called core-cordova found in this repository. This particular plugin has a dependency on another NPM package. The issue arises after installing the plugin in my app using: $ cordova plugin add @aerogears ...

Creating dynamic visual elements on a webpage using HTML: Video

As I continue to learn HTML, CSS, and JavaScript to create a basic website for educational purposes, I have successfully embedded a video stored in my drive using the video element on an HTML page. However, I now aim to also display the video's title, ...