GLSL ES片段着色器在不同设备上产生非常不同的结果

问题描述 投票:3回答:1

我正在使用OpenGL ES 2.0开发适用于Android的游戏,但片段着色器存在问题,无法在背景中绘制星星。我有以下代码:

precision mediump float;
varying vec2 transformed_position;

float rand(vec2 co) {
    return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}

void main(void) {
    float distance = 10.0;
    float quantization_strength = 4.0;
    vec3 background_color = vec3(0.09, 0.0, 0.288);
    vec2 zero = vec2(0.0, 0.0);
    vec2 distance_vec = vec2(distance, distance);
    vec2 quantization_vec = vec2(quantization_strength, quantization_strength);
    vec2 new_vec = floor(transformed_position / quantization_vec) * quantization_vec;
    if(all(equal(mod(new_vec, distance_vec), zero))) {
        float rand_val = rand(new_vec);
        vec3 current_color = background_color * (1.0 + rand_val);
        gl_FragColor = vec4(current_color.x, current_color.y, current_color.z, 1.0);
    } else {
        gl_FragColor = vec4(background_color.x, background_color.y, background_color.z, 1.0 );
    }
}

我的目标是“量化”片段坐标,因此“星星”的大小不是1px,然后照亮足够远的量化像素(随机数)。但是,此代码根据执行的位置产生不同的结果。我已经使用GLSL沙盒(http://glsl.heroku.com),Nexus 7和HTC Desire S进行了比较:

“着色器结果比较”“>

如您所见,GLSL沙箱产生密集的网格,其中可见许多恒星。在Nexus 7上,星号要少得多,并且沿线分布(在这张小图像上可能不太明显)-rand功能无法正常工作。欲望S完全不吸引星星。

[rand函数为什么在Nexus 7上如此奇怪(如果我修改了用于点积的矢量,则星形线沿不同角度分布)?是什么导致Desire S不渲染星星?

我也将感谢此着色器的所有优化技巧,因为我对GLSL经验不足。还是有更好的方法通过片段着色器绘制“星星”?

UPDATE

我将代码更改为此(我使用http://glsl.heroku.com/e#9364.0作为参考):

precision mediump float;
varying highp vec2 transformed_position;
highp float rand(vec2 co) {
    highp float a = 1e3;
    highp float b = 1e-3;
    highp float c = 1e5;
    return fract(sin((co.x+co.y*a)*b)*c);
}

void main(void) {
    float size = 15.0;
    float prob = 0.97;
    lowp vec3 background_color = vec3(0.09, 0.0, 0.288);
    highp vec2 world_pos = transformed_position;
    vec2 pos = floor(1.0 / size * world_pos);
    float color = 0.0;
    highp float starValue = rand(pos);
    if(starValue > prob) {
    vec2 center = size * pos + vec2(size, size) * 0.5;
    float xy_dist = abs(world_pos.x - center.x) * abs(world_pos.y - center.y) / 5.0;
    color = 0.6 - distance(world_pos, center) / (0.5 * size) * xy_dist;
    }
    if(starValue < prob || color < 0.0) {
        gl_FragColor = vec4(background_color, 1.0);
    } else {
        float starIntensity = fract(100.0 * starValue);
        gl_FragColor = vec4(background_color * (1.0 + color * 3.0 * starIntensity), 1.0);
    }
}

欲望S现在给了我非常好的,均匀分布的恒星。但是Nexus 7的问题仍然存在。概率= 0.97时,不显示任何恒星;而概率极低= 0.01时,它们沿水平线的位置非常稀疏。为什么Tegra 3的行为如此奇怪?

我正在使用OpenGL ES 2.0开发适用于Android的游戏,但片段着色器存在问题,无法在背景中绘制星星。我有以下代码:precision mediump float;变化...

android opengl-es-2.0 glsl fragment-shader glsles
1个回答
0
投票

使用Gold Noise,均匀的标准化分布。它是专为以低精度(lowp)运行而设计的。它还接受种子(例如时间)。

© www.soinside.com 2019 - 2024. All rights reserved.