Browse Source

Adding 3D WorleyNoise.hx

clementlandrin 11 months ago
parent
commit
985c7b7122
2 changed files with 117 additions and 22 deletions
  1. 22 22
      h3d/mat/Texture.hx
  2. 95 0
      h3d/mat/noise/WorleyNoise.hx

+ 22 - 22
h3d/mat/Texture.hx

@@ -331,12 +331,33 @@ class Texture {
 		flags.set(WasCleared);
 		checkMipMapGen(mipLevel, layer);
 	}
-
+	
 	public function dispose() {
 		if( t != null )
 			mem.deleteTexture(this);
 	}
 
+	public function hasStencil() {
+		return switch( format ) {
+		case Depth24Stencil8: true;
+		default: false;
+		}
+	}
+
+	public function isDepth() {
+		return switch( format ) {
+		case Depth16, Depth24, Depth24Stencil8, Depth32: true;
+		default: false;
+		}
+	}
+
+	/**
+		This will return the default depth buffer, which is automatically resized to the screen size.
+	**/
+	public static function getDefaultDepth() {
+		return h3d.Engine.getCurrent().driver.getDefaultDepthBuffer();
+	}
+
 	/**
 		Downloads the current texture data from the GPU.
 		Beware, this is a very slow operation that shouldn't be done during rendering.
@@ -494,25 +515,4 @@ class Texture {
 		t.uploadBitmap(b);
 		b.dispose();
 	}
-
-	public function hasStencil() {
-		return switch( format ) {
-		case Depth24Stencil8: true;
-		default: false;
-		}
-	}
-
-	public function isDepth() {
-		return switch( format ) {
-		case Depth16, Depth24, Depth24Stencil8, Depth32: true;
-		default: false;
-		}
-	}
-
-	/**
-		This will return the default depth buffer, which is automatically resized to the screen size.
-	**/
-	public static function getDefaultDepth() {
-		return h3d.Engine.getCurrent().driver.getDefaultDepthBuffer();
-	}
 }

+ 95 - 0
h3d/mat/noise/WorleyNoise.hx

@@ -0,0 +1,95 @@
+package h3d.mat.noise;
+
+class WorleyNoise {
+
+	public static function generate(texRes : Int = 64, gridSize : Int = 5) {
+
+		var points = [];
+		var ratio = gridSize / texRes;
+
+		for ( k in 0...gridSize ) {
+			for ( j in 0...gridSize ) {
+				for ( i in 0...gridSize ) {
+					var p = new h3d.col.Point(hxd.Math.random(), hxd.Math.random(), Math.random());
+					p.scale(1.0 / gridSize);
+					p.x += i / gridSize;
+					p.y += j / gridSize;
+					p.z += k / gridSize;
+					points.push(p);
+				}
+			}
+		}
+
+		inline function getPointTiling(idx : h3d.col.IPoint) {
+			var pointOffset = new h3d.col.Point();
+			if ( idx.x < 0 ) {
+				idx.x = gridSize - 1;
+				pointOffset.x -= 1.0;
+			}
+			if ( idx.y < 0 ) {
+				idx.y = gridSize - 1;
+				pointOffset.y -= 1.0;
+			}
+			if ( idx.z < 0 ) {
+				idx.z = gridSize - 1;
+				pointOffset.z -= 1.0;
+			}
+			if ( idx.x >= gridSize ) {
+				idx.x = 0;
+				pointOffset.x += 1.0;
+			}
+			if ( idx.y >= gridSize ) {
+				idx.y = 0;
+				pointOffset.y += 1.0;
+			}
+			if ( idx.z >= gridSize ) {
+				idx.z = 0;
+				pointOffset.z += 1.0;
+			}
+			return points[idx.x + idx.y * gridSize + idx.z * gridSize * gridSize].add(pointOffset);
+		}
+
+		var offsets : Array<h3d.col.IPoint> = [		
+			new h3d.col.IPoint(-1, 0, 0), new h3d.col.IPoint(1, 0, 0),
+			new h3d.col.IPoint(0, -1, 0), new h3d.col.IPoint(0, 1, 0),
+			new h3d.col.IPoint(1, 1, 0), new h3d.col.IPoint(-1, 1, 0),
+			new h3d.col.IPoint(1, -1, 0), new h3d.col.IPoint(-1, -1, 0),
+			new h3d.col.IPoint(),
+
+			new h3d.col.IPoint(-1, 0, 1), new h3d.col.IPoint(1, 0, 1),
+			new h3d.col.IPoint(0, 1, 1), new h3d.col.IPoint(0, -1, 1),
+			new h3d.col.IPoint(1, 1, 1), new h3d.col.IPoint(-1, 1, 1),
+			new h3d.col.IPoint(1, -1, 1), new h3d.col.IPoint(-1, -1, 1),
+			new h3d.col.IPoint(0, 0, 1),
+
+			new h3d.col.IPoint(-1, 0, -1), new h3d.col.IPoint(1, 0, -1),
+			new h3d.col.IPoint(0, 1, -1), new h3d.col.IPoint(0, -1, -1),
+			new h3d.col.IPoint(1, 1, -1), new h3d.col.IPoint(-1, 1, -1),
+			new h3d.col.IPoint(1, -1, -1), new h3d.col.IPoint(-1, -1, -1),
+			new h3d.col.IPoint(0, 0, -1),
+		];
+
+		var tex = new h3d.mat.Texture3D(texRes, texRes, texRes);
+
+		var pixels = hxd.Pixels.alloc(texRes, texRes, tex.format);
+		for ( k in 0...texRes ) {
+			for ( j in 0...texRes ) {
+				for ( i in 0...texRes ) {
+					var position = new h3d.col.Point(i / texRes, j / texRes, k / texRes);
+					var closestDistance = hxd.Math.POSITIVE_INFINITY;
+					var idx = new h3d.col.IPoint(Math.floor(i * ratio), Math.floor(j * ratio), Math.floor(k * ratio));
+					for ( offset in offsets ) {
+						var p = getPointTiling(idx.add(offset));
+						var distance = position.distance(p);
+						if ( distance < closestDistance )
+							closestDistance = distance;
+					}
+					pixels.setPixelF(i, j, new h3d.Vector4(closestDistance * texRes / gridSize / Math.sqrt(3.0)));
+				}
+			}
+			tex.uploadPixels(pixels, 0, k);
+		}
+
+		return tex;
+	}
+}