资讯专栏INFORMATION COLUMN

WebGL小姐姐教我学画画之起手式

BDEEFE / 1292人阅读

摘要:我们现在可以向她许愿,描述我们心中的猩福世界了的许愿池上的许愿树小姐姐有多个许愿池,我们这里使用。

初次接触WebGL,如有错误之处欢迎留言,共同学习进步. v

WebGL的自画像

我,WebGL,全名Web Graphics Library,是为了让死宅程序猿们(摊手)能在浏览器上为所欲为的画女朋友,并还能动手动脚,而屈尊降临于猿类的世界内。哇哈哈哈哈,快来臣服于我吧,哇嘎嘎嘎嗝~

WebGL启动说明书

WebGL小姐姐神通广大,法力无边。那我们怎么用她来创造一个猿猿幸(有)福(女)美(朋)满(友)的世界呢?

首先,我们需要一个名为canvas的祭坛,举行一个召唤WebGL小姐姐的小仪式。

const canvas = document.createElement("canvas");
const gl = canvas.getContext("webgl");

那么,WebGL小姐姐Get到手了,接下来我们需要先将两样"祭品"交给她的两名侍女。

准备用于创建躯体的原材料和赋予灵魂的色彩两样祭品

gl_Position是每次绘制的点,是vec4类型,分别空间点(x, y, z)和最后一个w。对于w可以参考文章Explaining Homogeneous Coordinates & Projective Geometry,可以理解为投影仪与空间点的距离,距离不同会导致缩放效应,距离远则投放的物体越大。我们这里使用没有缩放效果的值1.0,并使用了position这个定义的变量值。每次绘制gpu buffer会更新position的值.

const vertexShaderSource = `
precision mediump float;
attribute vec2 position;

void main(void) {
    gl_Position = vec4(position.x, position.y, 0.0, 1.0);
}
`;

每次绘制都会使用glFragColor定义的颜色值,同样是vec4类型,分别代表(r, g, b, a)

const fragmentShaderSource = `
precision mediump float;

void main(void) {
    gl_FragColor = vec4(0.7, 0.5, 0.38, 0.0);
}
`
关于precision:由于openGL没有声明float类型的默认精度,所以其姐妹WebGL也就需要为shader声明精度。又由于高精度openGL没有支持,低精度在手机上可以有兼容问题,所以默认推荐mediump。参考https://stackoverflow.com/a/28540641/2326199 和 Use mediump precision in WebGL when possible

唤醒侍女并让她们把祭品处理好

const vertexShader = gl.createShader(gl.VERTEX_SHADER); // 唤醒
gl.shaderSource(vertexShader, vertexShaderSource); // 上交祭品
gl.compileShader(vertexShader); // 处理祭品
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
    // 由于祭品偶尔不新鲜或者侍女偷懒,我们要好好确认祭品是否处理完毕
    throw new Error(`Error in compileing vertexShader: ${gl.getShaderInfoLog(vertexShader)}`);
}


const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
    throw new Error(`Error in compileing vertexShader: ${gl.getShaderInfoLog(vertexShader)}`);
}

祭品已准备妥当,接下来就是要请出WebGL小姐姐御用创世神器program并使用祭品开光,然后交与小姐姐手中。

const program = gl.createProgram(); // 神器现世
gl.attachShader(program, vertexShader); // 开第一封印:原料
gl.attachShader(program, fragmentShader); // 开第二封印:色开
gl.linkProgram(program); // 交与小姐姐

if(!gl.getProgramParameter(program, gl.LINK_STATUS)) {
    // 咳咳,由于神器与祭品偶尔无法契合,导致神器失效,需要检查一下 ~_~
    throw new Error(`invalid program: ${gl.getProgramInfoLog(program)}`);
}

注意了注意了,WebGL小姐姐起手式完毕,开天辟地,万物复苏。我们现在可以向她许愿,描述我们心中的猩福世界了~v;v~

WebGL的许愿池上的许愿树

WebGL小姐姐有多个许愿池,我们这里使用gl.ARRAY_BUFFER。然后告诉神器program怎么收取愿望。

const buffer = gl.createBuffer(); // 创建许愿树
gl.bindBuffer(gl.ARRAY_BUFFER, buffer); // 将许愿树种到`ARRAY_BUFFER`这个许愿池内

// 获取神器`program`的`position`之力
const position = gl.getAttribLocation(program, "position");
// position之力为2个float类型的数一组,不转化`buffer`类型,
// 从头开始,不跳过任何一个愿望
gl.vertexAttribPointer(position, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(position);
WebGl的创世之作

小姐姐迎着丝毫都没有的狂风,望着漫无编辑器的虚无黑暗,眼角迸发出一丝丝精光,大笔一挥, 左一划右一挥。

gl.viewport(0, 0, 400, 400);
gl.useProgram(program);

gl.clearColor(255 / 255, 192 / 255, 203 / 255, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);

gl.lineWidth(1.5);

const points = new Float32Array([
    -0.9, 0.9,
    0.0, 0.0,
    0.9, -0.9,
]);

gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW);
gl.drawArrays(gl.LINE_LOOP, 0, points.length / 2);

gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
    -0.9, -0.9,
    0.0, 0.0,
    0.9, 0.9
]), gl.STATIC_DRAW);
gl.drawArrays(gl.LINE_LOOP, 0, 3);

创世之作在漫天闪电,山崩海啸之下庄严出世!! 登登登,piapia(背景乐)

最后来一张WebGL绘制整个过程的流程图:

未完待续

本文章首发于本人公众号:枫之叶

若您能喜欢本文,并欲转发本文请保留公众号声明与公众号二维码。谢谢 ^v^

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/92467.html

相关文章

  • 一起抽圣诞的惊喜盒子吧!(程序起手式

    摘要:平安夜圣诞节总是让人联想到平安果圣诞袜圣诞树圣诞老人圣诞橱窗等等让人欢喜满满期望满满的词语。礼物祝福笑脸惊喜温暖都伴随而来,最近课程轻松,便想着做一个有关圣诞的小程序,来当作对小程序的初步学习。 Christmas is coming! 平安夜/圣诞节总是让人联想到平安果、圣诞袜、圣诞树、圣诞老人、圣诞橱窗等等让人欢喜满满、期望满满的词语。礼物、祝福、笑脸、惊喜、温暖都伴随而来,最...

    codecook 评论0 收藏0
  • 多机热部署工具 Capistrano 起手式

    摘要:多机热部署同时升级多台服务器什么是是一种在多台服务器上运行脚本的开源工具,它主要用于部署应用。它自动完成多台服务器上新版本的同步更新,包括数据库的改变。 Capistrano 什么是多机热部署 热部署,就是在应用正在运行的时候升级软件,却不需要重新启动应用。多机热部署 ,同时升级多台服务器 什么是Capistrano 是一种在多台服务器上运行脚本的开源工具,它主要用于部署web应用。它...

    vspiders 评论0 收藏0
  • 动手写个数字输入框2:起手式——拦截非法字符

    摘要:前言最近在用封装纯数字的输入框,开发过程中发现不是坑,也有不少值得研究的地方。因此我们要继续补充下面两步,并且由于事件触发时值还没被修改,于是我们需要将值和当前输入值做组合来做预判,进一步扩大非法字符集。 前言  最近在用Polymer封装纯数字的输入框,开发过程中发现不是坑,也有不少值得研究的地方。本系列打算分4篇来叙述这段可歌可泣的踩坑经历: 《动手写个数字输入框1:input[...

    microcosm1994 评论0 收藏0

发表评论

0条评论

BDEEFE

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<