使用pointSize触发片段着色器绘制像素

时间:2019-01-31 14:12:30

标签: webgl webgl2

我查询pointSize范围gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE)并得到[1,1024],这意味着,使用该点覆盖纹理(因此它触发片段着色器以{{{ 1}}

充其量,使用这种方法,我无法渲染大于1024x1024的图像??

我想我必须将2个三角形(6个点)绑定到片段着色器,以便它覆盖所有的剪贴空间,然后再覆盖gl.viewport(x,y,width,height);会将整个区域映射到输出纹理(帧缓冲区对象或画布)?

除了在片段着色器中使用属性外,还有其他方法(可能是webgl2中的新方法)吗?

1 个答案:

答案 0 :(得分:1)

正确,您可以用单点渲染的最大尺寸区域是gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE)返回的值

该规范不需要大于1的任何大小。GPU/驱动程序/浏览器返回1024的事实并不意味着您的用户的计算机也将返回1024。

注意:根据您的问题历史回答

在WebGL中,所有情况下要进行99%折算的正常操作是提交顶点。要绘制一个四边形,提交4个顶点和6个索引或6个顶点。要绘制一个三角形,提交3个顶点。要绘制一个圆,提交一个圆的顶点。想要绘制汽车,提交汽车的顶点或更可能提交车轮的顶点,使用这些顶点绘制4个车轮,提交汽车其他部分的顶点,绘制汽车的每个部分。

multiply those vertices by some matrices将其移动,缩放,旋转并将其投影到2D3D空间中。您所有喜欢的游戏都可以做到这一点。 canvas 2D api通过OpenGL ES内部执行此操作。 Chrome本身会执行此操作以呈现此网页的所有部分。那是常态。其他所有情况都是例外,可能会导致限制。

为了娱乐,在WebGL2中,您还可以执行其他一些操作。这不是正常的事情,不推荐来解决现实世界中的问题。他们可以很有趣,尽管只是为了挑战。

在WebGL2中,顶点着色器中有一个名为gl_VertexID的全局变量,它是当前正在处理的顶点的数量。您可以将其与聪明的数学一起使用,以在顶点着色器中生成顶点,而无需其他数据。

这里有一些代码绘制了一个覆盖画布的四边形

function main() {
  const gl = document.querySelector('canvas').getContext('webgl2');
  
  const vs = `#version 300 es
  void main() {
    int x = gl_VertexID % 2;
    int y = (gl_VertexID / 2 + gl_VertexID / 3) % 2;    
    gl_Position = vec4(ivec2(x, y) * 2 - 1, 0, 1);
  }
  `;
  
  const fs = `#version 300 es
  precision mediump float;
  out vec4 outColor;
  void main() {
    outColor = vec4(1, 0, 0, 1);
  }
  `;
  
  // compile shaders, link program
  const prg = twgl.createProgram(gl, [vs, fs]);
  
  gl.useProgram(prg);
  const count = 6;
  gl.drawArrays(gl.TRIANGLES, 0, count);
}
main();
<canvas></canvas>
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>

示例:然后画一个圆

function main() {
  const gl = document.querySelector('canvas').getContext('webgl2');
  
  const vs = `#version 300 es
  #define PI radians(180.0)
  void main() {
    const int TRIANGLES_AROUND_CIRCLE = 100;
    int triangleId = gl_VertexID / 3;
    int pointId = gl_VertexID % 3;
    int pointIdOffset = pointId % 2;
    
    float angle = float((triangleId + pointIdOffset) * 2) * PI /
                  float(TRIANGLES_AROUND_CIRCLE);
    float radius = 1. - step(1.5, float(pointId));
    float x = sin(angle) * radius;
    float y = cos(angle) * radius;
    
    gl_Position = vec4(x, y, 0, 1);
  }
  `;
  
  const fs = `#version 300 es
  precision mediump float;
  out vec4 outColor;
  void main() {
    outColor = vec4(1, 0, 0, 1);
  }
  `;
  
  // compile shaders, link program
  const prg = twgl.createProgram(gl, [vs, fs]);
  
  gl.useProgram(prg);
  const count = 300;  // 100 triangles, 3 points each
  gl.drawArrays(gl.TRIANGLES, 0, 300);
}
main();
<canvas></canvas>
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>

an entire website based on this idea。该网站的基础是制作漂亮的图片,每个顶点仅给出一个ID。它相当于shadertoy.com的顶点着色器。在Shadertoy.com上,基本上只有gl_FragCoord给出了难题,因为它是片段着色器的输入,并编写了绘制有趣内容的函数。

两个站点都是玩具/拼图。不建议使用这种方式来解决实际问题,例如在游戏中绘制3D世界,进行图像处理,渲染浏览器窗口的内容等。这些都是仅需最少输入即可绘制的有趣难题,可以绘制有趣的东西。

为什么不建议使用此技术?最明显的原因是它的硬编码和不灵活,而标准技术却具有很高的灵活性。例如,上面绘制一个全屏四边形需要一个着色器。要绘制圆,需要使用其他着色器。在基于标准顶点缓冲区的属性乘以矩阵的情况下,可将其用于提供的任何形状(2d或3d)。不仅是任何形状,只要在着色器中使用一个简单的单矩阵乘法,就可以将这些形状转换,旋转,缩放,投影到3D中,在那里可以独立设置旋转中心和比例中心,等等。

注意:您可以随意做任何想做的事情。如果您喜欢这些技术,请务必使用它们。我之所以试图将您从WebGL中分离出来,是基于您以前对WebGL刚接触的问题,我觉得如果使用诸如此类的晦涩难懂的编码技术,最终会使WebGL变得更难经验丰富的开发人员用来完成实际工作的传统更常见的灵活技术。但是,由您决定,做任何您想做的事。