如何在反应三纤维中生成水



我想用水创建3D场景,就像本例中的three.js着色器海洋或水一样,但我必须在react三纤维库中创建。我已经在网上搜索了一些很好的例子,但没有结果。

我可以请求帮助来弄清楚如何将上述示例实现为react三纤维方法吗?

以下是到目前为止我对metied Water组件的了解:

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 ;

由于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;

谢谢大家!这帮了很大的忙。。。

要想让它与其他版本的你一起工作,仍然有一些困难,所以添加我所做的更改,以防它们可以帮助其他人:

useFrame((state, delta) => {
const material = ref?.current?.material as THREE.ShaderMaterial;
material.uniforms.time.value += delta;
})

以防止对象可能为"null"错误。

声明了一个命名空间接口,因为小写的"water"在其他情况下确实不起作用:

extend({ Water });
declare global {
namespace JSX {
interface IntrinsicElements {
water: Object3DNode<Water, typeof Water>
}
}
}

最后。。。如果你的上方向向量是Z轴,而不是默认的Y轴,你会得到奇怪的结果,所以要注意对象的旋转。

相关内容

  • 没有找到相关文章

最新更新