271 lines
5.9 KiB
Markdown
271 lines
5.9 KiB
Markdown
# Three.js - Advanced Materials
|
|
|
|
PBR materials and custom shaders.
|
|
|
|
## MeshStandardMaterial (PBR)
|
|
|
|
Physically-based rendering with metallic/roughness workflow:
|
|
|
|
```javascript
|
|
const material = new THREE.MeshStandardMaterial({
|
|
color: 0xffffff,
|
|
metalness: 0.5, // 0 = dielectric, 1 = metal
|
|
roughness: 0.5, // 0 = smooth/shiny, 1 = rough/matte
|
|
|
|
map: colorTexture, // base color
|
|
normalMap: normalTexture, // surface detail
|
|
roughnessMap: roughnessTexture,
|
|
metalnessMap: metalnessTexture,
|
|
aoMap: aoTexture, // ambient occlusion
|
|
emissive: 0xff0000, // glow color
|
|
emissiveMap: emissiveTexture,
|
|
emissiveIntensity: 1.0,
|
|
|
|
envMap: environmentMap, // reflections
|
|
envMapIntensity: 1.0,
|
|
|
|
alphaMap: alphaTexture, // transparency control
|
|
transparent: true,
|
|
opacity: 1.0,
|
|
|
|
side: THREE.DoubleSide, // render both sides
|
|
flatShading: false // smooth normals
|
|
});
|
|
```
|
|
|
|
## MeshPhysicalMaterial (Enhanced PBR)
|
|
|
|
Extended PBR with clearcoat, transmission, sheen:
|
|
|
|
```javascript
|
|
const material = new THREE.MeshPhysicalMaterial({
|
|
// All MeshStandardMaterial properties plus:
|
|
|
|
// Clearcoat (protective layer)
|
|
clearcoat: 1.0,
|
|
clearcoatRoughness: 0.1,
|
|
clearcoatMap: clearcoatTexture,
|
|
clearcoatRoughnessMap: clearcoatRoughTexture,
|
|
clearcoatNormalMap: clearcoatNormalTexture,
|
|
|
|
// Transmission (transparency with refraction)
|
|
transmission: 1.0, // 0-1, glass-like
|
|
thickness: 0.5, // volumetric thickness
|
|
ior: 1.5, // index of refraction (glass = 1.5)
|
|
|
|
// Sheen (fabric-like edge glow)
|
|
sheen: 1.0,
|
|
sheenRoughness: 0.5,
|
|
sheenColor: new THREE.Color(0xffffff),
|
|
|
|
// Iridescence (rainbow effect)
|
|
iridescence: 1.0,
|
|
iridescenceIOR: 1.3,
|
|
iridescenceThicknessRange: [100, 400],
|
|
|
|
// Anisotropy (directional reflections)
|
|
anisotropy: 1.0,
|
|
anisotropyRotation: 0
|
|
});
|
|
```
|
|
|
|
## ShaderMaterial (Custom Shaders)
|
|
|
|
Full control over vertex and fragment shaders:
|
|
|
|
```javascript
|
|
const material = new THREE.ShaderMaterial({
|
|
uniforms: {
|
|
time: { value: 0.0 },
|
|
color: { value: new THREE.Color(0xff0000) },
|
|
texture1: { value: texture }
|
|
},
|
|
|
|
vertexShader: `
|
|
varying vec2 vUv;
|
|
varying vec3 vNormal;
|
|
|
|
void main() {
|
|
vUv = uv;
|
|
vNormal = normalize(normalMatrix * normal);
|
|
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
}
|
|
`,
|
|
|
|
fragmentShader: `
|
|
uniform float time;
|
|
uniform vec3 color;
|
|
uniform sampler2D texture1;
|
|
|
|
varying vec2 vUv;
|
|
varying vec3 vNormal;
|
|
|
|
void main() {
|
|
vec4 texColor = texture2D(texture1, vUv);
|
|
vec3 light = vec3(0.5, 0.2, 1.0);
|
|
float dProd = max(0.0, dot(vNormal, light));
|
|
|
|
gl_FragColor = vec4(color * dProd * texColor.rgb, 1.0);
|
|
}
|
|
`,
|
|
|
|
transparent: true,
|
|
side: THREE.DoubleSide
|
|
});
|
|
|
|
// Update uniform in animation loop
|
|
material.uniforms.time.value += 0.01;
|
|
```
|
|
|
|
## RawShaderMaterial
|
|
|
|
Like ShaderMaterial but without Three.js shader injection:
|
|
|
|
```javascript
|
|
const material = new THREE.RawShaderMaterial({
|
|
uniforms: {
|
|
// ...
|
|
},
|
|
vertexShader: `
|
|
precision mediump float;
|
|
precision mediump int;
|
|
|
|
uniform mat4 modelViewMatrix;
|
|
uniform mat4 projectionMatrix;
|
|
|
|
attribute vec3 position;
|
|
attribute vec2 uv;
|
|
|
|
varying vec2 vUv;
|
|
|
|
void main() {
|
|
vUv = uv;
|
|
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
}
|
|
`,
|
|
fragmentShader: `
|
|
precision mediump float;
|
|
|
|
varying vec2 vUv;
|
|
|
|
void main() {
|
|
gl_FragColor = vec4(vUv, 0.0, 1.0);
|
|
}
|
|
`
|
|
});
|
|
```
|
|
|
|
## Common Shader Patterns
|
|
|
|
### Fresnel Effect
|
|
```glsl
|
|
// In fragment shader
|
|
float fresnel = pow(1.0 - dot(vNormal, vViewDirection), 3.0);
|
|
gl_FragColor = vec4(mix(baseColor, edgeColor, fresnel), 1.0);
|
|
```
|
|
|
|
### Noise/Distortion
|
|
```glsl
|
|
// Simple noise function
|
|
float noise(vec2 p) {
|
|
return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453);
|
|
}
|
|
|
|
// UV distortion
|
|
vec2 distortedUV = vUv + vec2(
|
|
noise(vUv + time) * 0.1,
|
|
noise(vUv.yx + time) * 0.1
|
|
);
|
|
```
|
|
|
|
### Scrolling Texture
|
|
```glsl
|
|
uniform float time;
|
|
varying vec2 vUv;
|
|
|
|
vec2 scrollUV = vUv + vec2(time * 0.1, 0.0);
|
|
vec4 color = texture2D(map, scrollUV);
|
|
```
|
|
|
|
## Material Blending
|
|
|
|
```javascript
|
|
material.blending = THREE.AdditiveBlending;
|
|
// Options:
|
|
// THREE.NoBlending
|
|
// THREE.NormalBlending (default)
|
|
// THREE.AdditiveBlending (glow/light effects)
|
|
// THREE.SubtractiveBlending
|
|
// THREE.MultiplyBlending
|
|
|
|
// Custom blending
|
|
material.blending = THREE.CustomBlending;
|
|
material.blendEquation = THREE.AddEquation;
|
|
material.blendSrc = THREE.SrcAlphaFactor;
|
|
material.blendDst = THREE.OneMinusSrcAlphaFactor;
|
|
```
|
|
|
|
## Depth & Stencil
|
|
|
|
```javascript
|
|
// Depth testing
|
|
material.depthTest = true;
|
|
material.depthWrite = true;
|
|
material.depthFunc = THREE.LessEqualDepth;
|
|
|
|
// Alpha testing (discard transparent pixels)
|
|
material.alphaTest = 0.5;
|
|
|
|
// Render order
|
|
mesh.renderOrder = 1; // higher renders later
|
|
|
|
// Polygonoffset (prevent z-fighting)
|
|
material.polygonOffset = true;
|
|
material.polygonOffsetFactor = 1;
|
|
material.polygonOffsetUnits = 1;
|
|
```
|
|
|
|
## Material Cloning & Disposal
|
|
|
|
```javascript
|
|
// Clone material
|
|
const material2 = material.clone();
|
|
|
|
// Dispose when done (free GPU memory)
|
|
material.dispose();
|
|
texture.dispose();
|
|
geometry.dispose();
|
|
```
|
|
|
|
## Common Built-in Uniforms
|
|
|
|
Available in ShaderMaterial (automatic):
|
|
|
|
```glsl
|
|
// Matrices
|
|
uniform mat4 modelMatrix;
|
|
uniform mat4 modelViewMatrix;
|
|
uniform mat4 projectionMatrix;
|
|
uniform mat4 viewMatrix;
|
|
uniform mat3 normalMatrix;
|
|
|
|
// Camera
|
|
uniform vec3 cameraPosition;
|
|
|
|
// Attributes (vertex shader)
|
|
attribute vec3 position;
|
|
attribute vec3 normal;
|
|
attribute vec2 uv;
|
|
attribute vec2 uv2;
|
|
```
|
|
|
|
## Performance Tips
|
|
|
|
- Use MeshStandardMaterial for most cases (good balance)
|
|
- MeshPhysicalMaterial is expensive (use sparingly)
|
|
- ShaderMaterial requires GPU knowledge
|
|
- Avoid transparent materials when possible
|
|
- Use alphaTest instead of transparency for cutouts
|
|
- Minimize uniform updates
|
|
- Share materials between meshes
|