美文网首页
webgl 入门(二)

webgl 入门(二)

作者: Viewwei | 来源:发表于2021-06-22 09:21 被阅读0次

webgl 参数传递

webgl是基于着色器进行绘制的.着色器本身无法与 JavaScript 进行通讯以及数据的传输.为了能够与 JavaScript 语言进行数据的交互,webgl 封装了很多函数,这些函数根据GLSL ES 暴露出来地址来传递参数.下面主要介绍两种变量:attribute变量和和 uniform变量

attribute变量

attribute 变量是一种 GLSL ES 变量,被用来从外部想顶点着色器内传输数据.只有顶点着色器可以使用它 ,在对变量命名的时候,对于顶点变量一般使用 a_开头.
使用attribute 变量包含以下几个步骤

  1. 在顶点着色器中声明 attribute 变量
  2. 将 attribute 变量赋值给 gl_Position 变量
  3. 向 attribute 变量传输数据
    声明 attribute .attribute 变量必须声明为全局变量,数据从着色器外部传递给变量.变量声明的格式按照以下格式:<存储限定符><类型><变量名>
    变量如下所示
attribute vec4 a_Position;
存储限定符号 - 类型 - 变量名

将 attribute 变量赋值给 gl_Position.在赋值的数据的类型必须一致,否则将会报错
如下所示

gl_Position = a_Position;

向 attribute 变量传输数据

gl.vertexAttrib3f(a_Position,0.2,0.0,0.0)

完整代码如下所示

    <script id="vertextShader" type="x-shader/x-vertex">
        attribute vec4 a_Position;
        void main () {
            gl_Position = a_Position;
            gl_PointSize = 20.0;
        }
    </script>

定义完变量之后,需要在 JavaScript调用 gl.getAttribLocation函数得到 attribute 变量的地址.如果返回的值小于 0,则代表读取的变量为空.示例如下:

const a_Position = gl.getAttribLocation(gl.program,'a_Position')

getAttribLocation函数表示获取 attribute 变量的地址,它拥有两个参数:program,name

  • program:表示包含顶点着色器和片元着色器的程序对象
  • name:指定想要获取到的 attribute 变量的名称,名称的长度必须小于 256 个字节

Attribute 变量赋值

在 JavaScript 中使用 gl.vertexAttrib3f函数对 attribute 变量赋值.
gl.vertexAttrib3f()函数拥有很多同族函数,比如 gl.vertexAttrib1f,gl.vertexAttrib2f,gl.vertexAttrib3f gl.vertexAttrib4f.webgl 对于相关函数的命名规范一般遵循以下规律

<基础函数名><参数个数><参数类型>
gl.vertexAttrib4f(location,v0,v1,v2,v3)
  • vertexAttrib基础函数名
  • 4 参数个数 f: 参数类型 f 代表浮点数,i 代表整数,后续的参数参数参数的个数 v1,v2 默认值为 0 ,v3 默认值为 1

uniform变量

uniform变量将颜色值传递给着色器,其步骤与 attribute 变量传递类似,不过不同仅仅是,这次数据传输的目标是片元着色器.对于 uniform 变量的命名一般使用 u_开头,uniform 变量数据格式为<存储限定符号><类型><变量名>

  1. 在片元着色器准备 uniform变量
  2. 用 uniform 变量想 gl_FragColor 赋值
  3. 将颜色数据从 JavaScript 传递给 uniform 变量

获取 uniform 变量的存储地址

gl.getUniformLocation(program,name)

  • program:包含顶点着色器和片元着色器 的程序对象
  • name:uniform变量的名称

uniform 变量赋值

gl.uniform4f(location,v1,v2,v3,v4)

  • location:代表uniform 变量的地址
  • v1,v2,v3,v4 代表 4 个参数

uniform4f函数的同族函数

  • uniform代表函数名,
  • 4 代表 4 个参数,f 代表数据类型为浮点,i 代表未整数,
    对于uniform1f,uniform2f,uniform3f 这些同族函数,没有传递第四个参数,那么第四个参数默认为 1,其他参数如果不传递默认为了

实例代码如下

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <body onload="main()">
        <canvas id="webgl" width="400" height="400"></canvas>
    </body>
    <script id="vertextShader" type="x-shader/x-vertex">
        attribute vec4 a_Position;
        void main () {
            gl_Position = a_Position;
            gl_PointSize = 20.0;
        }
    </script>
    <script id="fragmentShader" type="x-shader/x-fragment">
        //  全局设置浮点数的精确度,其他类型都有默认的精度类型,浮点数需要单独的设置
        precision mediump float;
        uniform vec4 u_FragColor;
        void main () {
            gl_FragColor = u_FragColor;
        }
    </script>
    <script src="./jsm/util.js"></script>
    <script>
        function main () {
            const canvas = document.getElementById('webgl')
            const gl = canvas.getContext('webgl')
            const vertextShader  = document.getElementById('vertextShader').innerText
            const fragmentShader = document.getElementById('fragmentShader').innerText
            if (!initShaders(gl,vertextShader,fragmentShader)) return
            if (!gl) return
            const a_Position = gl.getAttribLocation(gl.program,'a_Position')
            const u_FragColor = gl.getUniformLocation(gl.program,'u_FragColor')
            if (a_Position < 0 && u_FragColor < 0) return
            gl.vertexAttrib3f(a_Position,0.2,0.0,0.0)
            gl.clearColor(0.0,0.0,0.0,1.0)
            gl.clear(gl.COLOR_BUFFER_BIT) 
            /**
             *  颜色缓冲区被 webgl 重置为(0,0,0, 0.0)
             *  每次绘制的时候都需要重新调用 gl.clear()函数来指定 canvas 的背景色清空
             * */ 
            // gl.drawArrays(gl.POINTS,0,1)
            canvas.onmousedown = function (e) {
                click(e,gl,canvas,a_Position,u_FragColor)
            } 
            
        }
        let g_Points = []
        let u_FragColors = []
        function click(e,gl,canvas,a_Position,u_FragColor) {
            const x = e.clientX
            const y = e.clientY
            let rect = canvas.getBoundingClientRect()
            const xBase = (x-rect.left - canvas.width/2) / (canvas.width/2)
            const yBase = (canvas.height/2 - (y-rect.top)) /(canvas.height/2)
            g_Points.push(xBase)
            g_Points.push(yBase)
            if (xBase>0.0) {
                u_FragColors.push([1.0,0.0,0.0,1.0])
            }else {
                u_FragColors.push([0.0,1.0,0.0,1])
            }
            gl.clear(gl.COLOR_BUFFER_BIT)
            const len = g_Points.length
            for(let index=0;index< len;index +=2) {
                gl.vertexAttrib3f(a_Position,g_Points[index],g_Points[index+1],0.0)
                gl.uniform4f(u_FragColor,u_FragColors[index/2][0],u_FragColors[index/2][1],u_FragColors[index/2][2],u_FragColors[index/2][3])
                gl.drawArrays(gl.g_Points,0,1)
            }
        }
    </script>
</html>

initShader 代码如下

function initShaders (gl,vsShader,fShader) {
    const program = gl.createProgram();
    const vertextShader = loaderShader(gl,gl.VERTEX_SHADER,vsShader)
    const fragmentShader = loaderShader(gl,gl.FRAGMENT_SHADER,fShader)
    gl.attachShader(program,vertextShader)
    gl.attachShader(program,fragmentShader)
    //  链接 webgl 上下文和程序对象
    gl.linkProgram(program)
    gl.useProgram(program)
    gl.program = program
    return true
    
}
//  加载着色器
function loaderShader (gl,type,source) {
    const shader = gl.createShader(type)
    gl.shaderSource(shader,source)
    //  编译着色器
    gl.compileShader(shader)
    return shader
}

相关文章

  • webgl 入门(二)

    webgl 参数传递 webgl是基于着色器进行绘制的.着色器本身无法与 JavaScript 进行通讯以及数据的...

  • Webgl入门的一些资料

    入门书籍 Webgl编程指南[待补充] 一些技术博客 Webgl&Three.js原理简介 Matrix入门 Ce...

  • 「笔记」OpenGL/webGL/地理坐标系 资料收集

    OpenGL/webGL: 【前端可视化】 OpenGL / WebGL 入门和实践[https://blog.c...

  • 五 WebGL

    ← Svg入门WebGL(Web Graphics Library)是一种 3D 绘图协议,WebGL可以为 HT...

  • WebGL入门

    一、WebGL 基本认识 WebGL(Web Graphics Library)是一个光栅化引擎,它可以根据你的代...

  • WebGL入门

    初识WebGL 01-手动绘制一个WebGL图形 实现的步骤: 添加一个画布元素 获取到画布元素的基于webgl上...

  • WebGL学习笔记--WebGL入门

    什么是WebGL?全称是Web Graphics Library,是一个javascript API,用于在支持的...

  • webgl 基础入门

    你既然来到这里了,肯定是在看web前端构建3d相关内容了。本人也是一个菜鸟,所以在学习webgl相关内容时整...

  • WebGL入门demo

    WebGL入门demo three.js入门 开场白 哇哦,绘制气球耶,在网页上?对啊!厉害了!3D效果图也能在网...

  • webgl入门(一)

    webgl是基于 canvas 进行绘制,通过 getWebGLContext()来获取 webgl 的绘图上下文...

网友评论

      本文标题:webgl 入门(二)

      本文链接:https://www.haomeiwen.com/subject/orepyltx.html