glsl - 着色器 : How to draw 3D point verts without generating geometry?

标签 glsl webgl shader

我有一个 3D Webgl 场景。我正在使用 Regl http://regl.party/ .这是 WebGL。所以我基本上是在直接编写 GLSL。

这是一个游戏项目。我有一组 3D 位置 [[x,y,z] ...],它们是子弹或射弹。我想将这些子弹绘制为简单的立方体、球体或粒子。外观无要求。

我如何制作着色器和绘制调用,而不必为子弹创建一组重复的几何图形?

更喜欢使用 vert 和 frag 着色器示例的答案,该示例演示了预期的数据输入并且可以通过逆向工程来处理 CPU 绑定(bind)层

最佳答案

您创建了一个封装了一堆数据的 regl 命令。然后您可以使用对象调用它。

每个 uniform 都可以使用一个可选函数来提供它的值。该函数传递一个 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>

关于glsl - 着色器 : How to draw 3D point verts without generating geometry?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54156753/

相关文章:

macos - Mac OS X 上的配置文件 GLSL 片段着色器?

javascript - 在 html 页面上嵌入 Web-GL 沙箱的效果

javascript - 在 Fabric.js 中真正旋转等边三 Angular 形的中心

opengl - 基于物理的着色器未产生预期结果

c++ - 法线贴图问题

OpenGL 着色器错误 : 0:1: '' : syntax error #version

javascript - 处理多个 Canvas 上下文的解决方案

c - highp float在GLSL中是如何呈现的?

opengl - 附加了分割着色器时,glDrawArrays失败

c - 如何显示这些小三角形或快速识别它们?