✨ Shaderid ja Visuaalsed Efektid
GLSL vertex/fragment shaderid, post-processing, bloom, cel-shading — kontrolli iga pikslit ekraanil!
🎨 Samm 1 — GLSL Põhialused
Shaderid on programmid mis jooksevad GPU-l. Vertex shader liigutab punkte, fragment shader värvib piksleid.
// Vertex Shader — iga tipu jaoks
uniform float uTime;
varying vec2 vUv; // Edasta fragment shaderile
varying vec3 vNormal;
varying vec3 vPosition;
void main() {
vUv = uv;
vNormal = normal;
vPosition = position;
// Laineline deformatsioon
vec3 pos = position;
pos.y += sin(pos.x * 3.0 + uTime * 2.0) * 0.3;
pos.y += cos(pos.z * 2.0 + uTime * 1.5) * 0.2;
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
}
// Fragment Shader — iga piksli jaoks
uniform float uTime;
uniform vec3 uColor;
uniform sampler2D uTexture;
varying vec2 vUv;
varying vec3 vNormal;
varying vec3 vPosition;
void main() {
// Lihtne valgustusmudel
vec3 lightDir = normalize(vec3(1.0, 1.0, 1.0));
float diff = max(dot(vNormal, lightDir), 0.0);
// Aeg-põhine värvivahetus
vec3 color = uColor;
color.r += sin(uTime) * 0.2;
color.g += cos(uTime * 0.7) * 0.2;
// Lõplik piksel
gl_FragColor = vec4(color * (diff * 0.8 + 0.2), 1.0);
}
🔧 Samm 2 — ShaderMaterial Three.js-s
import * as THREE from 'three';
const customMaterial = new THREE.ShaderMaterial({
uniforms: {
uTime: { value: 0 },
uColor: { value: new THREE.Color(0.13, 0.77, 0.36) },
uResolution: { value: new THREE.Vector2(window.innerWidth, window.innerHeight) },
},
vertexShader: `
uniform float uTime;
varying vec2 vUv;
varying vec3 vNormal;
void main() {
vUv = uv;
vNormal = normal;
vec3 pos = position;
pos += normal * sin(pos.y * 5.0 + uTime * 3.0) * 0.1;
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
}
`,
fragmentShader: `
uniform float uTime;
uniform vec3 uColor;
varying vec2 vUv;
varying vec3 vNormal;
void main() {
// Fresnel efekt (ääre helendus)
vec3 viewDir = normalize(cameraPosition - vNormal);
float fresnel = pow(1.0 - max(dot(vNormal, viewDir), 0.0), 3.0);
vec3 color = uColor + fresnel * vec3(0.3, 0.6, 1.0);
// Pulseeriv alpha
float alpha = 0.8 + sin(uTime * 2.0) * 0.2;
gl_FragColor = vec4(color, alpha);
}
`,
transparent: true,
side: THREE.DoubleSide,
});
// Mängutsüklis:
// customMaterial.uniforms.uTime.value = clock.getElapsedTime();
🌟 Samm 3 — Post-Processing
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer';
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass';
import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass';
import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass';
// Composer
const composer = new EffectComposer(renderer);
// 1. Render pass — põhi renderdamine
composer.addPass(new RenderPass(scene, camera));
// 2. Bloom — helendusefekt
const bloomPass = new UnrealBloomPass(
new THREE.Vector2(window.innerWidth, window.innerHeight),
0.8, // strength
0.3, // radius
0.85 // threshold
);
composer.addPass(bloomPass);
// 3. Custom post-processing shader (vignette)
const vignetteShader = {
uniforms: {
tDiffuse: { value: null },
uIntensity: { value: 0.4 },
},
vertexShader: `
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`,
fragmentShader: `
uniform sampler2D tDiffuse;
uniform float uIntensity;
varying vec2 vUv;
void main() {
vec4 color = texture2D(tDiffuse, vUv);
float dist = distance(vUv, vec2(0.5));
color.rgb *= 1.0 - dist * uIntensity;
gl_FragColor = color;
}
`,
};
composer.addPass(new ShaderPass(vignetteShader));
// Mängutsüklis kasuta composer.render() mitte renderer.render()
function animate() {
requestAnimationFrame(animate);
composer.render();
}
🖌️ Samm 4 — Populaarsed Shader Efektid
// Fragment shader — cel-shading
fragmentShader: `
varying vec3 vNormal;
uniform vec3 uColor;
uniform vec3 uLightDir;
void main() {
float intensity = dot(normalize(vNormal), normalize(uLightDir));
// Kvantiseeri valgus 4 tasemele
vec3 color;
if (intensity > 0.95) color = uColor * 1.0;
else if (intensity > 0.5) color = uColor * 0.7;
else if (intensity > 0.25) color = uColor * 0.4;
else color = uColor * 0.2;
gl_FragColor = vec4(color, 1.0);
}
`,
// Piirjoonte shader (outline)
// Teine pass — suurenda objekti normaalide suunas ja joonista mustana
outlineVertexShader: `
void main() {
vec3 pos = position + normal * 0.05;
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
}
`,
outlineFragmentShader: `
void main() {
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
}
`
📝 Harjutused
-
Esimene custom shader
Loo ShaderMaterial: vertex shader liigutab tippe sinusoidaalselt, fragment shader värvib UV-koordinaatide järgi. Lisa
uTimeuniform animatsiooniks. -
Fresnel ja hologramm efekt
Loo hologrammiline materjal: läbipaistev keskelt, helendav äärtest (Fresnel). Lisa skaneerimisjoone efekt mis liigub üles-alla. Sinine toon.
-
Post-processing pipeline
Seadista EffectComposer: Bloom (helendavad objektid), vignette (pimenev ääris), chromatic aberration (värvi nihe). GUI kontrollid igale efektile.
-
Cel-shading / toon shader
Loo cel-shading materjal: kvantiseeritud valgustus (3-4 astet), must piirjoon (outline pass). Rakenda 3D tegelasele. Anime/joonistusfilmi stiil.
-
Shader galerii
Loo veebileht 6+ erineva shader efektiga: vesi, tuli, portaal, dissolve, force field, glitch. Iga efekt oma sfääri/kuubiku peal. Lisa GUI kontrollid.