WebGL gl_FragColor alpha 在 Chrome 和 Firefox 中的行为不同

2024-06-22

下面的代码绘制了三个三角形alpha值 0.5 与{premultipliedAlpha: false}.

const gl = document.querySelector('canvas').getContext('webgl', {premultipliedAlpha: false});

const canvasWidthHeight = 300;
gl.clearColor(1, 0, 0, 0.4);
// gl.clear(gl.COLOR_BUFFER_BIT);

const vertexShaderSource = `
  attribute vec2 position;
  uniform vec2 resolution;

  // All shaders have a main function
  void main() {
    vec2 glSpacePosition = (position / resolution) * 2.0 - 1.0;
    gl_Position = vec4(glSpacePosition * vec2(1, -1), 0, 1);
  }
`;

const fragmentShaderSource = `
  precision mediump float;
  uniform vec4 color;
 
  void main() {
    gl_FragColor = color;
  }
`;

function createShader(gl, type, shaderSource) {
  const shader = gl.createShader(type);
  gl.shaderSource(shader, shaderSource);
  gl.compileShader(shader);

  const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
  if (!success) {
    console.warn(gl.getShaderInfoLog(shader));
    gl.deleteShader(shader);
  }

  return shader;
}

const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);

function createProgram(gl, vertexShader, fragmentShader) {
  const program = gl.createProgram();
  gl.attachShader(program, vertexShader);
  gl.attachShader(program, fragmentShader);
  gl.linkProgram(program);

  const success = gl.getProgramParameter(program, gl.LINK_STATUS);
  if (!success) {
    console.log(gl.getProgramInfoLog(program));
    gl.deleteProgram(program);
  }

  return program;
}

const program = createProgram(gl, vertexShader, fragmentShader);

// We created a program on GPU, so the next step is supplying data.
const positionAttributeLocation = gl.getAttribLocation(program, 'position');
const resolutionUniformLocation = gl.getUniformLocation(program, 'resolution');
const colorUniformLocation = gl.getUniformLocation(program, 'color');

const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);

gl.useProgram(program);
gl.uniform2f(resolutionUniformLocation, canvasWidthHeight, canvasWidthHeight);
gl.enableVertexAttribArray(positionAttributeLocation);

gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);

function drawRandomizedTriangles() {
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
    0, 0,
    0, canvasWidthHeight,
    canvasWidthHeight, 0
  ]), gl.STATIC_DRAW);

  gl.uniform4f(colorUniformLocation, 0, 0, 1, 0.5);

  gl.drawArrays(gl.TRIANGLES, 0, 3);

  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
    0 + 50, 0,
    0 + 50, canvasWidthHeight,
    canvasWidthHeight + 50, 0
  ]), gl.STATIC_DRAW);

  gl.uniform4f(colorUniformLocation, 1, 0, 0, 0.5);

  gl.drawArrays(gl.TRIANGLES, 0, 3);

  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
    0 + 100, 0,
    0 + 100, canvasWidthHeight,
    canvasWidthHeight + 100, 0
  ]), gl.STATIC_DRAW);

  gl.uniform4f(colorUniformLocation, 1, 1, 1, 0.5);

  gl.drawArrays(gl.TRIANGLES, 0, 3);
}

drawRandomizedTriangles();
body {
  display: flex;
  align-items: center;
  justify-content: center;
}

canvas {
  background: green;
}
<canvas width="300" height="300"></canvas>

Result in Chrome: enter image description here

Result in Firefox: enter image description here

Firefox 中的结果正是我所期望的。

我认为这与 WebGL 的混合无关,因为它是关于混合的gl_FragColor使用绘图缓冲区而不是浏览器 DOM,在本例中为绿色背景 Canvas。 (这个想法是基于我对WebGL如何工作的理解)

Also: In Chrome, if the gl_FragColor.rgb is vec3(1.0, 1.0, 1.0), no matter what the gl_FragColor.a is, as long as a is not 0, the output color is pure white(when the rgb is other values, it will behave much differently). enter image description here Here is the code pen https://codepen.io/davidguan/pen/mqWbZX for the image above(don't want to pollute this question with too much code).

更新 1:我相信这不是混合问题,如果我们通过以下方式启用混合:

gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);

The result will like this:enter image description here


这个问题我自己来回答一下。

正如 @gman 在评论区所说,这是 chromium 中的一个 bug。
这里是bug link https://bugs.chromium.org/p/chromium/issues/detail?id=599285(再次感谢@gman)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WebGL gl_FragColor alpha 在 Chrome 和 Firefox 中的行为不同 的相关文章

  • Puppeteer - 错误:协议错误 (Network.getResponseBody):找不到具有给定标识符的资源

    我正在尝试使用此代码使用 puppeteer 从网站获取响应正文 usr bin env node require dotenv config const puppeteer require puppeteer const readline
  • 使用 IE 11 和 AngularJS 的 2 路数据绑定问题

    我最近在使用 AngularJS 的 Web 应用程序上构建了一个功能 但在 IE 11 上遇到了一些问题 apply 将数据更改写入 DOM 由于某种原因 这种情况仅有时发生 而当我尝试调试问题时却从未发生 这使得它看起来像是一个计时问题
  • Javascript 字符串/整数比较

    我在 HTML 中存储一些客户端参数 然后需要将它们作为整数进行比较 不幸的是我遇到了一个我无法解释的严重错误 该错误似乎是我的 JS 将参数读取为字符串而不是整数 导致我的整数比较失败 我生成了一个错误的小例子 我也无法解释 运行时以下返
  • 客户端 GitHub 身份验证

    我正在使用 Javascript 对 GitHub 进行基本身份验证 例如 以下 shell 命令从 Github 获取令牌 curl i u uaername password k d scopes repo https api gith
  • 如何在react中返回点击元素的属性?

    我想知道是否有一种简单的方法来获取单击元素的属性React js function App return
  • $(document).ready 回调何时执行?

    假设我们附加一个 click http api jquery com click 锚点的处理程序 a 中的标签 document ready http api jquery com ready 打回来 该处理程序将取消默认操作 遵循href
  • html/js 中从右到左和/或从上到下的文本?

    如何在浏览器中为用户输入创建从右到左和从上到下的文本字段 有没有本地方法可以做到这一点 或者也许有解决方法 从上到下可能像日语或象形文字 对于 RTL 文本字段 您可以使用 HTMLdir属性 如 ime Vidas 已经提到的 或 wit
  • Angular 4 - 具有动态参数值的自定义验证器

    我编写了一个自定义验证器 用于检查日期是否高于某个最小日期 代码如下所示 export function validateMinDate min Date ValidatorFn return c AbstractControl gt if
  • 如何在 Google 地图上旋转叠加图像?

    我正在尝试将一系列叠加层放置到 Google 地图上 我正在跟随地面覆盖层的示例代码 https developers google com maps documentation javascript examples groundover
  • 重复 Pinterest Facebook 邀请功能

    I m trying to duplicate Pinterest s Invite Friends functionality In case you haven t seen what it looks like it looks li
  • javascript 中的工厂模式与构造函数模式[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我看到了关于 javascript 设计模式的教程 虽然教程很好 但它给我留下了很少的问题 正如我所见 工厂和构造函数产生相同的结果
  • 在 ReactJS 中更改 URL onClick

    在我的项目中我有一个TabComponent它显示 3 个选项卡 首页 热门 全部 现在 我正在使用context反应维持 activetab它存储当前选项卡 toggleTab改变的方法activetab using setState 选
  • 从数组中删除空字符串,同时保持记录而不循环?

    这个问题在这里被问到 从数组中删除空字符串 同时保留非空字符串的索引记录 https stackoverflow com questions 18113243 remove empty strings from array while ke
  • 抓取 Shopee API v4

    我有一个最终项目 其中我想要检索的数据是通过在shopee上抓取数据来获取的 但是当我在隐藏的API上抓取shopee时遇到问题 当我在Insomnia脚本上尝试时 脚本会运行 但是当我尝试时在本地或 google colab 脚本上 这是
  • 如何使用javascript将数据存储在xml文件中?

    我是 javascript 新手 并在我的项目中使用它 因为我需要读取 xml 文件 然后在操作后我想将更新后的值存储回 xml 文件中 我成功从 xml 文件获取值 但无法存储值返回到 xml 文件 这是我尝试过的代码
  • 如何从 Instagram 的 media_preview 原始数据重新创建预览?

    如果您从 Instagram 的 API 获取 JSON 数据 您会发现media previewkey 其值是一些 Base64 编码的数据 它看起来确实像一些非常小的预览二进制数据 也许是压缩的 Take 这个帖子 https www
  • Javascript - HTML Canvas 上的 Gecko 边框半径自适应(CSS border-radius)

    我试图弄清楚如何将 border radius css 属性的行为重现到 HTML 画布中 所以我已经在 J avascript 中做了一些事情 以便使用特定的半径 对于每个角 来计算给定形状的正确边界 如果需要的话 这是上一个问题 Gec
  • 如何拦截javascript中innerHTML的变化?

    我需要拦截网页内单元格内容的任何更改 以下代码显示 addEventListener 不起作用 function modifyText alert var el document getElementById mycell el inner
  • Promise链基本问题

    我正在尝试理解 Promise 我创建了一些有效的承诺链 而另一些则无效 我已经取得了进步 但显然缺乏基本概念 例如 以下承诺链不起作用 这是一个愚蠢的例子 但说明了问题 我正在尝试在链中使用 Node 的函数 randomBytes 两次
  • 在用户单击之前图像不会绘制在画布上?

    我使用执行类似以下操作的函数绘制几张图像 context drawImage img width 2 1 height 2 1 width height 我读过 我需要等待图像加载后才能绘制它 如下所示 img onload functio

随机推荐

  • 如何使用公钥隐私/完整性模式验证 PFX

    我有一个嵌入式软件 可以生成 P12 PFX 格式的输出数据 PFX 是not受密码保护 这意味着数据不是使用密码派生的加密 MAC 密钥 而是使用公钥加密并使用我的私钥签名 In RFC7292 第 3 1 节 https www rfc
  • 反转 PDF 中的白色和黑色

    给定一个黑白 PDF 如何反转颜色 使背景为黑色 其他所有内容为白色 Adobe Reader 可以做到这一点 首选项 gt 辅助功能 仅供节目中观看之用 但不会从本质上更改文档 从而使其他 PDF 阅读器中的颜色也发生反转 如何永久反转颜
  • Jlist 覆盖列表是自动的吗? (漏洞)?

    我希望我能得到帮助 我会问一般性问题 我正在使用一个JList 并且由于JList没有 值 文本 因此我可以显示文本并在代码中使用该值 由于这次泄漏 我创建了List对象 myList 与并行工作JList 我添加的每个项目JList我添加
  • 具有无限参数的 C# 方法或具有数组或列表的方法?

    我最近了解到您可以创建一些具有无限参数的方法 例如 SomeMethod params int numbers 但我的问题是 这与仅创建一个接收列表或数组的方法有什么区别 SomeMethod int numbers SomeMethod
  • jQuery cookie 过期时间

    我能够使用 jQuery 设置 cookie 并重定向到登陆页面 但我不知道如何将 cookie 到期日期设置为少于一天 例如 15 分钟 我无法在中找到解释插件文档 https github com carhartl jquery coo
  • 计算PE文件中入口点的文件偏移量

    In http en redinskala com finding the ep http en redinskala com finding the ep 有关于如何查找 exe 文件中入口点的文件偏移量的信息 在这里我可以读到 EP 文
  • fopen 中的 w+ 模式?

    fopen handle w 我想要打开一个 CSV 文件 读取每一行并对数据库执行一些操作 然后截断 CSV 文件并编写类似的内容 该文件已被读取 w 表示读 写 但文件也会被截断 那么 如果 fopen w 只会删除其中的内容 那么读取
  • 如何将后端计时器与移动应用程序同步

    我正在开发一个选择用户并有 15 秒时间的应用程序 该用户响应的计时器 用户应用程序每 5 秒查询一次数据库 以查看是否选择了该用户 如果是这样 移动应用程序将开始 15 秒 定时器 问题是计时器永远不会匹配 因为用户应用程序可以位于与后端
  • 现有的 swf mp4 播放器? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我的网站上放了一个 mp4 文件http example com a mp4 http example
  • 如何在 R 中分割数据集并绘图

    我正在使用如下数据集 1 48434 14566 1 56711 6289 1 58826 4174 2 56626 6374 2 58888 4112 2 59549 3451 2 60020 2980 2 60468 2532 3 56
  • .selectpicker 不是一个函数

    我正在尝试使用引导选择 http silviomoreto github io bootstrap select 并从 javascript 引用它 但我总是收到错误 selectpicker is not a function 我读到的有
  • C/C++ 中的两个“主要”函数

    我可以用 C 或 C 编写一个具有两个主要函数的程序吗 不 所有程序都有一个 main 这就是编译器和链接器生成从某个合理位置开始的可执行文件的方式 你基本上有两个选择 让 main 解释一些命令行参数来决定实际调用哪个 main 缺点是您
  • 在 jQuery 选择器中连接

    简单的问题 我有一个 js 变量 我也想在 jQuery 选择器中连接起来 但是它不起作用 也没有弹出任何错误 怎么了 如何正确地将变量连接到 jQuery 选择器中的某些文本 div div
  • .Net Framework 中的 HashCode 等效项

    在将 NET Core 项目转换为 NET Framework 时 需要注意的一件事是使用哈希码现在需要转换为等效的内容 可以看出 Hashcode 特定于 NET core 版本和一些扩展 https learn microsoft co
  • Pyinstaller 和 pandas:找不到 Python.Runtime

    我正在尝试使用 pyinstaller 从我的模块构建可执行文件 但每次尝试都以以下结果结束 File C Python 3 6 5 lib site packages PyInstaller hooks hook clr py line
  • 如何为你的 python 程序制作安装程序?

    我是Python新手 但我正在考虑用Python制作一个程序送给我的朋友 他们对计算机不太了解 所以如果我要求他们自己安装 python 他们将无法做到这一点 但是如果我可以制作一个安装程序来下载某个版本的 python 而该版本只包含所需
  • 如何使用 tnsname 从 Ant 连接到 Oracle 数据库?

    我正在寻找类似于 Ant sql 任务的东西 但它将接受以下格式的 JDBC url jdbc oracle thin TNS NAME 一种可能的方法似乎是编写我自己的 Ant 任务 该任务使用 OracleDataSource 来创建连
  • 如何在 Android-x86 中从命令行启动 GUI

    我设法让 Android x86 在 VMware Player 中运行 但如果我需要通过按 Alt F1 进入命令行 我无法返回 GUI 如何从命令行重新启动 GUI 要启动 GUI 我必须选择VboxVGA代替VMSVGA在 Virtu
  • Django中如何获取上传文件的名称

    我已经看到了一些关于它的问题 但这些无法解决我的问题 这就是为什么我要问一个新问题 所以 请不要将其标记为重复 使用 Python 3 6 和 Django 1 10 我试图获取上传文件的名称 但它返回 AttributeError Non
  • WebGL gl_FragColor alpha 在 Chrome 和 Firefox 中的行为不同

    下面的代码绘制了三个三角形alpha值 0 5 与 premultipliedAlpha false const gl document querySelector canvas getContext webgl premultiplied