02 传递颜色给着色器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了02 传递颜色给着色器相关的知识,希望对你有一定的参考价值。

    这一节介绍给着色器程序传值的方法。我们通过js把颜色传给着色器程序,来演示具体传值的方法。

    顶点坐标、顶点颜色、uv坐标等都可以使用“矩阵”把值传给着色器程序。这个“矩阵”(其实只是个数组)只是我们假想的一个矩阵,它的每一行表示一个顶点,例如:顶点坐标几行就有几个顶点,每一行是坐标xyz值;顶点颜色“矩阵”中每一行是对应顶点的颜色的rgba值(红、绿、蓝、透明度)。

    它们在着色器程序中,都可以使用vec3、vec4(向量)类型变量接收。虽然他们表示的含义不同,但是传值的方法是完全相同的。

    片源着色器会自动把颜色进行差值,例如你把三个顶点分别赋值为红、绿、蓝色,中间会出现渐变色。

<!DOCTYPE html>

<html lang="zh-CN">

<head>
    <meta charset="UTF-8" />
    <title>02_传递颜色给着色器</title>

    <!-- 顶点着色器 -->
    <script id="shader-vs" type="x-shader/x-vertex">
        attribute vec3 position; // 位置
        attribute vec4 color; // 颜色
        varying vec4 vColor;

        void main(void) {
        gl_Position = vec4(position, 1.0);
        vColor = color;
        }
    </script>

    <!-- 片源着色器 -->
    <script id="shader-fs" type="x-shader/x-fragment">
        precision mediump float;
        varying vec4 vColor;

        void main(void) {
        gl_FragColor = vColor;
        }
    </script>

    <script type="text/javascript">
        var start = function () {
            // 上下文环境
            var canvas = document.getElementById("mycanvas");
            var gl = canvas.getContext("experimental-webgl");
            gl.viewportWidth = canvas.width;
            gl.viewportHeight = canvas.height;
            gl.viewport(0, 0, gl.viewportWidth, gl.viewportWidth);
            gl.clearColor(0.0, 0.0, 0.0, 1.0);
            gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
            gl.enable(gl.DEPTH_TEST);

            // 顶点着色器
            var shader = gl.createShader(gl.VERTEX_SHADER);
            gl.shaderSource(shader, document.getElementById(shader-vs).innerHTML);
            gl.compileShader(shader);
            var vertexShader = shader;

            // 片源着色器
            var shader = gl.createShader(gl.FRAGMENT_SHADER);
            gl.shaderSource(shader, document.getElementById(shader-fs).innerHTML);
            gl.compileShader(shader);
            var fragmentShader = shader;

            // 着色器程序
            var shaderProgram = gl.createProgram();
            gl.attachShader(shaderProgram, vertexShader);
            gl.attachShader(shaderProgram, fragmentShader);
            gl.linkProgram(shaderProgram);
            gl.useProgram(shaderProgram);

            // 顶点
            var vertices = [
                 -0.5, -0.5, 0.0,
                 0.5, -0.5, 0.0,
                 0.0, 0.5, 0.0
            ];
            var buffer1 = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER, buffer1);
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

            var position = gl.getAttribLocation(shaderProgram, position);
            gl.enableVertexAttribArray(position);
            gl.vertexAttribPointer(position, 3, gl.FLOAT, false, 0, 0);

            // 颜色
            var colors = [
                1.0, 0.0, 0.0, 1.0,
                0.0, 1.0, 0.0, 1.0,
                0.0, 0.0, 10, 1.0
            ];
            var buffer2 = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER, buffer2);
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);

            var color = gl.getAttribLocation(shaderProgram, color);
            gl.enableVertexAttribArray(color);
            gl.vertexAttribPointer(color, 4, gl.FLOAT, false, 0, 0);

            // 绘制
            gl.drawArrays(gl.TRIANGLE_STRIP, 0, 3);
        }
    </script>
</head>

<body onload="start();">
    <canvas id="mycanvas" style="border: none;" width="500" height="500"></canvas>
</body>

</html>

    效果图:

技术分享

    参考资料:

    Lesson 2 添加颜色:http://www.hiwebgl.com/?p=133

 

以上是关于02 传递颜色给着色器的主要内容,如果未能解决你的问题,请参考以下文章

如何将数据从顶点着色器传递到片段着色器,中间有着色器[重复]

无法将颜色传递给 FragmentShader

如何将浮点矩阵作为 2D 纹理传递给片段着色器?

将统一值传递给顶点和片段着色器

使用金属顶点和片段着色器将 MTLTexture 传递给 SCNProgram

将不同类型的值传递给着色器