我正在查看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
变量,每次调用每个顶点时仅分配一次该变量,但像素比顶点多得多!
生成的图像清楚地显示出颜色渐变 - 为什么?vColor
WebGL 是否会自动在顶点之间插入像素值?如果是这样,插值是如何完成的?
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
编辑:此问题特定于此设置。如果您想提供帮助,请使用此处的代码。谢谢!
我正在使用 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) 我是WebGL的菜鸟。我读过几篇有关ND缓冲区和G缓冲区的文章,好像它是WebGL开发的战略选择。
ND缓冲区和G缓冲区与渲染管线有何关系?ND缓冲区仅用于正向渲染,G缓冲区仅用于延迟渲染吗?
一个JavaScript代码示例如何实现这两者将对我理解区别很有用。
我在将 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 中的等效项。
问题描述
你好!在我们的 WebGL 应用程序中,我们绘制了许多(甚至数十万)个形状,我们想发现当前鼠标下方的形状。我正在寻找一种有效的方法。
细节
这些形状是用Signed Distance Functions定义的。每个形状都是通过将预定义的 sdf 片段着色器应用于方形多边形(2 个三角形)来绘制的。每个形状都uint
在 Rust 端分配了一个唯一的 ID ( )(我们在这里使用 WASM)。这个想法是将场景渲染两次(在 WebGL 1.0 中)或一次到多个渲染目标(在 WebGL 2.0 中),其中一个目标是编码为颜色的 ID。然后我们可以使用readPixels
查询颜色并获取鼠标下形状的ID。不幸的是,我们尝试的每个解决方案都有一些缺点。
要求
到目前为止他所尝试的
RGBA32UI
纹理类型。在这个解决方案中,我们每个通道使用 32 位,因此我们可以使用 2 个通道来表示我们的 ID。不幸的是,混合仅适用于 RGBA 模式,并且仅当颜色缓冲区具有定点或浮点格式时才适用。我们需要某种形式的混合,因为在绘制形状(如圆形)时,某些部分需要透明。在 ID 颜色输出的情况下,我们的 alpha 始终为 0 或 1。RGBA
的质地和转换uint
到float
通过使用GLSL intBitsToFloat然后回float
至uint
在生锈。不幸的是,这在 GLSL 330 中可用,而我们仅限于 WebGL 中的 …当我使用 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)我希望使用片段着色器绘制一个简单的鼠标轨迹,其外观类似于在处理中绘制以下内容(省略清除画布的步骤)。我无法理解实现这一目标所需的设置。
// 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示例的徒劳方法:
// 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)
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) 我正在尝试使用一些 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 中启用实验支持?)
这是兔子标记。它以 17 fps 渲染 100k 精灵 https://pixijs.io/bunny-mark/
这是使用 pixi v3 的 bunnymark 的旧版本。它以 165 fps(至少)渲染 100k 精灵https://www.goodboydigital.com/pixijs/bunnymark/
旧的 pixijs v3 比现代 pixijs 快很多。我怎样才能用现代pixijs渲染得那么快???
webgl2 ×10
webgl ×9
glsl ×2
javascript ×2
opengl-es ×2
shader ×2
deck.gl ×1
emscripten ×1
performance ×1
pixi.js ×1
reactjs ×1
rust ×1