【问题标题】:How to use u_time in mapbox GL JS custom style layer如何在 mapbox GL JS 自定义样式层中使用 u_time
【发布时间】:2020-10-09 16:26:26
【问题描述】:

我想在 fragmentSource 中为 mapbox 着色器添加时间,但是当我添加 uniform float u_time; 时,三角形不会渲染。这是一个小提琴https://jsfiddle.net/benderlio/o4xc5hw7/33/

var fragmentSource =`
    uniform float u_time;
    void main() {
        gl_FragColor = vec4(sin(1.0*u_time),0.0,1.0,1);
    }`

【问题讨论】:

    标签: opengl-es glsl shader mapbox mapbox-gl-js


    【解决方案1】:

    OpenGL ES Shading Language 1.00 Specification - 4.5.3 Default Precision Qualifiers:

    片段语言没有浮点类型的默认精度限定符。因此对于浮动,浮动 点向量和矩阵变量声明,声明必须包含精度限定符或 默认浮点精度必须事先声明。

    由于统一变量具有浮点类型,您必须向片段着色器添加精度限定符。如果不指定精度限定符,则会导致编译错误(例如 _No precision qualifier for (float))。

    添加默认精度限定符:

    precision mediump float;
                
    uniform float u_time;
    

    或者为统一变量添加一个显式的精度限定符:

    uniform mediump float u_time;
    

    我建议验证着色器是否已成功编译 (gl.getShaderParameter/gl.getShaderInfoLog) 和程序是否已链接 (gl.getProgramParameter/gl.getProgramInfoLog)。例如:

    // create a vertex shader
    var vertexShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vertexShader, vertexSource);
    gl.compileShader(vertexShader);
    if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) 
        alert(gl.getShaderInfoLog(vertexShader));
    
    // create a fragment shader
    var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragmentShader, fragmentSource);
    gl.compileShader(fragmentShader);
    if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) 
        alert(gl.getShaderInfoLog(fragmentShader));
    
    // link the two shaders into a WebGL program
    this.program = gl.createProgram();
    gl.attachShader(this.program, vertexShader);
    gl.attachShader(this.program, fragmentShader);
    gl.linkProgram(this.program);
    if (!gl.getProgramParameter(this.program, gl.LINK_STATUS))
        alert(gl.getProgramInfoLog(this.program));
    

    mapboxgl.accessToken = 'pk.eyJ1IjoiYmVuZGVybGlkemUiLCJhIjoiY2pud3c0MnN1MDdraTN4cXBraDR3MHdyaCJ9.OsQLWGIWOutuIXCHgT8coQ';
    var map = (window.map = new mapboxgl.Map({
        container: 'map',
        zoom: 3,
        center: [7.5, 58],
        style: 'mapbox://styles/mapbox/light-v10',
        antialias: true // create the gl context with MSAA antialiasing, so custom layers are antialiased
    }));
    
    // create a custom style layer to implement the WebGL content
    var highlightLayer = {
        id: 'highlight',
        type: 'custom',
    
        // method called when the layer is added to the map
        // https://docs.mapbox.com/mapbox-gl-js/api/#styleimageinterface#onadd
        onAdd: function(map, gl) {
            // create GLSL source for vertex shader
            var vertexSource =
                `
                uniform mat4 u_matrix;
                attribute vec2 a_pos;
                void main() {
                    gl_Position = u_matrix * vec4(a_pos, 0.0, 1);
                }`;
    
            // create GLSL source for fragment shader
            var fragmentSource =
                `
                precision mediump float;
                uniform float u_time;
                void main() {
                    gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);
                }`;
    
            // create a vertex shader
            var vertexShader = gl.createShader(gl.VERTEX_SHADER);
            gl.shaderSource(vertexShader, vertexSource);
            gl.compileShader(vertexShader);
            if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) 
                alert(gl.getShaderInfoLog(vertexShader));
    
            // create a fragment shader
            var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
            gl.shaderSource(fragmentShader, fragmentSource);
            gl.compileShader(fragmentShader);
            if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) 
                alert(gl.getShaderInfoLog(fragmentShader));
    
            // link the two shaders into a WebGL program
            this.program = gl.createProgram();
            gl.attachShader(this.program, vertexShader);
            gl.attachShader(this.program, fragmentShader);
            gl.linkProgram(this.program);
            if (!gl.getProgramParameter(this.program, gl.LINK_STATUS))
                alert(gl.getProgramInfoLog(this.program));
    
            this.aPos = gl.getAttribLocation(this.program, 'a_pos');
    
            // define vertices of the triangle to be rendered in the custom style layer
            var helsinki = mapboxgl.MercatorCoordinate.fromLngLat({
                lng: 25.004,
                lat: 60.239
            });
            var berlin = mapboxgl.MercatorCoordinate.fromLngLat({
                lng: 13.403,
                lat: 52.562
            });
            var kyiv = mapboxgl.MercatorCoordinate.fromLngLat({
                lng: 30.498,
                lat: 50.541
            });
    
            // create and initialize a WebGLBuffer to store vertex and color data
            this.buffer = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
            gl.bufferData(
                gl.ARRAY_BUFFER,
                new Float32Array([
                    helsinki.x,
                    helsinki.y,
                    berlin.x,
                    berlin.y,
                    kyiv.x,
                    kyiv.y
                ]),
                gl.STATIC_DRAW
            );
        },
    
        // method fired on each animation frame
        // https://docs.mapbox.com/mapbox-gl-js/api/#map.event:render
        render: function(gl, matrix) {
        
            gl.useProgram(this.program);
            gl.uniformMatrix4fv(
                gl.getUniformLocation(this.program, 'u_matrix'),
                false,
                matrix
            );
            gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
            gl.enableVertexAttribArray(this.aPos);
            gl.vertexAttribPointer(this.aPos, 2, gl.FLOAT, false, 0, 0);
            gl.enable(gl.BLEND);
            gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
            gl.drawArrays(gl.TRIANGLE_STRIP, 0, 3);
        }
    };
    
    // add the custom style layer to the map
    map.on('load', function() {
        map.addLayer(highlightLayer);
    });
    body { margin: 0; padding: 0; }
    #map { position: absolute; top: 0; bottom: 0; width: 100%; }
    <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v1.4.0/mapbox-gl.js'></script>
    <div id='map'></div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-31
      • 1970-01-01
      • 1970-01-01
      • 2019-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多