【问题标题】:Shader not showing up properly着色器未正确显示
【发布时间】:2013-08-06 09:50:47
【问题描述】:

我一直在使用名为ShaderToy 的玩具玩着色器,并尝试根据 Jonas Wagner 的代码(用于着色器)为 2D 游戏创建自上而下的水景效果。您可以轻松地将这段代码复制/粘贴到 ShaderToy 中并查看效果。

着色器在 ShaderToy 中看起来很酷,但是当我尝试在我的代码中复制它时,出现了问题,请参见下图:

http://ivan.org.es/temp/shader_problems.png

我的顶点着色器(不知道ShaderToy里用的是什么):

uniform mat4 Projection;
attribute vec2 Position;

void main(){
    gl_Position = Projection*vec4(Position, 0.0, 1.0);
}

片段着色器:

precision lowp float;

vec3 sunDirection = normalize(vec3(0.0, -1.0, 0.0));
vec3 sunColor = vec3(1.0, 0.8, 0.7);
vec3 eye = vec3(0.0, 1.0, 0.0);

vec4 getNoise(vec2 uv){
    vec2 uv0 = (uv/103.0)+vec2(iGlobalTime/17.0, iGlobalTime/29.0);
    vec2 uv1 = uv/107.0-vec2(iGlobalTime/-19.0, iGlobalTime/31.0);
    vec2 uv2 = uv/vec2(897.0, 983.0)+vec2(iGlobalTime/101.0, iGlobalTime/97.0);
    vec2 uv3 = uv/vec2(991.0, 877.0)-vec2(iGlobalTime/109.0, iGlobalTime/-113.0);
    vec4 noise = (texture2D(iChannel0, uv0)) +
                 (texture2D(iChannel0, uv1)) +
                 (texture2D(iChannel0, uv2)) +
                 (texture2D(iChannel0, uv3));
    return noise*0.5-1.0;
}

void sunLight(const vec3 surfaceNormal, const vec3 eyeDirection, float shiny, float spec, float diffuse, inout vec3 diffuseColor, inout vec3 specularColor){
    vec3 reflection = normalize(reflect(-sunDirection, surfaceNormal));
    float direction = max(0.0, dot(eyeDirection, reflection));
    specularColor += pow(direction, shiny)*sunColor*spec;
    diffuseColor += max(dot(sunDirection, surfaceNormal),0.0)*sunColor*diffuse;
}

void main(){
    vec2 uv = gl_FragCoord.xy / iResolution.xy;
    uv *= 100.0;

    vec4 noise = getNoise(uv);
    vec3 surfaceNormal = normalize(noise.xzy*vec3(2.0, 1.0, 2.0));

    vec3 diffuse = vec3(0.3);
    vec3 specular = vec3(0.0);

    vec3 worldToEye = vec3(0.0, 1.0, 0.0);//eye-worldPosition;
    vec3 eyeDirection = normalize(worldToEye);
    sunLight(surfaceNormal, eyeDirection, 100.0, 1.5, 0.5, diffuse, specular);

    gl_FragColor = vec4((diffuse+specular+vec3(0.1))*vec3(0.3, 0.5, 0.9), 1.0);
}

请注意,ShaderToy 中的片段着色器代码和我的引擎中的片段着色器代码完全相同,在我看来,来自 gl_FragCoord 的 uv 坐标有某种错误或精度问题,因为一段时间后效果会越来越差。我正在使用正交投影,但它不应该与此有太多关系,因为我直接从屏幕获取 uv 坐标。

关于发生了什么的一些见解?

【问题讨论】:

  • 尝试提高精度,如此处所述stackoverflow.com/a/6336285/187752
  • 啊...我正在使用 GL_CLAMP_TO_EDGE 加载我的纹理,并且噪声函数假定为 GL_REPEAT。现在可以了。
  • 请回答您自己的问题。但无论如何,您必须在片段着色器中指定精度 - 这是根据 OpenGL ES 2.0 规范。请阅读@Kimi 提供的链接了解更多信息。
  • 完成。我也更新了代码,现在指定精度。

标签: opengl-es-2.0 shader fragment-shader


【解决方案1】:

事实证明,我正在使用

加载我的纹理
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

着色器噪波函数期待的是 GL_REPEAT

【讨论】:

    猜你喜欢
    • 2015-11-23
    • 1970-01-01
    • 2016-07-24
    • 2021-06-19
    • 1970-01-01
    • 2016-08-06
    • 2011-08-06
    • 2012-09-30
    • 2012-09-08
    相关资源
    最近更新 更多