import { Canvas } from '@react-three/fiber';
import { Suspense } from 'react';
import { MeshDistortMaterial, OrbitControls } from "@react-three/drei";
const Sphere = ({ position, children }) => {
return (
<mesh position={position}>
<sphereGeometry args={[1, 24, 24]} />
{children}
</mesh>
);
};
const Rounded = () => {
return (
<Canvas>
<pointLight position={[5, 5, 5]} />
<ambientLight intensity={0.3} />
<Sphere position={[-4, 0, 0]}>
<meshBasicMaterial color={"orange"} />
</Sphere>
<Sphere position={[-2, 0, 0]}>
<meshLambertMaterial color={"orange"} />
</Sphere>
<Sphere position={[0, 0, 0]}>
<meshPhongMaterial color={"orange"} />
</Sphere>
<Sphere position={[2, 0, 0]}>
<meshStandardMaterial color={"orange"} metalness={0.1} roughness={0.3} />
</Sphere>
<Sphere position={[4, 0, 0]}>
<meshPhysicalMaterial
color={"orange"}
metalness={0.2}
roughness={0}
clearcoat={0.8}
/>
</Sphere>
<OrbitControls />
</Canvas>
)
}
export default Rounded;
meshBasicMaterial
간단한 음영(평면 또는 와이어프레임) 방식으로 지오메트리를 그리기 위한 재료이다.
meshLambertMaterial
광택이 나지 않는 표면을 위한 재료이며, 특별한 하이라이트가 없다.
meshPhongMaterial
반짝이는 표면에 스펙터클한 하이라이트가 있는 소재이다.
meshStandardMaterial
Metallic-Roughness 작업속도를 사용하는 표준 물리적 기반 재료입니다.
meshPhysicalMaterial
Mesh Standard Material의 확장으로 보다 향상된 물리적 기반 렌더링 속성을 제공한다.
metalness
수치가 커질 수록 흰 점이 넓어진다.
roughness
광택층의 거칠기(0.0 ~ 1.0). 기본값은 1.0.
clearcoat
는 자동차 페인트, 탄소 섬유 및 젖은 표면과 같은 일부 재료는 불규칙하거나 거친 다른 층 위에 투명하고 반사되는 층을 필요로 한다. clearcoat는 별도의 투명 표면 없이도 이 효과를 근사하게 보여준다.
import { Canvas } from '@react-three/fiber';
import { Suspense } from 'react';
import { OrbitControls, Environment } from "@react-three/drei";
const Ball = ({ position, children }) => {
return (
<mesh position={position}>
<sphereGeometry args={[1, 24, 24]} />
{children}
</mesh>
);
};
const Rounded = () => {
const materials = [
<meshStandardMaterial metalness={0.9} roughness={0.1} />,
<meshStandardMaterial metalness={0.6} roughness={0.3} />,
<meshStandardMaterial metalness={0.5} roughness={0.5} />,
<meshStandardMaterial metalness={0.3} roughness={0.6} />,
<meshPhysicalMaterial clearcoat={0.6} roughness={0.1} />
];
return (
<Canvas style={{ height: 400, width: 600 }}>
<Suspense fallback={null}>
{materials.map((mat, i) => (
<Ball key={`ball-${i}`} position={[-4 + 2 * i, 0, 0]}>
{mat}
</Ball>
))}
<Environment
files={['colorful.hdr']}
path={'/'}
preset={'sunset'}
/>
</Suspense>
<OrbitControls />
</Canvas>
)
}
export default Rounded;
<Environment
background={true}
files={['colorful.hdr']}
path={'/'}
preset={'sunset'}
/>
background
를 넣어주면 배경이 생긴다.
https://polyhaven.com/hdris
무료 hdr 다운 사이트
import { Canvas } from '@react-three/fiber';
import { Suspense } from 'react';
import { Sphere, MeshDistortMaterial, OrbitControls } from "@react-three/drei";
const Circle = () => {
return (
<group>
<mesh>
<Sphere visible args={[1, 100, 200]}>
<MeshDistortMaterial
color="#7aaaff"
attach="material"
distort={0.5}
speed={2}
roughness={0}
/>
</Sphere>
</mesh>
</group>
);
};
const Rounded = () => {
return (
<Canvas>
<ambientLight intensity={0.3} />
<pointLight intensity={0.75} position={[5, 5, 5]} />
<Suspense fallback={null}>
<Circle />
</Suspense>
<OrbitControls />
</Canvas>
)
}
export default Rounded;
import { Sphere, MeshDistortMaterial } from "@react-three/drei";
이렇게 적용 시켜줘야 한다.
disport 값이 커질 수록 요동친다.
import { Canvas, useFrame, useLoader } from "react-three-fiber";
import { useRef } from 'react';
import { OrbitControls, Text } from "@react-three/drei";
const Sphere = (props) => {
const groupRef = useRef();
const fontProps = { font: '폰트.otf', fontSize: 0.8, letterSpacing: -0.05, lineHeight: 1, 'material-toneMapped': false }
useFrame(() => {
groupRef.current.rotation.x += 0.01;
groupRef.current.rotation.y += 0.01;
})
return (
<group ref={groupRef} scale={0.05}>
<mesh {...props}>
<torusGeometry args={[20, 5, 100, 200]} />
<meshStandardMaterial metalness={0.1} roughness={0.3} color={"pink"} />
<Text
scale={[10, 10, 10]}
color="black"
anchorX="center"
anchorY="middle"
{...fontProps}
>
해적왕
</Text>
</mesh>
</group>
);
};
const Rounded = () => {
return (
<Canvas>
<ambientLight intensity={0.3} />
<pointLight intensity={0.75} position={[5, 5, 5]} />
<Sphere />
<OrbitControls />
</Canvas>
)
}
export default Rounded;
Text
를 사용. 폰트 설정 하는 법에서 계속 콘솔 에러가 나서 애 먹었다. json파일이 아니고 폰트 파일 그대로 public
폴더 안에 넣어주면 된다.
Secene.js
export const Wall = () => {
return (
<>
<mesh position={[-0.5,6,-3]} castShadow receiveShadow>
<boxGeometry args={[16, 12, 1]} />
<meshLambertMaterial color={"pink"} />
</mesh>
<mesh
position={[-8, 6, 5]}
rotation={[0, -Math.PI * 0.5, 0]}
castShadow
receiveShadow
>
<boxGeometry args={[16, 12, 1]} />
<meshLambertMaterial color={"pink"} />
</mesh>
</>
)
}
export const Ground = () => {
return (
<mesh rotation={[-Math.PI * 0.5, 0, 0]} receiveShadow>
<planeGeometry attach="geometry" args={[100, 100]} />
<meshStandardMaterial color={"#ddddff"} />
</mesh>
)
}
export const Box = () => {
return (
<mesh position={[0,2.5,0]} castShadow receiveShadow>
<boxGeometry args={[5,5,5]} />
<meshLambertMaterial color={"green"} />
</mesh>
)
}
export const SmallBox = () => {
return(
<mesh position={[6,0.5,-2]} castShadow receiveShadow>
<boxGeometry args={[1,1,1]} />
<meshLambertMaterial color={"orange"} />
</mesh>
)
}
export const Ball = () => {
return (
<mesh position={[-0.3, 6, -1]} castShadow receiveShadow>
<sphereGeometry args={[1, 128, 128]} />
<meshStandardMaterial color={"yellow"} metalness={0.1} roughness={0.3}/>
</mesh>
);
};
Example.js
import { Canvas } from '@react-three/fiber'
import { OrbitControls } from "@react-three/drei";
import { Wall, Ground, Box, SmallBox, Ball } from "./Scene";
const Example = () => {
return (
<Canvas
style={{ height: 500, width: 400 }}
camera={{ position: [10, 10, 10] }}>
<ambientLight intensity={0.2} />
<directionalLight position={[2.5, 5, 5]} />
<Wall />
<Ground />
<Ball />
<Box />
<SmallBox />
<OrbitControls />
</Canvas>
)
}
export default Example;
directionalLight
특정 방향으로 방출되는 빛. 이 빛은 마치 무한히 멀리 떨어져 있는 것처럼 행동할 것이고 그것으로부터 생성된 광선은 모두 평행하다. 태양은 그 위치가 무한하다고 간주될 정도로 충분히 멀리 떨어져 있고, 태양으로부터 나오는 모든 광선은 평행하다.
이 조명은 그림자를 드리울 수 있다.
import { Canvas } from '@react-three/fiber'
import { OrbitControls } from "@react-three/drei";
import { Wall, Ground, Box, SmallBox, Ball } from "./Scene";
const Example = () => {
return (
<Canvas
style={{ height: 500, width: 400 }}
camera={{ position: [10, 10, 10] }}
shadows>
<pointLight
position={[15, 25, 5]}
intensity={0.1}
castShadow
shadow-mapSize-height={512}
shadow-mapSize-width={512}
shadow-radius={10}
shadow-bias={-0.0001}
/>
<pointLight
position={[15, 15, 15]}
intensity={0.1}
castShadow
shadow-mapSize-height={512}
shadow-mapSize-width={512}
shadow-radius={10}
shadow-bias={-0.0001}
/>
<pointLight
position={[0, 15, 15]}
intensity={0.7}
castShadow
shadow-mapSize-height={1024}
shadow-mapSize-width={1024}
shadow-radius={20}
shadow-bias={-0.0001}
/>
<Wall />
<Ground />
<Ball />
<Box />
<SmallBox />
<OrbitControls />
</Canvas>
)
}
export default Example;
그림자를 나타내기 위해 castShadow
를 입력해줘야 한다.
import { Canvas } from '@react-three/fiber'
import { OrbitControls, Reflector } from "@react-three/drei";
import { Wall, Ground, Box, SmallBox, Ball } from "./Scene";
const Example = () => {
return (
<Canvas
style={{ height: 400, width: 400 }}
camera={{ position: [10, 10, 10] }}
>
<pointLight position={[15, 15, 15]} />
<SmallBox />
<Box />
<Ball />
<Wall />
<Reflector
blur={[512, 512]} // 지면 반사 흐림(폭, 높이)
mixBlur={0.75} // 표면 거칠기와 블러 혼합되는 정도
mixStrength={0.25} // 반사 강도
resolution={1024} // Off-buffer 해상도, 더 낮은 = 더 높은 = 더 높은 품질
args={[50, 50]} // 평면 버퍼 지오메트리 인수
rotation={[-Math.PI * 0.5, 0, 0]}
mirror={0.5} // Mirror environment, 0 = texture colors, 1 = pick up env colors
minDepthThreshold={0.25}
maxDepthThreshold={1}
depthScale={50}
>
{(Material, props) => (
<Material metalness={0.5} roughness={1} {...props} />
)}
</Reflector>
<OrbitControls />
</Canvas>
)
}
export default Example;