【问题标题】:GLSL | Type mismatch in arithmetic operation between 'float' and 'int'GLSL | 'float' 和 'int' 之间的算术运算类型不匹配
【发布时间】:2014-12-16 17:24:23
【问题描述】:

我试图编译程序(我之前已经从Cg 语言移植了它)。片段着色器是

precision mediump float;
precision mediump int;

uniform float time;
uniform float aspect;
uniform sampler2D sampler_main;

varying vec4 v_texCoord;

void main()
{
    vec3 ret;
    vec2 uv = v_texCoord.xy;

    float rad=sqrt((uv.x-0.5)*(uv.x-0.5)*4.0+(uv.y-0.5)*(uv.y-0.5)*4.0)*.7071067;
    float ang=atan(((uv.y-0.5)*2.0),((uv.x-0.5)*2.0));

    vec2 uv1 = (uv-0.5)*aspect.xy;

    float rad1 = .1/(length(uv1) + .1)) ;

    vec2 uv2 = vec2 (ang/3.14, rad1);
    uv2.y = uv2.y  +0.1*time;
    uv2.x = uv2.x  +.0*time;

    vec2 uv3 = vec2 (ang/3.14, rad1*1.5);
    uv3.y = uv3.y + 0.08*time ;
    uv3.x = uv3.x + time/32;

    vec3 crisp = 2*texture2D(sampler_main, uv2).xyz;
    vec3 lay1 = vec3 (0,0,1)*uv.y*pow(1-rad,8);
    crisp = 3*crisp * pow(rad,1);
    float mask = saturate(1-4*rad);
    ret = crisp + lay1*mask + mask * texture2D(sampler_main, uv).xyz;

    gl_FragColor.xyz = ret;
    gl_FragColor.w = 1.0;
}

在线出错

uv3.x = uv3.x + time/32;

当我把它改成

uv3.x = uv3.x + time/32.0;

问题解决了,但我不明白问题的根源。

线路同样的问题

float mask = saturate(1-4*rad);                  => float mask = saturate(1.0-4.0*rad);
vec3 crisp = 2*texture2D(sampler_main, uv2).xyz; => vec3 crisp = 2.0*texture2D(sampler_main, uv2).xyz;
vec3 lay1 = vec3 (0,0,1)*uv.y*pow(1-rad,8);      => vec3 lay1 = vec3 (0,0,1)*uv.y*pow(1.0-rad,8.0); 
crisp = 3*crisp * pow(rad,1);                    => crisp = 3.0*crisp * pow(rad,1.0);

谁能解释一下:

  1. 为什么我不能在同一个表达式中混合使用 float 和 int 常量?
  2. 是否有任何解决方法可以让我混合使用 float 和 int 常量?

【问题讨论】:

  • 你不需要零;小数点本身可以​​正常工作。

标签: android-ndk glsl opengl-es-2.0


【解决方案1】:

早期的 GLSL 中不允许隐式转换。所以尝试显式转换:

uv3.x = uv3.x + time/float(32);

GLSL 1.1 Spec 在第 4 章(第 16 页)中说:

OpenGL 着色语言是类型安全的。类型之间没有隐式转换

最近的 GLSL 允许隐式类型转换。 GLSL 4.4 Spec 在第 4 章(第 25 页)中说:

OpenGL 着色语言是类型安全的。类型之间存在一些隐式转换。 在第 4.1.10 节“隐式转换”中描述了这种情况的确切发生方式和时间,以及 本规范的其他部分引用。

后来从第 39 页开始,有一个可能的隐式转换列表。

【讨论】:

  • +1,如果你能提供一些文档,我会接受你的回答。
【解决方案2】:

由于您的问题带有 标签,因此相关规范是对应的OpenGL ES Shading Language 规范。

它在“5.8 作业”部分(第 46 页)中说:

左值表达式和右值表达式必须具有相同的类型。所有需要的类型转换必须通过构造函数显式指定。

在“5.9 表达式”部分(第 48 页):

算术二元运算符加 (+)、减 (-)、乘 (*) 和除 (/) 对整数和浮点类型的表达式(包括向量和矩阵)进行运算。两个操作数必须是同一类型,或者一个是浮点标量,另一个是浮点向量或矩阵,或者一个是整数标量,另一个是整数向量。

您需要做的就是在浮点表达式中使用浮点常量。在您的第一个示例中,使用32.0 而不是32。微妙的细节,如果您习惯于从 C/C++ 编写 32.0ff 后缀在 ES 2.0 附带的 GLSL 版本中支持。所以写32.0f 是一个错误。它在 ES 3.0 中是允许的。

虽然我确信有些人会强烈反对我的观点:我认为不支持这些自动类型转换是一个很好的功能。我相信始终了解您正在操作的类型并使用正确的类型而不依赖于自动转换是很有用的。类型安全很重要,而 C 和 C++ 等语言的松散类型是错误的常见来源。

【讨论】:

    猜你喜欢
    • 2014-08-09
    • 2019-12-03
    • 1970-01-01
    • 2011-04-23
    • 1970-01-01
    • 2011-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多