使用 GLSL、lwjgl 将原始数据写入纹理
Writing raw data to texture using GLSL, lwjgl
目前,我需要片段着色器写入纹理(它确实如此),但不是覆盖,而是混合。这是片段着色器本身
#version 400 core
in vec2 pass_textureCoordinates;
out vec4 out_Color;
layout(location = 1) out vec4 out_location0;
uniform sampler2D modelTexture;
uniform sampler2D bumpTexture;
uniform sampler2D overlayTexture;
uniform sampler2D scratchLevels;
void main(void)
{
vec2 txt = pass_textureCoordinates;
vec4 base = texture(overlayTexture,txt);
vec4 over = texture(modelTexture,txt);
float baseA = base[3] * (1.0f - over[3]);
float overA = over[3];
float finalA = base[3] + (1.0f - base[3]) * overA;
if(finalA == 0)
{
out_Color[0] = 0;
out_Color[1] = 0;
out_Color[2] = 0;
}
else
{
out_Color[0] = (base[0] * baseA + over[0] * overA) / finalA;
out_Color[1] = (base[1] * baseA + over[1] * overA) / finalA;
out_Color[2] = (base[2] * baseA + over[2] * overA) / finalA;
}
out_Color[3] = finalA;
out_location0 = out_Color;
}
如何在不混合的情况下写入纹理?
编辑:我还需要覆盖 alpha 通道
Blending 取决于混合功能,可以禁用 (glDisable(GL_BLEND)
)。
如果您使用传统的 alpha 混合函数 (glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
) 或预乘 alpha 混合 (glBlendFunc(GL_SRC_ALPHA, GL_ONE)
),您可以通过将输出 alpha 通道设置为 1:
来将纹理视为不透明
out_Color[3] = finalA;
out_Color[3] = 1.0;
好吧,您有多种解决方案可供选择:
- 最简单的方法就是在渲染调用之前禁用混合
glDisable(GL_BLEND)
并在之后再次启用它
- 您可以在渲染前使用 opengl 调用清除纹理数据(如果这是您想要的),例如
glClear(GL_COLOR_BUFFER_BIT)
和 glClearColor(r,g,b)
- 更改片段着色器中的 alpha,例如到
if(out_Color.a > 0) out_Color = vec4(vec3(0,0,0)*(1.0-out_Color.a) + out_Color.rgb*out_Color.a, 1.0);
这只是手动将背景设置为黑色,但如果 out_Color.a == 0
(只是 discard;
,您也可以丢弃它 - 至少在没有 glClear 调用的情况下 - 会导致旧数据在此像素处保持可见)。
希望能帮到你:)
目前,我需要片段着色器写入纹理(它确实如此),但不是覆盖,而是混合。这是片段着色器本身
#version 400 core
in vec2 pass_textureCoordinates;
out vec4 out_Color;
layout(location = 1) out vec4 out_location0;
uniform sampler2D modelTexture;
uniform sampler2D bumpTexture;
uniform sampler2D overlayTexture;
uniform sampler2D scratchLevels;
void main(void)
{
vec2 txt = pass_textureCoordinates;
vec4 base = texture(overlayTexture,txt);
vec4 over = texture(modelTexture,txt);
float baseA = base[3] * (1.0f - over[3]);
float overA = over[3];
float finalA = base[3] + (1.0f - base[3]) * overA;
if(finalA == 0)
{
out_Color[0] = 0;
out_Color[1] = 0;
out_Color[2] = 0;
}
else
{
out_Color[0] = (base[0] * baseA + over[0] * overA) / finalA;
out_Color[1] = (base[1] * baseA + over[1] * overA) / finalA;
out_Color[2] = (base[2] * baseA + over[2] * overA) / finalA;
}
out_Color[3] = finalA;
out_location0 = out_Color;
}
如何在不混合的情况下写入纹理?
编辑:我还需要覆盖 alpha 通道
Blending 取决于混合功能,可以禁用 (glDisable(GL_BLEND)
)。
如果您使用传统的 alpha 混合函数 (glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
) 或预乘 alpha 混合 (glBlendFunc(GL_SRC_ALPHA, GL_ONE)
),您可以通过将输出 alpha 通道设置为 1:
out_Color[3] = finalA;
out_Color[3] = 1.0;
好吧,您有多种解决方案可供选择:
- 最简单的方法就是在渲染调用之前禁用混合
glDisable(GL_BLEND)
并在之后再次启用它 - 您可以在渲染前使用 opengl 调用清除纹理数据(如果这是您想要的),例如
glClear(GL_COLOR_BUFFER_BIT)
和glClearColor(r,g,b)
- 更改片段着色器中的 alpha,例如到
if(out_Color.a > 0) out_Color = vec4(vec3(0,0,0)*(1.0-out_Color.a) + out_Color.rgb*out_Color.a, 1.0);
这只是手动将背景设置为黑色,但如果out_Color.a == 0
(只是discard;
,您也可以丢弃它 - 至少在没有 glClear 调用的情况下 - 会导致旧数据在此像素处保持可见)。
希望能帮到你:)