从代码生成纹理
使用代码绘制纹理
使用在片段着色器中逐像素完成的计算为点精灵纹理化。
html
<script type="x-shader/x-vertex" id="vertex-shader">
#version 100
precision highp float;
attribute vec2 position;
void main() {
gl_Position = vec4(position, 0.0, 1.0);
gl_PointSize = 128.0;
}
</script>
html
<script type="x-shader/x-fragment" id="fragment-shader">
#version 100
precision mediump float;
void main() {
vec2 fragmentPosition = 2.0*gl_PointCoord - 1.0;
float distance = length(fragmentPosition);
float distanceSqrd = distance * distance;
gl_FragColor = vec4(
0.2/distanceSqrd,
0.1/distanceSqrd,
0.0, 1.0 );
}
</script>
js
window.addEventListener("load", setupWebGL, false);
let gl;
let program;
function setupWebGL(evt) {
window.removeEventListener(evt.type, setupWebGL, false);
if (!(gl = getRenderingContext())) return;
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);
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}`;
return;
}
initializeAttributes();
gl.useProgram(program);
gl.drawArrays(gl.POINTS, 0, 1);
cleanup();
}
let buffer;
function initializeAttributes() {
gl.enableVertexAttribArray(0);
buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0.0, 0.0]), gl.STATIC_DRAW);
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
}
function cleanup() {
gl.useProgram(null);
if (buffer) {
gl.deleteBuffer(buffer);
}
if (program) {
gl.deleteProgram(program);
}
}
此示例的源代码也可在 GitHub 上找到。