CommunityCodierung & Entwicklunggithub.com

UtkarshBirla28/threejs-materials

Auswahl und Konfiguration von three.js-Materialien – unlit, diffus, specular, PBR, Toon, Punkt- und Linienmaterialien – sowie gemeinsame Eigenschaften wie Blending und Stencil, Umgebungsreaktion und die WebGPU-Node-Material- und TSL-Äquivalente. Verwenden Sie dies beim Stylen von Meshes oder beim Anpassen des Materialverhaltens.

Was ist threejs-materials?

Diese Fähigkeit bietet eine umfassende Anleitung zur Auswahl und Konfiguration von Materialien in three.js, Version r186, mit besonderem Fokus auf WebGLRenderer und einem separaten Abschnitt für WebGPU und TSL. Sie deckt alle wichtigen Materialtypen ab, von einfachen unlit Materialien wie MeshBasicMaterial bis hin zu fortschrittlichen PBR-Materialien wie MeshPhysicalMaterial, einschließlich Spezialfällen wie MeshToonMaterial für Cel-Shading und PointsMaterial für Punktwolken. Die Anleitung enthält praktische Codebeispiele, erläutert gemeinsame Eigenschaften wie Textur-Farbräume, UV-Kanäle für Ambient Occlusion und Lightmaps, sowie Details zu ShaderMaterial und RawShaderMaterial für benutzerdefinierte GLSL-Shader. Ein lokaler Override-Abschnitt liefert spezifische Anpassungen für eine auf three.js r175 und Remotion basierte Animationspipeline, um Kompatibilitätsprobleme zu vermeiden und bewährte Verfahren für die frame-basierte Wiedergabe sicherzustellen.

Funktioniert mit✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/UtkarshBirla28/animated-shorts-pipeline/tree/HEAD/.claude/skills/threejs-materials

Installed? Explore more Codierung & Entwicklung skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Three.js-Materialien

Zielplattform: three.js r186. Die Beispiele verwenden WebGLRenderer; der Abschnitt zu WebGPU und TSL verwendet WebGPURenderer.

Lokaler Override (hinzugefügt 2026-11-10 von Claude für diesen PC; kein Teil des ursprünglichen Skills). Unsere Animationskurzfilm-Pipeline (<ROOT>\studio, von mromidev/claude-animated-shorts) ist auf three 0.175 (r175)

  • Remotion 4.0.290 + @react-three/fiber 9.1.2 + pmndrs postprocessing 6.37.2 festgelegt. Halten Sie three fest: shade.ts/cardshade.ts patcht three-Shader-Chunks mit Strings. Wenn Sie an dieser Pipeline arbeiten:
  • Ignorieren Sie "Häufige Fehler" / API-Hinweise, die r176+ erfordern (HDRLoader, Timer, PCFSoftShadowMap-Deprecation, setEffects, RenderPipeline, outputBufferType, mesh.pivot, Capsule height, TSL/WebGPU). Überprüfen Sie zuerst, ob die API in r175 existiert.
  • Animieren Sie niemals mit useFrame, Clock, Timer, delta time, setAnimationLoop oder requestAnimationFrame. Remotion rendert Bild für Bild: Leiten Sie jeden Wert von useCurrentFrame() / fps ab (und mixer.setTime(frame / fps) für Clips).
  • Post-Processing verwendet pmndrs postprocessing, nicht three/addons EffectComposer: Fügen Sie keinen OutputPass hinzu (doppelte sRGB-Kodierung).
  • Toon-Farben: Das Tone Mapping ist in unserem Composer NEUTRAL; achten Sie auf ACES-Standardwerte und tonemapping_fragment-Tönung.
  • Für andere three.js-Projekte gilt die ursprüngliche r186-Anleitung unten wie geschrieben.

Schnellstart

import * as THREE from "three";

const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

const scene = new THREE.Scene();

const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100);
camera.position.set(0, 0, 3);

// PBR-Material – die Standardwahl für beleuchtete, realistische Oberflächen
const material = new THREE.MeshStandardMaterial({
  color: 0x00aaff,
  roughness: 0.35,
  metalness: 0.1,
});
const mesh = new THREE.Mesh(new THREE.SphereGeometry(1, 48, 32), material);
scene.add(mesh);
scene.add(new THREE.HemisphereLight(0xffffff, 0x444444, 1)); // beleuchtete Materialien ohne Lichter schwarz rendern
const light = new THREE.DirectionalLight(0xffffff, 2);
light.position.set(3, 3, 3);
scene.add(light);

function animate() {
  mesh.rotation.y += 0.01;
  renderer.render(scene, camera);
}

renderer.setAnimationLoop(animate);

Übersicht über Materialtypen

MaterialAnwendungsfallBeleuchtung
MeshBasicMaterialUnlit Farbe, Texturen, DrahtgitterKeine
MeshLambertMaterialMatte diffuse OberflächenDiffus
MeshPhongMaterialGlänzendes Plastik, günstiger GlanzDiffus + Glanz
MeshStandardMaterialPBR Metall/Rauheits-WorkflowPBR
MeshPhysicalMaterialPBR plus Klarlack, Transmission, Schimmer, IrisierenPBR
MeshToonMaterialCel-ShadingToon-Stufen
MeshMatcapMaterialBeleuchteter Look in eine Matcap-Textur gebacken, keine Lichter benötigtGebacken
ShadowMaterialTransparente Oberfläche, die nur die empfangenen Schatten zeigtNur Schatten
PointsMaterialPunktwolkenKeine
LineBasicMaterial / LineDashedMaterialLinienKeine
ShaderMaterial / RawShaderMaterialBenutzerdefiniertes GLSL, nur WebGLRendererBenutzerdefiniert

Farb-Datentexturen (map, emissiveMap, specularMap, sheenColorMap, specularColorMap, LDR-Matcap, eine als Farbe verwendete Leinwand oder Video) benötigen texture.colorSpace = THREE.SRGBColorSpace, sonst werden Farben ausgewaschen dargestellt. Skalare Maps (normal, bump, displacement, roughness, metalness, ao, alpha, toon gradientMap) behalten die Standardeinstellung. HDR-Lader setzen ihren eigenen Farbraum.

MeshBasicMaterial

Keine Beleuchtungsberechnungen. Schnell, immer sichtbar. Unterstützt envMap mit reflectivity (0 bis 1) und combine (THREE.MultiplyOperation, THREE.MixOperation, THREE.AddOperation); specularMap (sRGB) maskiert den envMap-Beitrag.

const map = await new THREE.TextureLoader().loadAsync("color.jpg");
map.colorSpace = THREE.SRGBColorSpace;

const material = new THREE.MeshBasicMaterial({
  color: 0xffffff, // mit der Map multipliziert
  map,
  transparent: true,
  opacity: 0.5,
  side: THREE.DoubleSide, // FrontSide (Standard), BackSide, DoubleSide
  fog: true, // vom Szenen-Nebel beeinflusst
});

MeshLambertMaterial und MeshPhongMaterial

Lambert ist nur diffus. Phong fügt einen Glanzlichter-Highlight hinzu; es ist die günstige Alternative, wenn Standard zu schwer ist.

const lambert = new THREE.MeshLambertMaterial({
  color: 0x00ff00,
  emissive: 0x111111, // Eigenleuchtfarbe
  emissiveIntensity: 1,
});

const phong = new THREE.MeshPhongMaterial({
  color: 0x0000ff,
  specular: 0x111111, // Highlight-Farbe
  shininess: 30, // höher = schärferes Highlight
  flatShading: false, // flache vs. glatte Normalen
});

Beide unterstützen auch map, emissiveMap, specularMap (sRGB; maskiert die envMap-Reflexion und bei Phong das Highlight), normalMap, bumpMap, displacementMap, aoMap, envMap, envMapIntensity und envMapRotation.

MeshStandardMaterial (PBR)

Physikalisch basiertes Rendering. Empfohlen für realistische Ergebnisse.

const map = await new THREE.TextureLoader().loadAsync("color.jpg");
map.colorSpace = THREE.SRGBColorSpace;
const ormMap = await new THREE.TextureLoader().loadAsync("orm.jpg"); // glTF ORM: ao rot, roughness grün, metalness blau; skalar: Standardwert beibehalten

const material = new THREE.MeshStandardMaterial({
  color: 0xffffff, // mit der Map multipliziert
  roughness: 1.0, // 0 = Spiegel, 1 = vollständig diffus; mit roughnessMap (grün) multipliziert
  metalness: 1.0, // 0 = Dielektrikum, 1 = Metall; mit metalnessMap (blau) multipliziert, also bei einer Map auf 1 lassen
  map,
  roughnessMap: ormMap,
  metalnessMap: ormMap,
  normalMap: null, // Oberflächendetails; Skalierung mit normalScale (ein Vector2)
  aoMap: ormMap, // Ambient Occlusion (rot); Intensität mit aoMapIntensity
  displacementMap: null, // Vertex-Verschiebung; Skalierung mit displacementScale, Versatz mit displacementBias
  emissive: 0x000000,
  emissiveIntensity: 1,
  emissiveMap: null, // sRGB
  envMap: null, // oder auf scene.environment zurückgreifen (siehe unten)
  fog: true,
});

lightMap (mit lightMapIntensity) backt indirektes Licht genauso wie aoMap Okklusion backt; eine HDR- oder EXR-lightMap ist LinearSRGBColorSpace, was die Lader festlegen.

UV-Kanäle: aoMap und lightMap lesen den von Ihnen gewählten Kanal

Jede UV-gemappte Textur samplet das Attribut, das durch texture.channel ausgewählt wird: 0 liest uv (der Standard), 1 liest uv1, 2 liest uv2, 3 liest uv3. aoMap und lightMap benötigen kein zweites UV-Set – sie samplen uv, es sei denn, Sie ändern channel. GLTFLoader lädt TEXCOORD_1 als uv1 und setzt channel selbst.

const aoMap = await new THREE.TextureLoader().loadAsync("ao.jpg"); // skalar: Standardwert beibehalten
const material = new THREE.MeshStandardMaterial({ aoMap }); // samplet uv: kein zusätzliches Attribut erforderlich

// Alternative für eine separate Entfaltung (eine gebackene AO- oder Lightmap): Kopieren Sie die u,v-Paare Ihres Bakers in uv1
const bakedUv = new THREE.Float32BufferAttribute(mesh.geometry.attributes.position.count * 2, 2); // mit Nullen gefüllt, bis Sie sie hineinkopieren
mesh.geometry.setAttribute("uv1", bakedUv); mesh.material = material;
aoMap.channel = 1; // dieses Material samplet jetzt uv1 statt uv

MeshPhysicalMaterial (Erweitertes PBR)

Erweitert MeshStandardMaterial um Layer- und Volumenfunktionen. Texturvarianten existieren für die meisten davon: clearcoatMap, clearcoatRoughnessMap, clearcoatNormalMap, transmissionMap, thicknessMap, iridescenceMap, iridescenceThicknessMap, sheenColorMap, sheenRoughnessMap, anisotropyMap, specularIntensityMap, specularColorMap.

const material = new THREE.MeshPhysicalMaterial({
  // Klarlack (Autolack, Lack)
  clearcoat: 1.0, // 0 = keiner, 1 = vollständige Beschichtung
  clearcoatRoughness: 0.1,
  // Transmission (Glas, Wasser) – bricht die dahinter liegenden undurchsichtigen Objekte und den Szenenhintergrund
  transmission: 1.0, // 0 = undurchsichtig, 1 = vollständig durchlässig
  thickness: 0.5, // Volumendicke für Brechung
  attenuationDistance: 1, // Welteinheiten; Infinity (der Standard) = keine Absorption
  attenuationColor: new THREE.Color(0xffaa66), // weißes Licht wird nach attenuationDistance zu dieser Farbe
  ior: 1.5, // Brechungsindex, 1 bis 2,333
  // Schimmer (Stoff, Samt)
  sheen: 1.0,
  sheenColor: new THREE.Color(0xffffff),
  sheenRoughness: 0.5,
  // Irisieren (Seifenblasen, Ölfilme)
  iridescence: 1.0,
  iridescenceIOR: 1.3,
  iridescenceThicknessRange: [100, 400], // Nanometer
  // Anisotropie (gebürstetes Metall); Richtung mit anisotropyRotation
  anisotropy: 1.0,
  // Dispersion (prismatisches Glas); Retroreflexion (Verkehrsschilder, Sicherheitsausrüstung)
  dispersion: 0.0,
  retroreflectivity: 0.0,
  // Specular-Overrides: specularIntensity, specularColor (plus deren Maps)
});

Glas – Transmission mit einer glatten Oberfläche und etwas dahinter zum Brechen:

const glass = new THREE.MeshPhysicalMaterial({
  color: 0xffffff,
  metalness: 0,
  roughness: 0,
  transmission: 1,
  thickness: 0.5,
  ior: 1.5,
});
// transmission bricht die undurchsichtigen Objekte und den Hintergrund dahinter; scene.environment fügt seine Reflexionen hinzu

MeshToonMaterial

Cel-Shading. Die Gradienten-Map ist Nicht-Farbdaten – behalten Sie ihren Standard-Farbraum bei.

const steps = new Uint8Array([120, 200]); // zwei Schattierungsstufen
const gradientMap = new THREE.DataTexture(steps, 2, 1, THREE.RedFormat);
gradientMap.minFilter = THREE.NearestFilter; // harte Stufen; LinearFilter vermischt sie
gradientMap.magFilter = THREE.NearestFilter;
gradientMap.needsUpdate = true;

const material = new THREE.MeshToonMaterial({ color: 0x00ff00, gradientMap });

MeshNormalMaterial und MeshDepthMaterial

// Normalen als RGB codiert – Debugging und flache illustrative Darstellungen
const normals = new THREE.MeshNormalMaterial({ flatShading: false, wireframe: false });

// Tiefe als Graustufen (BasicDepthPacking, der Standard); RGBADepthPacking packt es zum Auslesen in einem Shader
const depth = new THREE.MeshDepthMaterial();

PointsMaterial

Für Punktwolken. size ist in Pixeln; mit sizeAttenuation (Standard, nur perspektivische Kameras) wird es mit der halben Canvas-Höhe multipliziert und durch die Tiefe des Punktes im View-Raum geteilt.

const geometry = new THREE.BufferGeometry();
geometry.setAttribute("position", new THREE.Float32BufferAttribute([0, 0, 0, 1, 0.5, 0, 0.5, 1, 0], 3));

const material = new THREE.PointsMaterial({
  color: 0xffffff,
  size: 0.1,
  sizeAttenuation: true, // mit der Entfernung skalieren
  alphaTest: 0.5, // mit einer map oder alphaMap: Fragmente unterhalb dieses Alphawerts verwerfen
});

const points = new THREE.Points(geometry, material);
scene.add(points);

LineBasicMaterial und LineDashedMaterial

WebGL und WebGPU zeichnen Linien-Primitive immer 1 px breit; linewidth, linecap und linejoin wirken sich nur auf den SVGRenderer aus. Für dicke Linien unter WebGLRenderer verwenden Sie Line2 mit LineGeometry und LineMaterial aus three/addons/lines/ (linewidth in Pixeln); LineMaterial ist ein ShaderMaterial, daher benötigt WebGPURenderer Line2 aus three/addons/lines/webgpu/Line2.js, welches Line2NodeMaterial verwendet.

const geometry = new THREE.BufferGeometry();
geometry.setAttribute("position", new THREE.Float32BufferAttribute([-1, 0, 0, 1, 0, 0], 3));

const solid = new THREE.LineBasicMaterial({ color: 0xffffff }); // immer 1 px

const dashed = new THREE.LineDashedMaterial({ color: 0xffffff, dashSize: 0.5, gapSize: 0.25 });
const line = new THREE.Line(geometry, dashed);
line.computeLineDistances(); // erforderlich, sonst wird die Linie durchgezogen gezeichnet
scene.add(line);

ShaderMaterial (nur WebGLRenderer)

Benutzerdefiniertes GLSL mit drei.js-Uniforms, die für Sie injiziert werden. Es wird immer als GLSL ES 3.00 kompiliert: texture(), textureLod() und dFdx funktionieren, und texture2D / gl_FragColor bleiben als Aliasse – lassen Sie glslVersion ungesetzt. ShaderMaterial, RawShaderMaterial und onBeforeCompile haben keinen WebGPURenderer-Pfad; verwenden Sie dort Node-Materialien und TSL.

const timer = new THREE.Timer();
timer.connect(document); // pausieren, wenn der Tab ausgeblendet ist

const material = new THREE.ShaderMaterial({
  uniforms: { time: { value: 0 } },
  vertexShader: `
    varying vec2 vUv;
    uniform float time;
    void main() {
      vUv = uv;
      vec3 pos = position;
      pos.z += sin(pos.x * 10.0 + time) * 0.1;
      gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
    }
  `,
  fragmentShader: `
    varying vec2 vUv;
    uniform float time;
    void main() {
      vec3 col = 0.5 + 0.5 * cos(time + vUv.xyx * 3.0);
      gl_FragColor = vec4(col, 1.0);
    }
  `,
});

function animate() {
  timer.update(); // als erstes jeden Frame, kein Argument
  material.uniforms.time.value = timer.getElapsed();
  renderer.render(scene, camera);
}

Für Sie im Shader deklariert: modelMatrix, modelViewMatrix, projectionMatrix, viewMatrix, normalMatrix, cameraPosition sowie die Attribute position, normal, uv (plus instanceMatrix bei einem InstancedMesh, das Sie selbst anwenden: projectionMatrix * modelViewMatrix * instanceMatrix * vec4(pos, 1.0), und color mit vertexColors). Die zusätzlichen UV-Sets und tangent werden nicht deklariert – fügen Sie in vec2 uv1; selbst hinzu.

RawShaderMaterial (nur WebGLRenderer)

Es werden keine Deklarationen vorangestellt (nur #version von glslVersion, die SHADER_TYPE- und SHADER_NAME-Defines sowie Ihre defines), aber der Renderer setzt trotzdem projectionMatrix, modelViewMatrix, viewMatrix, normalMatrix, modelMatrix und cameraPosition – deklarieren Sie sie im Shader und übergeben Sie sie niemals in uniforms: Ein gleichnamiger Eintrag wird bei jedem Draw überschrieben (modelMatrix, modelViewMatrix, normalMatrix) oder ersetzt den Wert der Kamera (projectionMatrix, viewMatrix, cameraPosition).

const material = new THREE.RawShaderMaterial({
  glslVersion: THREE.GLSL3, // ohne dies ist der Shader GLSL ES 1.00, das kein texture() hat
  vertexShader: `
    precision highp float;
    in vec3 position;
    uniform mat4 projectionMatrix;
    uniform mat4 modelViewMatrix;
    void main() {
      gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
  `,
  fragmentShader: `
    precision highp float;
    out vec4 fragColor;
    void main() {
      fragColor = vec4(1.0, 0.0, 0.0, 1.0);
    }
  `,
});

Gemeinsame Eigenschaften

Textur-Farbräume

  • Farbdaten (map, emissiveMap, specularMap, sheenColorMap, specularColorMap, Matcap, als Farbe verwendetes Video/Canvas): texture.colorSpace = THREE.SRGBColorSpace
  • Skalare Daten (normal, bump, displacement, roughness, metalness, ao, alpha, gradientMap): Standard THREE.LinearSRGBColorSpace belassen
  • HDR-Daten (PMREMGenerator, EXRLoader, RGBELoader): Lader setzen THREE.LinearSRGBColorSpace

side

  • THREE.FrontSide (Standard) – nur Vorderseite
  • THREE.BackSide – nur Rückseite (für Innenräume)
  • THREE.DoubleSide – beide Seiten (teurer, für transparente Blätter)

transparent

Legt fest, ob opaker Inhalt durch transparente Bereiche hindurchscheint und in welcher Reihenfolge Fragmente zusammengesetzt werden. Mit alphaTest können Fragmente unterhalb eines Schwellenwerts verworfen werden.

blending

  • THREE.NormalBlending (Standard)
  • THREE.AdditiveBlending – Farbe hinzufügen (Lichteffekte)
  • THREE.SubtractiveBlending – Farbe abziehen
  • THREE.MultiplyBlending – Farbe multiplizieren
  • THREE.CustomBlending – mit benutzerdefinierten blendSrc, blendDst, blendEquation, blendSrcAlpha, blendDstAlpha, blendEquationAlpha

stencil

Materialien können über die Stencil-Puffer-Funktionen des Renderers schreiben und testen: stencilWrite, stencilRef, stencilFunc, stencilFail, stencilZFail, stencilZPass.

depthWrite / depthTest

depthWrite (Standard true) steuert, ob das Material in den Tiefenpuffer schreibt. depthTest testet gegen den Tiefenpuffer. Schalten Sie depthWrite aus für transparente Objekte, wenn die Sortierung nicht der einzige Grund für Artefakte ist.

polygonOffset

Verhindert Z-Fighting, wenn zwei Flächen auf derselben Ebene liegen: polygonOffset, polygonOffsetFactor, polygonOffsetUnits.

Umgebungsreaktion und Beleuchtung

scene.environment

Setzen Sie scene.environment = pmremGenerator.fromScene(...).texture für Standard-Environment-Maps (falls ein Mesh keine eigene envMap hat). MeshPhysicalMaterial respektiert dies ebenfalls.

const pmremGenerator = new THREE.PMREMGenerator(renderer);
const envMapTexture = pmremGenerator.fromScene(new THREE.RoomEnvironment()).texture;
scene.environment = envMapTexture;

const material = new THREE.MeshStandardMaterial(); // verwendet scene.environment

envMap am Material

Eine Material-eigene envMap überschreibt scene.environment:

material.envMap = envMapTexture; // verwendet diese statt scene.environment
material.envMapIntensity = 1.5; // Standard 1
material.envMapRotation = new THREE.Euler(0, Math.PI / 2, 0); // Drehung der envMap um y

Lichter

Beleuchtete Materialien (Lambert, Phong, Standard, Physical, Toon) benötigen Lichter in der Szene, sonst sind sie schwarz. Fügen Sie immer mindestens ein ambient oder hemisphere light hinzu:

// Sanftes Umgebungslicht
scene.add(new THREE.AmbientLight(0xffffff, 0.5));
scene.add(new THREE.HemisphereLight(0xffffff, 0x444444, 1));
scene.add(new THREE.DirectionalLight(0xffffff, 2));

WebGPU und TSL (WebGPURenderer)

Ab three.js r186 (r185+ experimentell) bietet TSL (Three Shading Language) eine Alternative zu ShaderMaterial und Node-Materialien. Hier gezeigt mit dem WebGPURenderer.

import { WebGPURenderer, PostProcessing } from "three/addons";

const renderer = new WebGPURenderer();
const context = renderer.getContext();

// Beispiel für ein benutzerdefiniertes Node-Material mit TSL
const material = new THREE.MeshStandardNodeMaterial();
material.colorNode = new THREE.Color(0x00aaff).toNode();

TSL-Dokumentation in Entwicklung; siehe r186-Änderungsprotokoll.

Häufige Fehler

  1. Farbraum nicht gesetzt: map.colorSpace muss THREE.SRGBColorSpace für Farbdaten sein.
  2. Lichter vergessen: Beleuchtete Materialien ohne Lichter ergeben Schwarz.
  3. ShaderMaterial nur WebGL: Verwenden Sie für WebGPU Node-Materialien oder TSL.
  4. linewidth: WebGL/WebGPU ignorieren linewidth > 1; verwenden Sie Line2.
  5. depthWrite bei Transparenz: Deaktivieren Sie depthWrite nicht standardmäßig; schalten Sie es nur bei Bedarf aus.

Siehe auch

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Verwandte Skills