WebGL學習——存儲限定符(三)

介紹:定義存儲的變量是什麼類型,常用的有attribute、uniform

1、attribute

傳輸與頂點相關的數據。

定義方式:<存儲限定符><數據類型><變量名稱>

                 attribute vec4 a_Position

/**
 * 頂點着色器
 * gl_Position 常量 代表是位置  vec4 一個函數 返回一個vec4類型的數據
 * g1_PointSize 常量 代表是尺寸 float類型
 * @type {string}
 */
const VSHADER_SOURCE =
    'attribute vec4 a_Position;' + // 定義a_Position 頂點位置信息
    'attribute vec4 a_PointSize;' + // 定義a_Position 頂點位置信息
    'void main() { ' +
    'gl_Position = a_Position;' +
    'gl_PointSize = a_PointSize;' +
    '}';

 javaScript獲取變量:g1.get

2、uniform

傳輸與頂掉無關或者對所有頂點都相同的數據。

/**
     * 片元着色器
     * gl_FragColor 常量 代表顏色 類型爲vec4
     * @type {string}
     */
    const FSHADER_SOURCE =
        'precision mediump float;' + // uniform變量可以指定任意類型的數據 因此需使用精度限定詞指定精度 attribute只能指定float
        'uniform vec4 u_FragColor;' + // 定義a_FragColor 顏色信息
        'void main() {' +
        'gl_FragColor = u_FragColor;' +
        '}';

3、varying (待學習)

4、demo

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>webGl qualifier</title>
    <style>
        body {
            margin: 0px;
        }
    </style>
</head>
<body onload="main()">
<canvas id="webGl" width="900px" height="900px" style="width: 900px;height: 900px;"></canvas>
<script>
    /**
     * 頂點着色器
     * gl_Position 常量 代表是位置  vec4 一個函數 返回一個vec4類型的數據
     * g1_PointSize 常量 代表是尺寸 float類型
     * @type {string}
     */
    const VSHADER_SOURCE =
        'attribute vec4 a_Position;' + // 定義a_Position 頂點位置信息
        'attribute float a_PointSize;' + // 定義a_Position 頂點位置信息
        'void main() { ' +
        'gl_Position = a_Position;' +
        'gl_PointSize = a_PointSize;' +
        '}';
    /**
     * 片元着色器
     * gl_FragColor 常量 代表顏色 類型爲vec4
     * @type {string}
     */
    const FSHADER_SOURCE =
        'precision mediump float;' + // uniform變量可以指定任意類型的數據 因此需使用精度限定詞指定精度 attribute只能指定float
        'uniform vec4 u_FragColor;' + // 定義a_FragColor 顏色信息
        'void main() {' +
        'gl_FragColor = u_FragColor;' +
        '}';

    function main() {
        const canvas = document.getElementById('webGl');

        // Get the rendering context for WebGL
        const gl = canvas.getContext('experimental-webgl ') || canvas.getContext('webgl');
        if (!gl) {
            console.log('不支持webGl 請使用谷歌瀏覽器查看!');
            return;
        }
        if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
            console.log('着色器初始化失敗!');
            return;
        }
        // 獲取位置信息
        const a_Position = gl.getAttribLocation(gl.program, 'a_Position');
        // 獲取大小信息
        const a_PointSize = gl.getAttribLocation(gl.program, 'a_PointSize');
        // 獲取顏色信息
        const a_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor');
        // 將位置信息傳遞給着色器
        gl.vertexAttrib3f(a_Position, 0.1, 0.1, 0.1);
        // 將大小信息傳遞給着色器
        gl.vertexAttrib1f(a_PointSize, 100.0);
        // 將顏色信息傳遞給着色器
        gl.uniform4f(a_FragColor, 0.1, 0.1, 0.1, 1.0);
        // 清理顏色
        gl.clearColor(0.0, 0.0, 0.0, 1.0);
        // 清空canvas
        gl.clear(gl.COLOR_BUFFER_BIT);
        // 繪製一個點
        gl.drawArrays(gl.POINTS, 0, 1);
    }


    /**
     * 初始化着色器
     * @param gl
     * @param vshader
     * @param fshader
     * @returns {*}
     */
    function initShaders(gl, vshader, fshader) {
        const program = createProgram(gl, vshader, fshader);
        if (!program) {
            console.log('創建WebGLProgram程序失敗');
            return false;
        }
        // 方法將定義好的WebGLProgram 對象添加到當前的渲染狀態中。
        gl.useProgram(program);
        gl.program = program;

        return true;
    }

    /**
     * 創建着色器程序 WebGLProgram
     * @param gl
     * @param vshader
     * @param fshader
     * @returns {*}
     */
    function createProgram(gl, vshader, fshader) {
        // 創建着色器對象
        const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vshader);
        const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fshader);
        if (!vertexShader || !fragmentShader) {
            return null;
        }

        // 創建一個着色器程序對象
        const program = gl.createProgram();
        if (!program) {
            return null;
        }

        // 負責往 着色器程序對象(WebGLProgram) 添加一個片段或者頂點着色器。
        gl.attachShader(program, vertexShader);
        gl.attachShader(program, fragmentShader);

        // 鏈接給定的WebGLProgram,從而完成爲程序的片元和頂點着色器準備GPU代碼的過程。
        gl.linkProgram(program);

        // Check the result of linking
        const linked = gl.getProgramParameter(program, gl.LINK_STATUS);
        if (!linked) {
            const error = gl.getProgramInfoLog(program);
            console.log('鏈接程序失敗: ' + error);
            gl.deleteProgram(program);
            gl.deleteShader(fragmentShader);
            gl.deleteShader(vertexShader);
            return null;
        }
        return program;
    }

    /**
     * 加載着色器
     * @param gl
     * @param type
     * @param source
     * @returns {*}
     */
    function loadShader(gl, type, source) {
        // 創建着色器對象
        const shader = gl.createShader(type);
        if (shader == null) {
            console.log('unable to create shader');
            return null;
        }

        /**
         * 設置着色器程序
         * shader着色器對象
         * source 包含GLSL程序代碼的字符串。
         */
        gl.shaderSource(shader, source);

        // 編譯一個GLSL着色器,使其成爲爲二進制數據,然後就可以被WebGLProgram對象所使用.
        gl.compileShader(shader);
        // 返回給定的着色器信息
        const compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
        if (!compiled) {
            const error = gl.getShaderInfoLog(shader);
            console.log('編譯着色器失敗: ' + error);
            gl.deleteShader(shader);
            return null;
        }

        return shader;
    }
</script>
</body>
</html>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章