C# Simplexnoise Fehlersuche

Zespire

Lieutenant
Registriert
März 2007
Beiträge
857
Simplexnoise Fehlersuche (Erledigt)

Grüße ich brauche gerade ein zwei Rauschfunktionen und habe bei Wikipedia dieses PDF gefunden.
http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf
Jetzt habe ich die 2D und 3D version in C# implementiert nur leider habe ich in der 3D version irgendwo einen Fehler.
Nun bin seit etwa 20 Uhr auf Fehlersuche ohne Erfolg nun hoffe ich das hier einer erkennt was falsch läuft :)

noise.jpg

2D Version (scheint zu funktionieren)
Code:
using System.Collections;
using System;


public class Simplex2D 
{
	private readonly int[,] gradients = {{1,1},{-1,1},{1,-1},{-1,-1},{1,0},{-1,0},{1,0},{-1,0},{0,1},{0,-1},{0,1},{0,-1}};
	private readonly int[,] offsets = {{1,0},{0,1}};
	private readonly float G1 = 0.366025403784439f;
	private readonly float G2 = 0.211324865405187f;
	private readonly float G3 = 0.57735f;

	private Random random;
	private int[] permutationTable;

	public Simplex2D()
	{
		int[] tmpPermutationTable = {151,160,137,91,90,15,131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180};
		permutationTable = new int[512];
		for(int i = 0; i < 512; i++) 
		{	
			permutationTable[i] = tmpPermutationTable[i & 255];
		}
	}

	public float GetValue(float _x, float _z)
	{
		int offsetIndex = 0;

		float s = (_x+_z) * G1; 

		int i = Floor(_x+s);
		int j = Floor(_z+s);
		float t = (i+j)*G2;

		float x0 = _x-(i-t);
		float y0 = _z-(j-t);

		if(x0>y0) 
			offsetIndex = 0;
				else 
					offsetIndex = 1;    

		float x1 = x0 - offsets[offsetIndex,0] + G2; 
		float y1 = y0 - offsets[offsetIndex,1] + G2;

		float x2 = x0 - G3; 
		float y2 = y0 - G3;

		int ii = i & 255;
		int jj = j & 255;

		int gi0 = permutationTable[ii+permutationTable[jj]] % 12;
		int gi1 = permutationTable[ii+offsets[offsetIndex,0]+permutationTable[jj+offsets[offsetIndex,1]]] % 12;
		int gi2 = permutationTable[ii+1+permutationTable[jj+1]] % 12;

		return 70.0f * (GetSampleValue (gi0, x0, y0) + GetSampleValue (gi1, x1, y1) + GetSampleValue (gi2, x2, y2));
	}
	
	public void SetSeed(int _value)
	{
		random = new Random (_value);
		GeneratePermutationTable ();
	}
	
	private void GeneratePermutationTable()
	{
		int[] tmpPermutationTable = new int[256];
		permutationTable = new int[512];

		for (int i = 0; i < 255; i ++) 
			tmpPermutationTable[i] = random.Next(0,255);

		for(int i = 0; i < 512; i++) 
			permutationTable[i] = tmpPermutationTable[i & 255];
	}

	private float GetSampleValue(int _index,float _x, float _z)
	{
		float value = 0.5f - _x * _x - _z * _z;
		return (value < 0) ?  0.0f : value * value * dot(_index, _x, _z);
	}
	
	private int Floor(float _value) 
	{
		if(_value > 0)
			return (int) _value;
		return (int)_value-1;
	}

	private float dot(int _index, float _x, float _z) 
	{
		return gradients[_index,0]*_x + gradients[_index,1]*_z; 
	}
}

3D Version
Code:
using System.Collections;
using System;


public class Simplex3D  
{
	private readonly int[,] gradients = {{1,1,0},{-1,1,0},{1,-1,0},{-1,-1,0},{1,0,1},{-1,0,1},{1,0,-1},{-1,0,-1},{0,1,1},{0,-1,1},{0,1,-1},{0,-1,-1}};
	private readonly int[,] offsets = {{1,0,0,1,1,0},{1,0,0,1,0,1},{1,0,0,1,0,1},{0,0,1,0,1,1},{0,1,0,0,1,1},{0,1,0,1,1,0}};
	private readonly float G1 = 0.166666666666667f;
	private readonly float G2 = 0.333333333333333f;
	private readonly float G3 = 0.5f;

	private Random random;
	private int[] permutationTable;

	public Simplex3D()
	{
		int[] tmpPermutationTable = {151,160,137,91,90,15,131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180};
		permutationTable = new int[512];

		for(int i = 0; i < 512; i++) 
			permutationTable[i] = tmpPermutationTable[i & 255];
	}

	public float GetValue(float _x, float _y, float _z) 
	{
		int offsetIndex = 0;

		float s = (_x+_y+_z) * G2; 

		int i =  Floor(_x+s);
		int j =  Floor(_y+s);
		int k =  Floor(_z+s);

		float t = (i+j+k)*G1;

		float x0 = _x-(i-t); 
		float y0 = _y-(j-t);
		float z0 = _z-(k-t);

		if(x0>=y0) 
		{
			if(y0>=z0)
				offsetIndex = 0;
					else 
						if(x0>=z0) 
							offsetIndex = 1;
								else 
									offsetIndex = 2;
		}
		else 
		{ 
			if(y0<z0) 
				offsetIndex = 3;
					else 
						if(x0<z0) 
							offsetIndex = 4;
								else 
									offsetIndex = 5;
		}

		float x1 = x0 - offsets[offsetIndex,0] + G1; 
		float y1 = y0 - offsets[offsetIndex,1] + G1;
		float z1 = z0 - offsets[offsetIndex,2] + G1;

		float x2 = x0 - offsets[offsetIndex,3] + G2; 
		float y2 = y0 - offsets[offsetIndex,4] + G2;
		float z2 = z0 - offsets[offsetIndex,5] + G2;

		float x3 = x0 - G3; 
		float y3 = y0 - G3;
		float z3 = z0 - G3;

		int ii = i & 255;
		int jj = j & 255;
		int kk = k & 255;

		int gi0 = permutationTable[ii + permutationTable[jj+permutationTable[kk]]] % 12;
		int gi1 = permutationTable[ii + offsets[offsetIndex,0] + permutationTable[jj + offsets[offsetIndex,1] + permutationTable[kk + offsets[offsetIndex,2]]]] % 12;
		int gi2 = permutationTable[ii + offsets[offsetIndex,3] + permutationTable[jj + offsets[offsetIndex,4] + permutationTable[kk + offsets[offsetIndex,5]]]] % 12;
		int gi3 = permutationTable[ii + 1 + permutationTable[jj + 1 + permutationTable[kk + 1]]] % 12;

		return 32.0f*(GetSampleValue (gi0, x0, y0, z0) + GetSampleValue (gi1, x1, y1, z1) + GetSampleValue (gi2, x2, y2, z2) + GetSampleValue (gi3, x3, y3, z3));
	}
	
	public void SetSeed(int _value)
	{
		random = new Random (_value);
		GeneratePermutationTable ();
	}
	
	private void GeneratePermutationTable()
	{
		int[] tmpPermutationTable = new int[255];
		permutationTable = new int[512];

		for (int i = 0; i < 255; i ++) 
			tmpPermutationTable[i] = random.Next(0,255);

		for(int i = 0; i < 512; i++) 
			permutationTable[i] = tmpPermutationTable[i & 255];
	}

	private float GetSampleValue(int _index,float _x, float _y, float _z)
	{
		float value = 0.5f - _x * _x - _y * _y - _z * _z;
		return (value < 0) ?  0.0f : value * value * dot(_index, _x, _y, _z);
	}

	private int Floor(float _value) 
	{
		return (_value > 0) ? (int) _value : (int)_value-1;
	}

	private float dot(int _index, float _x,float _y, float _z) 
	{
		return gradients[_index,0]*_x + gradients[_index,1]*_y  + gradients[_index,2]*_z; 
	}
}
 
Zuletzt bearbeitet:
In Zeile 8 passt dein drittes Wertearray nicht und ist identisch mit dem 2.
0 0 1 1 0 1 müsste es laut dem Beispiel in der pdf sein.

Das passiert allerdings, wenn man copy-pasted und sich dann denkt "optimieren" zu können. :p
Allerdings ist die Stelle auch bei dir und im Beispiel echt unübersichtlich und Spaghetti.
Lager das aus und kürze das mit returns ab.
 
Tausend Dank !
Das ist mir Gestern ums Verrecken nicht aufgefallen jetzt wo du es erwähnt hast springt einem das förmlich ins Auge. :hammer_alt:
 
np, je nach Anwendungsbereich könnte ich auch noch andere Tipps geben. Musste mich letztens mit ähnlichem auseinandersetzen.
 
Zurück
Oben