opengl-es - 将负值混合到帧缓冲区 0 opengl
问题描述
该程序将一堆东西渲染到一个中间帧缓冲区中,该缓冲区使用无符号规范化纹理来存储数据。中间帧缓冲区与默认帧缓冲区混合。用于渲染与帧缓冲区 0 混合的中间体的像素着色器如下:
#version 300 es
precision mediump float;
out vec4 fragColor;
in vec2 texCoords;
uniform sampler2D textureToDraw;
void main()
{
vec4 sampleColor = texture(textureToDraw, texCoords);
fragColor = vec4(sampleColor.rgb * -1.0, sampleColor.a);
}
设置绘制到帧缓冲区 0 的代码如下:
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
// Draw the intermediate using the pixel shader above and a quad
的 rgb 分量fragColor
将在 [-1, 0] 范围内。预期的结果是从先前的帧缓冲区内容中减去中间颜色。实际结果是黑色与帧缓冲区 0 的正确 alpha 混合,这表明它fragColor
在某处被钳制到 [0, 1] 并且负部分被丢弃。
有没有办法禁用片段着色器输出到 [0, 1] 的钳位?
我知道没有办法渲染到签名的规范化纹理,所以也许有一个 OpenGL 限制可以防止这种情况发生。我正在考虑的替代方案是进行两次渲染,一次将负位渲染到中间,另一个将正位渲染到另一个中间。最后,将正面与GL_FUNC_ADD
负面与混合GL_FUNC_REVERSE_SUBTRACT
。维护起来既慢又麻烦。还有其他方法吗?
解决方案
有没有办法禁用片段着色器输出到 [0, 1] 的钳位?
让我引用OpenGL 4.6 Core Profile Specification的第17.3.6节(强调我的):
如果颜色缓冲区是定点的,则在评估之前,对于无符号归一化或有符号归一化颜色缓冲区,源值和目标值以及混合因子的分量分别被钳制为 [0, 1] 或 [-1, 1]混合方程。如果颜色缓冲区是浮点数,则不会发生钳位。产生的四个值被发送到下一个操作。
因此,您可以使用其中一种*16F
或*32F
格式来摆脱钳制。
我知道没有办法渲染到签名的规范化纹理,所以也许有一个 OpenGL 限制可以防止这种情况发生。
该规范将各种标记_SNORM
为color-renderable。但是,与此同时,规范并没有将这些格式标记为渲染目标需要支持,因此实现可以允许您使用这种格式,但它们不是必须的,所以是的,您不能以任何方式依赖它...
推荐阅读
- powershell - 使用 powershell 获取对 powerBI 报告具有查看权限的用户列表
- python - 将两个 PNG 图像转换为 numpy 数组会产生两种不同的形状
- angular - Angular根服务重复
- decorator - 为什么 AutoFac 多余地装饰我的服务
- jmeter - 如何在 Jmeter 中解析以 {} && 开头的 JSON 响应
- c++ - 如何将字符串与对象匹配?
- node.js - Node.js:为什么纯黑色 (#000000) 会被检测为 RGB 4、4、4?
- android-studio - 如何将 getIntent.getStringExtra("username") 放入 android 适配器 onBindViewHolder(@NonNull final ViewHolder holder, final int position)
- pandas - 使用多索引计算数据框中数字连续出现的次数
- excel - 根据另一个工作表上的数据标准填充工作表