【问题标题】:Why does webgl-noise not give random values?为什么 webgl-noise 不给出随机值?
【发布时间】:2013-09-13 15:38:28
【问题描述】:

我正在使用以下代码,以及来自 webgl-noise 的 noise3D 生成器

void main() {
float noise = snoise(vec3(gl_FragCoord.x, gl_FragCoord.y, 0.0));
    vec4(1.0, 1.0, 1.0, noise);
}

我期待一个完全随机的输出,但我得到的是:

我做错了什么?

编辑:您看到的是单个纹理,我将 SFML 中的着色器应用到该纹理,如下所示:

window.draw(myTexture, myShader);

【问题讨论】:

  • 不要指望噪音的“随机性”。尤其是 Perlin/simplex(顺便说一下,这是单纯形噪声,它会定期重复)。如果你通过一些不同的输入来调制噪声,那么你会得到类似于“随机性”的东西。例如,如果您要将采样的纹理乘以 gl_FragCoord 处的噪声函数的输出...

标签: glsl shader sfml


【解决方案1】:

为了更好地表达@Alchemist 的意思:

snoise(vec3(gl_FragCoord.x, gl_FragCoord.y, 0.0));

使用的 xy 值变化太快(“频率”太高)。像 snoise 这样的 Perlin 噪声在那个尺度上看起来并不好。它被设计成具有大致单位大小的特征。您使用像素(或多或少)作为单位,因此随机特征是像素大小的,使其不平滑,并且周期也太小。

改为使用

float r = 10.0 / iResolution.y; // pseudocode
snoise(vec3(gl_FragCoord.x * r, gl_FragCoord.y * r, 0.0));

其中iResolution.y 是窗口的y 分辨率。现在,噪点图案将大到足以看起来像预期的那样平滑,并且周期将大到不会在您的图像中明显重复。

【讨论】:

    【解决方案2】:

    据我了解,噪音并不是随机的,而是看起来更自然的“随机性”。 http://en.wikipedia.org/wiki/Perlin_noise 很好地概述了 Perlin 噪声,我认为这就是您正在使用的。

    你的图片有点非随机,我怀疑你的编码有错误。我们可以看看整个应用吗?

    好的,@Andon 已经破解了。

    【讨论】:

    【解决方案3】:

    如果你包含noise3D库的功能,你可以做一个“分屏”与“随机”比较

    // My own random number generator
    // See Stack Overflow: http://stackoverflow.com/questions/5149544/can-i-generate-a-random-number-inside-a-pixel-shader/10625698#10625698
    float random( vec2 p )
    {
        vec2 r = vec2(23.14069263277926,2.665144142690225 );
        return fract( cos( mod( 12345678., 256. * dot(p,r) ) ) );
    }
    
    void main()
    {
        vec2  p  = (-iResolution.xy + 2.0*gl_FragCoord.xy) / iResolution.y;
        float th = (-iResolution.x + 2.0*iMouse.x) / iResolution.y;
    
        if( iMouse.z<0.01) th = 0.5/ iResolution.y;
        float noise = snoise(vec3(gl_FragCoord.x, gl_FragCoord.y, 0.0));
    
        // Thanks to I.Q. for this interactive split screen!
        // https://www.shadertoy.com/view/MdjGR1
        if( p.x > th )
            noise = random( p );
    
        vec3 color = vec3(noise, noise, noise );
        color *= smoothstep( 0.006, 0.008, abs(p.x-th) );
        gl_FragColor = vec4( color, 1.0 );
    }
    

    带有“分屏”对比的ShaderToy版本:https://www.shadertoy.com/view/XtX3D4

    【讨论】:

    • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
    • 这如何回答“为什么 webgl-noise 不给出随机值?”的问题
    【解决方案4】:

    首先,这不是柏林噪声应该使用的方式。

    这个不平铺的 perlin 函数生成每 1x1 单位的梯度。

        snoise(vec3(gl_FragCoord.x, gl_FragCoord.y, 0.0))
    

    这行很愚蠢。因为它正在调用 snoise(1, 1, 0), snoise(1, 2, 0).. 它在这里等于一个随机函数。

    你应该得到 snoise(1.001, 1, 0), snoise(1.002, 1, 0).. 然后你会看到美丽的自然柏林噪音。

    perlin 噪声着色器的简化版本使用一种快速但较差的方式来生成随机渐变。作者假设你会放大噪音,重复的图案将不明显。

    我建议使用基于纹理的着色器来获得良好的随机效果。纹理应该包含复杂的排列信息,这有助于着色器生成随机效果。

    【讨论】:

    • 实际上您引用的行不是(在所有环境中)使用整数值调用 snoise() :如果您尝试 shadertoy.com/view/XtX3D4 并将 snoise(q) 更改为 snoise(floor(q)) (靠近底部),结果变化。它也不是愚蠢的...... OP 引用的 snoise() 实现没有附带描述适当输入的文档。 (它也不是一个真正的随机函数......这正是 OP 的问题。)但是你的观点是正确的,Perlin 噪声被设计为在更小尺度的值上工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-10
    • 2017-06-03
    • 1970-01-01
    • 1970-01-01
    • 2021-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多