なにかお手伝いできることがあればご連絡ください。
※Googleフォームが表示されます
メッシュにマテリアルを割り当てるソースコードは以下のようになります。
import "./App.css";
import { Canvas } from "@react-three/fiber";
import {
Environment,
OrbitControls,
Plane,
Stats,
useMatcapTexture,
} from "@react-three/drei";
/** @jsxImportSource @emotion/react */
import { css } from "@emotion/react";
import { Suspense } from "react";
import * as THREE from "three";
const canvas = css`
height: 100vh !important;
width: 100vw !important;
`;
function App() {
return (
<>
<Canvas
css={canvas}
camera={{
position: [0, 5, 8],
fov: 50,
aspect: window.innerWidth / window.innerHeight,
near: 0.1,
far: 2000,
}}
dpr={window.devicePixelRatio}
shadows
>
<Stats />
<OrbitControls />
<ambientLight intensity={0.1} />
<directionalLight
position={[5, 5, 5]}
intensity={1}
shadow-mapSize-width={2048}
shadow-mapSize-height={2048}
castShadow
/>
<Suspense fallback={null}>
<Environment files="https://dl.polyhaven.org/file/ph-assets/HDRIs/hdr/1k/potsdamer_platz_1k.hdr" />
{/* ここ */}
<mesh position={[1, 3, 2]} castShadow receiveShadow>
<sphereGeometry args={[0.6, 32, 32]} />
<meshBasicMaterial color="#0404E8" />
</mesh>
<Plane rotation={[-Math.PI / 2, 0, 0]} args={[10, 10]} receiveShadow>
<meshStandardMaterial color="#fff" side={THREE.DoubleSide} />
</Plane>
</Suspense>
</Canvas>
</>
);
}
基本的なマテリアルです。
...省略
<mesh position={[1, 3, 2]} castShadow receiveShadow>
<sphereGeometry args={[0.6, 32, 32]} />
<meshBasicMaterial color="#0404E8" />
</mesh>
...省略
物理ベースレンダリング(PBR)を実現するマテリアルです。
荒さ(roughness)や金属度(metalness)などのパラメータを設定できる。
...省略
<mesh position={[1, 1, 2]} castShadow receiveShadow>
<sphereGeometry args={[0.6, 32, 32]} />
<meshStandardMaterial color="#0404E8" />
</mesh>
roughnessとmetalnessを設定してみる。
<mesh position={[1, 1, 2]} castShadow receiveShadow>
<sphereGeometry args={[0.6, 32, 32]} />
<meshStandardMaterial color={"#0404E8"} roughness={5} metalness={5} />
</mesh>
法線ベクトルをRGB値に変換して、色を表現するマテリアルです。
...省略
<mesh position={[1, 1, 2]} castShadow receiveShadow>
<sphereGeometry args={[0.6, 32, 32]} />
<meshNormalMaterial />
</mesh>
...省略
光沢感を表現できるマテリアルです。
shinineess(光沢)とspecular(反射)を設定できる。
MeshLambertMaterialと似ている。
...省略
<mesh position={[1, 1, 2]} castShadow receiveShadow>
<sphereGeometry args={[0.6, 32, 32]} />
<meshPhongMaterial color="#0404E8" />
</mesh>
...省略
...省略
<mesh position={[1, 1, 2]} castShadow receiveShadow>
<sphereGeometry args={[0.6, 32, 32]} />
<meshPhongMaterial color="#0404E8" shininess={100} specular={1000} />
</mesh>
...省略
アニメっぽい質感を表現できるマテリアルです。
...省略
<mesh position={[1, 1, 2]} castShadow receiveShadow>
<sphereGeometry args={[0.6, 32, 32]} />
<methToonMaterial color="#0404E8" />
</mesh>
...省略
光沢感のないマットな質感を表現できるマテリアルです。
...省略
<mesh position={[1, 1, 2]} castShadow receiveShadow>
<sphereGeometry args={[0.6, 32, 32]} />
<meshLambertMaterial color="#0404E8" />
</mesh>
...省略
Matcapは、物体の光沢感や質感をリアルに見せることができます。
...省略
<mesh position={[1, 1, 2]} castShadow receiveShadow>
<sphereGeometry args={[0.6, 32, 32]} />
<meshMatcapMaterial color="#0404E8" />
</mesh>
...省略
https://github.com/emmelleppi/matcapsからテクスチャを読み込んで利用することもできます。
const Objects = () => {
const [matcap] = useMatcapTexture("0404E8_0404B5_0404CB_3333FC", 512);
return (
<>
<mesh position={[1, 1, 2]} castShadow receiveShadow>
<sphereGeometry args={[0.6, 32, 32]} />
<meshMatcapMaterial matcap={matcap} />
</mesh>
</>
);
};
テクスチャの設定方法です。
画像は以下を用意します。
useLoaderを使って、textureを読み込みます。
useLoaderは、任意の Three.jsローダーモジュールを最初の引数として使用します。
今回はテクスチャ画像を利用するので、THREE.TextureLoaderモジュールを渡します。
第二引数には、読み込みたいファイルのパスを指定します。
const texture = useLoader(THREE.TextureLoader, "./img/img01.png");
複数のテクスチャを読み込む場合は、配列で指定します。
const [img01, img02, img03] = useLoader(THREE.TextureLoader, [
"./img/img01.png",
"./img/img02.png",
"./img/img03.png",
]);
各画像を読み込んで、マテリアルに設定します。
function App() {
const name = (type: string) => `/textures/Stone_Path_007_${type}.jpg`;
const [colorMap, displacementMap, normalMap, roughnessMap, aoMap] = useLoader(
THREE.TextureLoader,
[
name("basecolor"),
name("height"),
name("normal"),
name("roughness"),
name("ambientOcclusion"),
]
);
return (
<>
<Canvas
css={canvas}
camera={{
position: [0, 5, 8],
fov: 50,
aspect: window.innerWidth / window.innerHeight,
near: 0.1,
far: 2000,
}}
dpr={window.devicePixelRatio}
shadows
>
<Stats />
<OrbitControls />
<ambientLight intensity={0.1} />
<directionalLight
position={[0, 5, 5]}
intensity={1}
shadow-mapSize-width={2048}
shadow-mapSize-height={2048}
castShadow
/>
<Suspense fallback={null}>
<Environment files="https://dl.polyhaven.org/file/ph-assets/HDRIs/hdr/1k/potsdamer_platz_1k.hdr" />
<mesh position={[0, 1, 2]} castShadow receiveShadow>
<sphereGeometry args={[0.6, 32, 32]} />
<meshStandardMaterial
displacementScale={0.2}
map={colorMap}
displacementMap={displacementMap}
normalMap={normalMap}
roughnessMap={roughnessMap}
aoMap={aoMap}
/>
</mesh>
<Plane rotation={[-Math.PI / 2, 0, 0]} args={[10, 10]} receiveShadow>
<meshStandardMaterial color="#7c7c7c" side={THREE.DoubleSide} />
</Plane>
</Suspense>
</Canvas>
</>
);
}
表示はこんな感じになります。
RenderTextureを利用すると、テクスチャを動的に変更することができます。
オフスクリーンレンダリングのようなものかも?
やり方としては、マテリアルコンポーネントの中でRenderTextureを設定します。
カメラも設定することで、設定したカメラ視点のテクスチャとして設定することができます。
import "./App.css";
import { Canvas, useFrame } from "@react-three/fiber";
import {
Environment,
OrbitControls,
PerspectiveCamera,
Plane,
RenderTexture,
Stats,
Text,
} from "@react-three/drei";
/** @jsxImportSource @emotion/react */
import { css } from "@emotion/react";
import { Suspense, useRef } from "react";
import * as THREE from "three";
const canvas = css`
height: 100vh !important;
width: 100vw !important;
`;
function App() {
return (
<>
<Canvas
css={canvas}
camera={{
position: [0, 5, 8],
fov: 50,
aspect: window.innerWidth / window.innerHeight,
near: 0.1,
far: 2000,
}}
dpr={window.devicePixelRatio}
shadows
>
<Stats />
<OrbitControls />
<ambientLight intensity={0.1} />
<directionalLight
position={[0, 5, 5]}
intensity={1}
shadow-mapSize-width={2048}
shadow-mapSize-height={2048}
castShadow
/>
<Suspense fallback={null}>
<Environment files="https://dl.polyhaven.org/file/ph-assets/HDRIs/hdr/1k/potsdamer_platz_1k.hdr" />
<Object />
<Plane rotation={[-Math.PI / 2, 0, 0]} args={[10, 10]} receiveShadow>
<meshStandardMaterial color="#7c7c7c" side={THREE.DoubleSide} />
</Plane>
</Suspense>
</Canvas>
</>
);
}
const Object = () => {
const textRef = useRef(null!);
useFrame(
(state) =>
(textRef.current.position.x = Math.sin(state.clock.elapsedTime) * 2)
);
return (
<>
<mesh position={[0, 1, 2]} castShadow receiveShadow>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial>
<RenderTexture attach="map" anisotropy={16}>
<PerspectiveCamera
makeDefault
manual
aspect={1 / 1}
position={[0, 0, 5]}
/>
<color attach="background" args={["red"]} />
<ambientLight intensity={0.5} />
<directionalLight position={[10, 10, 5]} />
<Text fontSize={2} color="#FFF" ref={textRef}>
Hello World
</Text>
</RenderTexture>
</meshStandardMaterial>
</mesh>
</>
);
};
export default App;
表示はこんな感じになります。
やり方次第で色々な表現ができそうです。
なにかお手伝いできることがあればご連絡ください。
※Googleフォームが表示されます