mcpField
R
r3f-materials

r3f-materials

github.com/bbeierle12开发969 次安装1 天前更新
代码仓库

关于 r3f-materials

面向 React Three Fiber 开发者的材质参考技能,涵盖 3D 表面外观与着色器效果。内容从内置材质选择延伸到 GLSL 自定义和 uniform 管理。

主要功能

  1. 01内置材质对比
  2. 02常见材质属性
  3. 03GLSL ShaderMaterial 指南
  4. 04Uniform 类型与动画
  5. 05RawShaderMaterial 示例
  6. 06PBR 与着色器参考

适用场景

  1. 01为 3D 场景选择材质
  2. 02创建自定义着色器效果
  3. 03制作着色器 uniform 动画

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/bbeierle12/skill-mcp-claude --skill r3f-materials

安装后在 Claude Code 中输入/r3f-materials确认已加载。

附带文件_meta.jsonreferences/shader-templates.md

详细介绍

R3F 材质

材质定义表面的外观,包括颜色、纹理、反射率、透明度和自定义着色器效果。

快速入门

// Built-in material
<mesh>
  <boxGeometry />
  <meshStandardMaterial color="hotpink" metalness={0.8} roughness={0.2} />
</mesh>

// Custom shader
<mesh>
  <planeGeometry />
  <shaderMaterial
    uniforms={{ uTime: { value: 0 } }}
    vertexShader={vertexShader}
    fragmentShader={fragmentShader}
  />
</mesh>

内置材质

材质比较
材质光照使用场景性能
MeshBasicMaterial无UI、无光照、调试最快
MeshStandardMaterialPBR通用 3D良好
MeshPhysicalMaterialPBR+玻璃、汽车漆较慢
MeshLambertMaterial漫反射哑光表面快
MeshPhongMaterial高光闪亮塑料快
MeshToonMaterial卡通着色风格化效果良好
MeshNormalMaterial无调试法线最快
MeshDepthMaterial无深度通道最快
MeshBasicMaterial(无光照)
<meshBasicMaterial
  color="#ff0000"           // Base color
  map={texture}             // Color texture
  transparent={true}        // Enable transparency
  opacity={0.5}             // Transparency level
  alphaMap={alphaTexture}   // Transparency texture
  side={THREE.DoubleSide}   // Render both sides
  wireframe={true}          // Wireframe mode
  fog={false}               // Ignore scene fog
/>
MeshStandardMaterial(PBR)
<meshStandardMaterial
  // Base
  color="#ffffff"
  map={colorTexture}
  
  // PBR properties
  metalness={0.5}           // 0 = dielectric, 1 = metal
  metalnessMap={metalMap}
  roughness={0.5}           // 0 = mirror, 1 = diffuse
  roughnessMap={roughMap}
  
  // Normal mapping
  normalMap={normalTexture}
  normalScale={[1, 1]}
  
  // Ambient occlusion
  aoMap={aoTexture}
  aoMapIntensity={1}
  
  // Displacement
  displacementMap={dispMap}
  displacementScale={0.1}
  
  // Emission
  emissive="#000000"
  emissiveMap={emissiveTexture}
  emissiveIntensity={1}
  
  // Environment
  envMap={cubeTexture}
  envMapIntensity={1}
/>
MeshPhysicalMaterial(高级 PBR)
<meshPhysicalMaterial
  // Inherits all MeshStandardMaterial props, plus:
  
  // Clearcoat (car paint, lacquer)
  clearcoat={1}
  clearcoatRoughness={0.1}
  clearcoatNormalMap={ccNormal}
  
  // Transmission (glass, water)
  transmission={0.9}        // 0 = opaque, 1 = fully transmissive
  thickness={0.5}           // Volume thickness
  ior={1.5}                 // Index of refraction
  
  // Sheen (fabric, velvet)
  sheen={1}
  sheenRoughness={0.5}
  sheenColor="#ff00ff"
  
  // Iridescence (soap bubbles, oil slicks)
  iridescence={1}
  iridescenceIOR={1.3}
  iridescenceThicknessRange={[100, 400]}
/>
MeshToonMaterial(卡通着色)
<meshToonMaterial
  color="#6fa8dc"
  gradientMap={gradientTexture}  // 3-5 color ramp texture
/>

// Create gradient texture
const gradientTexture = useMemo(() => {
  const canvas = document.createElement('canvas');
  canvas.width = 4;
  canvas.height = 1;
  const ctx = canvas.getContext('2d')!;
  
  // 4-step toon shading
  ctx.fillStyle = '#444'; ctx.fillRect(0, 0, 1, 1);
  ctx.fillStyle = '#888'; ctx.fillRect(1, 0, 1, 1);
  ctx.fillStyle = '#bbb'; ctx.fillRect(2, 0, 1, 1);
  ctx.fillStyle = '#fff'; ctx.fillRect(3, 0, 1, 1);
  
  const texture = new THREE.CanvasTexture(canvas);
  texture.minFilter = THREE.NearestFilter;
  texture.magFilter = THREE.NearestFilter;
  
  return texture;
}, []);

常用属性(所有材质)

<meshStandardMaterial
  // Rendering
  transparent={false}
  opacity={1}
  alphaTest={0}           // Discard pixels below threshold
  alphaToCoverage={false} // MSAA alpha
  
  // Faces
  side={THREE.FrontSide}  // FrontSide | BackSide | DoubleSide
  
  // Depth
  depthTest={true}
  depthWrite={true}
  
  // Stencil
  stencilWrite={false}
  stencilFunc={THREE.AlwaysStencilFunc}
  
  // Blending
  blending={THREE.NormalBlending}
  
  // Other
  visible={true}
  fog={true}
  toneMapped={true}
/>

纹理

加载纹理
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>
  );
}
纹理设置
import { useTexture } from '@react-three/drei';
import * as THREE from 'three';

const texture = useTexture('/texture.jpg', (tex) => {
  tex.wrapS = tex.wrapT = THREE.RepeatWrapping;
  tex.repeat.set(4, 4);
  tex.anisotropy = 16;  // Sharper at angles
});

ShaderMaterial

通过 GLSL 顶点着色器和片元着色器进行完全控制:

import { useRef } from 'react';
import { useFrame } from '@react-three/fiber';
import * as THREE from 'three';

const vertexShader = `
  varying vec2 vUv;
  varying vec3 vNormal;
  
  void main() {
    vUv = uv;
    vNormal = normalize(normalMatrix * normal);
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
  }
`;

const fragmentShader = `
  uniform float uTime;
  uniform vec3 uColor;
  varying vec2 vUv;
  varying vec3 vNormal;
  
  void main() {
    float pulse = sin(uTime * 2.0) * 0.5 + 0.5;
    vec3 color = mix(uColor, vec3(1.0), pulse * 0.3);
    
    // Simple rim lighting
    float rim = 1.0 - dot(vNormal, vec3(0.0, 0.0, 1.0));
    color += rim * 0.5;
    
    gl_FragColor = vec4(color, 1.0);
  }
`;

function CustomShaderMesh() {
  const materialRef = useRef<THREE.ShaderMaterial>(null!);
  
  useFrame(({ clock }) => {
    materialRef.current.uniforms.uTime.value = clock.elapsedTime;
  });
  
  return (
    <mesh>
      <sphereGeometry args={[1, 32, 32]} />
      <shaderMaterial
        ref={materialRef}
        vertexShader={vertexShader}
        fragmentShader={fragmentShader}
        uniforms={{
          uTime: { value: 0 },
          uColor: { value: new THREE.Color('#ff6b6b') }
        }}
      />
    </mesh>
  );
}

Uniform

Uniform 类型
uniforms={{
  // Scalars
  uFloat: { value: 1.0 },
  uInt: { value: 1 },
  uBool: { value: true },
  
  // Vectors
  uVec2: { value: new THREE.Vector2(1, 2) },
  uVec3: { value: new THREE.Vector3(1, 2, 3) },
  uVec4: { value: new THREE.Vector4(1, 2, 3, 4) },
  uColor: { value: new THREE.Color('#ff0000') },
  
  // Matrices
  uMat3: { value: new THREE.Matrix3() },
  uMat4: { value: new THREE.Matrix4() },
  
  // Textures
  uTexture: { value: texture },
  uCubeTexture: { value: cubeTexture },
  
  // Arrays
  uFloatArray: { value: [1.0, 2.0, 3.0] },
  uVec3Array: { value: [new THREE.Vector3(), new THREE.Vector3()] }
}}
为 Uniform 添加动画
function AnimatedShader() {
  const materialRef = useRef<THREE.ShaderMaterial>(null!);
  
  useFrame(({ clock, mouse }) => {
    const uniforms = materialRef.current.uniforms;
    
    uniforms.uTime.value = clock.elapsedTime;
    uniforms.uMouse.value.set(mouse.x, mouse.y);
    uniforms.uResolution.value.set(window.innerWidth, window.innerHeight);
  });
  
  return (
    <shaderMaterial
      ref={materialRef}
      uniforms={{
        uTime: { value: 0 },
        uMouse: { value: new THREE.Vector2() },
        uResolution: { value: new THREE.Vector2() }
      }}
      // ...
    />
  );
}
共享 Uniform
// Create shared uniform object
const globalUniforms = useMemo(() => ({
  uTime: { value: 0 },
  uGlobalColor: { value: new THREE.Color('#00ff00') }
}), []);

// Update in useFrame
useFrame(({ clock }) => {
  globalUniforms.uTime.value = clock.elapsedTime;
});

// Use in multiple materials
<mesh>
  <boxGeometry />
  <shaderMaterial uniforms={{ ...globalUniforms, uLocalProp: { value: 1 } }} />
</mesh>

<mesh position={[2, 0, 0]}>
  <sphereGeometry />
  <shaderMaterial uniforms={{ ...globalUniforms, uLocalProp: { value: 2 } }} />
</mesh>

RawShaderMaterial

没有内置 Uniform 或属性,可进行完全控制:

<rawShaderMaterial
  vertexShader={`
    precision highp float;
    
    // Must declare all inputs manually
    attribute vec3 position;
    attribute vec2 uv;
    
    uniform mat4 projectionMatrix;
    uniform mat4 modelViewMatrix;
    
    varying vec2 vUv;
    
    void main() {
      vUv = uv;
      gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
  `}
  fragmentShader={`
    precision highp float;
    
    varying vec2 vUv;
    
    void main() {
      gl_FragColor = vec4(vUv, 0.0, 1.0);
    }
  `}
/>

材质扩展

扩展现有材质
import { extend } from '@react-three/fiber';
import { shaderMaterial } from '@react-three/drei';

// Create extended material
const GradientMaterial = shaderMaterial(
  // Uniforms
  { uColorA: new THREE.Color('#ff0000'), uColorB: new THREE.Color('#0000ff') },
  // Vertex
  `
    varying vec2 vUv;
    void main() {
      vUv = uv;
      gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
  `,
  // Fragment
  `
    uniform vec3 uColorA;
    uniform vec3 uColorB;
    varying vec2 vUv;
    void main() {
      gl_FragColor = vec4(mix(uColorA, uColorB, vUv.y), 1.0);
    }
  `
);

// Register with R3F
extend({ GradientMaterial });

// Use in JSX
function Gradient() {
  return (
    <mesh>
      <planeGeometry args={[2, 2]} />
      <gradientMaterial uColorA="#ff0000" uColorB="#0000ff" />
    </mesh>
  );
}

性能技巧

技巧使用时机
共享材质多个网格具有相同外观时
使用开销更低的材质远处的物体(Basic 而非 Standard)
限制纹理尺寸移动设备、大型场景
禁用不需要的功能fog={false}、toneMapped={false}
材质复用
// Define once
const sharedMaterial = useMemo(() => (
  <meshStandardMaterial color="red" roughness={0.5} />
), []);

// Reuse (same GPU program)
{items.map((item, i) => (
  <mesh key={i} position={item.pos}>
    <boxGeometry />
    {sharedMaterial}
  </mesh>
))}

文件结构

r3f-materials/
├── SKILL.md
├── references/
│   ├── pbr-properties.md     # PBR material deep-dive
│   ├── uniform-types.md      # Complete uniform reference
│   └── shader-templates.md   # Common shader patterns
└── scripts/
    ├── materials/
    │   ├── gradient.ts       # Gradient shader material
    │   ├── fresnel.ts        # Fresnel/rim effect
    │   └── dissolve.ts       # Dissolve effect
    └── utils/
        └── uniform-helpers.ts # Uniform animation utilities

参考资料

  • references/pbr-properties.md — 深入了解 PBR 材质属性
  • references/uniform-types.md — 所有 Uniform 类型及其 GLSL 映射
  • references/shader-templates.md — 常见着色器效果模式

评论

支持 Markdown