Optimizing normals for unindexed BufferGeometry in Three.js

Currently, I am attempting to refine the normals of a mesh starting from an non indexed BufferGeometry. A similar query has been addressed in the past, however, the Three.js API has undergone significant changes since then and I am unable to make it work on r130

As far as my understanding goes, I need to merge the vertices initially to obtain an indexed BufferGeometry and then recalculate the normals, but unfortunately, it doesn't yield the desired result.

Below is a basic example using the default cube :

    // Scene
    const scene = new THREE.Scene();
    
    // Geometry
    const boxGeometry = new THREE.BoxGeometry(.7,.7,.7);
    
    // Materials
    const shadedMaterial = new THREE.MeshStandardMaterial();
    shadedMaterial.metalness = 0.4;
    shadedMaterial.roughness = 0.4;
    shadedMaterial.color = new THREE.Color(0xffffff);
    
    // Mesh
    const smoothBoxGeometry=BufferGeometryUtils
    .mergeVertices(new THREE.BufferGeometry().copy(boxGeometry))
    smoothBoxGeometry.computeVertexNormals();
    smoothBoxGeometry.computeBoundingBox();
    smoothBoxGeometry.normalizeNormals();
    
    const box = new THREE.Mesh(smoothBoxGeometry, shadedMaterial);
    scene.add(box);

Instead of the expected smooth shaded cube, a flat shaded cube is displayed

What could be the missing piece of the puzzle here?

Answer №1

Give it a shot this way:

let camera, scene, renderer;

let mesh;

init();
animate();

function init() {

  camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10);
  camera.position.z = 4;

  scene = new THREE.Scene();

  const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444);
  hemiLight.position.set(0, 20, 0);
  scene.add(hemiLight);

  const dirLight = new THREE.DirectionalLight(0xffffff);
  dirLight.position.set(-3, 10, -10);
  scene.add(dirLight);

  let geometry = new THREE.BoxGeometry();
  geometry.deleteAttribute('normal');
  geometry.deleteAttribute('uv');
  geometry = THREE.BufferGeometryUtils.mergeVertices(geometry);
  geometry.computeVertexNormals();
  const material = new THREE.MeshStandardMaterial();

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

  renderer = new THREE.WebGLRenderer({
    antialias: true
  });
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

}

function animate() {

  requestAnimationFrame(animate);

  mesh.rotation.x += 0.01;
  mesh.rotation.y += 0.02;

  renderer.render(scene, camera);

}
body {
      margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1e6a766c7b7b5e2e302f2d2e302f">[email protected]</a>/build/three.js"></script>
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0e7a667c6b6b4e3e203f3d3e203f">[email protected]</a>/examples/js/utils/BufferGeometryUtils.js"></script>

BufferGeometryUtils.mergeVertices()
will merge vertices only if their data is identical. To ensure this, it's important to remove the existing normal and uv attribute.

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

What method would you recommend for modifying HTML text that has already been loaded using JSP?

Is there a way to update text on an HTML document without reloading the entire page? I'm looking to create a simple "cart" functionality with 5 links on a page. When a link is clicked, I want it to increment the "items in cart" counter displayed on th ...

Can you include the dollar symbol in the currency format?

I currently have this code that formats numbers into currency format, however I would like to include the dollar sign ($) before the numbers. document.getElementById("numbers").onblur = function (){ this.value = parseFloat(this.value.r ...

Difficulty applying texture to Three.js sides

After creating a mesh by extruding a png image, I used the code reference from . The issue I encountered is that when using a THREE.MeshPhongMaterial with a texture map, the texture only applies to the front and back of the mesh, not the sides. The sides e ...

What is the best practice for naming variables in JavaScript?

Currently, my API is built using PHP Laravel and MySQL, which uses snake_case for field names. I am considering using the same naming convention in client-side JavaScript to make it easier to transfer field names from PHP code to JavaScript code and when m ...

Blip Scripts: Converting JSON to JavaScript - Dealing with Undefined Arrays

I am currently working on a project to develop a bot on Blip. There are certain parts where I need to send a request to an API and then use a JavaScript script to extract elements from the JSON response. The JSON response I received from the API is stored ...

Showing the output variable from node.js on a canvas

Is it possible to display the output of my node.js program, which consists of a series of points (x,y), on canvas without a browser? I came across this module that could potentially help with displaying the points: (https://www.npmjs.com/package/canvas) ...

Craving assistance in coding permutations

Thank you for responding. I want to express my gratitude for your efforts in trying to assist me. Unfortunately, I have posted this problem on multiple websites and no one has been willing to help. Regarding my code, my objective is to count permutations. ...

Using Vue.js, send information from an Ajax request to a Laravel controller for processing

As someone new to development, I have a little confusion with handling data from a multi-step form in an AJAX request on my controller. While I've been able to successfully collect all form inputs at once, I'm struggling to use the data from $req ...

What is the best way to modify the values in an initialized array once the fetchData method has been executed?

As a beginner in Vue.js, I am currently working on a project that involves updating initialized arrays in the data() section of my component using the fetchData method. Below is a simplified version of the code: <script> import axios from 'axi ...

In ReactJS, one can create a variable and include a map function by first declaring the variable and then using the map function within the component. If you

Having trouble integrating the accordian.js page into the app.js main page for compilation. Need help defining and writing out the function correctly, any suggestions? Below is my code: App.js: How do I incorporate the components from the accordian.js pa ...

What is preventing this from functioning properly? (html/javascript)

I need help checking if this code is correct, as I am not very knowledgeable about HTML. I would appreciate it if someone could explain it to me in simple terms so I can understand. Here is the code: <input type="text" id="user" value=""> <inpu ...

Update your mappings for the city of Istanbul when utilizing both TypeScript and Babel

Currently, I am facing the challenge of generating code coverage for my TypeScript project using remap Istanbul. The issue arises due to the usage of async/await in my code, which TypeScript cannot transpile into ES5 directly. To circumvent this limitation ...

How to disable the onChange event in PrimeNG p-dropdown?

I'm currently utilizing PrimeNG's dropdown component. Each option in the list includes an icon that, when clicked, should trigger a specific method. Additionally, I need to execute another method when the onChange event of the dropdown is trigger ...

Updating an array of data in D3

Seeking guidance on implementing the general update pattern in D3... My goal is to create a basic bar chart displaying data from an array, with an input form to add new data and dynamically update the chart. Struggling with repetition while trying to ref ...

FNS Date-Timezone Abbreviation

Is there a way to shorten the Australian Eastern Daylight Time abbreviation to just AEDT? When I use it currently, it displays as 11/11/2022 15:29:25 Australian Eastern Daylight Time. I would like it to show as 11/11/2022 15:29:25 AEDT import { formatInT ...

Tips for assigning unique non-changing keys to siblings in React components

I've been searching for a solution for more than an hour without success. The structure of the data is as follows: const arr = [ { id: 1, title: 'something', tags: ['first', 'second', 'third'] }, { id: 2, t ...

Having difficulty retrieving values while using async-await

Utilizing the code below has been successful for me. I managed to retrieve the data in the spread (then), returning a http200 response. Promise.all([ axios({ method: 'post', url: 'https://oauth2.-arch.mand.com/oauth2/token&a ...

My jquery is malfunctioning when trying to retrieve values

I am facing an issue with accessing server-side values in my jQuery function. When I use my localhost path (NewsRecord.php) as the AJAX URL, it works fine. However, when I use the server path, it does not work. The strange thing is that the server URL pr ...

looking to display the latest status value in a separate component

I am interested in monitoring when a mutation is called and updates a status. I have created a component that displays the count of database table rows when an API call is made. Below is the store I have implemented: const state = { opportunity: "" } ...

What is the best method for effectively organizing and storing DOM elements alongside their related objects?

In order to efficiently handle key input events for multiple textareas on the page, I have decided to create a TextareaState object to cache information related to each textarea. This includes data such as whether changes have been made and the previous co ...