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

WebGL编程指南 - 入门续

相关内容:在attribute变量传递参数的基础上,通过JavaScript获取鼠标事件的坐标,再经过坐标转换传递给attribute变量;Web颜色缓冲区每次绘制之后都会重置
相关函数:JavaScript鼠标事件onmousedown/onmouseup/onclick

html代码还是老一套

js代码:

// ClickedPoints.js
// 顶点着色器
var VSHADER_SOURCE =
  'attribute vec4 a_Position;\n' +
  'void main() {\n' +
  ' gl_Position = a_Position;\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'
// 主函数
function main() {
  // 获取<canvas>元素
  let canvas = document.getElementById('webgl')
  // 获取WebGL绘图上下文
  let gl = getWebGLContext(canvas)
  if (!gl) {
    console.log('Failed to get the rendering context for WebGL')
    return
  }
  // 初始化着色器
  if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
    console.log('Failed to initialize shaders')
    return
  }
  // 获取a_Position变量的存储位置
  let a_Position = gl.getAttribLocation(gl.program, 'a_Position')
  if (a_Position < 0) {
    console.log('Failed to get the storage location of a_Position')
  }
  // 注册鼠标点击事件响应函数
  canvas.onmousedown = function (ev) {
    // console.log(ev)
    click(ev, gl, canvas, a_Position)
  }
  // 设置背景色
  gl.clearColor(0.0, 0.0, 0.0, 1.0)
  // 清空绘图区域
  gl.clear(gl.COLOR_BUFFER_BIT)
}
var g_points = [] // 鼠标点击位置数组
function click(ev, gl, canvas, a_Position) {
  let x = ev.clientX // 鼠标点击处的x坐标
  let y = ev.clientY // 鼠标点击处的y坐标
  let rect = ev.target.getBoundingClientRect() //cnavas边界坐标
  // 坐标转换
  x = (x - rect.left - canvas.width / 2) / (canvas.width / 2)
  y = (canvas.height / 2 - (y - rect.top)) / (canvas.height / 2)
  // 将坐标存储到g_points数组中
  g_points.push(x)
  g_points.push(y)

  // 清空绘图区
  gl.clear(gl.COLOR_BUFFER_BIT)
  // 绘制数组中的点
  let len = g_points.length
  for (let i = 0; i < len; i += 2) {
    // 将点的位置传递到变量中a_Position
    gl.vertexAttrib3f(a_Position, g_points[i], g_points[i + 1], 0.0)
    // 绘制点
    gl.drawArrays(gl.POINTS, 0, 1)
  }
}

此处将x和y坐标通过JavaScript自带的鼠标点击事件来获取,通过坐标转换传递到着色器中。

注册事件响应函数:

// 注册鼠标点击事件响应函数
  canvas.onmousedown = function (ev) {
    // console.log(ev)
    click(ev, gl, canvas, a_Position)
  }

此处用ev作为函数的形参接收,ev中挂载了许多关于这一事件的属性,包括触发对象(target)、坐标等,不同事件传递的事件对象不同

改变点的颜色与uniform变量(动态设置片元着色器)

相关内容:JavaScript设置点的颜色;JavaScript传递点的颜色给片元着色器(通过uniform变量)
相关函数:gl.getUniformLocation(), gl.uniform4f()

  • 在片元着色器中准备 uniform 变量
  • 用这个 uniform 变量向 gl_FragColor 赋值
  • 将颜色数据从 JavaScript 传给 uniform 变量

根据位置不同显示不同地颜色

// ClickedPoints.js
// 顶点着色器
var VSHADER_SOURCE =
  'attribute vec4 a_Position;\n' +
  'void main() {\n' +
  ' gl_Position = a_Position;\n' +
  ' gl_PointSize = 10.0;\n' +
  '}\n'
// 片元着色器
var FSHADER_SOURCE =
  'precision mediump float;\n' +
  'uniform vec4 u_FragColor;\n' +
  'void main() {\n' +
  ' gl_FragColor = u_FragColor;\n' + // 设置颜色
  '}\n'
// 主函数
function main() {
  // 获取<canvas>元素
  let canvas = document.getElementById('webgl')
  // 获取WebGL绘图上下文
  let gl = getWebGLContext(canvas)
  if (!gl) {
    console.log('Failed to get the rendering context for WebGL')
    return
  }
  // 初始化着色器
  if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
    console.log('Failed to initialize shaders')
    return
  }
  // 获取a_Position变量的存储位置
  let a_Position = gl.getAttribLocation(gl.program, 'a_Position')
  if (a_Position < 0) {
    console.log('Failed to get the storage location of a_Position')
  }
  //获取u_FragColor 变量的存储位置
  let u_FragColor = gl.getUniformLocation(gl.program,'u_FragColor');
  if(u_FragColor < 0) {
    console.log('Failed to get the storage location of u_FragColor');
  }
  // 注册鼠标点击事件响应函数
  canvas.onmousedown = function (ev) {
    // console.log(ev)
    click(ev, gl, canvas, a_Position,u_FragColor);
  }
  // 设置背景色
  gl.clearColor(0.0, 0.0, 0.0, 1.0)
  // 清空绘图区域
  gl.clear(gl.COLOR_BUFFER_BIT)
}
var g_points = [] // 鼠标点击位置数组
var g_colors = [];// 存储点颜色的数组
function click(ev, gl, canvas, a_Position,u_FragColor) {
  let x = ev.clientX // 鼠标点击处的x坐标
  let y = ev.clientY // 鼠标点击处的y坐标
  let rect = ev.target.getBoundingClientRect() //cnavas边界坐标
  // 坐标转换
  x = (x - rect.left - canvas.width / 2) / (canvas.width / 2)
  y = (canvas.height / 2 - (y - rect.top)) / (canvas.height / 2)
  // 将坐标存储到g_points数组中
  g_points.push(x)
  g_points.push(y)

// 将点的颜色存储到g_colors中
if (x >= 0.0 && y >= 0.0) {
    // 第一象限
    g_colors.push([1.0, 0.0, 0.0, 1.0]) // 红色
  } else if (x < 0.0 && y < 0.0) {
    // 第三象限
    g_colors.push([0.0, 0.0, 1.0, 1.0]) // 绿色
  } else {
    // 其他
    g_colors.push([1.0, 1.0, 1.0, 1.0]) // 白色
  }

  // 清空绘图区
  gl.clear(gl.COLOR_BUFFER_BIT)
  // 绘制数组中的点
  let len = g_points.length
  for (let i = 0; i < len; i += 2) {
    let rgba = g_colors[i/2];
    // 将点的位置传递到变量中a_Position
    gl.vertexAttrib3f(a_Position, g_points[i], g_points[i + 1], 0.0);
    gl.uniform4fv(u_FragColor,rgba);
    // 绘制点
    gl.drawArrays(gl.POINTS, 0, 1)
  }
}

uniform 变量

// 片元着色器
var FSHADER_SOURCE =
  'precision mediump float;\n' +
  'uniform vec4 u_FragColor;\n' + // uniform变量
  'void main() {\n' +
  ' gl_FragColor = u_FragColor;\n' +
  '}\n'
  • uniform变量的声明遵循与attribute变量相同的格式<存储限定符><类型><变量名>

获取uniform变量的存储地址

  // 获取u_FragColor变量的存储位置
  let u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor')
  if (!u_FragColor) {
    console.log('Failed to get the storage location of u_FragColor')
  }

指定变量不存在时,返回的是null而不是-1。所以在检查的时候,需要用’!‘(取反)操作符而不是’<0’

向 uniform 变量赋值

参考:【《WebGL编程指南》读书笔记】_webgl 编程指南笔记-CSDN博客


http://www.kler.cn/news/363417.html

相关文章:

  • Lua表(Table)
  • 多模态大语言模型(MLLM)-Deepseek Janus
  • docker容器无法连接宿主机mysql排查
  • 深入解析Python数据容器
  • Build an Android project and get a `.apk` file on a Debian 11 command line
  • RHCE的学习(6)
  • 喜讯!望繁信科技荣膺2022年中国超自动化先锋企业TOP20
  • RHCSA学习_1使用rhel9练习Linux基础命令
  • 安全见闻(9)——开阔眼界,不做井底之蛙
  • VASCO:增减材混合制造的体积和表面共分解
  • python -【流式接口返回响应处理】
  • 分布式数据库的搭建
  • PDF文件为什么不能编辑是?是啥原因导致的,有何解决方法
  • Android音视频 MediaCodec框架-启动编码(4)
  • React1-基础概念
  • 探秘磁盘的奥秘:物理结构、缓存和虚拟内存的作用
  • 【Java数据结构】---Map和Set(二叉搜索树)
  • 力扣382:链表随机结点
  • 计算广告第三版pdf
  • V2X介绍
  • 未来医疗:大语言模型如何改变临床实践、研究和教育|文献精析·24-10-23
  • Java毕业设计项目-ssm图书管理系统
  • 每日回顾:简单用C写 直接插入排序、希尔排序
  • 面试经典算法题63-只出现一次的数字
  • 使用json模块解析JSON数据
  • oracle和hive之间关于sql的语法差异及转换