在react-three-fiber中创建自定义BufferGeometry

3

我想使用react-three-fiber制作自定义几何体。 我刚接触three.js,最初完成了这个很棒的教程:https://threejsfundamentals.org/threejs/lessons/threejs-custom-buffergeometry.html 一切都进展顺利,但后来我决定使用react改善我的应用程序。 我无法找到如何声明式地创建自定义形状。 在官方API中,我找到了以下内容:

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

我尝试使用这个基本示例: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
] );

以上代码位于自定义函数组件内,该组件被放置在画布上。返回语句如下:

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

但是没有任何东西显示出来。 如何使用react-three-fiber从坐标和法线数组创建自定义几何体?


2
和第三个例子一样,你可以将 new BufferGeometry() 直接放入 useStateuseMemo 中,也可以像之前那样声明式地创建它。不过我觉得缺少了 count 属性。 - hpalu
是的,你说得对,我忘记添加 count 属性了。 还有一个错误是没有将我另一个测试位置数组转换为 Float32Array。 但我有另一个问题。 如果我提供自己的法向量集,一切都很好。 但在声明式工作时如何调用 geometry.computeVertexNormals() - agt-ru
1
这是一个副作用。在React中,一切都是被管理的。你可以将ref放到网格或几何体上,然后在useLayoutEffect内调用它。使用LayoutEffect是因为它允许您在实际渲染到屏幕之前进行变异。而useEffect会在之后触发。 - hpalu
hpalu,谢谢,它有帮助。 - agt-ru
你好....Cloud hpalu或agtr-ru能分享一个代码片段或者一个codepen示例,演示如何利用react-three-fiber通过顶点和连接线创建自定义形状。并且,如何使用鼠标选择这个形状呢?我刚接触three-fiber,希望从你们这里学习。如果可以的话,请提供一个示例链接以便我查看演示。 - Naresh
1个回答

0

我认为你很接近了,可能是由于缺少索引导致它没有起作用。

此外,attachObject已被弃用,建议使用attach='attributes-position'等替代方案。

这里有一个简单的例子:

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>


如果需要更多阅读材料,这篇教程 介绍了属性动画。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接