• 《WEBGL编程指南》练习记录(一)


    0、点点!

    在这里插入图片描述
    是第二章的点点!!好好玩喔!!!

    因为键盘上的 - 键不太好使所以有时候敲变量名有点痛0 0、

    需要解决的问题:

    1. 锯齿有点严重(在下一个练习中使用了两倍宽高的canvas =。=)
    2. shader 调试不太方便(在刚开始总有一些意想不到的问题)

    1、点点和线线!

    在这里插入图片描述
    模拟了逻辑函数的迭代过程!左边是离散值连线,右边是左边收敛值的散点图。
    (考虑到之后做局部放大的分形效果展示,应该会有大量的数据和计算,所以试着用webgl写哩)

    但是同一个canvas不会有两个上下文环境,所以坐标轴用额外的svg叠在下面实现了。

    注:Svg动态创建元素需要包含命名空间规则的NS后缀的Dom API createElementNS,新建该元素的各个属性也使用NS后缀的 setAttributeNS

    这里的收敛值计算得比较简单,因为已知了左侧的离散值会规律地收敛到某个或多个值,所以直接取了最符合偏差值的原数值,没有做另外的拟合。

    2、 是融球哒!

    融球公式:∑ (r² / (x² + y²)) < N

    在这里插入图片描述

    我准备给背景添加那种很潮流的叉叉,所以先写了这样的逻辑:

    if( x > 400.0 && x < 1400.0 && y > 500.0 && // 背景范围
    (mod(x, GAP) > PADDING) &&  (mod(y, GAP) > PADDING) && // 控制每个叉叉的间距
    ((mod((y - x)/ GAP - 1., 2.) < BIOS) || (mod(y + x, GAP * 2.) < BIOS))){ // 叉叉的xy关系
          float g =  max(1. - y / HEIGHT / 2., x / WIDTH * 1.1) - 0.1;// 那种渐变的感觉
          gl_FragColor = vec4(g,g,g,1.0);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    然后这个叉叉就。。。歪了 (。-ω-)-ω-)-ω-)、——ヾ(´▽`;)ゝ

    在这里插入图片描述
    xy给了偏差值之后调参了大约是这样子的:
    在这里插入图片描述
    然后我想加上那种渐变的点阵,画圆的时候意识到单纯的mod取余计算是不正确的(每个维度各漏掉了一半,如果单位图样是圆,就只有第一象限的1/4圆)

    所以我加上了其余的三个象限:

    float DOT = 32.;
    float dott = 158.;
    float xb = mod(x,DOT);float mxb = DOT- mod(x,DOT);
    float yb = mod(y,DOT);float myb = DOT- mod(y,DOT);
    float xbb = xb*xb; float xmm = mxb*mxb;
    float ybb = yb*yb; float ymm = myb*myb;
    if(xbb+ybb < dott || xmm+ybb < dott || xbb+ymm < dott || xmm+ymm < dott ){
    	float b = x/WIDTH*2.;
    	gl_FragColor = vec4(b,b,b,1.0);
    }
    // 在我写出这样的代码的瞬间,我的命名,我的代码规范,和一些其他的可读性的品德,
    // 都在急切的求知求得的过程中短暂地丢失了
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    后记:在逛一些绘制几何的文章的时候,看到类似的重复图元可以将坐标扩大整数倍后取小数,就可以得到在当前单元的相对位置,很方便。(而且在写的时候感觉取余的算法比较受限)

    另:还没有深入研究各种图元的表达方式,所以写的表达式感觉不太优雅。

    然后是想要加其他的UI上去,所以添加了会随时间旋转和变大小的三角形:

    在这里插入图片描述
    这个主要是练习二维变换矩阵,刚开始写的时候鬼畜了,后来想起来闫老师说过变换是基于原点的,所以要先平移到原点进行大小和旋转变换之后再回去(づ ●─● )づ,然后就写好了。

    在尝试使用多个着色器进行切换的时候遇到了Vertex buffer is not big enough for the draw call 的问题,找了蛮多资料之后确定了原因:
    切换着色器之后要重新绑定缓冲区
    然后就修好了( ̄ω ̄;)。。

    然后想要旋转三角形是背景的一部分,不应该遮挡主体,而之前融球和背景其实是从后往前一层一层覆盖画的(会很浪费),所以要调整 shader 的绘制顺序。

    在调整层级的过程中,发现 discard舍弃片元会无视gl_fragColor的赋值;在叠加层级的过程中,对于满屏绘制的 shader,对非主体的背景色赋值 alpha = 0. 依然会有问题,需要执行discard

    留下一个问题:为什么 alpha = 0. 的透明色依然无法做到透出下层内容?这样的表现是否与缓冲区颜色相关?我尝试使用清除缓冲区的gl.clearColor指定透明颜色,似乎达到了目标效果,但是 rAF 的动画完全阻塞了,我的程序变成了静态帧。

    最后调整了层级的结果截图:
    在这里插入图片描述
    地址:https://arthur19312.gitee.io 的 metaball 目录。

    之后准备进入三维的练习,但是对于二维 sdf 还没有练习和掌握。之后想继续看 102 的几何(其实 101 的后半段看得比较模糊,想过段时间深入体验之后再二刷一下)

  • 相关阅读:
    Java集合之LinedList
    大数据讲课笔记1.1 安装配置CentOS
    nginx
    认真啃透,带你玩转网络开发框架中的Spring——Netty
    一个数组的异或和是指数组中所有的数异或在一起的结果,给定一个数组arr,求最大子数组异或和。
    第十四届蓝桥杯省赛 C/C++ A 组 H 题——异或和之和(AC)
    Java-序列化是什么?哪里有应用?
    【多用户】k8s多用户配置 kubeconfig
    【MyBatis系列】Mybatis多表查询与动态SQL
    问题:EventSource 收不到流数据及 EventSource 的 onmessage 方法为null
  • 原文地址:https://blog.csdn.net/fruiva/article/details/124654988