@react-three/fiber绘制自定义顶点

3

我正在尝试使用@react-three/fiber在bufferGeometry上绘制自定义网格。我看过无数教程,教授如何绘制点、球体、盒子和线条。但我无法弄清楚如何绘制自定义网格,并且由于我使用的是具有不同语法的react,阅读three.js文档很困难。有人能帮帮我吗?我只想做一些像两个或更多三角形的事情:

const vertices = [ 
    0.0, 0.0, 0.0,
    1.0, 0.0, 0.0,
    0.0, 0.0, 1.0,

    1.0, 0.0, 0.0,
    0.0, 0.0, 1.0,
    1.0, 0.0, 1.0,

    ...
];

return (
    <mesh>
      <bufferGeometry ???>
        <bufferAttribute ??? />
      </bufferGeometry>
      <meshLambertMaterial attach="material" color="hotpink" />
    </mesh>
);

我手头的数据也可以生成指数,如果这是更好的解决方案的话。
2个回答

2
在最新版本中有一些不同:
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 attach="geometry">
        <bufferAttribute attach="attributes-position" array={vertices} itemSize={3} count={6} />
      </bufferGeometry>
      <meshBasicMaterial attach="material" color="hotpink" />
    </mesh>
  );

1

受到react-three-fiber中自定义BufferGeometry评论的启发,我找到了答案:

const vertices = new Float32Array([
  0.0, 0.0,  0.0,
  1.0, 0.0,  0.0,
  0.0, 1.0,  0.0,
    
  1.0, 0.0,  0.0,
  1.0, 1.0,  0.0,
  0.0, 1.0,  0.0
]);

return (
  <mesh>
    <bufferGeometry>
      <bufferAttribute
        attachObject={["attributes", "position"]}
        array={vertices}
        itemSize={3}
        count={6}
      />
    </bufferGeometry>
    <meshStandardMaterial attach="material" color="hotpink" flatShading={true} />
  </mesh>
)

我注意到three.js只有在法线(来自著名的右手定则)指向屏幕外时才显示表面。因此,以下内容将不会被显示

const vertices = new Float32Array([
  0.0, 0.0,  0.0,
  0.0, 1.0,  0.0,
  1.0, 0.0,  0.0,
    
  1.0, 0.0,  0.0,
  0.0, 1.0,  0.0,
  1.0, 1.0,  0.0
]);

更高级的用法需要自定义着色器。Uniforms 和 attributes 允许用户传递对象的颜色(uniform)或顶点的颜色(attribute)。但是,需要更多的包才能编写 glsl 的自定义着色器。以下是使用 attributes 传递颜色并使用 varying 插值颜色的示例。

/**
 * Documentation: https://threejs.org/docs/#api/en/renderers/webgl/WebGLProgram
 * 
 * default vertex attributes provided by Geometry and BufferGeometry
 * attribute vec3 position;
 * attribute vec3 normal;
 * attribute vec2 uv;
 */

import React from 'react';
import { extend } from "@react-three/fiber";
import { shaderMaterial } from '@react-three/drei';
import * as THREE from 'three';
import glsl from 'babel-plugin-glsl/macro';

export default function Square() {
    const vertices = new Float32Array([
      0.0, 0.0,  0.0,
      1.0, 0.0,  0.0,
      0.0, 1.0,  0.0,
        
      1.0, 0.0,  0.0,
      1.0, 1.0,  0.0,
      0.0, 1.0,  0.0
    ]);

    const colors = new Float32Array([
      1.0, 0.0, 0.0,
      0.0, 1.0, 0.0,
      0.0, 0.0, 1.0,

      1.0, 0.0, 0.0,
      0.0, 1.0, 0.0,
      0.0, 0.0, 1.0,
    ]);

    // shaderMaterial's name must be <Something>ShaderMaterial
    // use extend below to add it to shader component
    // The component's first letter need to be uppercase when defined but lowercase when called.
    const SquareShaderMaterial = shaderMaterial(
        // Uniform -> Allow to pass data in object level from react component to glsl
        {
            uColor: new THREE.Color(0.0, 0.0, 1.0)
        },
        // Vertex Shader -> Corner points of polygons
        glsl`
            attribute vec3 color;
            varying lowp vec3 vColor;
            void main() {
                gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
                vColor = color;
            }
        `,
        // Fragment Shader -> Color the polygon surface
        glsl`
            uniform vec3 uColor;
            varying lowp vec3 vColor;
            void main() {
                gl_FragColor = vec4(vColor, 1.0); // modify to uColor if using uniform
            }
        `
    );
      
    extend({ SquareShaderMaterial });
    
    return (
      <mesh>
        <bufferGeometry>
          <bufferAttribute
            attachObject={["attributes", "position"]}
            array={vertices}
            itemSize={3}
            count={6}
          />
          <bufferAttribute
            attachObject={["attributes", "color"]}
            array={colors}
            itemSize={3}
            count={6}
          />
        </bufferGeometry>
        <squareShaderMaterial uColor="hotpink"/>
        
      </mesh>
    );
}

The result is the following:

React three fiber custom shader 101


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