WebGL Shaders
Custom shader implementation for advanced molecular visualization effects.
Shader Types
Vertex Shaders
Transform vertex positions and calculate lighting
Fragment Shaders
Calculate final pixel colors and effects
Shader Configuration
interface ShaderConfig {
vertexShader: string; // Vertex shader source code
fragmentShader: string; // Fragment shader source code
uniforms?: { // Shader uniforms
[key: string]: {
type: string; // Uniform type
value: any; // Uniform value
};
};
attributes?: { // Vertex attributes
[key: string]: {
size: number; // Attribute size
type: string; // Attribute type
normalized?: boolean; // Normalize attribute values
};
};
}
Built-in Shaders
Phong Shader
Classic Phong lighting model
// Vertex shader
varying vec3 vNormal;
varying vec3 vPosition;
void main() {
vNormal = normalize(normalMatrix * normal);
vPosition = position;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
// Fragment shader
uniform vec3 color;
uniform float shininess;
varying vec3 vNormal;
varying vec3 vPosition;
void main() {
vec3 light = normalize(vec3(1.0, 1.0, 1.0));
float diff = max(dot(vNormal, light), 0.0);
vec3 viewDir = normalize(cameraPosition - vPosition);
vec3 reflectDir = reflect(-light, vNormal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), shininess);
gl_FragColor = vec4(color * (diff + spec), 1.0);
}
Toon Shader
Cel-shading effect
// Vertex shader
varying vec3 vNormal;
varying vec3 vPosition;
void main() {
vNormal = normalize(normalMatrix * normal);
vPosition = position;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
// Fragment shader
uniform vec3 color;
uniform float levels;
varying vec3 vNormal;
varying vec3 vPosition;
void main() {
vec3 light = normalize(vec3(1.0, 1.0, 1.0));
float diff = max(dot(vNormal, light), 0.0);
float level = floor(diff * levels) / levels;
gl_FragColor = vec4(color * level, 1.0);
}
Wireframe Shader
Edge detection and wireframe rendering
// Vertex shader
varying vec3 vBarycentric;
void main() {
vBarycentric = barycentric;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
// Fragment shader
uniform vec3 color;
uniform float lineWidth;
varying vec3 vBarycentric;
void main() {
vec3 d = fwidth(vBarycentric);
vec3 a3 = smoothstep(vec3(0.0), d * lineWidth, vBarycentric);
float edge = min(min(a3.x, a3.y), a3.z);
gl_FragColor = vec4(color, 1.0 - edge);
}
Example
// Create custom shader
const shader = new GLShader({
vertexShader: `
varying vec3 vNormal;
varying vec3 vPosition;
void main() {
vNormal = normalize(normalMatrix * normal);
vPosition = position;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`,
fragmentShader: `
uniform vec3 color;
uniform float time;
varying vec3 vNormal;
varying vec3 vPosition;
void main() {
vec3 light = normalize(vec3(1.0, 1.0, 1.0));
float diff = max(dot(vNormal, light), 0.0);
float pulse = sin(time * 2.0) * 0.5 + 0.5;
gl_FragColor = vec4(color * (diff + pulse), 1.0);
}
`,
uniforms: {
color: { type: 'vec3', value: new THREE.Color(0xff0000) },
time: { type: 'float', value: 0 }
}
});
// Update shader uniforms
function animate() {
shader.uniforms.time.value += 0.016;
requestAnimationFrame(animate);
}
animate();
Related Topics
Learn more about WebGL implementation: