【问题标题】:Phone unable to compile shader手机无法编译着色器
【发布时间】:2015-02-12 14:30:39
【问题描述】:

我有一个正在 libGDX 中工作的项目。我正在对距离场字体进行测试,并且在我的 Android 手机(Galaxy Core 2 4.4.2)上编译着色器时遇到了问题。当部署在我的手机上时,我会遇到错误,而桌面应用程序工作正常(主要是 - 我会解决的)。

我会带你完成我一直在尝试的事情。

我希望能够在运行时启用和禁用字体边框,我可以使用以下着色器和方法在桌面应用程序上很好地做到这一点。

.frag:

#ifdef GL_ES

precision mediump float;
#else
#define LOWP
#endif

uniform sampler2D u_texture;
uniform float u_lower;
uniform float u_upper;

varying vec4 v_color;
uniform vec4 u_outlineColor;
uniform float u_enableOutline;
varying vec2 v_texCoord;

const float smoothing = 1.0/12.0;

const float outlineWidth = 3.0/12.0; //will need to be tweaked
const float outerEdgeCenter = 0.5 - outlineWidth; //for optimizing below calculation

void main() {

    float distance = texture2D(u_texture, v_texCoord).a;    

    if (u_enableOutline > 0){
        float alpha = smoothstep(outerEdgeCenter - smoothing, outerEdgeCenter + smoothing, distance);//Bigger to accomodate outline
        float border = smoothstep(0.45 - smoothing, 0.55 + smoothing, distance);
        gl_FragColor = vec4( mix(u_outlineColor.rgb, v_color.rgb, border), alpha );
    }
    else{
        float alpha = smoothstep(0.5 - smoothing, 0.5 + smoothing, distance);
        gl_FragColor = vec4(v_color.rgb, alpha);
    }   
}

.vert:

uniform mat4 u_projTrans;

attribute vec4 a_position;
attribute vec2 a_texCoord0;
attribute vec4 a_color;

varying vec4 v_color;
varying vec2 v_texCoord;

void main() {


    gl_Position = u_projTrans * a_position;
    v_texCoord = a_texCoord0;
    v_color = a_color;

}

用距离字体方法启用/禁用轮廓正在:

public void enableOutline(float enable) {
        ENABLE_OUTLINE = enable;
}

ENABLE_OUTLINE 传递给着色器的位置

distanceFieldShader.setUniformf("u_enableOutline", ENABLE_OUTLINE);

在此设置中,在我的手机上运行会出现以下错误:

"cannot compare float to int"

在 .frag 中引用这一行

if (u_enableOutline > 0){

我说的很公平,所以我像这样更改数据类型:

uniform int u_enableOutline;

以及通过int的方法:

public void enableOutline(int enable) {
        ENABLE_OUTLINE = enable;
}

但是没有办法将 int 传递给着色器(这就是我选择使用浮点数的原因,请参见这张图片:http://imgur.com/nVTN12i),因此我启用轮廓的方法由于混合而不起作用增加数据类型。

所以我的问题是:我能否以某种方式解决这个问题,以便在考虑到这些限制的情况下启用和禁用手机上的边框?

【问题讨论】:

  • 如果你尝试if (u_enableOutline > 0f){
  • 除此之外还应该有一个 setUniformi 版本,它采用整数
  • 如果您在比较中使用 0.0 而不是 0,它应该可以编译。
  • 我尝试使用0f,但它也在 Android 上产生了语法错误。指定 0.0 反而解决了这个问题。

标签: java android opengl-es libgdx shader


【解决方案1】:

听起来您使用的 API 不提供将 bool 和 int 用作 Uniforms 的可能性。使用浮点数来规避这种情况的解决方案似乎是一个好主意。

在您的示例中,您遇到的问题是,与 C 和 java 不同,GLSL 编译器不会将整数隐式转换为浮点数。

你需要做的是告诉编译器你的“0”的类型。

通过使用语法 0.0,编译器知道您的常量是浮点数而不是整数。

if (u_enableOutline > 0.0){

应该解决你的问题

【讨论】:

  • 谢谢,这成功了!我尝试使用0f,但这也产生了错误。我没想到将其格式化为0.0
  • 是的,GLSL 的语法可能有点棘手,尤其是如果您习惯于 java 和 C。我使用这个不错的工具来验证我的片段着色器:shadertoy.com/new。它不适用于顶点着色器,但有助于验证语法。
猜你喜欢
  • 1970-01-01
  • 2018-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-24
  • 1970-01-01
相关资源
最近更新 更多