更新2017年7月:我做了 “伪随机性” 更稳定
// Version 3
float random(vec2 p)
{
vec2 K1 = vec2(
23.14069263277926, // e^pi (Gelfond's constant)
2.665144142690225 // 2^sqrt(2) (Gelfond–Schneider constant)
);
return fract(cos(dot(p,K1)) * 12345.6789);
}
这是版本:
float random(vec2 p)
{
// e^pi (Gelfond's constant)
// 2^sqrt(2) (Gelfond–Schneider constant)
vec2 K1 = vec2(23.14069263277926, 2.665144142690225);
//return fract(cos(mod(12345678., 256. * dot(p,K1)))); // ver1
//return fract(cos(dot(p,K1)) * 123456.); // ver2
return fract(cos(dot(p,K1)) * 12345.6789); // ver3
}
// Minified version 3:
float random(vec2 p){return fract(cos(dot(p,vec2(23.14069263277926,2.665144142690225)))*12345.6789);}
在纹理产生噪声传递(通常)超过工程设计。有些时候它很方便,但是对于大多数情况,只需计算一个随机数就简单快捷。
由于着色器变量是独立于每个片段的,因此它们无法在它们之间重新使用现有变量。问题就成为如何使用“好”随机数种子的问题之一。不合理的数字似乎符合开始的法案。那么选择一个好的“排列”功能只是一个'简单'的问题。
下面是一些免费代码做的伎俩:
// Input: It uses texture coords as the random number seed.
// Output: Random number: [0,1), that is between 0.0 and 0.999999... inclusive.
// Author: Michael Pohoreski
// Copyright: Copyleft 2012 :-)
// NOTE: This has been upgraded to version 3 !!
float random(vec2 p)
{
// We need irrationals for pseudo randomness.
// Most (all?) known transcendental numbers will (generally) work.
const vec2 r = vec2(
23.1406926327792690, // e^pi (Gelfond's constant)
2.6651441426902251); // 2^sqrt(2) (Gelfond–Schneider constant)
return fract(cos(mod(123456789., 1e-7 + 256. * dot(p,r))));
}
要理解它是如何工作的,如果我们打破公式分解成它的组成部分变得更容易想象这是怎么回事:
const vec2 k = vec2(23.1406926327792690,2.6651441426902251);
float rnd0(vec2 uv) {return dot(uv,k); }
float rnd1(vec2 uv) { return 1e-7 + 256. + dot(uv,k); }
float rnd2(vec2 uv) { return mod(123456789., 256. * dot(uv,k)); }
float rnd3(vec2 uv) { return cos(mod(123456789., 256. * dot(uv,k))); }
// We can even tweak the formula
float rnd4(vec2 uv) { return fract(cos(mod(1234., 1024. * dot(uv,k)))); }
float rnd5(vec2 uv) { return fract(cos(mod(12345., 1024. * dot(uv,k)))); }
float rnd6(vec2 uv) { return fract(cos(mod(123456., 1024. * dot(uv,k)))); }
float rnd7(vec2 uv) { return fract(cos(mod(1234567., 1024. * dot(uv,k)))); }
float rnd8(vec2 uv) { return fract(cos(mod(12345678., 1024. * dot(uv,k)))); }
float rnd9(vec2 uv) { return fract(cos(mod(123456780., 1024. * dot(uv,k)))); }
void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
mediump vec2 uv = fragCoord.xy/iResolution.xy;
float i = rnd9(uv);
fragColor = vec4(i,i,i,1.);
}
粘贴到上述:
我还创建与2层噪声的功能,和图2个随机函数 “比较” ShaderToy例如:
演示“[2TC 15]散斑交叉淡出”
“经典”随机函数,有时也被称为snoise3
是这样bad one:
return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453);
如果你想比较“伪随机”功能检查Dave的Hash without sine着色器。
虽然这两个答案都有帮助,但这个更适合我所寻找的。谢谢! – chaosTechnician 2011-03-06 03:22:31