前言: 感谢XXHolic 大佬的翻译以及部分的解读内容,接着大佬的内容补充部分不够详细的点?(大概是对纹理一无所知的人,这篇文章看到你会失声尖叫然后迷恋上我)由于仍处于学习阶段,仅作部分自己的理解拓展,说白了没啥文化,术语也不懂几个,你喜欢,那就再好不过了。
参考与感谢
译者XXHolic How I built a wind map with WebGL译文 【译】A GPU Approach to Particle Physics
作者Clawko图形学底层探秘 - 纹理采样、环绕、过滤与Mipmap的那些事
绘制风场数据与为何使用图片存储的道理
根据原文中的部分,水平 即 u ,垂直为v ,对应 rgba 颜色里的 red 与 green 的值, 如何求这个值 以及渲染这个图像?
function generateWindMap(data) {
let canvas = document.createElement('canvas')
let [u_obj, v_obj] = data
let [u_header, v_header] = [u_obj.header, v_obj.header]
let [u_data, v_data] = [u_obj.data, v_obj.data]
let { nx, ny } = u_header
let [u_min, u_max, v_min, v_max] = [u_header.minData, u_header.maxData, v_header.minData, v_header.maxData]
let ctx = canvas.getContext('2d')
canvas.width = nx
canvas.height = ny
let imgData = new ImageData(nx, ny)
function reflect(datau, datav) {
let u = (datau - u_min) / (u_max - u_min) * 255
let v = (datav - v_min) / (v_max - v_min) * 255
return [u, v]
}
for (let i = 0; i < ny; i++) {
for (let j = 0; j < nx; j++) {
let dataIndex = i * nx + j;
let res = reflect(u_data[dataIndex], v_data[dataIndex])
imgData.data[4 * dataIndex + 0] = res[0];
imgData.data[4 * dataIndex + 1] = res[1];
imgData.data[4 * dataIndex + 2] = 0;
imgData.data[4 * dataIndex + 3] = 255;
}
}
ctx.putImageData(imgData, 0, 0);
console.log(canvas.toDataURL());
return canvas.toDataURL();
}
- 具体原理
- 为何将 u v 值 转换成rgb值 最后保存成一张图片?
最简单、快速的理解:存7,8M的数据还是存一个80K的图片好?这张图片上面根据这个映射的规律或者说是解码 我们就可以通过纹理采样读取到原来的数据。
绘制点的顶点着色器分析
precision mediump float;
attribute float a_index;
uniform sampler2D u_particles;
uniform float u_particles_res;
varying vec2 v_particle_pos;
void main() {
vec4 color = texture2D(u_particles, vec2(
fract(a_index / u_particles_res),
floor(a_index / u_particles_res) / u_particles_res));
v_particle_pos = vec2(
color.r / 255.0 + color.b,
color.g / 255.0 + color.a);
gl_PointSize = 1.0;
gl_Position = vec4(2.0 * v_particle_pos.x - 1.0, 1.0 - 2.0 * v_particle_pos.y, 0, 1);
}
假设粒子数量为 particlesNum , 我们用纹理(图片)保存他的状态,如法炮制,但首先明确的是这个只是一个数字,但我们可以对他开根号,得到一个长宽同样的空的纹理图片面积 u_particles_res 则是粒子数量开根的结果,就相当于映射的边界,统一看图。
- vec4 color 这段有啥意义?
texture2D 获取u_particles 这张纹理,将在此纹理坐标上的颜色取出来。 为啥是这个计算?这个计算想表达什么?一图给你讲明白。 x轴方向上应该比较好理解,y轴上为什么还要再除一次res? 获得的整数部分 相当于只是我们在普通的xy的坐标上的位置,再除一次 才是它真实的纹理y方向上的值。
|