DGL
https://delphigl.com/forum/

noise1 gibt immer 0.0?
https://delphigl.com/forum/viewtopic.php?f=20&t=9511
Seite 1 von 1

Autor:  sharkman [ Sa Okt 02, 2010 19:09 ]
Betreff des Beitrags:  noise1 gibt immer 0.0?

Code:
uniform float height;

void main() { 
  vec3 pos = vec3(gl_FragCoord.xy, floor(height));
  float color = noise1(pos);
  gl_FragColor = vec4(color, color, color, 1.0);
}


Ich hab auch schon versucht, color mit 10000 zu multiplizieren, hat aber auch nix gebracht. Sieht sehr danach aus, als ob ich wirklich immer nur 0.0 kriegen würde. Angeblich soll noise doch von -1 bis 1 gehen, und zumindest im Bereich von -0.6 bis 0.6 normalverteilt sein. ok, normalverteilt isses so ja auch irgendwie, aber vom Bereich -1 bis 1 keine Spur. Oder mach ich da sonst iwas falsch?

Und wenn noise wirklich nicht funktioniert, gibts irgendeine halbwegs einfache Möglichkeit, reproduzierbare Zufallszahlen zu erzeugen, die zwischen -1 und 1 liegen (*)? normalverteilung ist mir eigentlich egal.

(*)ähm, noise - texturen einmal ausgenommen.

Autor:  mrtrain [ Sa Okt 02, 2010 20:41 ]
Betreff des Beitrags:  Re: noise1 gibt immer 0.0?

Ich verlinke dich mal ins Wiki. Das sollte deine Frage eigentlich beantworten. :wink:

Autor:  Coolcat [ Sa Okt 02, 2010 20:45 ]
Betreff des Beitrags:  Re: noise1 gibt immer 0.0?

Nein, du machst nichts falsch. 3DLabs ist der einzige Hersteller der das entsprechend der Spec implementiert hat. ATI schaltet in den Softwaremodus und Nvidia gibt einfach 0.0 zurück....und hat das sicher im Quellcode mit "fairly choosen random number" kommentiert ;)
Siehe auch den Artikel GLSL_noise.

Eine Alternative ist einfach selbst einen lineareren Kongruenzgenerator zu bauen, was anderes sind "Zufallszahlen" am Computer nämlich nicht. Dazu findet sich von mir in der Shadersammlung ein shader_Zufallsgenerator.

Theoretisch lässt sich das auch ohne ShaderModell 4 bauen, allerdings musst du m dann kleiner als 2^23 wählen, da ein Float bekanntlich nur eine 23bit Mantisse hat. Keine Ahnung ob man da geeignete Werte für a,c und m im Internet findet.

Autor:  sharkman [ So Okt 03, 2010 09:27 ]
Betreff des Beitrags:  Re: noise1 gibt immer 0.0?

ok. jetzt wirds immer weiß. Auch wenn ich die Zufallszahl durch irgendwas großes durchdividiere.
Code:
uniform float height;
const unsigned int repeat = 1024

unsigned int seed;
 
/* return pseudorandom float with values between 0 and 1. */
float random() {
    seed = (seed * 1103515245u + 12345u);
    return float(seed) / 4294967296.0;
}

float random(unsigned int new_seed) {
    seed = (new_seed * 1103515245u + 12345u);
    return float(seed) / 4294967296.0;
}

void main() {
  unsigned int pos = gl_FragCoord.x + gl_FragCoord.y * repeat + height * repeat * repeat;
  float color = random(pos);
  color /= 1000000000000000000000000000;
  gl_FragColor = vec4(color, color, color, 1.0);
}


compiliert zumindest ohne Fehlermeldung...
muss ich da irgendeine #version angeben, damits funktioniert? Wenn ja, welche?

Zitat:
ATI schaltet in den Softwaremodus und Nvidia gibt einfach 0.0 zurück
Also von der Geschwindigkeit her passt softwaremodus ja aber da kam trotzdem immer 0.0

Autor:  Coolcat [ So Okt 03, 2010 09:42 ]
Betreff des Beitrags:  Re: noise1 gibt immer 0.0?

Zitat:
compiliert zumindest ohne Fehlermeldung...

Bezweifele ich irgendwie, den hier fehlt ein Semikolon:
Code:
const unsigned int repeat = 1024

Und du wandelst da float implizit in uint um, zumindest Nvidia meckert da.
=> Check mal deine Fehlerausgabe. ;)

BTW: Durch 1000000000000000000000000000 zu teilen ist keine gute Idee...das ist nämlich ein Integer und der kriegt irgendwo bei 2 Mrd. schon einen Überlauf. Du solltest im Shader immer angeben ob es sich um einen int, einen uint oder einen float handelt, da dieser nur widerwillig implizit umwandelt. Nicht grundlos teile ich da z.B. durch 4294967296.0 und nicht durch 4294967296 oder 4294967296u.

Als Version brauchst du GLSL 1.3, also #version 130. Alternativ kannst du die Extension benutzten wie im Wiki, also #extension ... , dann geht es auch mit älteren GLSL-Versionen, zumindest falls die Extension vorhanden ist.

Autor:  sharkman [ So Okt 03, 2010 10:06 ]
Betreff des Beitrags:  Re: noise1 gibt immer 0.0?

Ja, Fehlerausgabe hat nicht funktioniert. Warum auch immer.
Zitat:
Vertex shader was successfully compiled to run on hardware.
WARNING: 0:4: deprecated130(#55) 'ftransform()' is deprecated since GLSL1.3, we suggest to use 'invariant'
Fragment shader failed to compile with the following errors:
ERROR: 0:39: error(#160) Cannot convert from 'float' to 'unsigned int'
ERROR: error(#273) 1 compilation errors. No code generated
Code:
unsigned int pos = unsigned int(gl_FragCoord.x) + unsigned int(gl_FragCoord.y) * repeat + height * repeat * repeat;
Explizite Umwandlung geht auch nicht?

Autor:  Coolcat [ So Okt 03, 2010 10:19 ]
Betreff des Beitrags:  Re: noise1 gibt immer 0.0?

Zitat:
Explizite Umwandlung geht auch nicht?

height ist ein float.

Autor:  sharkman [ So Okt 03, 2010 12:20 ]
Betreff des Beitrags:  Re: noise1 gibt immer 0.0?

ja. jetzt laufts. aber nicht ganz so, wie ich mir das vorgestellt hab. wenn ich random einmal aufruf, krieg ich schöne schräge linien :( Wenn ichs öfter aufruf (zB 15 mal bevor ich den Wert dann verwende), wirds ein bissel chaotischer, man sieht aber immer noch eindeutig, dass es immer dasselbe ist. Wenn ichs noch öfter aufruf (50 mal) krieg ich einen schönen schrägen farbverlauf, der sich alle paar Pixel wiederholt. Das kann irgendwie nicht so ganz der Sinn von ner random funktion sein, oder?
Code:
void main() { 
  unsigned int pos = unsigned int(gl_FragCoord.x) + unsigned int(gl_FragCoord.y) * repeat + unsigned int(floor(height)) * repeat * repeat;
  float color = random(pos); 
  for (int i = 0; i<50; ++i) {
    color = random();
  }
 
  gl_FragColor = vec4(color, color, color, 1.0);
}

Wies aussieht kommen da immer irgendwelche Muster raus. gibts vielleicht noch ne andere art, random zu implementieren, so dass da keine Muster rauskommen?

Autor:  sharkman [ So Okt 03, 2010 13:26 ]
Betreff des Beitrags:  Re: noise1 gibt immer 0.0?

konnte das Problem lösen.
Code:
unsigned int seed;
unsigned int seed2;
 
/* return pseudorandom float with values between 0 and 1. */
float random() {
    unsigned int lastseed = seed;
    seed *= seed2;
    seed2 = lastseed;
    seed = (seed * 1103515245u + 12345u);
    return float(seed) / 4294967296.0;
}


so ab dem dritten Wert kommen einige, wo das Bild dann wirklich einigermaßen zufällig aussieht, wenn ich sowohl seed als auch seed2 abhängig von den Pixelkoordinaten initialisiere, aber nicht beide mir dem gleichen Wert

Autor:  Coolcat [ So Okt 03, 2010 15:46 ]
Betreff des Beitrags:  Re: noise1 gibt immer 0.0?

Vielleicht solltest du als "repeat" mal irgendwas krummes nehmen....ne große Primzahl oder so.

Autor:  sharkman [ So Okt 03, 2010 16:12 ]
Betreff des Beitrags:  Re: noise1 gibt immer 0.0?

repeat hat aber nen anderen Sinn. Das sorgt nur dafür, dass die x und y koordinate und height sich nicht gegenseitig beeinflussen, weil wenn sie das täten, sähe das erst recht blöd aus. dass sich das so nach 1024 pixeln wiederholen muss ist mir auch klar, aber das ist ja gerade der Sinn dabei (*). Außerdem, zu groß kann repeat dann auch nicht sein, weil das muss ja auch noch in ein uint passen. und ^3 muss es immer noch reinpassen (bzw gerade eben nicht mehr aber bei 32 bit wird das schwer, so zu machen). Aber mit der Random funktion selbst hat repeat nix zu tun

(*)ich nehm da jetzt nämlich für jeden Pixel die 125 umliegenden mit Gewichtung von 2^-(distance + 1), und versuch so, eine Noisetextur zu machen. Deswegen wärs eher unpraktisch, wenn sich die Textur nach einer Primzahl anfangen würde, zu wiederholen (nicht kachelbar und so). Sieht auch einigermaßen so aus, wie ich mir das vorstell. Ob dieses Vorgehen sinnvoll ist, ist wieder was anderes. Weil schnell isses natürlich nicht.

Seite 1 von 1 Alle Zeiten sind UTC + 1 Stunde
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/