注明
该代码源于Interactive Computer Graphics
Edward Angel and Dave Shreiner
Eighth Edition, Pearson Education, 2020
为更好理解此代码,仅添加部分注释
WebGL 多点三角型
大概思路
先确定主体三角形的三个角的位置,然后,将三点的 x,y 坐标相加再除4, 就得到了在三角形内部的一点 p0 ,然后进入循环
在循环内部,开头是随机初始化一个点 p1,求该点与 p0的中间点,将该点记录下来,以此类推,总共记录5000个点,然后绘制出这些点,就如上图所示了
HTML文件
<!DOCTYPE html>
<html>
<head>
<!--meta 元素可提供有关页面的元信息, 其属性定义了与文档相关联的名称/值对-->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>2D Sierpinski Gasket</title>
<script id="fragment-shader" type="x-shader/x-fragment">
#version 300 es
precision mediump float;
out vec4 fColor;
void
main()
{
fColor = vec4(1.0, 0.0, 0.0, 1.0);
}
</script>
<script id="vertex-shader" type="x-shader/x-vertex">
#version 300 es
in vec4 aPosition;
void
main()
{
gl_PointSize = 1.0;
gl_Position = aPosition;
}
</script>
<script src="../Common/initShaders.js"></script>
<script src="../Common/MVnew.js"></script>
<script src="gasket1.js"></script>
</head>
<body>
<canvas id="gl-canvas" width="512" height="512">
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
</body>
</html>
JavaSript文件
"use strict";
var gl;
var positions =[];
var numPositions = 5000;
window.onload = function init()
{
var canvas = document.getElementById("gl-canvas");
gl = canvas.getContext('webgl2');
if (!gl) alert( "WebGL 2.0 isn't available" );
//
// Initialize our data for the Sierpinski Gasket
//
// First, initialize the corners of our gasket with three positions.
var vertices = [
vec2(-1, -1),
vec2(0, 1),
vec2( 1, -1)
];
// Specify a starting positions p for our iterations
// p must lie inside any set of three vertices
// add应该是两个顶点位置相加?
var u = add(vertices[0], vertices[1]);
var v = add(vertices[0], vertices[2]);
var p = mult(0.25, add( u, v )); // mult 两个参数依次相乘,此处应为缩小顶点位置为原的 1/4
// And, add our initial positions into our array of points
positions.push(p); //把p添加进positions里面
// Compute new positions
// Each new point is located midway between
// last point and a randomly chosen vertex
for ( var i = 0; positions.length < numPositions; ++i ) {
var j = Math.floor(3*Math.random()); //返回小于等于该参数的最大整数
p = add(positions[i], vertices[j]);
p = mult(0.5, p); //将两点坐标相加再除二,得到中间点
positions.push(p);
}
//
// Configure WebGL
//
gl.viewport(0, 0, canvas.width, canvas.height);
gl.clearColor(1.0, 1.0, 1.0, 1.0);
// Load shaders and initialize attribute buffers
var program = initShaders(gl, "vertex-shader", "fragment-shader");
gl.useProgram(program);
// Load the data into the GPU
var bufferId = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, bufferId );
gl.bufferData(gl.ARRAY_BUFFER, flatten(positions), gl.STATIC_DRAW); //flatten 把数据转为一维
// Associate out shader variables with our data buffer
var positionLoc = gl.getAttribLocation(program, "aPosition");
gl.vertexAttribPointer(positionLoc, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionLoc);
render();
};
function render() {
gl.clear( gl.COLOR_BUFFER_BIT );
gl.drawArrays(gl.POINTS, 0, positions.length); //gl.POINTS: 绘制单一点,0表示启示index,最后参数表示总的 index 数量
}