zoukankan      html  css  js  c++  java
  • [WebGL]Shader中的数据和简单的工作流

    1 Shader中的数据

    1.1 获取数据的方式

    1.1.1 属性(attribute)和缓冲(buffer)

    缓冲是发送到GPU的一些二进制数据序列,通常情况下包括位置、法向量、纹理坐标、顶点颜色值等。一下是常用的API(gl代表WebGLRenderingContext)

    • gl.createBuffer(),创建并初始化一个用于储存顶点数据或着色数据的WebGLBuffer对象
    • gl.bindBuffer(target, buffer),target是绑定点,可以理解为将缓冲绑定为当前缓冲,之后的操作就可以在这个缓冲上进行,当要对别的缓冲进行设置操作时,要绑定切换成别的缓冲。
    • gl.bufferData(target, ArrayBufferView srcData, usage, srcOffset, length),创建并初始化WebGLBuffer对象的数据存储区,可以理解为将数据复制进缓冲中。target是绑定点,srcData是将要被复制到数据存储区的数据,usage是存储区使用的方式,例如是否被经常使用?修改?srcOffset初始元素索引的偏移量。
    • gl.deleteBuffer(buffer),用于删除指定的缓冲,若已经删除,则不做操作。
    • gl.isBuffer(buffer),检查缓冲区是否有效。
    • gl.getAttribLocation(program, name),返回给定的WebGLProgram对象中某属性在program中的位置,相当于是索引。

    创建缓存,绑定缓存,发送数据,查询属性的索引,一般在初始化部分完成。
    接下来就是,告诉gl,我们想从缓冲中提供数据,从哪个缓冲呢?所以要bind一个我们需要缓冲到当前缓冲以便操作,然后将属性和缓冲链接起来,并设定读取、解析的方式。

    • gl.enableVertexAttribArray(index),在使用属性之前要使用此方法进行激活,没有激活的属性不会被使用。这里index是一个GLuint类型的索引值,这个值在初始化的时候一般会获取,这个索引是针对当前使用的program来说的,因为这个索引就是类似于0,1...这样的数字,不是唯一的,所以是针对当前的program来说的。
    • gl.vertexAttribPointer( index, numComponents, typeOfData, normalizeFlag, strideToNextPieceOfData, offsetIntoBuffer);
      将属性与当前gl.ARRAY_BUFFER绑定的缓冲区绑定,并指定如何从缓冲区里读取数据,index是属性的索引,numComponents为1,2,3,4中的一个,指定一个顶点数据由几个component组成,typeOfData是每个数据(component)的类型,normalizeFlag数据要不要归一化,strideToNextPieceOfData,指明顶点属性是不是紧密连续的,中间有没有空隙,一般为0,offset初始的偏移量,一般为0

    属性来指明如何从缓冲中读取数据并提供给vertex shader,每次vertex shader会按照规则读取。

    1.1.2 全局变量(Uniforms)

    全局变量在shader program运行前赋值,在运行过程中全局有效,在一次绘制过程中,传递给shader的值都是一样的。例如Varyings的值是在fragment shader里插值得到的,所以可能每个像素的值都不同。全局变量的设置方式是,先找到全局变量的地址,然后给其设置值

    • gl.getUniformLocation(program, name),从program中找到全局变量的位置
    • gl.uniform[1234][fi][v]()(index, value),设定全局变量的值

    全局变量有许多类型,每个类型都对应不同的设置方法。

    1.1.3 纹理(Textures)

    纹理是一个数据序列,可以在program运行中随意读取其中的数据。 大多数情况存放的是图像数据,但是纹理仅仅是数据序列, 可以随意存放除了颜色数据以外的其它数据。
    在着色器中获取纹理信息,可以先创建一个sampler2D类型全局变量,然后用GLSL方法texture2D 从纹理中提取信息。在渲染的时候webGL要求纹理必须绑定到一个纹理单元上

    • uniform sampler2D u_texture
    • texture2D(u_texture, texcoord)
    • gl.getUniformLocation(someProgram, "u_texture")
    • gl.activeTexture(gl.TEXTURE0 + unit),激活指定的纹理
    • gl.bindTexture(target, texture),将纹理绑定到绑定点
    • gl.uniform1i(someSamplerLoc, unit),设定全局变量的值

    1.1.4 变量(Varyings)

    vertex shaderfragment shader传值的方式,依照渲染的图元是点, 线还是三角形,顶点着色器中设置的可变量会在片断着色器运行中获取不同的插值。在两个shader中,名字要定义成一样。

    1.2 vertex shader

    • 属性
    • 全局
    • 纹理
      将顶点转换到裁剪空间的坐标中去,每个顶点会调用一次,设置一个特殊的变量gl_Position,裁剪空间中的坐标值,GPU接收该值,并保存

    1.3 fragment shader

    • 全局
    • 纹理
    • 可变量
      基于vertex shader的结果,绘制像素点,每个像素都会调用设置gl_FragColor,定义像素颜色

    2 简单的工作流

    • 初始化阶段
      1. 获取htmlcanvas元素
      2. 获取webgl上下文
      3. 获取vertex shaderfragment shader的字符串
      4. 创建和编译shader
      5. 链接两个shader,成为一个program
      6. 获取属性的地址
      7. 创建缓冲
      8. 绑定新建的缓冲到当前缓冲
      9. 给缓冲发送数据
    • 渲染阶段
      1. 从裁剪空间到像素空间
      2. 清空Canvas
      3. 设置我们要使用的program程序
      4. 打开属性
      5. 绑定缓冲到当前缓冲
      6. 将属性绑定到当前缓冲,并设置读取的方式
      7. 画图
  • 相关阅读:
    星云精准测试有力提升金融复杂系统的测试能效
    疫情之下,精准测试的智能可信模式正在成为中流砥柱
    星云测试插装编译流程与CI集成
    自动化测试与精准测试的无缝对接
    “静默式”精准测试,让企业零成本完成黑盒测试的升级对接
    精准测试与开源工具Jacoco的覆盖率能力大PK
    【星云测试】Devops微服务架构下具有代码级穿透能力的精准测试
    【星云测试】开发者测试-采用精准测试工具对Spring Boot应用进行测试
    分享我们团队管理的最佳实践——程序员的周报应如何填写
    [原创]基于VueJs的前后端分离框架搭建之完全攻略
  • 原文地址:https://www.cnblogs.com/WAoyu/p/13032517.html
Copyright © 2011-2022 走看看