我试图编译程序(我以前从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);
有人能解释一下吗:
- 为什么我不能在同一个表达式中混合使用float和int常量
- 有什么变通方法可以让我混合使用float和int常量吗
uv3.x = uv3.x + time/float(32);
GLSL 1.1规范第4章(第16页)规定:
OpenGL着色语言是类型安全的。类型之间没有隐式转换
最近的GLSL允许隐式类型转换。GLSL 4.4规范第4章(第25页)规定:
OpenGL着色语言是类型安全的。类型之间存在一些隐式转换。第4.1.10节"隐式转换"中描述了具体的发生方式和时间本规范中的其他章节引用。
稍后从第39页开始,有一个可能的隐式转换列表。
由于您的问题带有opengl-es-2.0标签,因此相关规范是相应的opengl es着色语言规范。
它在"5.8作业"部分(第46页)中写道:
左值表达式和右值表达式必须具有相同的类型。所有需要的类型转换都必须通过构造函数显式指定。
以及在"5.9表达式"一节(第48页)中:
算术二进制运算符加法(+)、减法(-)、乘法(*)和除法(/)对整型和浮点型表达式(包括向量和矩阵)进行运算。两个操作数必须是相同的类型,或者一个可以是标量浮点,另一个是浮点向量或矩阵,或者一种可以是标量整数,另一种是整数向量。
您所需要做的就是在浮点表达式中使用浮点常量。在第一个示例中,使用32.0
而不是32
。微妙的细节,如果您习惯于从C/C++编写32.0f
:ES2.0附带的GLSL版本不支持f
后缀。所以写32.0f
是一个错误。它在ES 3.0中是允许的。
虽然我相信有些人会强烈反对我的观点:我认为不支持这些自动类型转换是一个很好的功能。我相信,在不依赖自动转换的情况下,始终了解您正在操作的类型并使用正确的类型是有用的。类型安全是很有价值的,在C和C++等语言中松散的类型是错误的常见来源。