actualización de julio de 2017 He hecho el "pseudo-aleatoriedad" más estable
// 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);
}
Esta son las versiones:
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);}
aéreas en una textura a generar ruido está (generalmente) sobre ingeniería. Hay momentos en los que es útil, pero para la mayoría de los casos es más simple y más rápido calcular un número aleatorio.
Dado que las variables de sombreado son independientes por fragmento, no pueden reutilizar las variables existentes entre ellas. El problema entonces se convierte en uno de cómo usar una semilla "buena" de números aleatorios. Los números irracionales parecen encajar en la factura para empezar. Entonces es solo una cuestión 'simple' de elegir una buena función de "permutar".
Aquí hay un código libre que hace el truco:
// 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))));
}
Para entender cómo funciona esto si rompemos la fórmula hacia abajo en sus partes constituyentes se hace más fácil de visualizar lo que está pasando:
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.);
}
Pegado lo anterior en:
También he creado una "comparación" ejemplo ShaderToy con 2 funciones de ruido, y 2 funciones aleatorias:
demostración de la utilización de ruido "[2TC 15] moteado Cruz fade"
una función aleatoria "clásico", a veces llamado snoise3
es este bad one:
return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453);
Si desea comparar "pseudo aleatorios" funciones echa un vistazo a Hash without sine shader de Dave.
Aunque ambas respuestas son útiles, esta se ajusta mejor a lo que estaba buscando. ¡Gracias! – chaosTechnician