返回 Skill 列表
extension
分类: 开发与工程无需 API Key

ta-r3f-materials

R3F的材质选择、着色器和视觉效果。在处理材质、PBR纹理、着色器材质时使用。

person作者: jakexiaohubgithub

R3F Materials Skill

"Materials define the soul of your 3D objects – choose wisely."

When to Use This Skill

Use when:

  • Choosing material type for objects
  • Creating custom shaders
  • Implementing visual effects
  • Optimizing material performance

Quick Start

// Standard PBR material (recommended default)
<meshStandardMaterial
  color="royalblue"
  roughness={0.5}
  metalness={0.5}
/>

// Basic material (unlit, best performance)
<meshBasicMaterial color="red" />

// Physical material (advanced PBR)
<meshPhysicalMaterial
  clearcoat={1}
  clearcoatRoughness={0.1}
  transmission={0.9}
  thickness={0.5}
/>

Decision Framework

| Need | Material | Performance | | --------------- | ---------------------- | ------------- | | Unlit color | meshBasicMaterial | ⚡ Fastest | | Simple shading | meshLambertMaterial | ⚡⚡ Fast | | Stylized look | meshToonMaterial | ⚡⚡ Fast | | Realistic PBR | meshStandardMaterial | ⚡⚡⚡ Medium | | Glass/water | meshPhysicalMaterial | ⚡⚡⚡⚡ Slow | | Custom effects | shaderMaterial | Varies | | Matcap lighting | meshMatcapMaterial | ⚡⚡ Fast |

Progressive Guide

Level 1: Standard Materials

// Most common choice - good balance of quality and performance
<meshStandardMaterial
  color="#ff6600"
  roughness={0.7} // 0 = smooth, 1 = rough
  metalness={0.3} // 0 = dielectric, 1 = metal
  envMapIntensity={1}
/>

Level 2: Textured Materials

import { useTexture } from '@react-three/drei';

function TexturedMesh() {
  const [colorMap, normalMap, roughnessMap] = useTexture([
    '/textures/color.jpg',
    '/textures/normal.jpg',
    '/textures/roughness.jpg',
  ]);

  return (
    <mesh>
      <boxGeometry />
      <meshStandardMaterial map={colorMap} normalMap={normalMap} roughnessMap={roughnessMap} />
    </mesh>
  );
}

Level 3: Matcap Materials (Fast & Stylized)

import { useMatcapTexture } from '@react-three/drei';

function MatcapMesh() {
  const [matcap] = useMatcapTexture('3B3C3F_DAD9D5_929290_ABACA8');

  return (
    <mesh>
      <sphereGeometry />
      <meshMatcapMaterial matcap={matcap} />
    </mesh>
  );
}

Level 4: Custom Shaders

import { shaderMaterial } from '@react-three/drei';
import { extend, useFrame } from '@react-three/fiber';

const WaveShaderMaterial = shaderMaterial(
  { uTime: 0, uColor: new THREE.Color('hotpink') },
  // Vertex shader
  `
    uniform float uTime;
    varying vec2 vUv;

    void main() {
      vUv = uv;
      vec3 pos = position;
      pos.z += sin(pos.x * 4.0 + uTime) * 0.1;
      gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
    }
  `,
  // Fragment shader
  `
    uniform vec3 uColor;
    varying vec2 vUv;

    void main() {
      gl_FragColor = vec4(uColor, 1.0);
    }
  `
);

extend({ WaveShaderMaterial });

function WavyPlane() {
  const materialRef = useRef();

  useFrame((state) => {
    if (materialRef.current) {
      materialRef.current.uTime = state.clock.elapsedTime;
    }
  });

  return (
    <mesh>
      <planeGeometry args={[4, 4, 32, 32]} />
      <waveShaderMaterial ref={materialRef} />
    </mesh>
  );
}

Level 5: Transparent & Glass

// Glass/water with transmission
<meshPhysicalMaterial
  transmission={0.95}      // 0-1, how much light passes through
  thickness={0.5}          // Simulated thickness
  roughness={0.05}
  ior={1.5}               // Index of refraction
  clearcoat={1}
  clearcoatRoughness={0.1}
/>

// Simple transparency
<meshStandardMaterial
  transparent
  opacity={0.5}
  side={THREE.DoubleSide}
/>

Material Comparison

| Property | Basic | Lambert | Standard | Physical | | ------------ | ----- | ------- | -------- | ------------ | | Lighting | No | Diffuse | PBR | Advanced PBR | | Roughness | No | No | Yes | Yes | | Metalness | No | No | Yes | Yes | | Clearcoat | No | No | No | Yes | | Transmission | No | No | No | Yes | | GPU Cost | Low | Low | Medium | High |

Anti-Patterns

DON'T:

  • Use meshPhysicalMaterial everywhere (performance killer)
  • Create new materials every render
  • Forget side={THREE.DoubleSide} for visible interiors
  • Use transmission without proper scene setup
  • Skip texture optimization (uncompressed textures)

DO:

  • Use simplest material that achieves the look
  • Reuse materials across similar objects
  • Use meshBasicMaterial for distant/small objects
  • Compress textures (WebP, basis universal)
  • Use material instances with drei

Performance Tips

// Share materials across instances
const sharedMaterial = useMemo(
  () => new THREE.MeshStandardMaterial({ color: 'red' }),
  []
);

// Use for many objects
<mesh material={sharedMaterial}>...</mesh>
<mesh material={sharedMaterial}>...</mesh>

Checklist

Before finalizing materials:

  • [ ] Appropriate material type for use case
  • [ ] Textures are optimized (compressed, power-of-2)
  • [ ] Materials shared where possible
  • [ ] Transparent materials have transparent: true
  • [ ] Double-sided materials explicitly set
  • [ ] Shader uniforms use refs for animation

Related Skills

For R3F fundamentals: Skill("ta-r3f-fundamentals") For performance optimization: Skill("ta-r3f-performance")

External References