init
This commit is contained in:
270
.opencode/skills/threejs/references/11-materials-advanced.md
Normal file
270
.opencode/skills/threejs/references/11-materials-advanced.md
Normal file
@@ -0,0 +1,270 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user