Cesium 中的Shader解析2

一、简介

采用纯WebGL实现纹理贴图,并修改shader,对比Cesium中的实现,从而感受Cesium对WebGL的封装,以及用法上的异同点。

可以对比Cesium 中的Shader解析1https://blog.csdn.net/u014556081/article/details/124577509中用Cesium实现相同功能代码。

二、代码

 <!-- 
    纹理映射的过程需要顶点着色器和片元着色器二者的配合:首先在顶点着色器中为每个顶点指定纹理坐标,
    然后在片元着色器中根据每个片元的纹理坐标从纹理图像中抽取纹素颜色。
    程序主要包括五个部分,已经在代码中用数字标记了出来。
 -->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../lib/webgl-utils.js"></script>
    <script src="../lib/webgl-debug.js"></script>
    <script src="../lib/cuon-utils.js"></script>
    <script src="../lib/cuon-matrix.js"></script>
</head>

<body onload="main()">
    <canvas id="webgl" width="400" height="400">
        Please use a browser that supports "canvas"
    </canvas>
    <script>
        var VSHADER_SOURCE = /* glsl */ `
            attribute vec4 a_Position;
            attribute vec2 a_TexCoord;
            varying vec2 v_TexCoord;
            void main(){
                gl_Position=a_Position;
                v_TexCoord=a_TexCoord;
            }
        `;
        var FSHADER_SOURCE = /* glsl */ `
            #ifdef GL_ES
            precision mediump float;
            #endif
            uniform sampler2D u_Sampler;
            uniform float color2;
            varying vec2 v_TexCoord;
            void main(){
                vec4 color =texture2D(u_Sampler,v_TexCoord);
                vec2 center=vec2(0.5,0.5);
                vec2 pos=vec2(gl_FragCoord.x/400.0,gl_FragCoord.y/400.0);                
                float dis=distance(center,pos);
                if(dis>0.25){
                    color=vec4(vec3(0),1.0);
                }
                if(dis<0.1){
                    color=vec4(vec3(0),1.0);
                }
                gl_FragColor=color;
            }
        `;
        // 内置变量gl_FragCoord表示WebGL在canvas画布上渲染的所有片元或者说像素的坐标,
        // 坐标原点是canvas画布的左上角,x轴水平向右,y竖直向下,
        // gl_FragCoord坐标的单位是像素,gl_FragCoord的值是vec2(x,y),
        // 通过gl_FragCoord.x、gl_FragCoord.y方式可以分别访问片元坐标的纵横坐标。
        function main() {
            var canvas = document.getElementById('webgl');
            var gl = getWebGLContext(canvas);
            if (!gl) {
                return;
            }
            if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
                return;
            }
            var n = initVertexBuffers(gl);
            if (n < 0) {
                return;
            }
            // Specify the color for clearing <canvas>
            gl.clearColor(0.0, 0.0, 0.0, 1.0);

            // Set texture
            if (!initTextures(gl, n)) {
                console.log('Failed to intialize the texture.');
                return;
            }

            
        }

        // 设置纹理坐标
        /*
        将纹理坐标传入顶点着色器。我们可以将纹理坐标和顶点坐标写在同一个缓冲区中,成对记录每个顶点的顶点坐标和纹理坐标。
        */
        function initVertexBuffers(gl) {
            var verticesTexCoords = new Float32Array([
                //vertex coord,texture coord
                -0.5, 0.5, 0.0, 1.0, //webgl坐标系顶点坐标——左上角
                -0.5, -0.5, 0.0, 0.0, //webgl坐标系顶点坐标——左下角
                0.5, 0.5, 1.0, 1.0, //webgl坐标系顶点坐标——右上角
                0.5, -0.5, 1.0, 0.0, //webgl坐标系顶点坐标——右下角

            ]);
            var n = 4; //the number of vertices
            //create the buffer object
            var vertexTexCoordBuffer = gl.createBuffer();
            if (!vertexTexCoordBuffer) {
                return -1;
            }
            //Bind the buffer object to target
            gl.bindBuffer(gl.ARRAY_BUFFER, vertexTexCoordBuffer);
            gl.bufferData(gl.ARRAY_BUFFER, verticesTexCoords, gl.STATIC_DRAW);
            var FSIZE = verticesTexCoords.BYTES_PER_ELEMENT;
            //Get the storage location of a_Position,assign and enable buffer
            var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
            if (a_Position < 0) {
                return -1;
            }
            // undefined vertexAttribPointer(GLuint index, GLint size, GLenum type,
            //                       GLboolean normalized, GLsizei stride, GLintptr offset);
            // index:第几个属性,从0开始取,0,1,2,顺序自己定义,例如顶点位置,纹理,法线
            // size:一个顶点所有数据的个数,这里每个顶点有两个浮点数属性值,所以是2
            // type:顶点描述数据的类型,这里position数组中的数据全部为float,所以是GL_FLOAT
            // normalized:是否需要显卡帮忙把数据归一化到-1到+1区间,这里不需要,所以设置GL_FALSE
            // stride:一个顶点占有的总的字节数,这里为两个float,所以是FSIZE * 4
            // offset:当前指针指向的vertex内部的偏离字节数,可以唯一的标识顶点某个属性的偏移量
            // 这里是指向第一个属性,顶点坐标,偏移量为0
            gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 4, 0);
            gl.enableVertexAttribArray(a_Position); //Enable the assignment of the buffer object
            //Get the Storge location of a_TexCoord
            var a_TexCoord = gl.getAttribLocation(gl.program, 'a_TexCoord');
            if (a_TexCoord < 0) {
                return -1;
            }
            //Assign the buffer object to a_TexCoord variable
            gl.vertexAttribPointer(a_TexCoord, 2, gl.FLOAT, false, FSIZE * 4, FSIZE * 2);
            gl.enableVertexAttribArray(a_TexCoord);
            gll = gl;

            return n;
        }



        function initTextures(gl, n) {
            var texture = gl.createTexture(); //Create a texture object
            if (!texture) {
                return false
            }
            //Get the storge location of u_Sampler
            var u_Sampler = gl.getUniformLocation(gl.program, 'u_Sampler');
            if (!u_Sampler) {
                return;
            }
            var image = new Image(); //Create the image object
            if (!image) {
                return;
            }
            //Register the event handler to be called on loading an image
            image.onload = () => {
                loadTexture(gl, n, texture, u_Sampler, image);
            }
            image.src = '../resources/sky.JPG';
            return true;
        }

        function loadTexture(gl, n, texture, u_Sampler, image) {
            gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); //Flip the image's y axis
            //Enable texture unit0
            gl.activeTexture(gl.TEXTURE0);
            //Bind the texture object to the target
            gl.bindTexture(gl.TEXTURE_2D, texture);
            //Set the texture parameters
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
            //Set the texture image
            gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);
            //Set the texture unit 0 to the sampler
            gl.uniform1i(u_Sampler, 0);
            gl.clear(gl.COLOR_BUFFER_BIT); //Clear canvas
            gl.drawArrays(gl.TRIANGLE_STRIP, 0, n); //Draw the rectangle
        }
    </script>
</body>

</html>


三、效果

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Cesium Shader is a set of shader programs and techniques used to render 3D graphics in the Cesium JavaScript library. These shaders are designed to run on the GPU (graphics processing unit) and provide high-performance rendering of various types of visual effects such as lighting, shadows, reflections, and more. The Cesium Shader system is built on top of WebGL, a standard API for rendering 3D graphics in web browsers. Cesium Shader uses a combination of vertex shaders and fragment shaders to render 3D models with high fidelity and realism. The vertex shader is responsible for transforming the 3D model's vertices into screen space coordinates. It also calculates lighting and other effects based on the position and orientation of the camera and other factors. The fragment shader is responsible for rendering each pixel of the 3D model based on the lighting and other effects calculated by the vertex shader. This includes determining the color and intensity of each pixel, as well as handling transparency and other visual effects. Cesium Shader also includes advanced techniques such as deferred shading, which allows for complex lighting effects with multiple light sources and shadows. This technique involves rendering the scene in multiple passes, with each pass generating a separate buffer of information that is then combined to produce the final image. Overall, Cesium Shader provides a powerful and flexible system for rendering 3D graphics in web-based applications. Its use of WebGL and GPU acceleration allows for high-performance rendering of complex scenes and effects, making it a popular choice for a wide range of applications, from games and simulations to scientific data visualization and more.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苹果园dog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值