opengl-es - 如何在mapbox GL JS自定义样式层中使用u_time

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

我想在 fragmentSource 中为 mapbox 着色器添加时间,但是当我添加 uniform float u_time; 时三角形不渲染。这是一个 fiddle 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 Shading Language 1.00 Specification - 4.5.3 Default Precision Qualifiers :

The fragment language has no default precision qualifier for floating point types. Hence for float, floating point vector and matrix variable declarations, either the declaration must include a precision qualifier or the default float precision must have been previously declared.


由于统一变量具有浮点类型,因此您必须向片段着色器添加精度限定符。如果不指定精度限定符,则会导致编译错误(例如 _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>

关于opengl-es - 如何在mapbox GL JS自定义样式层中使用u_time,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62469878/

相关文章:

ios - 在 iOS 5.1 上的 OpenGL ES 应用程序中,它们真的使用它们声明的顶点数组吗?

opengl - GLSL Matrix 的意外行为

opengl - 这个简单的FxAA如何工作?

javascript 生成类似的随机颜色(着色器 || 色调 || 单色)

opengl - 对渲染的 FBO 的纹理查找偏差了半个像素

math - 快速、不准确的 sin 函数,无需查找

android - 在 Android 上的 OpenGL 程序中调用 glViewport 是必要的吗?

java - 在Android中用手指旋转3D对象

android - 安装并运行 - Android 上的 OpenGL ES 3.0

python-3.x - 具有超过 4 个组件的 GLSL 纹理