three.js 기초 02

해적왕·2022년 8월 21일
0
post-thumbnail

광택

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;
profile
프론트엔드

0개의 댓글