详尽Shader模拟水面及webgl源码(一)开始及加载2d图像

写在前面

虽然玩Shader不一定要webgl,但看看其其他工具,opengl和directx使用之前要经过一堆繁琐的设置,很容易劝退,unity玩起来需要考虑许多与shader无关的东西,shadertoy则是连顶点这个概念都没有。相比之下,webgl可要友好亲切得多了,况且wengl就是网页版的opengl,查起资料来也非常方便。

本系列假设读者已经对webgl有一定的了解。如果你还不知道webgl是什么的话,可以参考《webgl编程指南》,这是写的非常好的一本书。以及两个系列的csdn博客作为辅助,https://blog.csdn.net/charlee44/category_8676774.html以及https://blog.csdn.net/lufy_legend/category_9262828.html

首先会使用http://www.ibiblio.org/e-notes/webgl/gpu/contents.htm上的Demo作为例子讲解,感谢作者Evgeny Demidov 。

本系列文章将会用到webgl2-compute,你可以试试打开下面这个网页http://www.ibiblio.org/e-notes/webgl/gpu/CSimage2D.htm,如果能看到下面图像的话,就可以了。

如果不行的话,请使用Google Chrome浏览器或者Microsoft Edge Insider Channels浏览器,后者下载地址:https://www.microsoftedgeinsider.com/en-us/download/?platform=win10。然后在属性框的目标栏加入参数

--enable-webgl2-compute-context --use-angle=gl --use-cmd-decoder=passthrough

但笔者的Chrome浏览器加了参数后似乎并不起作用,用来Edgeinsider才能正常显示。好了,那么开始吧!

加载2D图像

Demo地址:http://www.ibiblio.org/e-notes/webgl/gpu/CSimage2D.htm,源码请自己扒。

分析70行左右的代码。很明显,将每个像素分为RGBA四个通道,然后再用texSubImage2D函数将这些像素绘制出来,这样绘制了作为背景的绿色。

     pix = new Float32Array(4*n*n)
       for(var i = 0; i<n; i++)
         for(var j = 0; j<n; j++){
           pix[t++] = 0;  pix[t++] = 1
           pix[t++] = 0;  pix[t++] = 1
         }
    
       texture = gl.createTexture()
       gl.activeTexture(gl.TEXTURE0)
       gl.bindTexture(gl.TEXTURE_2D, texture)
       gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, n,n)
       gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0, n,n, gl.RGBA, gl.FLOAT,pix)
       gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
       gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)

蓝色则用着色器绘制,代码在14行左右

  const CSs = `#version 310 es
     layout (binding = 0, rgba32f) uniform writeonly highp image2D destTex;
     layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
    void main() {
       ivec2 storePos = ivec2(gl_GlobalInvocationID.xy);
       imageStore(destTex, storePos, vec4(0.,0.,1.,1.));
    }
    `;

87行创建Css着色器,然后94行用dispathCompute将其分别在x,y,z方向上重复绘制16,16,1次。这样就是8*16 = 128长的蓝色正方形了。

扫描二维码关注公众号,回复: 9485856 查看本文章
gl.dispatchCompute(16, 16, 1);
发布了194 篇原创文章 · 获赞 8 · 访问量 9865

猜你喜欢

转载自blog.csdn.net/qq_43439240/article/details/104209660