💭
React+TypeScriptなWebアプリで、R3Fのtutorial14。(影(Shadow)を設定する)
Abstract
今回の参考はここ(Shadows)。
影(Shadow)は、出す/出さない、受ける/受けないの設定がある。
- ambientLight(環境光源)はShadow属性はない。
- directionalLight(指向性光源(太陽光))、pointLight(点光源)、spotLight(線光源)にはShadow属性をつけれる。
- 影を受け付ける設定 ... receiveShadow
- 影を出す設定 ... castShadow
結論
今回の成果物はココ↓
前提
- React+Typescriptの開発環境は構築済 Ubuntu22.04+VSCode+React+TypeScriptの開発環境を構築してみた。
- このスケルトンコードから始める。react-r3f-tutorial004
手順
1.プロジェクト生成 -> VSCodeで開く
めんどいから、このスケルトンコードから始める。react-r3f-tutorial004
で、下記コマンドでフォルダ名とか整備する。
フォルダリネームとか
$ BaseProject=react-r3f-tutorial004
$ NewProject=react-r3f-tutorial014
$ cd ~
$ rm -rf ${BaseProject}
$ git clone https://github.com/aaaa1597/${BaseProject}.git
$ rm -rf ${BaseProject}/.git
$ mv ${BaseProject} ${NewProject}
$ cd ${NewProject}
準備
$ npm install --save three
$ npm install --save @types/three
$ npm install --save @react-three/fiber
$ npm install --save @react-three/drei
$ npm install --save-dev leva
.eslintrc.js
ビルドエラー回避の設定
.eslintrc.js
"rules": {
- "react/no-unknown-property": ['error', { ignore: ['css', "args", 'wireframe'] }],
+ "react/no-unknown-property": ['error', { ignore: ['css', "args", 'wireframe', 'visible', 'intensity', 'position', 'castShadow', 'castShadow', 'receiveShadow', 'rotation-x']}],
}
App.tsx
まず全体。
App.tsx
import React, {useRef} from 'react';
import './App.css';
import { Canvas, MeshProps, useFrame } from '@react-three/fiber'
import * as THREE from 'three'
+import { Stats, OrbitControls } from '@react-three/drei'
+import { useControls } from 'leva'
+const Lights = () => {
+ const ambientCtl = useControls('Ambient Light', {
+ visible: false,
+ intensity : {value: 1.0, min: 0, max: 1.0, step: 0.1}
+ })
+ const directionalCtl = useControls('Directional Light', {
+ visible: true,
+ position : {x: 3.3, y: 1.0, z: 4.4},
+ castShadow: true,
+ })
+ const pointCtl = useControls('Point Light', {
+ visible: false,
+ position : {x: 2, y: 0, z: 0},
+ castShadow: true,
+ })
+ const spotCtl = useControls('Spot Light', {
+ visible: false,
+ position : {x: 3, y: 2.5, z: 1},
+ castShadow: true,
+ })
+
+ return (
+ <>
+ <ambientLight visible={ ambientCtl.visible} intensity={ambientCtl.intensity}/>
+ <directionalLight visible={directionalCtl.visible} position ={[directionalCtl.position.x, directionalCtl.position.y, directionalCtl.position.z]} castShadow={directionalCtl.castShadow}/>
+ <pointLight visible={ pointCtl.visible} position ={[ pointCtl.position.x, pointCtl.position.y, pointCtl.position.z]} castShadow={ pointCtl.castShadow}/>
+ <spotLight visible={ spotCtl.visible} position ={[ spotCtl.position.x, spotCtl.position.y, spotCtl.position.z]} castShadow={ spotCtl.castShadow}/>
+ </>
+ )
+}
const Box = (props: MeshProps) => {
const ref = useRef<THREE.Mesh>(null!)
useFrame((_, delta) => {
ref.current!.rotation.x += 1 * delta
ref.current!.rotation.y += 1 * delta
})
return (
- <mesh {...props} ref={ref}>
- <boxGeometry />
- <meshBasicMaterial color={0x00ff00} wireframe />
+ <mesh {...props} ref={ref} castShadow receiveShadow>
+ <icosahedronGeometry args={[1, 1]} />
</mesh>
)
}
+const Floor = () => {
+ return (
+ <mesh rotation-x={-Math.PI / 2} receiveShadow>
+ <circleGeometry args={[10]} />
+ <meshStandardMaterial />
+ </mesh>
+ )
+}
const App = () => {
return (
<div style={{ width: "75vw", height: "75vh" }}>
<Canvas camera={{ position: [4, 4, 1.5] }}>
+ <Lights />
- <Box position={[0.75, 0, 0]} name="A" />
- <Box position={[0.75, 0, 0]} name="B" />
+ <Box name="meshBasicMaterial" position={[-2, 2, 0]} material={new THREE.MeshBasicMaterial ({ color: 'yellow' })} />
+ <Box name="meshNormalMaterial" position={[ 2, 2, 0]} material={new THREE.MeshNormalMaterial ({ flatShading: true })} />
+ <Box name="meshPhongMaterial" position={[-2, 0, 0]} material={new THREE.MeshPhongMaterial ({ color: 'lime', flatShading: true })} />
+ <Box name="meshStandardMaterial" position={[ 2, 0, 0]} material={new THREE.MeshStandardMaterial({ color: 0xff0033, flatShading: true })} />
+ <Floor />
+ <OrbitControls target={[2, 2, 0]} />
+ <axesHelper args={[5]} />
+ <Stats />
</Canvas>
</div>
);
}
export default App;
で、実行。
出来た!!
ポイント
光源にcastShadowの属性をつける.
directionalLight(指向性光源(太陽光))、pointLight(点光源)、spotLight(線光源)にShadow属性をつける。
App.tsx
<directionalLight castShadow/>
<pointLight castShadow>
<spotLight castShadow=/>
物体の方にreceiveShadowとcastShadowをつける。
- 影を受け付ける設定 ... receiveShadow
- 影を出す設定 ... castShadow
そんなにムズくはないかな。
React+TypeScriptなWebアプリで、R3Fのtutorial13。(光源)
React+TypeScriptなWebアプリで、R3Fのtutorial15。(useLoaderでテクスチャ読込み)
Discussion