CARVIEW |
Select Language
HTTP/2 301
content-length: 162
content-type: text/html
date: Wed, 15 Oct 2025 03:48:20 GMT
location: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/By_example/Hello_vertex_attributes
server: nginx
strict-transport-security: max-age=60; includeSubDomains
via: 1.1 google
alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
HTTP/2 200
content-type: text/html
x-guploader-uploadid: AAwnv3L0UYOOBKUvJpfjDL6-fAMcBRW0kAGGHHjq4AzaIs5EeYlic-sHFhP462bvSPHoj_J0
cache-control: public, max-age=3600
expires: Wed, 15 Oct 2025 04:48:22 GMT
last-modified: Tue, 14 Oct 2025 01:07:33 GMT
etag: W/"63991a66a33c720112768aa45c5e3e30"
x-goog-generation: 1760404053614679
x-goog-metageneration: 1
x-goog-stored-content-encoding: identity
x-goog-stored-content-length: 139315
x-goog-meta-goog-reserved-file-mtime: 1760402583
x-goog-hash: crc32c=lszt7Q==, md5=Y5kaZqM8cgESdoqkXF4+MA==
x-goog-storage-class: STANDARD
accept-ranges: none
alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
alt-svc: clear
referrer-policy: strict-origin-when-cross-origin
x-content-type-options: nosniff
strict-transport-security: max-age=63072000
content-security-policy: default-src 'self'; script-src 'report-sample' 'self' 'wasm-unsafe-eval' https://www.google-analytics.com/analytics.js https://www.googletagmanager.com/gtag/js assets.codepen.io production-assets.codepen.io https://js.stripe.com 'sha256-XNBp89FG76amD8BqrJzyflxOF9PaWPqPqvJfKZPCv7M=' 'sha256-YCNoU9DNiinACbd8n6UPyB/8vj0kXvhkOni9/06SuYw=' 'sha256-PZjP7OR6mBEtnvXIZfCZ5PuOlxoDF1LDZL8aj8c42rw='; script-src-elem 'report-sample' 'self' 'wasm-unsafe-eval' https://www.google-analytics.com/analytics.js https://www.googletagmanager.com/gtag/js assets.codepen.io production-assets.codepen.io https://js.stripe.com 'sha256-XNBp89FG76amD8BqrJzyflxOF9PaWPqPqvJfKZPCv7M=' 'sha256-YCNoU9DNiinACbd8n6UPyB/8vj0kXvhkOni9/06SuYw=' 'sha256-PZjP7OR6mBEtnvXIZfCZ5PuOlxoDF1LDZL8aj8c42rw='; style-src 'report-sample' 'self' 'unsafe-inline'; object-src 'none'; base-uri 'self'; connect-src 'self' developer.allizom.org bcd.developer.allizom.org bcd.developer.mozilla.org updates.developer.allizom.org updates.developer.mozilla.org https://*.google-analytics.com https://*.analytics.google.com https://*.googletagmanager.com https://incoming.telemetry.mozilla.org https://observatory-api.mdn.allizom.net https://observatory-api.mdn.mozilla.net https://api.github.com/search/issues stats.g.doubleclick.net https://api.stripe.com; font-src 'self'; frame-src 'self' interactive-examples.mdn.mozilla.net interactive-examples.mdn.allizom.net mdn.github.io live-samples.mdn.mozilla.net live-samples.mdn.allizom.net *.mdnplay.dev *.mdnyalp.dev *.play.test.mdn.allizom.net https://v2.scrimba.com https://scrimba.com jsfiddle.net www.youtube-nocookie.com codepen.io survey.alchemer.com https://js.stripe.com; img-src 'self' data: *.githubusercontent.com *.googleusercontent.com *.gravatar.com mozillausercontent.com firefoxusercontent.com profile.stage.mozaws.net profile.accounts.firefox.com developer.mozilla.org mdn.dev interactive-examples.mdn.mozilla.net interactive-examples.mdn.allizom.net wikipedia.org upload.wikimedia.org https://mdn.github.io/shared-assets/ https://mdn.dev/ https://*.google-analytics.com https://*.googletagmanager.com www.gstatic.com; manifest-src 'self'; media-src 'self' archive.org videos.cdn.mozilla.net https://mdn.github.io/shared-assets/; child-src 'self'; worker-src 'self';
x-frame-options: DENY
origin-trial: AxVILwizhbMjxFeHOn1P3R8niO1RJY/smaK4B4d1rLzc1gTaxtXMSaTi+FoigYgCw40uFRDwFcEAeqDR+vVLOW4AAABfeyJvcmlnaW4iOiJodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZyIsImZlYXR1cmUiOiJQcml2YXRlQXR0cmlidXRpb25WMiIsImV4cGlyeSI6MTc0MjA3OTYwMH0=
x-cloud-trace-context: 4ff3c43482823b4a88bd3c5931feb20b
date: Wed, 15 Oct 2025 03:48:22 GMT
server: Google Frontend
via: 1.1 google
vary: Accept-Encoding
content-encoding: gzip
x-cache: miss
Hello vertex attributes - Web APIs | MDN
Toggle sidebar
Hello vertex attributes
This WebGL example demonstrates how to combine shader programming and user interaction by sending user input to the shader using vertex attributes.
Hello World program in GLSL
How to send input to a shader program by saving data in GPU memory.
<p>
First encounter with attributes and sending data to GPU. Click on the canvas
to change the horizontal position of the square.
</p>
<canvas>Your browser does not seem to support HTML canvas.</canvas>
body {
text-align: center;
}
canvas {
width: 280px;
height: 210px;
margin: auto;
padding: 0;
border: none;
background-color: black;
}
button {
display: block;
font-size: inherit;
margin: auto;
padding: 0.6em;
}
html
<script type="x-shader/x-vertex" id="vertex-shader">
#version 100
precision highp float;
attribute float position;
void main() {
gl_Position = vec4(position, 0.0, 0.0, 1.0);
gl_PointSize = 64.0;
}
</script>
html
<script type="x-shader/x-fragment" id="fragment-shader">
#version 100
precision mediump float;
void main() {
gl_FragColor = vec4(0.18, 0.54, 0.34, 1.0);
}
</script>
js
const canvas = document.querySelector("canvas");
const gl = getRenderingContext();
let source = document.querySelector("#vertex-shader").innerHTML;
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, source);
gl.compileShader(vertexShader);
source = document.querySelector("#fragment-shader").innerHTML;
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, source);
gl.compileShader(fragmentShader);
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.detachShader(program, vertexShader);
gl.detachShader(program, fragmentShader);
gl.deleteShader(vertexShader);
gl.deleteShader(fragmentShader);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
const linkErrLog = gl.getProgramInfoLog(program);
cleanup();
document.querySelector("p").textContent =
`Shader program did not link successfully. Error log: ${linkErrLog}`;
throw new Error("Program failed to link");
}
let buffer;
initializeAttributes();
gl.useProgram(program);
gl.drawArrays(gl.POINTS, 0, 1);
canvas.addEventListener("click", (evt) => {
const clickXRelativeToCanvas = evt.pageX - evt.target.offsetLeft;
const clickXinWebGLCoords =
(2.0 * (clickXRelativeToCanvas - gl.drawingBufferWidth / 2)) /
gl.drawingBufferWidth;
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array([clickXinWebGLCoords]),
gl.STATIC_DRAW,
);
gl.drawArrays(gl.POINTS, 0, 1);
});
function getRenderingContext() {
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
const gl = canvas.getContext("webgl");
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
return gl;
}
function initializeAttributes() {
gl.enableVertexAttribArray(0);
buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0.0]), gl.STATIC_DRAW);
gl.vertexAttribPointer(0, 1, gl.FLOAT, false, 0, 0);
}
window.addEventListener("beforeunload", cleanup);
function cleanup() {
gl.useProgram(null);
if (buffer) {
gl.deleteBuffer(buffer);
}
if (program) {
gl.deleteProgram(program);
}
}
The source code of this example is also available on GitHub.