4

I want to make a custom geometry using react-three-fiber. I am new to three.js and at first completed this great tutorial: https://threejsfundamentals.org/threejs/lessons/threejs-custom-buffergeometry.html All went well, but then I decided to fascilitate my app with react. I couldn't figure out how to declaratively create a custom shape. All I found on the official API was:

<bufferGeometry attach="geometry">
  <bufferAttribute attachObject={['attributes', 'position']} count={v.length / 3} array={v} itemSize={3} />

So I tried it with the basic example from here: https://threejs.org/docs/#api/en/core/BufferGeometry

const vertices = new Float32Array( [
    -1.0, -1.0,  1.0,
     1.0, -1.0,  1.0,
     1.0,  1.0,  1.0,

     1.0,  1.0,  1.0,
    -1.0,  1.0,  1.0,
    -1.0, -1.0,  1.0
] );

The above code is located inside a custom functional component, which is put on the canvas. The return statement looks like this:

  return (
    <mesh>
      <bufferGeometry>
        <bufferAttribute
          attachObject={["attributes", "position"]}
          array={vertices}
          itemSize={3}
        />
      </bufferGeometry>
      <meshNormalMaterial />
    </mesh>
  );

But nothing displays. How do you create custom geometry from arrays of coordinates and normals using react-three-fiber?

5
  • 2
    The same as in three, you can either sick plain new buffergeom() into useState/use memo or create it declaratively like you did. I think the count prop is missing though. Commented May 16, 2021 at 12:36
  • Yes you are right, I forgot to add count prop. And another mistake was not converting another my testing array of positions to Float32Array. But I got another question. If I provide my own set of normals, all is fine. But how do you call geometry.computeVertexNormals() when working declaratively? Commented May 16, 2021 at 17:52
  • 1
    this is a side-effect. in react everything is managed. you would put a ref onto the mesh or geom and then call it inside useLayoutEffect. Layout because this one allows you to mutate before it actually renders on screen. useEffect would trigger afterwards. Commented May 16, 2021 at 18:35
  • hpalu, thank you, it helped Commented May 17, 2021 at 20:23
  • Hello....Cloud hpalu or agt-ru share a code snippet or a clodepen example on creating a custom shape by using vertex and joining lines by react-three-fiber. Also, how one can select the shape using a mouse? Im absolutely new to three-fiber and learning from you guyes.... Alternate, please provide a link where I can see this as a Demo.... Commented Jul 2, 2021 at 19:24

1 Answer 1

0

I think you're very close, it could be that it didn't work because the indices are missing.

Also attachObject is deprecated in favour of attach='attributes-position' etc.

Here's a simple example:

import React from 'react'
import { DoubleSide } from 'three'

const positions = new Float32Array([
    1, 0, 0,
    0, 1, 0,
    -1, 0, 0,
    0, -1, 0
])

const normals = new Float32Array([
    0, 0, 1,
    0, 0, 1,
    0, 0, 1,
    0, 0, 1,
])

const colors = new Float32Array([
    0, 1, 1, 1,
    1, 0, 1, 1,
    1, 1, 0, 1,
    1, 1, 1, 1,
])

const indices = new Uint16Array([
    0, 1, 3,
    2, 3, 1,
])

const Comp = () =>
    <mesh>
        <bufferGeometry>
            <bufferAttribute
                attach='attributes-position'
                array={positions}
                count={positions.length / 3}
                itemSize={3}
            />
            <bufferAttribute
                attach='attributes-color'
                array={colors}
                count={colors.length / 3}
                itemSize={3}
            />
            <bufferAttribute
                attach='attributes-normal'
                array={normals}
                count={normals.length / 3}
                itemSize={3}
            />
            <bufferAttribute
                attach="index"
                array={indices}
                count={indices.length}
                itemSize={1}
            />
        </bufferGeometry>
        <meshStandardMaterial
            vertexColors
            side={DoubleSide}
        />
    </mesh>


For extra reading this tutorial covers animating attributes.

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

Comments

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.