glsl - 着色器:如何在不生成几何图形的情况下绘制 3D 点顶点?
问题描述
我有一个 3D Webgl 场景。我正在使用 Regl http://regl.party/。这是WebGL。所以我基本上是在写直接的 GLSL。
这是一个游戏项目。我有一组 3D 位置 [[x,y,z] ...],它们是子弹或射弹。我想把这些子弹画成一个简单的立方体、球体或粒子。对外观没有要求。
我怎样才能为此制作着色器和绘制调用,而不必为子弹创建重复的几何图形集?
更喜欢带有 vert 和 frag 着色器示例的答案,该示例演示了预期的数据输入,并且可以进行逆向工程以处理 CPU 绑定层
解决方案
您创建一个封装了一堆数据的 regl 命令。然后,您可以使用对象调用它。
每个制服都可以采用可选功能来提供其价值。该函数作为第一个参数传递一个 regl 上下文,然后作为第二个参数传递的对象,因此您可以使用不同的对象多次调用它以在其他地方绘制相同的东西(相同的顶点,相同的着色器)。
var regl = createREGL()
const objects = [];
const numObjects = 100;
for (let i = 0; i < numObjects; ++i) {
objects.push({
x: rand(-1, 1),
y: rand(-1, 1),
speed: rand(.5, 1.5),
direction: rand(0, Math.PI * 2),
color: [rand(0, 1), rand(0, 1), rand(0, 1), 1],
});
}
function rand(min, max) {
return Math.random() * (max - min) + min;
}
const starPositions = [[0, 0, 0]];
const starElements = [];
const numPoints = 5;
for (let i = 0; i < numPoints; ++i) {
for (let j = 0; j < 2; ++j) {
const a = (i * 2 + j) / (numPoints * 2) * Math.PI * 2;
const r = 0.5 + j * 0.5;
starPositions.push([
Math.sin(a) * r,
Math.cos(a) * r,
0,
]);
}
starElements.push([
0, 1 + i * 2, 1 + i * 2 + 1,
]);
}
const drawStar = regl({
frag: `
precision mediump float;
uniform vec4 color;
void main () {
gl_FragColor = color;
}`,
vert: `
precision mediump float;
attribute vec3 position;
uniform mat4 mat;
void main() {
gl_Position = mat * vec4(position, 1);
}`,
attributes: {
position: starPositions,
},
elements: starElements,
uniforms: {
mat: (ctx, props) => {
const {viewportWidth, viewportHeight} = ctx;
const {x, y} = props;
const aspect = viewportWidth / viewportHeight;
return [.1 / aspect, 0, 0, 0,
0, .1, 0, 0,
0, 0, 0, 0,
x, y, 0, 1];
},
color: (ctx, props) => props.color,
}
})
regl.frame(function () {
regl.clear({
color: [0, 0, 0, 1]
});
objects.forEach((o) => {
o.direction += rand(-0.1, 0.1);
o.x += Math.cos(o.direction) * o.speed * 0.01;
o.y += Math.sin(o.direction) * o.speed * 0.01;
o.x = (o.x + 3) % 2 - 1;
o.y = (o.y + 3) % 2 - 1;
drawStar(o);
});
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/regl/1.3.11/regl.min.js"></script>
推荐阅读
- node.js - 是否可以通过 nodejs 检查系统是否在 LAN 和 WiFi 上?
- javascript - 旋转自定义形状将其移动到角落
- ios - Swift 4 - iPhone 上的限制问题
- postgresql - 如何在 PostgreSQL 中按状态 DENSE_RANK()?
- python - 如何对包含多个文件的文件夹进行多线程处理?
- elasticsearch - 具有多个 must_not 条件的 Elasticsearch 行为不一致
- c++ - 我可以阻止用户在后台运行我的 C++ 程序吗?
- python - TypeError:“NoneType”对象不可迭代(h5 文件)
- kubernetes - _condition_ 在公制中是什么意思?
- google-cloud-platform - 需要帮助在 Google Cloud 上设置 A 记录