Prompt
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebGL Milkdrop-style Visualizer</title>
<style>
body { margin: 0; overflow: hidden; }
canvas { width: 100%; height: 100%; }
</style>
</head>
<body>
<canvas id="glCanvas"></canvas>
<script>
const canvas = document.getElementById('glCanvas');
const gl = canvas.getContext('webgl');
if (!gl) {
alert('WebGL not supported');
throw new Error('WebGL not supported');
}
const vertexShaderSource = `
attribute vec4 a_position;
void main() {
gl_Position = a_position;
}
`;
const fragmentShaderSource = `
precision mediump float;
uniform vec2 u_resolution;
uniform float u_time;
vec3 palette(float t) {
vec3 a = vec3(0.5, 0.5, 0.5);
vec3 b = vec3(0.5, 0.5, 0.5);
vec3 c = vec3(1.0, 1.0, 1.0);
vec3 d = vec3(0.263, 0.416, 0.557);
return a + b * cos(6.28318 * (c * t + d));
}
void main() {
vec2 uv = (gl_FragCoord.xy * 2.0 - u_resolution.xy) / u_resolution.y;
vec2 uv0 = uv;
vec3 finalColor = vec3(0.0);
for (float i = 0.0; i < 4.0; i++) {
uv = fract(uv * 1.5) - 0.5;
float d = length(uv) * exp(-length(uv0));
vec3 col = palette(length(uv0) + i*.4 + u_time*.4);
d = sin(d*8. + u_time)/8.;
d = abs(d);
d = pow(0.01 / d, 1.2);
finalColor += col * d;
}
gl_FragColor = vec4(finalColor, 1.0);
}
`;
function createShader(gl, type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.error('Shader compilation error:', gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
return null;
}
return shader;
}
const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
console.error('Program linking error:', gl.getProgramInfoLog(program));
throw new Error('Program linking error');
}
const positionAttributeLocation = gl.getAttribLocation(program, 'a_position');
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
const positions = [
-1, -1,
1, -1,
-1, 1,
1, 1,
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
const resolutionUniformLocation = gl.getUniformLocation(program, 'u_resolution');
const timeUniformLocation = gl.getUniformLocation(program, 'u_time');
function resizeCanvasToDisplaySize(canvas) {
const displayWidth = canvas.clientWidth;
const displayHeight = canvas.clientHeight;
if (canvas.width !== displayWidth || canvas.height !== displayHeight) {
canvas.width = displayWidth;
canvas.height = displayHeight;
}
}
function render(time) {
resizeCanvasToDisplaySize(gl.canvas);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.useProgram(program);
gl.enableVertexAttribArray(positionAttributeLocation);
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height);
gl.uniform1f(timeUniformLocation, time * 0.001);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
</script>
</body>
</html>
Answer
Explanation of the WebGL Milkdrop-style Visualizer Code
HTML Structure
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebGL Milkdrop-style Visualizer</title>
<style>
body { margin: 0; overflow: hidden; }
canvas { width: 100%; height: 100%; }
</style>
</head>
<body>
<canvas id="glCanvas"></canvas>
<script src="script.js"></script>
</body>
</html>
<!DOCTYPE html>
: Indicates that the document is HTML5.<html lang="en">
: Starts the HTML document, specifying the language as English.<head>
: Contains meta-information about the document.<meta charset="UTF-8">
: Specifies the character encoding.<meta name="viewport" content="width=device-width, initial-scale=1.0">
: Ensures the website scales correctly on all devices.<title>
: Sets the title of the webpage.<style>
: Adds CSS directly within the HTML for styling purposes. It sets the body to have no margin and the canvas to take up the full width and height of the screen.
<body>
: The main content of the document.<canvas id="glCanvas"></canvas>
: HTML canvas element where the WebGL rendering will occur.<script src="script.js"></script>
: Links to an external JavaScript file that brings the visualization to life (assuming code would be moved there).
JavaScript (WebGL Implementation)
const canvas = document.getElementById('glCanvas');
const gl = canvas.getContext('webgl');
if (!gl) {
alert('WebGL not supported');
throw new Error('WebGL not supported');
}
// Vertex Shader Source Code
const vertexShaderSource = `
attribute vec4 a_position;
void main() {
gl_Position = a_position;
}
`;
// Fragment Shader Source Code
const fragmentShaderSource = `
precision mediump float;
uniform vec2 u_resolution;
uniform float u_time;
vec3 palette(float t) {
vec3 a = vec3(0.5, 0.5, 0.5);
vec3 b = vec3(0.5, 0.5, 0.5);
vec3 c = vec3(1.0, 1.0, 1.0);
vec3 d = vec3(0.263, 0.416, 0.557);
return a + b * cos(6.28318 * (c * t + d));
}
void main() {
vec2 uv = (gl_FragCoord.xy * 2.0 - u_resolution.xy) / u_resolution.y;
vec2 uv0 = uv;
vec3 finalColor = vec3(0.0);
for (float i = 0.0; i < 4.0; i++) {
uv = fract(uv * 1.5) - 0.5;
float d = length(uv) * exp(-length(uv0));
vec3 col = palette(length(uv0) + i*.4 + u_time*.4);
d = sin(d*8. + u_time)/8.;
d = abs(d);
d = pow(0.01 / d, 1.2);
finalColor += col * d;
}
gl_FragColor = vec4(finalColor, 1.0);
}
`;
// Function to Create Shader
function createShader(gl, type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.error('Shader compilation error:', gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
return null;
}
return shader;
}
const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
console.error('Program linking error:', gl.getProgramInfoLog(program));
throw new Error('Program linking error');
}
const positionAttributeLocation = gl.getAttribLocation(program, 'a_position');
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
const positions = [
-1, -1,
1, -1,
-1, 1,
1, 1,
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
const resolutionUniformLocation = gl.getUniformLocation(program, 'u_resolution');
const timeUniformLocation = gl.getUniformLocation(program, 'u_time');
function resizeCanvasToDisplaySize(canvas) {
const displayWidth = canvas.clientWidth;
const displayHeight = canvas.clientHeight;
if (canvas.width !== displayWidth || canvas.height !== displayHeight) {
canvas.width = displayWidth;
canvas.height = displayHeight;
}
}
function render(time) {
resizeCanvasToDisplaySize(gl.canvas);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.useProgram(program);
gl.enableVertexAttribArray(positionAttributeLocation);
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height);
gl.uniform1f(timeUniformLocation, time * 0.001);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
Steps Explained
Canvas and WebGL Context Initialization:
const canvas = document.getElementById('glCanvas');
: Selects the<canvas>
element by its ID.const gl = canvas.getContext('webgl');
: Retrieves the WebGL rendering context. If WebGL is not supported, an alert is shown and an error is thrown.
Shader Source Code:
- Vertex Shader: Specifies that the position of each vertex should be passed as an attribute.
- Fragment Shader: Handles coloring of each pixel, using a custom palette function and some mathematical operations to create visual effects.
Shader Creation Function:
createShader
: Compiles the shader source code and logs errors if present.
Program Creation:
- Compiles vertex and fragment shaders.
- Links shaders to create a WebGL program.
Attribute and Buffer Setup:
positionAttributeLocation
: Finds the location of thea_position
attribute in the shader program.positionBuffer
: Creates and binds a buffer for vertex positions.- Vertices Data: Defines the positions of the vertices forming two triangles that cover the entire canvas.
Uniform Setup:
resolutionUniformLocation
: Finds the location of the resolution uniform in the shader program.timeUniformLocation
: Finds the location of the time uniform in the shader program.
Resize Canvas:
resizeCanvasToDisplaySize
: Adjusts the canvas size to match its displayed size.
Render Function:
- Adjusts the viewport and clears the canvas.
- Uses the shader program and updates attribute pointers.
- Sets the uniform values.
- Draws the triangles as a triangle strip.
- Calls
requestAnimationFrame
to repeat the rendering process, creating the animation effect.
The given script leverages WebGL to create a dynamic, real-time visual effect by manipulating vertex and fragment shaders. Each frame is dynamically rendered based on the current time, creating complex, animated patterns.
Description
Detailed explanation and implementation of a WebGL Milkdrop-style visualizer using HTML, CSS, and JavaScript to create intricate visual effects in real-time.
More Explain Simplys
Apache Flink Explain SimplyApache Pig Explain SimplyAzure Data Factory Explain SimplyC/C++ Explain SimplyCouchDB Explain SimplyDAX Explain SimplyExcel Explain SimplyFirebase Explain SimplyGoogle BigQuery Explain SimplyGoogle Sheets Explain SimplyGraphQL Explain SimplyHive Explain SimplyJava Explain SimplyJavaScript Explain SimplyJulia Explain SimplyLua Explain SimplyM (Power Query) Explain SimplyMATLAB Explain SimplyMongoDB Explain SimplyOracle Explain SimplyPostgreSQL Explain SimplyPower BI Explain SimplyPython Explain SimplyR Explain SimplyRedis Explain SimplyRegex Explain SimplyRuby Explain SimplySAS Explain SimplyScala Explain SimplyShell Explain SimplySPSS Explain SimplySQL Explain SimplySQLite Explain SimplyStata Explain SimplyTableau Explain SimplyVBA Explain Simply