首页 > 解决方案 > 如何在反应三纤维中产生水

问题描述

我想用水创建 3D 场景,就像在这个示例中一样,three.js 着色器海洋,但我必须在 react-three-fiber 库中创建它。我已经在互联网上搜索了这个案例的一些很好的工作示例,但没有结果。

我可以寻求帮助以弄清楚如何将上述示例实施到 react-three-fiber 方法中吗?

这是我迄今为止提到的水成分:

import React from "react";
import waterNormal from "./waternormals.jpg";
//import { useLoader } from "react-three-fiber";
import * as THREE from "three";

import { Water } from "three/examples/jsm/objects/Water.js";

const WaterObject = () => {
  //const mapNormalWater = useLoader(TextureLoader, waterNormal);

  return (
    <mesh>
      <planeBufferGeometry attach="geometry" args={[100, 100]} />
      <Water
        options={{
          textureWidth: 512,
          textureHeight: 512,
          waterNormals: new THREE.TextureLoader().load(
            waterNormal,
            function (texture) {
              texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
            }
          ),
          sunDirection: new THREE.Vector3(),
          sunColor: 0xffffff,
          waterColor: 0x001e0f,
          distortionScale: 3.7,
          // fog: scene.fog !== undefined
        }}
      ></Water>
    </mesh>
  );
};

export default WaterObject ;

标签: javascriptreactjsthree.jsshaderreact-three-fiber

解决方案


感谢hpalu解决了。

下面是可以在画布组件中导入和使用的组件的代码。

import React, { useRef, useMemo } from "react";
import { extend, useThree, useLoader, useFrame } from "@react-three/fiber";
import * as THREE from "three";

import { Water } from "three/examples/jsm/objects/Water.js";

extend({ Water });

function Ocean() {
  const ref = useRef();
  const gl = useThree((state) => state.gl);
  const waterNormals = useLoader(
    THREE.TextureLoader, "https://raw.githubusercontent.com/mrdoob/three.js/master/examples/textures/waternormals.jpg"
  );


  waterNormals.wrapS = waterNormals.wrapT = THREE.RepeatWrapping;
  const geom = useMemo(() => new THREE.PlaneGeometry(30000, 30000), []);
  const config = useMemo(
    () => ({
      textureWidth: 512,
      textureHeight: 512,
      waterNormals,
      sunDirection: new THREE.Vector3(),
      sunColor: 0xeb8934,
      waterColor: 0x0064b5,
      distortionScale: 40,
      fog: false,
      format: gl.encoding,
    }),
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [waterNormals]
  );
  useFrame(
    (state, delta) => (ref.current.material.uniforms.time.value += delta)
  );
  return (
    <water
      ref={ref}
      args={[geom, config]}
      rotation-x={-Math.PI / 2}
      position={[0, 0, 0]}
    />
  );
}

export default Ocean;

推荐阅读