👏
【React Three Fiber】Reactで作る3D【#18Examples Water】
【#18Examples Water】
YouTube:https://youtu.be/Xc-gGDpHTWs
今回は「React-Three-Fiber」の「Examples」から
「Water shader」を実装する方法について解説します。
まずは、「src」->「components」フォルダに
「GeoOcean.tsx」というファイルを作成します。
そして、「codesandbox」の内容をすべてコピーします。
コピーができましたら、
「App」となっているコンポーネント名を「GeoOcean」に変更します。
「React-Three-Fiber」で「water」のタグを使用するためには、
「extend({ Water })」を使用します。
src/components/GeoOcean.tsx
import * as THREE from 'three'
import React, { Suspense, useRef, useMemo } from 'react'
import {
Canvas,
extend,
useThree,
useLoader,
useFrame,
} from '@react-three/fiber'
import { OrbitControls, Sky } from '@react-three/drei'
import { Water } from 'three-stdlib'
extend({ Water })
function Ocean() {
const ref = useRef()
const gl = useThree((state) => state.gl)
const waterNormals = useLoader(THREE.TextureLoader, '/waternormals.jpeg')
waterNormals.wrapS = waterNormals.wrapT = THREE.RepeatWrapping
const geom = useMemo(() => new THREE.PlaneGeometry(10000, 10000), [])
const config = useMemo(
() => ({
textureWidth: 512,
textureHeight: 512,
waterNormals,
sunDirection: new THREE.Vector3(),
sunColor: 0xffffff,
waterColor: 0x001e0f,
distortionScale: 3.7,
fog: false,
format: gl.encoding,
}),
[waterNormals]
)
useFrame(
(state, delta) => (ref.current.material.uniforms.time.value += delta)
)
return <water ref={ref} args={[geom, config]} rotation-x={-Math.PI / 2} />
}
function Box() {
const ref = useRef()
useFrame((state, delta) => {
ref.current.position.y = 10 + Math.sin(state.clock.elapsedTime) * 20
ref.current.rotation.x =
ref.current.rotation.y =
ref.current.rotation.z +=
delta
})
return (
<mesh ref={ref} scale={20}>
<boxGeometry />
<meshStandardMaterial />
</mesh>
)
}
export default function GeoOcean() {
return (
<Canvas camera={{ position: [0, 5, 100], fov: 55, near: 1, far: 20000 }}>
<pointLight position={[100, 100, 100]} />
<pointLight position={[-100, -100, -100]} />
<Suspense fallback={null}>
<Ocean />
<Box />
</Suspense>
<Sky scale={1000} sunPosition={[500, 150, -1000]} turbidity={0.1} />
<OrbitControls />
</Canvas>
)
}
ここまでできましたら、
App.tsxに上記のコンポーネントを設定します。
src/App.tsx
import { Canvas } from '@react-three/fiber'
import { OrbitControls } from '@react-three/drei'
import GeoBox from './components/GeoBox'
import GeoText from './components/GeoText'
import GeoText3d from './components/GeoText3d'
import GeoTexture from './components/GeoTexture'
import GeoEnv from './components/GeoEnv'
import GeoGltf from './components/GeoGltf'
import GeoStars from './components/GeoStars'
import GeoParticles from './components/GeoParticles'
import GeoMaath from './components/GeoMaath'
import GeoShader from './components/GeoShaders'
import GeoOcean from './components/GeoOcean'
function App() {
return (
// <div className="w-full h-screen">
// <Canvas shadows camera={{ position: [0, 0, 10] }}>
// <ambientLight intensity={0.1} />
// <directionalLight position={[0, 0, 5]} castShadow />
// {/* <GeoBox /> */}
// {/* <GeoText /> */}
// {/* <GeoText3d /> */}
// {/* <GeoTexture /> */}
// {/* <GeoEnv /> */}
// {/* <GeoGltf /> */}
// {/* <GeoStars /> */}
// {/* <GeoParticles /> */}
// {/* <GeoMaath /> */}
// <OrbitControls />
// </Canvas>
// </div>
<div className="w-full h-screen">
<GeoOcean />
</div>
)
}
export default App
ここまでできましたら、
「codesandbox」の「public」フォルダ内にある
「waternormals.jpeg」をダウンロードして、
自分のアプリの「public」フォルダの直下に移動します。
Discussion