【webgl学习二】&顶点着色器、片元着色器

2023-11-15

按照《webgl编程指南》学习着色器,webgl分为两种着色器,顶底着色器,片元着色器。

  • 顶点着色器:描述顶点的特性(位置、颜色等)的程序,顶点:二维、三维空间的点,图形的端点或交点、
  • 片元着色器:进行着片元处理过程的程序。

着色器使用类似c语言的OpenGL ES着色器语言来编写,下面分别编写顶点和片元着色器程序。

            //顶点着色器
            var  VSHADER_SOURCE=
            'void main(){\n'+
            'gl_Position=vec4(0.0,0.0,0.0,1.0);\n'+//点的位置
            'gl_PointSize=10.0;\n'+//点尺寸
            '}\n';
            //片元着色器
            var FSHADER_SOURCE=
                'void main(){\n'+
                    'gl_FragColor=vec4(1.0,0.0,0.0,1.0);\n'+//设置颜色
                 '}\n'

写好了的着色器程序,需要拿去创建program。来创建shader。

        function createProgram(gl, vshader, fshader) {
            // 创建着色器对象
            var vertexShader = loadShader(gl, gl.VERTEX_SHADER, vshader);
            var fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fshader);
            if (!vertexShader || !fragmentShader) {
                return null;
            }

            // 创建程序对象
            var program = gl.createProgram();
            if (!program) {
                return null;
            }

            // 为程序对象分配顶点着色器和片元着色器
            gl.attachShader(program, vertexShader);
            gl.attachShader(program, fragmentShader);

            // 连接着色器
            gl.linkProgram(program);

            // 检查连接
            var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
            if (!linked) {
                var error = gl.getProgramInfoLog(program);
                console.log('无法连接程序对象: ' + error);
                gl.deleteProgram(program);
                gl.deleteShader(fragmentShader);
                gl.deleteShader(vertexShader);
                return null;
            }
            return program;
        }

最后,webgl将程序添加。

 gl.useProgram(program);
            gl.program = program;

好了,我们来看一下完整的代码。

<html>
  <head>
      <title>webgl学习</title>
      <meta charset="utf-8"/>
  </head>
  <body onload="main()">
    <canvas width="200" height="300" id="canvas"></canvas>
    <script>
        function  main() {
            //顶点着色器
            var  VSHADER_SOURCE=
            'void main(){\n'+
            'gl_Position=vec4(0.0,0.0,0.0,1.0);\n'+//点的位置
            'gl_PointSize=10.0;\n'+//点尺寸
            '}\n';
            //片元着色器
            var FSHADER_SOURCE=
                'void main(){\n'+
                    'gl_FragColor=vec4(1.0,0.0,0.0,1.0);\n'+//设置颜色
                 '}\n'
            var canvas=document.getElementById('canvas');
            var  ctx= canvas.getContext("webgl");

            if(!initShaders(ctx,VSHADER_SOURCE,FSHADER_SOURCE)){
                console.log("初始化chader出现了错误");
            };
            /*设置canvas的背景颜色*/
            ctx.clearColor(0.0,0.0,0.0,1.0);
            /*清空canvas*/
            ctx.clear(ctx.COLOR_BUFFER_BIT);
            /*绘制点*/
            ctx.drawArrays(ctx.POINTS,0,1);

        }
        function initShaders(gl, vshader, fshader) {
            var program = createProgram(gl, vshader, fshader);
            if (!program) {
                console.log('无法创建程序对象');
                return false;
            }

            gl.useProgram(program);
            gl.program = program;

            return true;
        }

        function loadShader(gl, type, source) {
            // Create shader object
            var shader = gl.createShader(type);
            if (shader == null) {
                console.log('unable to create shader');
                return null;
            }

            // Set the shader program
            gl.shaderSource(shader, source);

            // Compile the shader
            gl.compileShader(shader);

            // Check the result of compilation
            var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
            if (!compiled) {
                var error = gl.getShaderInfoLog(shader);
                console.log('Failed to compile shader: ' + error);
                gl.deleteShader(shader);
                return null;
            }

            return shader;
        }

        function createProgram(gl, vshader, fshader) {
            // 创建着色器对象
            var vertexShader = loadShader(gl, gl.VERTEX_SHADER, vshader);
            var fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fshader);
            if (!vertexShader || !fragmentShader) {
                return null;
            }

            // 创建程序对象
            var program = gl.createProgram();
            if (!program) {
                return null;
            }

            // 为程序对象分配顶点着色器和片元着色器
            gl.attachShader(program, vertexShader);
            gl.attachShader(program, fragmentShader);

            // 连接着色器
            gl.linkProgram(program);

            // 检查连接
            var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
            if (!linked) {
                var error = gl.getProgramInfoLog(program);
                console.log('无法连接程序对象: ' + error);
                gl.deleteProgram(program);
                gl.deleteShader(fragmentShader);
                gl.deleteShader(vertexShader);
                return null;
            }
            return program;
        }


    </script>
  </body>
</html>

最后,来看一下绘制效果。

这其中遇到的错误,如下所示。

如下所示,缺少了main函数的定义,主要是定义错了main名称。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【webgl学习二】&顶点着色器、片元着色器 的相关文章

  • 如何按多个项目搜索/过滤列表?

    我正在寻找一个示例 或者可能是一个关于通过在文本框中输入的多个项目来过滤 搜索项目列表的方法的一点提示 假设我有一个列表 ul li Coffee li li Tea li li Milk li li Water li li Juice l
  • 按键对 JavaScript 对象进行排序

    我需要按键对 JavaScript 对象进行排序 因此 以下内容 b asdsad c masdas a dsfdsfsdf 会成为 a dsfdsfsdf b asdsad c masdas 这个问题的其他答案已经过时 与实施现实不符 并
  • ReactiveX:仅对每组中的最后一项进行分组和缓冲

    如何对 Observable 进行分组 并从每个 GroupedObservable 中仅将最后发出的项保留在内存中 这样每个组的行为就像BehaviorSubject 一样 像这样的东西 user 1 msg Anyone here us
  • 从 php 到 JavaScript 的数组

    我正在尝试使用 json 将数组列表从 php 传输到 javascript 但它不起作用 JS ajax url getProfilePhotos php type post post or get method data if you
  • React Native:不透明视图内的透明视图

    我想用不透明框架和透明中心显示相机的视图 就像图片中的一样 黑色部分是相机的视图 我正在寻找具有纯反应本机组件的解决方案 没有额外的库 例如https github com gilbox react native masked view h
  • 如何在bootstrap中默认隐藏侧边栏?

    我在这里有一个很好的参考 作为 Bootstrap 在设计 Web 表单应用程序时的侧边栏 http startbootstrap com template overviews simple sidebar http startbootst
  • 如何使用 JavaScript 选择预节点/块中的文本?

    我了解不允许 JS 将任意文本复制到剪贴板背后的安全原因 但是是否有一种方法可以通过单击按钮来选择预节点中的文本 类似于 select 函数在输入中的工作方式 我不是在寻找复制到剪贴板的 jQuery 插件 我只想突出显示预块中的文本 以便
  • Sequelize - 使用 es6 和模块运行迁移

    我不确定我是否做错了什么或者什么 我觉得我正在运行一个现代的 相当常见的堆栈 但我无法让新的 Sequelize v6 与我的设置完美配合 我在 Node v14 17 Sequelize v6 6 2 上 在我的 package json
  • 使用命名的成功/错误回调在 AngularJS 中声明一个 Promise

    我正在尝试做一些与 http 服务非常相似的事情 根据我的理解 http 返回一个 Promise 对象 使用它时 语法是 http success function data success callback error function
  • 在 setInterval / setTimeout 中使用变量作为时间[重复]

    这个问题在这里已经有答案了 这是一个示例情况 var count time 1000 setInterval function count 1 time 上面的代码会将 count 变量加 1 即 1000 毫秒 看来 setInterva
  • 使用 :hover 作为元素的内联样式(使用 HTML/CSS/php)[重复]

    这个问题在这里已经有答案了 可能的重复 如何将 a hover 规则嵌入到文档中间的样式属性中 https stackoverflow com questions 131653 how do i embed an ahover rule i
  • 避免在 ES6 的函数内定位 this 的对象作用域

    例如 我正在使用 D3 js 运行一个项目 导入特定模块并调用它们的函数 Setup TypeScript ES6 导入特定的 D3 组件 角6 我有一个对象 在本例中是一个角度指令 并在 SVG 画布上绘制一些圆圈 并希望它们在拖动事件上
  • “|”是什么意思(单管道)在 JavaScript 中做什么?

    console log 0 5 0 0 console log 1 0 1 console log 1 0 1 为什么0 5 0返回零 但任何整数 包括负数 都返回输入整数 单管道 有什么作用 这是一个按位或 https developer
  • 如何使用 JavaScript 获取元素的填充值?

    我有一个textarea在我的 HTML 中 我需要获取整数或浮点形式的填充数值 以像素为单位 我如何使用 JavaScript 获取它 我没有使用 jQuery 所以我正在寻找纯 JavaScript 解决方案 这将返回padding l
  • 不使用控件时,视频元素在 Chrome 中消失

    So I think这是一个浏览器错误 它出现在一个更复杂的设计 网站中 但我已经进行了很好的尝试 简化了我的代码和设计等 并发现了以下内容 嵌入时
  • 如何:带有 onclick 的 div 位于另一个带有 onclick 的 div 中

    只是一个简单的问题 我遇到了 div 与 onclick javascript 之间的问题 当我点击内部 div 时 它应该只触发它的 onclick javascript 但外部 div 的 javascript 也会被触发 用户如何点击
  • 在方法内部执行方法

    我目前正在 FreeCodeCamp 中进行 JavaScript 练习 我的代码应该使用的测试用例之一是函数调用 如下所示 addTogether 2 3 这是我得到的基本功能 function addTogether return 当我
  • 搜索多维数组 JavaScript

    我有一个如下所示的数组 selected products 0 r1 7up 61 Albertsons selected products 1 r3 Arrowhead 78 Arrowhead selected products 2 r
  • p5 向量减法“sub”返回错误

    我一直在尝试将 p5 草图上传到 React 构建中 使用react p5 wrapper 我能够成功在屏幕上渲染画布 但是 某些矢量函数会导致错误 var distance this position dist ball position
  • DOM 解析器 Chrome 扩展内存泄漏

    问题 我开发了一个扩展程序 可以拦截 Web 请求 获取 Web 请求来源的 HTML 并对其进行处理 我使用 DOMParser 来解析 HTML 并且意识到 DOMParser 正在导致大量内存泄漏问题 最终导致 chrome 扩展崩溃

随机推荐