LibGDX 着色器停用重要的 SpriteBatch 方法
LibGDX Shader inactivates important SpriteBatch methods
我正在开发一款游戏并添加了一个着色器,它将所有内容淡化为灰度,然后变为黑色。着色器本身工作正常,但是当我启动它时,Spritebatch 和 Sprites 的一些功能停止工作。忽略颜色变化,任何事物的 Alpha 始终为 1。这些方法通常负责图形变化,在使用默认着色器时效果非常好:
sprite.setColor(Color.RED);
sprite.setAlpha((float)lifeTime/100f);
sprite.draw(pBatch);
此代码将弹出窗口着色为红色,更改 alpha,然后绘制它。当着色器打开时,它只是绘制它,就像前两行不存在一样。
这是着色器的代码:
顶点:
attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord0;
uniform mat4 u_projTrans;
varying vec4 v_color;
varying vec2 v_texCoords;
void main() {
v_color = a_color;
v_texCoords = a_texCoord0;
gl_Position = u_projTrans * a_position;
}
片段:
#ifdef GL_ES
precision mediump float;
#endif
varying vec2 v_texCoords;
uniform sampler2D u_texture;
uniform mat4 u_projTrans;
uniform float u_fade;
void main() {
float gray_fade = u_fade;
float dark_fade = 1;
if(u_fade >= 1){
gray_fade = 1;
dark_fade = 2-u_fade;
}
vec4 color = texture2D(u_texture, v_texCoords).rgba;
float gRed = color.r - (color.r - (0.299*color.r + 0.587*color.g + 0.114*color.b))* gray_fade;
float gGreen = color.g - (color.g - (0.299*color.r + 0.587*color.g + 0.114*color.b))* gray_fade;
float gBlue = color.b - (color.b - (0.299*color.r + 0.587*color.g + 0.114*color.b))* gray_fade;
vec3 grayscale = vec3(gRed * dark_fade, gGreen * dark_fade, gBlue * dark_fade);
gl_FragColor = vec4(grayscale, color.a);
}
您的着色器忽略了精灵的顶点颜色。
将声明 varying vec4 v_color;
放入片段着色器并将最后一行更改为:
gl_FragColor = vec4(grayscale*v_color.rgb, color.a*v_color.a);
编辑:
我想到上面的设置会破坏灰度设置,如果场景中的某些精灵是彩色的,处理起来会很痛苦。因此,请保留 gl_FragColor
行,并将乘法移动到您对纹理颜色进行采样的位置:
vec4 color = texture2D(u_texture, v_texCoords) * v_color;
你的shader也有很大的效率低下,同一个点积计算了3次!另外,我认为在某些情况下,一次对整个向量进行计算可能比单独手动计算更快。
所以我要把中间那五行改成:
vec4 color = texture2D(u_texture, v_texCoords);
float grayValue = dot(color.rgb, vec3(0.299, 0.587, 0.1144));
vec3 grayscale = (color.rgb - (color.rgb - grayValue) * gray_fade) * dark_fade;
关于着色器中的 if
语句:一般而言,分支语句在片段着色器中具有非常重要的影响,应避免使用。但在这种情况下,分支是制服上的 if 语句,所以我不确定它是否会产生任何重大影响,因为它会在整个绘制调用中评估相同的内容。也许其他人可以插话。如果这确实导致了很大的性能问题,您可以通过将 u_fade
替换为 u_gray_fade
和 u_dark_fade
并将此计算移出着色器来解决它。
我正在开发一款游戏并添加了一个着色器,它将所有内容淡化为灰度,然后变为黑色。着色器本身工作正常,但是当我启动它时,Spritebatch 和 Sprites 的一些功能停止工作。忽略颜色变化,任何事物的 Alpha 始终为 1。这些方法通常负责图形变化,在使用默认着色器时效果非常好:
sprite.setColor(Color.RED);
sprite.setAlpha((float)lifeTime/100f);
sprite.draw(pBatch);
此代码将弹出窗口着色为红色,更改 alpha,然后绘制它。当着色器打开时,它只是绘制它,就像前两行不存在一样。
这是着色器的代码:
顶点:
attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord0;
uniform mat4 u_projTrans;
varying vec4 v_color;
varying vec2 v_texCoords;
void main() {
v_color = a_color;
v_texCoords = a_texCoord0;
gl_Position = u_projTrans * a_position;
}
片段:
#ifdef GL_ES
precision mediump float;
#endif
varying vec2 v_texCoords;
uniform sampler2D u_texture;
uniform mat4 u_projTrans;
uniform float u_fade;
void main() {
float gray_fade = u_fade;
float dark_fade = 1;
if(u_fade >= 1){
gray_fade = 1;
dark_fade = 2-u_fade;
}
vec4 color = texture2D(u_texture, v_texCoords).rgba;
float gRed = color.r - (color.r - (0.299*color.r + 0.587*color.g + 0.114*color.b))* gray_fade;
float gGreen = color.g - (color.g - (0.299*color.r + 0.587*color.g + 0.114*color.b))* gray_fade;
float gBlue = color.b - (color.b - (0.299*color.r + 0.587*color.g + 0.114*color.b))* gray_fade;
vec3 grayscale = vec3(gRed * dark_fade, gGreen * dark_fade, gBlue * dark_fade);
gl_FragColor = vec4(grayscale, color.a);
}
您的着色器忽略了精灵的顶点颜色。
将声明 varying vec4 v_color;
放入片段着色器并将最后一行更改为:
gl_FragColor = vec4(grayscale*v_color.rgb, color.a*v_color.a);
编辑:
我想到上面的设置会破坏灰度设置,如果场景中的某些精灵是彩色的,处理起来会很痛苦。因此,请保留 gl_FragColor
行,并将乘法移动到您对纹理颜色进行采样的位置:
vec4 color = texture2D(u_texture, v_texCoords) * v_color;
你的shader也有很大的效率低下,同一个点积计算了3次!另外,我认为在某些情况下,一次对整个向量进行计算可能比单独手动计算更快。
所以我要把中间那五行改成:
vec4 color = texture2D(u_texture, v_texCoords);
float grayValue = dot(color.rgb, vec3(0.299, 0.587, 0.1144));
vec3 grayscale = (color.rgb - (color.rgb - grayValue) * gray_fade) * dark_fade;
关于着色器中的 if
语句:一般而言,分支语句在片段着色器中具有非常重要的影响,应避免使用。但在这种情况下,分支是制服上的 if 语句,所以我不确定它是否会产生任何重大影响,因为它会在整个绘制调用中评估相同的内容。也许其他人可以插话。如果这确实导致了很大的性能问题,您可以通过将 u_fade
替换为 u_gray_fade
和 u_dark_fade
并将此计算移出着色器来解决它。