Loading...
Loading...
Compare original and translation side by side
import { Canvas } from '@react-three/fiber'
function Scene() {
return (
<Canvas>
<ambientLight intensity={0.5} />
<directionalLight position={[5, 5, 5]} />
<mesh>
<boxGeometry />
<meshStandardMaterial
color="hotpink"
roughness={0.5}
metalness={0.5}
/>
</mesh>
</Canvas>
)
}import { Canvas } from '@react-three/fiber'
function Scene() {
return (
<Canvas>
<ambientLight intensity={0.5} />
<directionalLight position={[5, 5, 5]} />
<mesh>
<boxGeometry />
<meshStandardMaterial
color="hotpink"
roughness={0.5}
metalness={0.5}
/>
</mesh>
</Canvas>
)
}| Material | Use Case | Lighting |
|---|---|---|
| meshBasicMaterial | Unlit, flat colors | No |
| meshLambertMaterial | Matte surfaces, fast | Yes (diffuse) |
| meshPhongMaterial | Shiny, specular | Yes |
| meshStandardMaterial | PBR, realistic | Yes (PBR) |
| meshPhysicalMaterial | Advanced PBR | Yes (PBR+) |
| meshToonMaterial | Cel-shaded | Yes (toon) |
| meshNormalMaterial | Debug normals | No |
| shaderMaterial | Custom GLSL | Custom |
| 材质 | 适用场景 | 光照支持 |
|---|---|---|
| meshBasicMaterial | 无光照、纯色平面 | 否 |
| meshLambertMaterial | 哑光表面、性能优先 | 是(漫反射) |
| meshPhongMaterial | 高光镜面效果 | 是 |
| meshStandardMaterial | PBR、真实感渲染 | 是(PBR) |
| meshPhysicalMaterial | 进阶PBR | 是(PBR+) |
| meshToonMaterial | 卡通着色风格 | 是(卡通光照) |
| meshNormalMaterial | 法线调试 | 否 |
| shaderMaterial | 自定义GLSL着色器 | 自定义 |
<mesh>
<boxGeometry />
<meshBasicMaterial
color="red"
transparent
opacity={0.5}
side={THREE.DoubleSide} // FrontSide, BackSide, DoubleSide
wireframe={false}
map={colorTexture}
alphaMap={alphaTexture}
envMap={envTexture}
fog={true}
/>
</mesh><mesh>
<boxGeometry />
<meshBasicMaterial
color="red"
transparent
opacity={0.5}
side={THREE.DoubleSide} // FrontSide, BackSide, DoubleSide
wireframe={false}
map={colorTexture}
alphaMap={alphaTexture}
envMap={envTexture}
fog={true}
/>
</mesh>import { useTexture } from '@react-three/drei'
import * as THREE from 'three'
function PBRMesh() {
// Load PBR texture set
const [colorMap, normalMap, roughnessMap, metalnessMap, aoMap] = useTexture([
'/textures/color.jpg',
'/textures/normal.jpg',
'/textures/roughness.jpg',
'/textures/metalness.jpg',
'/textures/ao.jpg',
])
return (
<mesh>
<sphereGeometry args={[1, 64, 64]} />
<meshStandardMaterial
// Base color
color="#ffffff"
map={colorMap}
// PBR properties
roughness={1} // 0 = mirror, 1 = diffuse
roughnessMap={roughnessMap}
metalness={0} // 0 = dielectric, 1 = metal
metalnessMap={metalnessMap}
// Surface detail
normalMap={normalMap}
normalScale={[1, 1]}
// Ambient occlusion (requires uv2)
aoMap={aoMap}
aoMapIntensity={1}
// Emissive
emissive="#000000"
emissiveIntensity={1}
emissiveMap={emissiveTexture}
// Environment
envMap={envTexture}
envMapIntensity={1}
// Other
flatShading={false}
fog={true}
transparent={false}
/>
</mesh>
)
}import { useTexture } from '@react-three/drei'
import * as THREE from 'three'
function PBRMesh() {
// 加载PBR纹理集
const [colorMap, normalMap, roughnessMap, metalnessMap, aoMap] = useTexture([
'/textures/color.jpg',
'/textures/normal.jpg',
'/textures/roughness.jpg',
'/textures/metalness.jpg',
'/textures/ao.jpg',
])
return (
<mesh>
<sphereGeometry args={[1, 64, 64]} />
<meshStandardMaterial
// 基础颜色
color="#ffffff"
map={colorMap}
// PBR属性
roughness={1} // 0 = 镜面效果, 1 = 漫反射
roughnessMap={roughnessMap}
metalness={0} // 0 = 电介质, 1 = 金属
metalnessMap={metalnessMap}
// 表面细节
normalMap={normalMap}
normalScale={[1, 1]}
// 环境光遮蔽(需要uv2)
aoMap={aoMap}
aoMapIntensity={1}
// 自发光
emissive="#000000"
emissiveIntensity={1}
emissiveMap={emissiveTexture}
// 环境贴图
envMap={envTexture}
envMapIntensity={1}
// 其他属性
flatShading={false}
fog={true}
transparent={false}
/>
</mesh>
)
}// Glass material
function Glass() {
return (
<mesh>
<sphereGeometry args={[1, 64, 64]} />
<meshPhysicalMaterial
color="#ffffff"
metalness={0}
roughness={0}
transmission={1} // 0 = opaque, 1 = fully transparent
thickness={0.5} // Volume thickness for refraction
ior={1.5} // Index of refraction (glass ~1.5)
envMapIntensity={1}
/>
</mesh>
)
}
// Car paint
function CarPaint() {
return (
<mesh>
<boxGeometry />
<meshPhysicalMaterial
color="#ff0000"
metalness={0.9}
roughness={0.5}
clearcoat={1} // Clearcoat layer strength
clearcoatRoughness={0.1} // Clearcoat roughness
/>
</mesh>
)
}
// Fabric/velvet (sheen)
function Fabric() {
return (
<mesh>
<sphereGeometry args={[1, 64, 64]} />
<meshPhysicalMaterial
color="#8844aa"
roughness={0.8}
sheen={1}
sheenRoughness={0.5}
sheenColor="#ff88ff"
/>
</mesh>
)
}
// Iridescent (soap bubbles)
function Iridescent() {
return (
<mesh>
<sphereGeometry args={[1, 64, 64]} />
<meshPhysicalMaterial
color="#ffffff"
iridescence={1}
iridescenceIOR={1.3}
iridescenceThicknessRange={[100, 400]}
/>
</mesh>
)
}// 玻璃材质
function Glass() {
return (
<mesh>
<sphereGeometry args={[1, 64, 64]} />
<meshPhysicalMaterial
color="#ffffff"
metalness={0}
roughness={0}
transmission={1} // 0 = 不透明, 1 = 完全透明
thickness={0.5} // 折射体积厚度
ior={1.5} // 折射率(玻璃约1.5)
envMapIntensity={1}
/>
</mesh>
)
}
// 汽车车漆
function CarPaint() {
return (
<mesh>
<boxGeometry />
<meshPhysicalMaterial
color="#ff0000"
metalness={0.9}
roughness={0.5}
clearcoat={1} // 清漆层强度
clearcoatRoughness={0.1} // 清漆粗糙度
/>
</mesh>
)
}
// 织物/天鹅绒(光泽效果)
function Fabric() {
return (
<mesh>
<sphereGeometry args={[1, 64, 64]} />
<meshPhysicalMaterial
color="#8844aa"
roughness={0.8}
sheen={1}
sheenRoughness={0.5}
sheenColor="#ff88ff"
/>
</mesh>
)
}
// 彩虹效果(肥皂泡)
function Iridescent() {
return (
<mesh>
<sphereGeometry args={[1, 64, 64]} />
<meshPhysicalMaterial
color="#ffffff"
iridescence={1}
iridescenceIOR={1.3}
iridescenceThicknessRange={[100, 400]}
/>
</mesh>
)
}import { MeshReflectorMaterial } from '@react-three/drei'
function ReflectiveFloor() {
return (
<mesh rotation={[-Math.PI / 2, 0, 0]} position={[0, -0.5, 0]}>
<planeGeometry args={[10, 10]} />
<MeshReflectorMaterial
blur={[400, 100]} // Blur amount [x, y]
resolution={1024} // Reflection resolution
mixBlur={1} // Mix blur with reflection
mixStrength={0.5} // Reflection strength
roughness={1}
depthScale={1.2}
minDepthThreshold={0.4}
maxDepthThreshold={1.4}
color="#333"
metalness={0.5}
mirror={0.5}
/>
</mesh>
)
}import { MeshReflectorMaterial } from '@react-three/drei'
function ReflectiveFloor() {
return (
<mesh rotation={[-Math.PI / 2, 0, 0]} position={[0, -0.5, 0]}>
<planeGeometry args={[10, 10]} />
<MeshReflectorMaterial
blur={[400, 100]} // 模糊程度 [x, y]
resolution={1024} // 反射分辨率
mixBlur={1} // 模糊与反射的混合度
mixStrength={0.5} // 反射强度
roughness={1}
depthScale={1.2}
minDepthThreshold={0.4}
maxDepthThreshold={1.4}
color="#333"
metalness={0.5}
mirror={0.5}
/>
</mesh>
)
}import { MeshWobbleMaterial } from '@react-three/drei'
function WobblyMesh() {
return (
<mesh>
<torusKnotGeometry args={[1, 0.4, 100, 16]} />
<MeshWobbleMaterial
factor={1} // Wobble amplitude
speed={2} // Wobble speed
color="hotpink"
metalness={0}
roughness={0.5}
/>
</mesh>
)
}import { MeshWobbleMaterial } from '@react-three/drei'
function WobblyMesh() {
return (
<mesh>
<torusKnotGeometry args={[1, 0.4, 100, 16]} />
<MeshWobbleMaterial
factor={1} // 摇摆幅度
speed={2} // 摇摆速度
color="hotpink"
metalness={0}
roughness={0.5}
/>
</mesh>
)
}import { MeshDistortMaterial } from '@react-three/drei'
function DistortedMesh() {
return (
<mesh>
<sphereGeometry args={[1, 64, 64]} />
<MeshDistortMaterial
distort={0.5} // Distortion amount
speed={2} // Animation speed
color="cyan"
roughness={0.2}
/>
</mesh>
)
}import { MeshDistortMaterial } from '@react-three/drei'
function DistortedMesh() {
return (
<mesh>
<sphereGeometry args={[1, 64, 64]} />
<MeshDistortMaterial
distort={0.5} // 扭曲程度
speed={2} // 动画速度
color="cyan"
roughness={0.2}
/>
</mesh>
)
}import { MeshTransmissionMaterial } from '@react-three/drei'
function GlassSphere() {
return (
<mesh>
<sphereGeometry args={[1, 64, 64]} />
<MeshTransmissionMaterial
backside // Render backside
samples={16} // Refraction samples
resolution={1024} // Buffer resolution
transmission={1} // Transmission factor
roughness={0.0}
thickness={0.5} // Volume thickness
ior={1.5} // Index of refraction
chromaticAberration={0.06}
anisotropy={0.1}
distortion={0.0}
distortionScale={0.3}
temporalDistortion={0.5}
clearcoat={1}
attenuationDistance={0.5}
attenuationColor="#ffffff"
color="#c9ffa1"
/>
</mesh>
)
}import { MeshTransmissionMaterial } from '@react-three/drei'
function GlassSphere() {
return (
<mesh>
<sphereGeometry args={[1, 64, 64]} />
<MeshTransmissionMaterial
backside // 渲染背面
samples={16} // 折射采样数
resolution={1024} // 缓冲区分辨率
transmission={1} // 透射系数
roughness={0.0}
thickness={0.5} // 体积厚度
ior={1.5} // 折射率
chromaticAberration={0.06}
anisotropy={0.1}
distortion={0.0}
distortionScale={0.3}
temporalDistortion={0.5}
clearcoat={1}
attenuationDistance={0.5}
attenuationColor="#ffffff"
color="#c9ffa1"
/>
</mesh>
)
}import { MeshDiscardMaterial } from '@react-three/drei'
function ShadowOnlyMesh() {
return (
<mesh castShadow>
<boxGeometry />
<MeshDiscardMaterial /> {/* Invisible but casts shadows */}
</mesh>
)
}import { MeshDiscardMaterial } from '@react-three/drei'
function ShadowOnlyMesh() {
return (
<mesh castShadow>
<boxGeometry />
<MeshDiscardMaterial /> {/* 不可见但可投射阴影 */}
</mesh>
)
}// Points material
<points>
<bufferGeometry />
<pointsMaterial
size={0.1}
sizeAttenuation={true}
color="white"
map={spriteTexture}
transparent
alphaTest={0.5}
vertexColors
/>
</points>
// Line materials
<line>
<bufferGeometry />
<lineBasicMaterial color="white" linewidth={1} />
</line>
<line>
<bufferGeometry />
<lineDashedMaterial
color="white"
dashSize={0.5}
gapSize={0.25}
scale={1}
/>
</line>// 点材质
<points>
<bufferGeometry />
<pointsMaterial
size={0.1}
sizeAttenuation={true}
color="white"
map={spriteTexture}
transparent
alphaTest={0.5}
vertexColors
/>
</points>
// 线材质
<line>
<bufferGeometry />
<lineBasicMaterial color="white" linewidth={1} />
</line>
<line>
<bufferGeometry />
<lineDashedMaterial
color="white"
dashSize={0.5}
gapSize={0.25}
scale={1}
/>
</line><meshStandardMaterial
// Visibility
visible={true}
transparent={false}
opacity={1}
alphaTest={0} // Discard pixels with alpha < value
// Rendering
side={THREE.FrontSide} // FrontSide, BackSide, DoubleSide
depthTest={true}
depthWrite={true}
colorWrite={true}
// Blending
blending={THREE.NormalBlending}
// NormalBlending, AdditiveBlending, SubtractiveBlending, MultiplyBlending
// Polygon offset (z-fighting fix)
polygonOffset={false}
polygonOffsetFactor={0}
polygonOffsetUnits={0}
// Misc
dithering={false}
toneMapped={true}
/><meshStandardMaterial
// 可见性
visible={true}
transparent={false}
opacity={1}
alphaTest={0} // 丢弃alpha值小于该阈值的像素
// 渲染设置
side={THREE.FrontSide} // FrontSide, BackSide, DoubleSide
depthTest={true}
depthWrite={true}
colorWrite={true}
// 混合模式
blending={THREE.NormalBlending}
// NormalBlending, AdditiveBlending, SubtractiveBlending, MultiplyBlending
// 多边形偏移(解决Z-fighting问题)
polygonOffset={false}
polygonOffsetFactor={0}
polygonOffsetUnits={0}
// 其他
dithering={false}
toneMapped={true}
/>import { useRef } from 'react'
import { useFrame } from '@react-three/fiber'
function AnimatedMaterial() {
const materialRef = useRef()
useFrame(({ clock }) => {
const t = clock.elapsedTime
// Update color
materialRef.current.color.setHSL((t * 0.1) % 1, 1, 0.5)
// Update properties
materialRef.current.roughness = (Math.sin(t) + 1) / 2
})
return (
<mesh>
<boxGeometry />
<meshStandardMaterial ref={materialRef} />
</mesh>
)
}import { useRef } from 'react'
import { useFrame } from '@react-three/fiber'
function AnimatedMaterial() {
const materialRef = useRef()
useFrame(({ clock }) => {
const t = clock.elapsedTime
// 更新颜色
materialRef.current.color.setHSL((t * 0.1) % 1, 1, 0.5)
// 更新属性
materialRef.current.roughness = (Math.sin(t) + 1) / 2
})
return (
<mesh>
<boxGeometry />
<meshStandardMaterial ref={materialRef} />
</mesh>
)
}import { useMemo } from 'react'
import * as THREE from 'three'
function SharedMaterial() {
// Create once, use many times
const material = useMemo(() =>
new THREE.MeshStandardMaterial({ color: 'red' }),
[])
return (
<>
<mesh position={[-2, 0, 0]} material={material}>
<boxGeometry />
</mesh>
<mesh position={[0, 0, 0]} material={material}>
<sphereGeometry />
</mesh>
<mesh position={[2, 0, 0]} material={material}>
<coneGeometry />
</mesh>
</>
)
}import { useMemo } from 'react'
import * as THREE from 'three'
function SharedMaterial() {
// 仅创建一次,多次复用
const material = useMemo(() =>
new THREE.MeshStandardMaterial({ color: 'red' }),
[])
return (
<>
<mesh position={[-2, 0, 0]} material={material}>
<boxGeometry />
</mesh>
<mesh position={[0, 0, 0]} material={material}>
<sphereGeometry />
</mesh>
<mesh position={[2, 0, 0]} material={material}>
<coneGeometry />
</mesh>
</>
)
}// Different materials per face (BoxGeometry has 6 material groups)
<mesh>
<boxGeometry />
<meshStandardMaterial attach="material-0" color="red" /> {/* +X */}
<meshStandardMaterial attach="material-1" color="green" /> {/* -X */}
<meshStandardMaterial attach="material-2" color="blue" /> {/* +Y */}
<meshStandardMaterial attach="material-3" color="yellow" />{/* -Y */}
<meshStandardMaterial attach="material-4" color="cyan" /> {/* +Z */}
<meshStandardMaterial attach="material-5" color="magenta" />{/* -Z */}
</mesh>// 每个面使用不同材质(BoxGeometry包含6个材质组)
<mesh>
<boxGeometry />
<meshStandardMaterial attach="material-0" color="red" /> {/* +X方向 */}
<meshStandardMaterial attach="material-1" color="green" /> {/* -X方向 */}
<meshStandardMaterial attach="material-2" color="blue" /> {/* +Y方向 */}
<meshStandardMaterial attach="material-3" color="yellow" />{/* -Y方向 */}
<meshStandardMaterial attach="material-4" color="cyan" /> {/* +Z方向 */}
<meshStandardMaterial attach="material-5" color="magenta" />{/* -Z方向 */}
</mesh>import { useTexture } from '@react-three/drei'
import * as THREE from 'three'
function TexturedMaterial() {
// Named object pattern (recommended)
const textures = useTexture({
map: '/textures/color.jpg',
normalMap: '/textures/normal.jpg',
roughnessMap: '/textures/roughness.jpg',
})
// Set texture properties
Object.values(textures).forEach(texture => {
texture.wrapS = texture.wrapT = THREE.RepeatWrapping
texture.repeat.set(2, 2)
})
return (
<mesh>
<planeGeometry args={[5, 5]} />
<meshStandardMaterial {...textures} />
</mesh>
)
}import { useTexture } from '@react-three/drei'
import * as THREE from 'three'
function TexturedMaterial() {
// 命名对象模式(推荐)
const textures = useTexture({
map: '/textures/color.jpg',
normalMap: '/textures/normal.jpg',
roughnessMap: '/textures/roughness.jpg',
})
// 设置纹理属性
Object.values(textures).forEach(texture => {
texture.wrapS = texture.wrapT = THREE.RepeatWrapping
texture.repeat.set(2, 2)
})
return (
<mesh>
<planeGeometry args={[5, 5]} />
<meshStandardMaterial {...textures} />
</mesh>
)
}// For bloom effect, emissive colors should exceed normal range
<meshStandardMaterial
color="black"
emissive="#ff0000"
emissiveIntensity={2} // > 1 for bloom
toneMapped={false} // Required for colors > 1
/>
// With emissive map
<meshStandardMaterial
emissive="white"
emissiveMap={emissiveTexture}
emissiveIntensity={2}
toneMapped={false}
/>// 要实现 bloom 效果,自发光颜色应超过常规范围
<meshStandardMaterial
color="black"
emissive="#ff0000"
emissiveIntensity={2} // >1 时可触发 bloom 效果
toneMapped={false} // 颜色值>1时必须设置为false
/>
// 结合自发光贴图
<meshStandardMaterial
emissive="white"
emissiveMap={emissiveTexture}
emissiveIntensity={2}
toneMapped={false}
/>import { useEnvironment } from '@react-three/drei'
function EnvMappedMaterial() {
const envMap = useEnvironment({ preset: 'sunset' })
return (
<mesh>
<sphereGeometry args={[1, 64, 64]} />
<meshStandardMaterial
metalness={1}
roughness={0}
envMap={envMap}
envMapIntensity={1}
/>
</mesh>
)
}import { useEnvironment } from '@react-three/drei'
function EnvMappedMaterial() {
const envMap = useEnvironment({ preset: 'sunset' })
return (
<mesh>
<sphereGeometry args={[1, 64, 64]} />
<meshStandardMaterial
metalness={1}
roughness={0}
envMap={envMap}
envMapIntensity={1}
/>
</mesh>
)
}r3f-shadersimport { shaderMaterial } from '@react-three/drei'
import { extend } from '@react-three/fiber'
const CustomMaterial = shaderMaterial(
{ time: 0, color: new THREE.Color('hotpink') },
// Vertex shader
`
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`,
// Fragment shader
`
uniform float time;
uniform vec3 color;
varying vec2 vUv;
void main() {
gl_FragColor = vec4(color * (sin(time + vUv.x * 10.0) * 0.5 + 0.5), 1.0);
}
`
)
extend({ CustomMaterial })
function CustomShaderMesh() {
const materialRef = useRef()
useFrame(({ clock }) => {
materialRef.current.time = clock.elapsedTime
})
return (
<mesh>
<boxGeometry />
<customMaterial ref={materialRef} />
</mesh>
)
}r3f-shadersimport { shaderMaterial } from '@react-three/drei'
import { extend } from '@react-three/fiber'
const CustomMaterial = shaderMaterial(
{ time: 0, color: new THREE.Color('hotpink') },
// 顶点着色器
`
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`,
// 片元着色器
`
uniform float time;
uniform vec3 color;
varying vec2 vUv;
void main() {
gl_FragColor = vec4(color * (sin(time + vUv.x * 10.0) * 0.5 + 0.5), 1.0);
}
`
)
extend({ CustomMaterial })
function CustomShaderMesh() {
const materialRef = useRef()
useFrame(({ clock }) => {
materialRef.current.time = clock.elapsedTime
})
return (
<mesh>
<boxGeometry />
<customMaterial ref={materialRef} />
</mesh>
)
}// Material caching pattern
const materialCache = new Map()
function getCachedMaterial(color) {
const key = color.toString()
if (!materialCache.has(key)) {
materialCache.set(key, new THREE.MeshStandardMaterial({ color }))
}
return materialCache.get(key)
}// 材质缓存模式
const materialCache = new Map()
function getCachedMaterial(color) {
const key = color.toString()
if (!materialCache.has(key)) {
materialCache.set(key, new THREE.MeshStandardMaterial({ color }))
}
return materialCache.get(key)
}r3f-texturesr3f-shadersr3f-lightingr3f-texturesr3f-shadersr3f-lighting