WebGL着色器使用

1、着色器

webgl绘图必须依赖于 着色器,这是一种新的绘图机制,它可以灵活而且强大的绘制二维和三维图形。

首先,需要了解以下什么是着色器

着色器代码写在javaScript中,以字符串的形式存在。

webgl需要两种着色器代码:

  • 顶点着色器
  • 片元着色器

1.1 顶点着色器

首先来看一下代码

// 顶点着色器
var vertex_shader_source =
    'void main() {' +
    '   gl_Position = vec4(0.0, 0.0, 0.0, 1.0);' + // 设置顶点坐标
    '   gl_PointSize = 10.0;' + // 设置顶点的大小
    '' +
    '}';

上面的字符串是着色器程序,它类似于C语言,有一个main入口函数,C语言是强类型的语言,变量的赋值必须类型一致,浮点说必须加小数点等等,上面这种代码叫做GLSL ES语言,是继承自OpenGL ES得着色器语言。

顶点着色器是用来描述顶点得特性如位置颜色等等得程序,顶点是二维或者三维空间中的一个点

上面的顶点着色器设置了顶点的位置坐标,和顶点的大小,变量gl_Positiongl_PointSizewebgl内置的变量,所以可以直接使用,但是赋值的类型需要一致。

gl_Position 表示顶点的位置

gl_PointSize 表示顶点的尺寸

类型和变量名描述
vec4 gl_Position表示顶点位置
float gl_PointSize表示顶点的尺寸(像素数)

gl_Position变量必须被赋值,否则着色器无法工作,gl_PointSize有一个默认值,不是必须被赋值

float是浮点数,vec4表示由四个浮点数组成的矢量,如果你熟悉three.js,里面有一个类型就是vector4()

vec4是四个参数,这是一个 齐次坐标,如果最后一个分量是1.0的话 那么前三个分量就是坐标值,齐次坐标(x, y, z, w)等于 (x/w, y/w, z/w)

1.2 片元着色器

首先来看一下着色器代码

// 片元着色器
var fragment_shader_source =
    'void main(){' +
    '   gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);' + //设置顶点颜色
    '}';

同样和顶点着色器一样,是一个字符串,也是类似 C语言的代码,片元着色器是对逐个片元进行颜色处理过程的程序。

片元 可以理解为像素,图像的每一个单元

片元着色器中的片元就是显示在屏幕上的一个像素,准确来说是这个像素的位置、颜色和其它信息

2、绘制一个点

暂时把webgl的坐标系统的远点位置理解为canvas的中心,也就是(0, 0, 0)

具体代码

1、首先声明两个字符串,顶点着色器和片元着色器程序

// 顶点着色器
var vertex_shader_source =
    'void main() {' +
    '   gl_Position = vec4(0.0, 0.0, 0.0, 1.0);' + // 设置顶点坐标
    '   gl_PointSize = 10.0;' + // 设置顶点的大小
    '' +
    '}';

// 片元着色器
var fragment_shader_source =
    'void main(){' +
    '   gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);' + //设置顶点颜色
    '}';

2、获取canvas并初始化着色器

// 获取 canvas 对象
var canvas = document.getElementById('webgl');

// 获取webgl上下文对象
var gl = getWebGLContext(canvas);

// 初始化着色器
if (!initShader(gl, vertex_shader_source, fragment_shader_source)) {

    console.log('初始化着色器失败');
    return false;

}

3、清空绘图区域并绘制顶点

// 指定canvas背景颜色
gl.clearColor(0.0, 0.5, 0.5, 1.0);

// 清除颜色缓冲区
gl.clear(gl.COLOR_BUFFER_BIT);

gl.drawArrays(gl.POINTS, 0, 1);

上面的initShader是内部封装的一个方法,暂时不需要了解其中的实现原理

注意:上面的着色器代码是运行在 webgl 系统的程序,是运行在 js 程序中

上面的第三步需要了解几个gl身上的内置方法

gl.drawArrays(mode, first, count)

这是一个用来绘制各种图形的方法,它可以按照某种模式(mode),来绘制图形

方法名参数返回值
gl.drawArrays(mode, first, count)mode:绘制方式,first:指定从那个顶点开始绘制,count:绘制需要多少个顶点INVALID_ENUM:传入的参数不是前述参数之一,INVALID_VALUE:参数first或者count是负数

具体可以绘制,、 线 一些绘制细节后面会阐述

因为我们仅仅是绘制了一个点,所以第一个参数是gl.POINTS,设置第二个参数为0,表示从第一个顶点开始绘制,第三个参数是1表示绘制一个点

示例地址

绘制一个点

示例代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>绘制一个点</title>
    <link rel="stylesheet" href="../css/common.css">
</head>
<body>
<canvas id="webgl" width="512" height="512"></canvas>
</body>
<script src="../lib/webgl-utils.js"></script>
<script src="../lib/webgl-debug.js"></script>
<script src="../lib/cuon-utils.js"></script>
<script>

    // 顶点着色器
    var vertex_shader_source =
        'void main() {' +
        '   gl_Position = vec4(0.0, 0.0, 0.0, 1.0);' + // 设置顶点坐标
        '   gl_PointSize = 10.0;' + // 设置顶点的大小
        '' +
        '}';

    // 片元着色器
    var fragment_shader_source =
        'void main(){' +
        '   gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);' + //设置顶点颜色
        '}';

    (function () {


        // 获取 canvas 对象
        var canvas = document.getElementById('webgl');

        // 获取webgl上下文对象
        var gl = getWebGLContext(canvas);

        // 初始化着色器
        if (!initShader(gl, vertex_shader_source, fragment_shader_source)) {

            console.log('初始化着色器失败');
            return false;

        }

        // 指定canvas背景颜色
        gl.clearColor(0.0, 0.5, 0.5, 1.0);

        // 清除颜色缓冲区
        gl.clear(gl.COLOR_BUFFER_BIT);

        gl.drawArrays(gl.POINTS, 0, 1);


    }());

    // 初始化着色器方法
    function initShader(gl, vertexShaderSource, fragmentShaderSource) {

        // 创建顶点着色器对象
        var vertexShader = gl.createShader(gl.VERTEX_SHADER);

        // 创建片元着色器对象
        var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);

        // 引入着色器代码
        gl.shaderSource(vertexShader, vertexShaderSource);
        gl.shaderSource(fragmentShader, fragmentShaderSource);

        // 编译顶点和片元着色器代码
        gl.compileShader(vertexShader);
        gl.compileShader(fragmentShader);

        // 创建程序对象
        var program = gl.createProgram();

        // 附着附着着色器到程序
        gl.attachShader(program, vertexShader);
        gl.attachShader(program, fragmentShader);

        // 链接程序
        gl.linkProgram(program);

        // 使用程序
        gl.useProgram(program);

        // 返回 program 对象
        return program;

    }


</script>
</html>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值