当前位置: 首页 > news >正文

WebGL学习及项目实战(第02期:绘制一个点)

@

目录
  • 目标
  • WebGL原理示意图
  • 着色器
    • 顶点着色器:
    • 片元着色器:
    • 着色器代码如下
  • web端(js)
    • js代码
    • 代码结构梳理
    • 流程图
    • 完整代码(可直接在浏览器中查看)
    • 运行效果

目标

  • 使用WebgL绘制一个点
  • 了解整个绘制的编写流程并进行梳理和记录

WebGL原理示意图

在这里插入图片描述

  • 在示意图中,我们看到程序分为两个部分,一个部分是浏览器端,一个部分是GPU端。
  • 因此我们需要编写两个地方的代码,一个是js代码,一个是着色器代码(shader 编程)。

着色器

顶点着色器:

位置:js给顶点着色器传入一个位置数据,即一个二维的向量(x,y),着色器中将这个位置信息连同两个写死的数据,设置给gl_Position,这里需要attribute变量来接收,并赋值给gl_Position。

大小:本次采用直接在着色器中写死数据,也就是设置gl_PointSize = 10.0

片元着色器:

颜色:片元着色器中需要对颜色进行指定,我们也是采取写死的方式,即:gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
需要注意颜色是一个四维向量,前三个数据分别代表红、绿、蓝光学三原色。

着色器代码如下

<!-- 顶点着色器源码 -->
<script id="vertexShader" type="x-shader/x-vertex">attribute vec2 a_position;void main() {gl_Position = vec4(a_position, 0.0, 1.0);gl_PointSize = 10.0;}
</script>
<!-- 片元着色器源码 -->
<script id="fragmentShader" type="x-shader/x-fragment">void main() {gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);}
</script>

web端(js)

  • webgl:在js代码中,我们需要获取三维的画笔,也就是webgl,函数我们命名为initWebGL
  • 位置:需要准备顶点数据,因为我们只需要画一个点,所以准备一个2维的向量,也就是(x,y)
  • 大小:和一个点的大小,点本来没有大小,但我们需要看到它,所以给设置一个大小,事实上画的是一个面,但不纠结这些。
  • 颜色:还需要准备一个颜色的数据,这一次我们直接在着色器中写死数据。

js代码

<script>let canvasElementlet glfunction init() {// 初始化webglinitWebGL()// 初始化shadersinitShaders()// 初始化buffer,这里暂时没有用到buffer,我们在buffer中直接通过attribute设置了位置的值initBuffers()// 绘制draw()}function initWebGL() {// 在这个函数执行的过程中,输入、输出,没有,过程:canvasElement gl// 获取canvas元素canvasElement = document.getElementById('canvasId')// 获取WebGL上下文gl = canvasElement.getContext('webgl')}function initShaders() {// 获取着色器源码const vsSource = document.getElementById('vertexShader').innerTextconst fsSource = document.getElementById('fragmentShader').innerText// 初始化着色器initShader(gl, vsSource, fsSource)}function initBuffers() {setPointPosition(0.5, 0.5)}function setPointPosition(x, y) {// 获取位置属性const a_position = gl.getAttribLocation(gl.program, 'a_position')// 设置位置属性gl.vertexAttrib2f(a_position, x, y)}function draw() {// 清空画布颜色gl.clearColor(0.0, 0.0, 0.0, 1.0)// 清空画布gl.clear(gl.COLOR_BUFFER_BIT)// 绘制gl.drawArrays(gl.POINTS, 0, 1)}// -----------------这些代码之后需要单独封装,因此gl需要传递过来---------------------function initShader(gl, vsSource, fsSource) {// 创建着色器对象const vShader = loadShader(gl, gl.VERTEX_SHADER, vsSource)const fShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource)// 创建程序对象const program = gl.createProgram()// 将着色器对象分配给程序对象gl.attachShader(program, vShader)gl.attachShader(program, fShader)// 链接程序对象gl.linkProgram(program)// 使用程序对象gl.useProgram(program)// 将程序对象分配给gl.programgl.program = program}function loadShader(gl, type, source) {// 创建着色器const shader = gl.createShader(type)// 加载着色器源码gl.shaderSource(shader, source)// 编译着色器gl.compileShader(shader)return shader}
</script>

代码结构梳理

下图为对代码的一个视图化展示,使其分类清晰,并且层次感更强。

在这里插入图片描述

流程图

graph TDA([初始化WebGL]) --> B[初始化Shaders]B --> C[初始化Buffers]C --> D([draw])style A fill:#e1f5festyle B fill:#c8e6c9style C fill:#fff3e0style D fill:#f3e5f5

完整代码(可直接在浏览器中查看)

<!doctype html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>画一个点</title><!-- 需要:位置,color --><!-- 顶点着色器源码 --><script id="vertexShader" type="x-shader/x-vertex">attribute vec2 a_position;void main() {gl_Position = vec4(a_position, 0.0, 1.0);gl_PointSize = 10.0;}</script><!-- 片元着色器源码 --><script id="fragmentShader" type="x-shader/x-fragment">void main() {gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);}</script><script>let canvasElementlet glfunction init() {// 初始化WebGLinitWebGL()// 初始化着色器initShaders()// 初始化缓冲区initBuffers()// 绘制draw()}function initWebGL() {// 在这个函数执行的过程中,输入、输出,没有,过程:canvasElement gl// 获取canvas元素canvasElement = document.getElementById('canvasId')// 获取WebGL上下文gl = canvasElement.getContext('webgl')}function initShaders() {// 获取着色器源码const vsSource = document.getElementById('vertexShader').innerTextconst fsSource = document.getElementById('fragmentShader').innerText// 初始化着色器initShader(gl, vsSource, fsSource)}function initBuffers() {setPointPosition(0.5, 0.5)}function setPointPosition(x, y) {// 获取位置属性const a_position = gl.getAttribLocation(gl.program, 'a_position')// 设置位置属性gl.vertexAttrib2f(a_position, x, y)}function draw() {// 清空画布颜色gl.clearColor(0.0, 0.0, 0.0, 1.0)// 清空画布gl.clear(gl.COLOR_BUFFER_BIT)// 绘制gl.drawArrays(gl.POINTS, 0, 1)}// --------------------------------------function initShader(gl, vsSource, fsSource) {// 创建着色器对象const vShader = loadShader(gl, gl.VERTEX_SHADER, vsSource)const fShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource)// 创建程序对象const program = gl.createProgram()// 将着色器对象分配给程序对象gl.attachShader(program, vShader)gl.attachShader(program, fShader)// 链接程序对象gl.linkProgram(program)// 使用程序对象gl.useProgram(program)// 将程序对象分配给gl.programgl.program = program}function loadShader(gl, type, source) {// 创建着色器const shader = gl.createShader(type)// 加载着色器源码gl.shaderSource(shader, source)// 编译着色器gl.compileShader(shader)return shader}</script></head><body onload="init()"><canvas id="canvasId"></canvas></body>
</html>

运行效果

在这里插入图片描述

总结:本文主要梳理了在Webgl中如何绘制一个点,也就是提供了位置,大小,颜色等信息之后,我们使用shader绘制出一个红色的点,旨在掌握基本的编程流程,下次我们从绘制线和面开始,逐步更深入代码,力求在前三次把代码中的细节走一遍。

上一篇:WebGL学习及项目实战(第01期:原理篇)
下一篇:WebGL学习及项目实战(第03期:绘制多个点,线,面)
返回系列首页

http://www.hskmm.com/?act=detail&tid=31773

相关文章:

  • 2025 年 10 月国内加工中心制造商最新推荐排行榜:涵盖立式、卧式、龙门及多规格型号!
  • display ip routing-table protocol ospf 概念及题目 - 详解
  • C语言学习——小数数据类型
  • 高敏感人应对焦虑
  • Palantir本体论以及对智能体建设的价值与意义
  • 2025 年执业兽医资格证备考服务机构推荐榜,执业兽医资格证培训机构/执兽考试机构/考试辅导机构获得行业推荐
  • [LangChain] 基本介绍
  • 题解:P6755 [BalticOI 2013] Pipes (Day1)
  • Palantir 的“本体工程”的核心思路、技术架构与实践示例
  • P14164 [ICPC 2022 Nanjing R] 命题作文
  • C语言学习——整数变量
  • 语音合成技术从1秒样本学习表达风格
  • 我的高敏感和家人
  • 对称多项式
  • usb储存之BOT/UAS内核驱动
  • 简述flux思想?
  • 风控评分卡
  • 20232428 2025-2026-1 《网络与系统攻防技术》实验一实验报告
  • JAVA对象内存布局
  • 20232409 2025-2026-1 《网络与系统攻防技术》实验二实验报告
  • 10月15号
  • 记录一次客户现场环境,银河麒麟V10操作系统重启后,进入登录页面后卡死,鼠标键盘无响应的解决过程
  • 图 生成树
  • DolphinScheduler 3.1.9 单机版重启后,项目、流程定义等数据全部丢失
  • ManySpeech.AliParaformerAsr 使用指南
  • 资料拿取表
  • 易路:以“薪酬科技+AI”重塑中国企业薪酬管理新范式
  • 2025年太阳能板终极指南:选择、趋势与品牌推荐
  • 洛谷题单指南-进阶数论-CF776B Sherlock and his girlfriend
  • 下雪了 - L