WebGL彩色图转灰度图

彩色图转灰度图

本文是WebGL电子书的1.13节内容

上一节课讲解了纹理贴图的知识点,本节课通过一个把彩色图处理为灰度图的案例进一步认识可编程片元着色器和逐片元的概念。

在这里插入图片描述在这里插入图片描述

纹理贴图可以经过渲染管线处理后映射到三维空间中顶点坐标定义的位置,在这个过程中,执行方法texture2D()提取的像素值直接赋值给片元,存入帧缓存的颜色缓冲区中, 显示系统扫描颜色缓冲区中的像素值显示在屏幕上。渲染过线的片元着色器是可编程的,可以执行着色器语言编写的程序,也就是说可以对图片的纹素进行后期处理, 就像生活中你利用PS等软件去处理你拍的照片风格化,它的本质都是按照一定的算法处理图片,更改像素RGBA值。

亮度

灰度图颜色只有黑白两色,或者说灰度图颜色分量只有光亮度这一个分量,黑色相当于没有光照,白色相当于最大光照强度。那么光的亮度和RGB颜色模型的三原色有什么样的数学关系, 简单的理解,RGB分量越大,灰度图就越接近于白色,具体的计算公式如下,RGB的系数之和为1,这样可以保证计算的结果不会超出WebGL颜色分量默认的最大值1。

亮度 = 0.299 x R + 0.587 x G + 0.114 x B

纹理的加载处理处理过程和上一节课的一样,这里只列出片元着色器要执行的程序,片元着色器的计算语句要写在主函数main()里面。

void main() {
  //采集纹素
  vec4 texture = texture2D(u_Sampler,v_TexCoord);
  //计算RGB三个分量光能量之和,也就是亮度
  float luminance = 0.299*texture.r+0.587*texture.g+0.114*texture.b;
  //逐片元赋值,RGB相同均为亮度值,用黑白两色表达图片的明暗变化
  gl_FragColor = vec4(luminance,luminance,luminance,1.0);
}

执行vec4 texture = texture2D(u_Sampler,v_TexCoord);代码中WebGL API gl.texture2D(),片元着色器会从纹理缓冲区的纹理单元中获取像素值RGB,返回vec4类型向量数据,vec4的三个分量分别是RGB和A,jpg格式图片没有透明度分量, 程序默认补1表示不透明,通过运算符点(.)可以访问RGBA分量,float luminance = 0.299*texture.r+0.587*texture.g+0.114*texture.b;代码执行的是彩色图转灰度图的公式:亮度 = 0.299 x R + 0.587 x G + 0.114 x B, 通过代码gl_FragColor = vec4(luminance,luminance,luminance,1.0);把计算结果赋值给片元,片元的RGB分量相同都是亮度值,显示效果只有黑白两色。

其它后期处理

更改透明度

在这里插入图片描述

在实际的工程中,对像素值进行后期处理是很常见的操作,通常都是通过片元着色器程序控制片元着色器处理像素值的分量,你可以把gl_FragColor = vec4(luminance,luminance,luminance,1.0);代码vec4构造函数的最后一个分量1.0更改为0.5, 你会发现熊猫图片的颜色会与canvas画布的背景颜色进行融合,熊猫图片呈现出半透明状态。

拉深图片

在这里插入图片描述

图片颜色值可以更改,显示尺寸也可以实现拉伸,本案例程序中图片的尺寸宽高比例是1,顶点坐标矩形区域宽高比也是1,显示效果正常。你可以把顶点数据的y值正值变大,负值变小, 刷新浏览器查看效果你会发现熊猫图片纵向拉伸。

/**
 * 四个顶点坐标数据data,z轴为零
 * 定义纹理贴图在WebGL坐标系中位置
 **/
var data=new Float32Array([
    -0.5, 0.5,//左上角——v0
    -0.5,-0.5,//左下角——v1
    0.5,  0.5,//右上角——v2
    0.5, -0.5 //右下角——v3
]);
/**
 * 四个顶点坐标数据data,z轴为零
 * 定义纹理贴图在WebGL坐标系中位置
 **/
var data=new Float32Array([
    -0.5, 0.7,//左上角——v0
    -0.5,-0.7,//左下角——v1
    0.5,  0.7,//右上角——v2
    0.5, -0.7 //右下角——v3
]);

旋转图片

在这里插入图片描述

纹理贴图是映射在WebGL顶点位置坐标数据定义的矩形平面上,如果把矩形顶点位置和前面课程中立方体一样绕着x和y轴进行旋转,自然可以呈现出图片旋转的效果。

具体效果查看案例源码“1.图片映射的位置旋转变换.html”

/**uniform声明旋转矩阵变量mx、my**/
uniform mat4 mx;//绕x轴旋转矩阵
uniform mat4 my;//绕y轴旋转矩阵
void main() {
  //两个旋转矩阵、顶点齐次坐标连乘
  gl_Position = mx*my*a_Position;
  //纹理坐标插值计算
  v_TexCoord = a_TexCoord;
}
/**
 * 传入旋转矩阵数据
 ***/
var angle = Math.PI/6;//旋转角度
var sin = Math.sin(angle);
var cos = Math.cos(angle);
//旋转矩阵数据
var mxArr = new Float32Array([1,0,0,0,  0,cos,-sin,0,  0,sin,cos,0,  0,0,0,1]);
var myArr = new Float32Array([cos,0,-sin,0,  0,1,0,0,  sin,0,cos,0,  0,0,0,1]);
//类型数组传入矩阵
gl.uniformMatrix4fv(mx, false, mxArr);
gl.uniformMatrix4fv(my, false, myArr);
WebGL Radar Gray Scale Fill 图是一种将雷达数据可视化到三维空间中的技术,并且通过灰色阶的颜色映射表示数据的强度或密度。这种类型的图形通常用于显示天气预报、飞行路径跟踪、军事应用等场景。 ### 实现步骤: #### 1. 准备数据 首先,你需要收集并准备雷达数据。这通常包括时间、距离以及对应的数据值,例如反射率因子或其他气象变量。这些数据可以以二维矩阵的形式存在,每一行代表一条扫描线,每一列则代表距离上的一系列点。 #### 2. 创建 WebGL 环境 初始化 WebGL 渲染上下文,创建一个 WebGL 对象,并设置渲染目标(通常是画布)。这通常需要 HTML5 `<canvas>` 元素作为渲染区域。 ```html <canvas id="radarCanvas" width="800" height="600"></canvas> ``` #### 3. 编写顶点着色器和片段着色器 编写顶点着色器 (Vertex Shader) 来处理三维模型的位置;编写片段着色器 (Fragment Shader) 来确定每个像素的颜色值。对于雷达灰度图,颜色值应基于数据值的大小,一般使用线性插值得出各点的颜色索引,在灰度范围内的颜色由灰度级表示。 #### 4. 配置着色器和绘制几何体 配置顶点数组、纹理坐标和其他需要传递给着色器的信息。通常会使用一个立方体或是一个网格来模拟雷达的视场,以便于数据的可视化。在 `drawArrays()` 或者 `drawElements()` 中指定如何从顶点缓冲区中读取数据进行绘制。 #### 5. 应用颜色映射 为了生成灰度图,可以利用数据值计算出相应的颜色。这通常涉及将数据值映射到一个灰度范围(如0至255),然后转换为 RGB 颜色。例如,可以采用以下函数将数值映射到灰度: ```javascript function valueToGray(value, minValue, maxValue, minColor, maxColor) { let grayScale = ((value - minValue) / (maxValue - minValue)) * 255; return (grayColor * (minColor + Math.max(0, Math.min(grayScale, 255))) + (255-grayColor) * (maxColor + Math.min(Math.abs(255 - grayScale), 255))); } ``` 这里,`grayColor` 表示灰度颜色的占比。 #### 6. 更新着色器和重绘 随着时间推移更新雷达数据并在每次循环时重绘整个视图,以反映最新的数据变化。 ### 相关问题: 1. **如何优化 WebGL Radar Gray Scale Fill 的性能?** 优化 WebGL 性能可以通过减少不必要的计算、缓存结果、使用 GPU 加速的库(如 Three.js)和调整着色器代码来实现。 2. **WebGL Radar Gray Scale Fill 是否适用于所有设备?** WebGL 的兼容性依赖于浏览器支持程度和设备硬件能力。部分旧版或不支持 WebGL 的设备可能会出现问题。 3. **如何在雷达灰度图中添加额外信息,比如风向、温度等?** 可以通过增加额外的数据通道来展示其他信息。例如,使用另一个纹理通道存储额外数据,并在着色器中混合颜色以反映多重属性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Threejs可视化

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

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

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

打赏作者

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

抵扣说明:

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

余额充值