标签: webgl2

此 WebGL 程序中的顶点着色器和片段着色器之间何时进行插值?

背景

我正在查看WebGL2 库PicoGL.js中的示例代码

它描述了一个三角形(三个顶点:)(-0.5, -0.5), (0.5, -0.5), (0.0, 0.5),顶点着色器为每个三角形分配了一种颜色(红、绿、蓝):

    #version 300 es

    layout(location=0) in vec4 position;
    layout(location=1) in vec3 color;

    out vec3 vColor; 
    void main() {
        vColor = color;
        gl_Position = position;
    }
Run Code Online (Sandbox Code Playgroud)

输出vColor被传递到片段着色器:

    #version 300 es
    precision highp float;

    in vec3 vColor;

    out vec4 fragColor;
    void main() {
        fragColor = vec4(vColor, 1.0);
    }
Run Code Online (Sandbox Code Playgroud)

它们一起渲染出以下图像:

一个五彩三角形

问题)

我的理解是,顶点着色器每个顶点调用一次,而片段着色器每个像素调用一次。

然而,片段着色器引用该vColor变量,每次调用每个顶点时仅分配一次该变量,但像素比顶点多得多!

生成的图像清楚地显示出颜色渐变 - 为什么?vColorWebGL 是否会自动在顶点之间插入像素值?如果是这样,插值是如何完成的?

shader opengl-es glsl webgl webgl2

10
推荐指数
1
解决办法
6878
查看次数

模板缓冲和遮罩如何工作?

我只想在特定区域绘制对象。请看一下这张图片以供参考
图片

2 个三角形(图片 A)只是在四边形(图片 B)内的区域中绘制,因此结果看起来会被剪裁(图片 C)。

首先,我只是在模板缓冲区中绘制四边形。

gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);

gl.stencilFunc(gl.ALWAYS, 1, 0xff);
gl.stencilMask(0xff);
gl.depthMask(false);
gl.colorMask(false, false, false, false);

drawQuads();
Run Code Online (Sandbox Code Playgroud)

根据我的理解,现在模板缓冲区在四边形区域的值为 1。然后,绘制三角形。

gl.stencilFunc(gl.EQUAL, 1, 0xff);
gl.stencilMask(0x00);
gl.depthMask(true);
gl.colorMask(true, true, true, true);

drawTriagles();
Run Code Online (Sandbox Code Playgroud)

我原以为结果会像图片 (C) 那样,但事实并非如此。我做错了什么?

请在这里找到完整的代码https://jsfiddle.net/z11zhf01/1

stencil-buffer webgl webgl2

8
推荐指数
1
解决办法
3292
查看次数

Display: none on Deck.gl React 组件导致巨大的性能问题

编辑:此问题特定于此设置。如果您想提供帮助,请使用此处的代码。谢谢!

我正在使用 Deck.gl 和 react 来显示地图。当我尝试使用 display: none 隐藏地图时,它开始冻结我的整个计算机。我已经通过使用可见性:折叠来解决这个问题,但我想知道为什么 display: none 会导致这个问题。

控制台开始永远充满警告:

luma: Device pixel ratio clamped context.js:202:84
Error: WebGL warning: clear: Requested size 21535x8218 was too large, but resize to 10767x4109 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawElements: Drawing to a destination rect smaller than the viewport rect. (This warning will only be given once) bundle.min.js line 15214 > eval:32:191695
Error: WebGL warning: drawingBufferWidth: Requested size 21535x8218 was too large, but resize to 10767x4109 …
Run Code Online (Sandbox Code Playgroud)

performance webgl reactjs webgl2 deck.gl

7
推荐指数
1
解决办法
848
查看次数

ND缓冲区和G缓冲区有什么区别?

我是WebGL的菜鸟。我读过几篇有关ND缓冲区和G缓冲区的文章,好像它是WebGL开发的战略选择。

ND缓冲区和G缓冲区与渲染管线有何关系?ND缓冲区仅用于正向渲染,G缓冲区仅用于延迟渲染吗?

一个JavaScript代码示例如何实现这两者将对我理解区别很有用。

javascript webgl deferred-rendering webgl-extensions webgl2

5
推荐指数
1
解决办法
880
查看次数

如何在 WebGL2 中实现伽玛校正工作流程?

我在将 sRGB 纹理与 WebGL2 结合使用时遇到问题。我正在尝试加载纹理并将其显示为全屏四边形,但图像显示不正确(太暗。)

纹理加载代码如下。

const texture0 = await (() => {
    const image = new Image()
    const promise = new Promise(resolve => image.onload = () => {
        const texture = gl.createTexture()
        gl.bindTexture(gl.TEXTURE_2D, texture)
        gl.texStorage2D(gl.TEXTURE_2D, 1, gl.SRGB8_ALPHA8, 256, 256)
        gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 256, 256, gl.RGBA, gl.UNSIGNED_BYTE, image) 
        resolve(texture)
    })
    image.src = "./images/texture.png"
    return promise
})()
Run Code Online (Sandbox Code Playgroud)

我想这可能与帧缓冲区的编码有关,但我没有看到与glEnable(GL_FRAMEBUFFER_SRGB)WebGL 中的等效项。

webgl2

5
推荐指数
1
解决办法
1289
查看次数

用于对象拾取的 Alpha 与整数纹理混合

问题描述

你好!在我们的 WebGL 应用程序中,我们绘制了许多(甚至数十万)个形状,我们想发现当前鼠标下方的形状。我正在寻找一种有效的方法。

细节

这些形状是用Signed Distance Functions定义的。每个形状都是通过将预定义的 sdf 片段着色器应用于方形多边形(2 个三角形)来绘制的。每个形状都uint在 Rust 端分配了一个唯一的 ID ( )(我们在这里使用 WASM)。这个想法是将场景渲染两次(在 WebGL 1.0 中)或一次到多个渲染目标(在 WebGL 2.0 中),其中一个目标是编码为颜色的 ID。然后我们可以使用readPixels查询颜色并获取鼠标下形状的ID。不幸的是,我们尝试的每个解决方案都有一些缺点。

要求

  • 我们需要为每个形状编码 2 个整数(一个告诉我们它是什么形状,比如它是一个按钮,或者可能是一个滑块),第二个告诉我们它是哪个对象实例(例如第 5 个滑块)。
  • 我们将在舞台上有很多形状(和实例),因此对于每个 int,我们至少需要 24 位,最好是 32 位精度。

到目前为止他所尝试的

  • 将 ID 信息渲染为RGBA32UI纹理类型。在这个解决方案中,我们每个通道使用 32 位,因此我们可以使用 2 个通道来表示我们的 ID。不幸的是,混合仅适用于 RGBA 模式,并且仅当颜色缓冲区具有定点或浮点格式时才适用。我们需要某种形式的混合,因为在绘制形状(如圆形)时,某些部分需要透明。在 ID 颜色输出的情况下,我们的 alpha 始终为 0 或 1。
  • 渲染ID信息RGBA的质地和转换uintfloat通过使用GLSL intBitsToFloat然后回floatuint在生锈。不幸的是,这在 GLSL 330 中可用,而我们仅限于 WebGL 中的 …

shader webgl rust webgl2

5
推荐指数
1
解决办法
291
查看次数

回调变换反馈以防止 getBufferSubData 图形管道停顿

当我使用 getBufferSubData 从 Chrome 中的转换缓冲区读取顶点数据到 Float32Array 时,我收到警告“性能警告:READ-usage 缓冲区在没有等待栅栏的情况下被读回。这导致了图形管道停顿。 ”。我的理解是,一旦调用 getBufferSubData,GPU 就会尝试将顶点数据写回 CPU,这可能是在着色器完成之前。我认为如果我能阻止这种情况,我也许能够加快我的应用程序的速度,并且我认为最好的方法是使用回调。澄清一下,返回的数据是正确的;我希望加快我的申请速度并更好地了解正在发生的事情。

我尝试使用 fenceSync 实现回调,类似于此答案。这应该在执行 getBufferSubData 之前检查 GPU 是否已完成执行当前命令(包括变换反馈)。这是我的代码。

(function () {
    'use strict';

    const createRandomF32Array = (arrSize) => {
        return Float32Array.from({length: arrSize}, () => Math.floor(Math.random() * 1000));
    };

    const createGlContext = () => {
        const canvas = document.createElement("canvas");
        const gl = canvas.getContext("webgl2");
        canvas.id = 'webgl_canvas';
        document.body.appendChild(canvas);
        if (gl === null) {
            alert("Unable to initialize WebGL. Your browser or machine may not support it.");
            return;
          }
        return …
Run Code Online (Sandbox Code Playgroud)

webgl webgl2

5
推荐指数
1
解决办法
1081
查看次数

使用片段着色器创建光标轨迹

我希望使用片段着色器绘制一个简单的鼠标轨迹,其外观类似于在处理中绘制以下内容(省略清除画布的步骤)。我无法理解实现这一目标所需的设置。

加工参考

// processing reference using cursor as paintbrush
void setup () {
  size(400, 400);
  background(255);
  fill(0);
}

void draw () {
  ellipse(mouseX, mouseY, 20, 20);
}
Run Code Online (Sandbox Code Playgroud)

这是我基于这个shadertoy示例的徒劳方法:

  1. 我在光标位置绘制一个简单的形状
// processing reference using cursor as paintbrush
void setup () {
  size(400, 400);
  background(255);
  fill(0);
}

void draw () {
  ellipse(mouseX, mouseY, 20, 20);
}
Run Code Online (Sandbox Code Playgroud)
  1. 然后我的困惑开始了。我的想法是,我需要将上面的输出与包含我之前的通道的纹理混合。这至少会创建一条可靠的轨迹,尽管仅在距鼠标位置设定的距离内复制前一个通道。
void main(void) {
    float pct = 0.0;
    pct = distance(inData.v_texcoord.xy, vec2(mouse.x, 1.-mouse.y)) * SIZE;
    pct = 1.0 - pct - BRIGHTNESS;
    vec3 blob = …
Run Code Online (Sandbox Code Playgroud)

glsl webgl webgl2

5
推荐指数
1
解决办法
1032
查看次数

emscripten 支持哪些最新版本的 OpenGL ES?如何使用它们?

我正在尝试使用一些 ES 3.1 功能,目前尚不清楚是否支持:

我注意到 emscripten 存储库中有一个 OpenGL ES 3.1 标头,它定义了我正在寻找的一些函数,我可以将它们成功地包含在我的项目中。但是,当我尝试链接时它们不可用:

error: undefined symbol: glDispatchCompute (referenced by top-level compiled C/C++ code)
warning: _glDispatchCompute may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
Run Code Online (Sandbox Code Playgroud)

文档说,如果我指定(我正在这样做),支持 OpenGL ES3 。-s FULL_ES3=1

既然有它的标题,那么这个功能可用吗?如果是这样,我如何启用对其的支持?(例如,是否需要手动加载扩展或在 emscripten 中启用实验支持?)

opengl-es webgl emscripten webgl2

5
推荐指数
1
解决办法
2220
查看次数

为什么现代的pixijs比v3.0.0慢这么多?

这是兔子标记。它以 17 fps 渲染 100k 精灵 https://pixijs.io/bunny-mark/

这是使用 pixi v3 的 bunnymark 的旧版本。它以 165 fps(至少)渲染 100k 精灵https://www.goodboydigital.com/pixijs/bunnymark/

旧的 pixijs v3 比现代 pixijs 快很多。我怎样才能用现代pixijs渲染得那么快???

javascript webgl pixi.js webgl2

5
推荐指数
0
解决办法
965
查看次数