glsl着色器学习(八)通用模板

news2024/9/20 10:35:24

下面是一个简单的通用WebGL模板

Study.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      body {
        margin: 0;
      }
      canvas {
        width: 100vw;
        height: 100vh;
        overflow: hidden;
        display: block;
      }
    </style>
  </head>
  <body>
    <!-- 
    width="400" height="400" 
    是画布的 drawingbuffer尺寸 tyle设置的是显示尺寸
    如果style设置的是显示尺寸大于drawingbuffer尺寸,会导致则可能被拉伸
    -->
    <canvas id="canvas"></canvas>
    <script id="vertex-shader-2d" type="x-shader/x-vertex">
      // 顶点着色器接收的唯一一个输入变量 a_position
      attribute vec4 a_position;
      void main() {
         gl_Position = a_position;
      }
    </script>
    <script id="fragment-shader-2d" type="x-shader/x-fragment">
      precision mediump float;
      void main() {
        gl_FragColor = vec4(1.0,1.0,0.0,1.0);

      }
    </script>
    <script src="https://webglfundamentals.org/webgl/resources/webgl-utils.js"></script>
    <script type="module">
      'use strict';
      import { createProgramFromScripts, resetCanvas } from './utils/index.js';
      const canvas = document.querySelector('canvas');
      // 创建上下文
      const gl = canvas.getContext('webgl');

      // 创建着色器程序
      const program = createProgramFromScripts(gl, 'vertex-shader-2d', 'fragment-shader-2d');

      // 获取顶点着色器的属性变量的位置
      const positionAttributeLocation = gl.getAttribLocation(program, 'a_position');

      // 创建顶点位置缓冲对象
      const positionBuffer = gl.createBuffer();

      // 绑定顶点位置缓冲对象到顶点着色器的属性变量
      // 可以简单理解为 gl.ARRAY_BUFFER = positionBuffer
      gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);

      // 设置三个顶点位置
      const positions = [0, 0, 0, 0.5, 0.7, 0];

      /**
       *  WebGL需要强类型数据 所以需要将顶点位置数据转换为 Float32Array 类型
       *
       *  这里也可以简单理解为 Float32Array(positions) = gl.ARRAY_BUFFER
       *  通过前面的 gl.ARRAY_BUFFER = positionBuffer
       *  就相当于把 Float32Array(positions) 赋值给 positionBuffer
       *
       *  这样我们就把顶点位置数据传递给顶点着色器了
       * */
      gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);

      // 清理画布
      webglUtils.resizeCanvasToDisplaySize(gl.canvas);
      resetCanvas(gl);

      // 告诉webgl使用这个程序
      gl.useProgram(program);

      // 启用对应属性
      gl.enableVertexAttribArray(positionAttributeLocation);

      // 从缓冲中获取数据
      gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);

      // 绘制三角形
      gl.drawArrays(gl.TRIANGLES, 0, 3);
    </script>
  </body>
</html>

index.js

/**
 * 创建并编译一个着色器
 *
 * @param {!WebGLRenderingContext} gl WebGL上下文。
 * @param {string} shaderSource GLSL 格式的着色器代码
 * @param {number} shaderType 着色器类型, VERTEX_SHADER 或
 *     FRAGMENT_SHADER。
 * @return {!WebGLShader} 着色器。
 */
function _compileShader(gl, shaderSource, shaderType) {
  // 创建着色器程序
  const shader = gl.createShader(shaderType);

  // 设置着色器的源码
  gl.shaderSource(shader, shaderSource);

  // 编译着色器
  gl.compileShader(shader);

  // 检测编译是否成功
  const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
  if (!success) {
    // 编译过程出错,获取错误信息。
    throw 'could not compile shader:' + gl.getShaderInfoLog(shader);
  }

  return shader;
}

/**
 * 从 2 个着色器中创建一个程序
 *
 * @param {!WebGLRenderingContext) gl WebGL上下文。
 * @param {!WebGLShader} vertexShader 一个顶点着色器。
 * @param {!WebGLShader} fragmentShader 一个片段着色器。
 * @return {!WebGLProgram} 程序
 */
function _createProgram(gl, vertexShader, fragmentShader) {
  // 创建一个程序
  const program = gl.createProgram();

  // 附上着色器
  gl.attachShader(program, vertexShader);
  gl.attachShader(program, fragmentShader);

  // 链接到程序
  gl.linkProgram(program);

  // 检查链接是否成功
  const success = gl.getProgramParameter(program, gl.LINK_STATUS);
  if (!success) {
    // 链接过程出现问题
    throw 'program failed to link:' + gl.getProgramInfoLog(program);
  }

  return program;
}

/**
 * 用 script 标签的内容创建着色器
 *
 * @param {!WebGLRenderingContext} gl WebGL上下文。
 * @param {string} scriptId script标签的id。
 * @param {string} opt_shaderType. 要创建的着色器类型。
 *     如果没有定义,就使用script标签的type属性。
 *
 * @return {!WebGLShader} 着色器。
 */
function _createShaderFromScriptTag(gl, scriptId, opt_shaderType) {
  // 通过id找到script标签
  var shaderScript = document.getElementById(scriptId);
  if (!shaderScript) {
    throw '*** Error: unknown script element' + scriptId;
  }

  // 提取标签内容。
  var shaderSource = shaderScript.text;

  // 如果没有传着色器类型,就使用标签的 ‘type’ 属性
  if (!opt_shaderType) {
    if (shaderScript.type == 'x-shader/x-vertex') {
      opt_shaderType = gl.VERTEX_SHADER;
    } else if (shaderScript.type == 'x-shader/x-fragment') {
      opt_shaderType = gl.FRAGMENT_SHADER;
    } else if (!opt_shaderType) {
      throw '*** Error: shader type not set';
    }
  }

  return _compileShader(gl, shaderSource, opt_shaderType);
}

/**
 * 通过两个 script 标签创建程序。
 *
 * @param {!WebGLRenderingContext} gl WebGL上下文。
 * @param {string} vertexShaderId 顶点着色器的标签id。
 * @param {string} fragmentShaderId 片段着色器的标签id。
 * @return {!WebGLProgram} 程序。
 */
export function createProgramFromScripts(gl, vertexShaderId, fragmentShaderId) {
  var vertexShader = _createShaderFromScriptTag(gl, vertexShaderId, gl.VERTEX_SHADER);
  var fragmentShader = _createShaderFromScriptTag(gl, fragmentShaderId, gl.FRAGMENT_SHADER);
  return _createProgram(gl, vertexShader, fragmentShader);
}

/**
 * 清理画布
 * @param {*} gl WebGL上下文
 */
export function resetCanvas(gl) {
  //裁剪空间坐标对应到画布像素坐标
  gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
  // 清空画布
  gl.clearColor(0, 0, 0, 0);
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
}

然后运行Study.html,不出意外的话将显示下面的一个三角形 

 

知识来源:WebGL 理论基础 (webglfundamentals.org) 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2103532.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

QQ聊天记录删除了怎么恢复?学会这3个方法,简单又有效

QQ作为我们日常沟通的重要工具之一&#xff0c;其聊天记录往往承载着许多珍贵的记忆和重要的信息。但在操作中我们会不小心删除或丢失这些聊天记录&#xff0c;那么QQ聊天记录删除了怎么恢复就成为我们急切需要解决的问题。先别急&#xff0c;本文就为你介绍3种简单又有效的QQ聊…

SpringBoot 大学生体质测试管理系统

摘要 大学生体质测试管理系统提供给用户一个简单方便体质测试管理信息&#xff0c;通过留言区互动更方便。本系统采用了B/S体系的结构&#xff0c;使用了java技术以及MYSQL作为后台数据库进行开发。系统主要分为系统管理员、教师和用户三个部分&#xff0c;系统管理员主要功能…

【STM32+HAL库】---- 驱动DHT11温湿度传感器

硬件开发板&#xff1a;STM32F407VET6 软件平台&#xff1a;cubemaxkeilVScode1 DHT11工作原理 1.1 简介 DHT11温湿度传感器是一种数字式温湿度传感器&#xff0c;其工作原理基于集成了湿度感测元件和NTC温度感测元件的传感器模块。以下是DHT11温湿度传感器的工作原理&#x…

【安全生产】叉车安全带报警器有哪些特点?

叉车安全带报警器是用于防止在叉车发生猛烈碰撞或紧急制动时&#xff0c;司机不与方向盘、挡风玻璃等发生二次碰撞或抛出车外&#xff0c;从而造成的严重伤害的一种叉车安全装置、配件。 很多司机在开叉车时经常有不系安全带的习惯&#xff0c;有很多不负责任的人会认为&#…

智能水培机

目录 一. 选型 1.1 Lichee RV Dock 1.1.1 芯片&#xff1a;D1-H 1.1.2 镜像选择&#xff1a;Tina Linux 二. QT上位机 2.1 选择ID 2.2 主界面刷新数据 2.2.1 设置定时器 2.2.3 定义查询数据库表qtnew的函数checkNew_data 2.2.2 定义槽函数 Refresh_data 2.3 主界面按…

讨论运维监控工具的普及程度

在讨论运维监控工具的普及程度时&#xff0c;加入PIGOSS BSM产品的分析是非常有意义的&#xff0c;因为PIGOSS BSM是一款在中国市场具有一定影响力的运维监控工具。 PIGOSS BSM运维监控工具是一款综合性的IT运维监控解决方案&#xff0c;它能够对多层次的IT资源进行监测&#x…

2024.09.04【读书笔记】|如何使用GATK ASEReadCounter工具进行ASE(等位基因特异性表达)分析

准备数据&#xff1a; 获取基因组序列&#xff08;FASTA格式&#xff09;和对应的基因组注释文件&#xff08;GTF或GFF格式&#xff09;。获取样本的BAM文件&#xff0c;确保这些文件已经过排序和索引。获取变异信息文件&#xff08;VCF格式&#xff09;&#xff0c;包含样本的…

运动耳机哪个牌子的好?精选5款值得入手的骨传导运动耳机分享!

在过去的两年里&#xff0c;骨传导耳机逐渐被大众的所熟知。可能毕竟长时间使用音量过大的传统入耳式耳机&#xff0c;多多少少会对我们的听力健康构成威胁。所以很多人就想找一款不伤耳朵的耳机。然后就了解到了骨传导耳机&#xff0c;所以就会延伸出这些问题——骨传导耳机好…

【效率工具】推荐五款电脑桌面软件,轻量好用!

电脑桌面软件可以帮助我们在电脑上创建分区&#xff0c;然后将文件、文件夹、应用程序等图标整理到对应的分区中&#xff0c;方便我们精准访问文件。不同的电脑桌面软件功能可能存在一些差异&#xff0c;本文分享几个常用的桌面整理工具&#xff0c;以及一些以及分享一些关于电…

EvoSuite使用总结

1.安装EvoSuite插件 以IDEA为例&#xff0c;在Plugins栏搜索EvoSuite后点击install&#xff0c;安装完成后重启IDEA 2.使用EvoSuite 选中文件右键选择Run EvoSuite 生成成功可以看到如下提示&#xff1a; 注意事项&#xff1a; 生成路径&#xff1a;src/test/java 使用juni…

【C++ 第十九章】异常

1.C语言传统的处理错误的方式 传统的错误处理机制&#xff1a; 终止程序&#xff0c;如 assert&#xff0c;缺陷&#xff1a;用户难以接受。如发生内存错误、除 0 错误时就会终止程序。 返回错误码&#xff0c;缺陷&#xff1a;需要程序员自己去查找对应的错误。如系统的很多库…

趣解网络安全专业术语(保密性、暴露)零基础入门到精通,收藏这一篇就够了

保密性confidentiality 使信息不泄露给未授权的个人、实体、进程&#xff0c;或不被其利用的特性。 想象一下&#xff0c;你有一个神秘的盒子&#xff0c;里面装满了你最珍贵的秘密。这个盒子有一个特殊的锁&#xff0c;只有你和你最亲密的朋友能打开它。这个锁特别聪明&#…

新一代交互模式:LUICUIVUI

随着技术的发展&#xff0c;特别是人工智能和机器学习的进步&#xff0c;交互方式也在不断演变。以下是一些新概念&#xff0c;它们描述了当下和未来可能的交互方式&#xff1a; Conversational UI (CUI)&#xff1a; 以对话为基础的用户界面&#xff0c;用户通过自然语言与系统…

Moveit2 Move Group C++ 接口

系列文章目录 留空 文章目录 系列文章目录前言一、完整代码二、编写步骤三、代码分析1. 引入必要的头文件2. 初始化和配置 ROS2 环境3. 设置 MoveIt 规划组和场景4. 可视化5. 获取基本信息6. 开始演示7. 规划姿态目标8. 可视化计划路径9. 移动到姿势目标10. 规划关节空间目标1…

OpenAI发布GPT-4o mini,3.5从此退出历史舞台?

随着OpenAI在2024年7月18日正式发布GPT-4o Mini&#xff0c;无疑在科技界引发了一场新的风暴。这一创新不仅标志着GPT-3.5模型正式退出历史舞台&#xff0c;更预示着人工智能在自然语言处理领域迈入了一个全新的时代。 之前速度最快的模型一直是GPT3.5&#xff0c;随着后来的GP…

数据结构——开篇

一、数据结构&#xff08;内存中&#xff09; 1、定义 用来保存一种或多种特定关系的数据的集合&#xff08;组织和存储数据&#xff09;。 程序 数据结构算法 2、特定关系 &#xff08;1&#xff09;逻辑结构 数据元素与元素之间的关系。 分类&#xff1a;①集合&…

电脑找不到x3daudio1_7.dll怎么解决?5种方法科学修复x3daudio1_7.dll

如果在使用电脑过程中遇到“找不到x3daudio1_7.dll”的错误&#xff0c;这通常意味着您的系统缺少一个关键组件&#xff0c;它是与 Microsoft DirectX 相关的一个文件&#xff0c;主要用于处理高级音频功能&#xff0c;尤其是在游戏和其他多媒体应用程序中。其实这个问题通常可…

传统CV算法——基于Opencv的多目标追踪算法

基于 OpenCV 的跟踪算法有多种&#xff0c;每种算法都有其特定的应用场景和优缺点。以下是一些常见的基于 OpenCV 的目标跟踪算法&#xff1a; 1. BOOSTING 跟踪器 描述&#xff1a;基于 AdaBoost 算法的跟踪器。它是一种早期的跟踪算法&#xff0c;使用的是基于弱分类器的强…

归并、计数排序(画图详解)

归并排序&#xff1a; 基本思想&#xff1a;先递归再回归&#xff0c;在回归的时候进行归并排序 归并排序&#xff1a; 适用于两个有序数组&#xff0c;合并成一个数组的时候&#xff0c;也就是先要递归&#xff0c;递归到最后就相当于一个元素&#xff0c;一个元素就是有序的。…

Unity数据持久化 之 二进制存储法

本文仅作笔记学习和分享&#xff0c;不用做任何商业用途 本文包括但不限于unity官方手册&#xff0c;unity唐老狮等教程知识&#xff0c;如有不足还请斧正​​ 前置知识&#xff1a;1 Byte 8 bit &#xff0c;所以0000 00001 就是一个字节&#xff0c; 该串数字转为十进制代表1…