diff --git a/CHANGELOG.md b/CHANGELOG.md
index c282319..c1c388f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,9 @@
# TSL Textures
+## 0.21.0
+* Added "Dalmatian spots" in *dalmatian-spots.js*
+
## 0.20.0
* Added "Karst rock" in *karst-rock.js*
diff --git a/docs/dalmatian-spots.md b/docs/dalmatian-spots.md
new file mode 100644
index 0000000..81e20f3
--- /dev/null
+++ b/docs/dalmatian-spots.md
@@ -0,0 +1,67 @@
+
+
+
+# TSL Textures
+
+
+## Dalmatian spots
+
+This texture generates dotted image which resenbles the spots of
+[Dalmatian dog](https://en.wikipedia.org/wiki/Dalmatian_dog) coat.
+Click on a snapshot to open it online.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+### Code example
+
+```js
+import { dalmatianSpots } from "tsl-textures/dalmatian-spots.js";
+
+model.material.colorNode = dalmatianSpots ( {
+ scale: 2,
+ density: 0.6,
+ color: new THREE.Color(16777215),
+ background: new THREE.Color(0),
+ seed: 0
+} );
+```
+
+
+### Parameters
+
+* `scale` – level of details of the pattern, higher value generates finer details, [0, 4]
+* `density` – density of spots, [0,1]
+* `color` – color of spots
+* `background` – color of background
+* `seed` – number for the random generator, each value generates specific pattern
+
+
+### Online generator
+
+[online/dalmatian-spots.html](../online/dalmatian-spots.html)
+
+
+### Source
+
+[src/dalmatian-spots.js](https://github.com/boytchev/tsl-textures/blob/main/src/dalmatian-spots.js)
+
+
+
+
\ No newline at end of file
diff --git a/docs/images/dalmatian-spots-1.png b/docs/images/dalmatian-spots-1.png
new file mode 100644
index 0000000..e7acff9
Binary files /dev/null and b/docs/images/dalmatian-spots-1.png differ
diff --git a/docs/images/dalmatian-spots-2.png b/docs/images/dalmatian-spots-2.png
new file mode 100644
index 0000000..da73b91
Binary files /dev/null and b/docs/images/dalmatian-spots-2.png differ
diff --git a/docs/images/dalmatian-spots-3.png b/docs/images/dalmatian-spots-3.png
new file mode 100644
index 0000000..8c78bfe
Binary files /dev/null and b/docs/images/dalmatian-spots-3.png differ
diff --git a/docs/images/dalmatian-spots.png b/docs/images/dalmatian-spots.png
new file mode 100644
index 0000000..d89c9a0
Binary files /dev/null and b/docs/images/dalmatian-spots.png differ
diff --git a/index.html b/index.html
index c810a24..c2f0226 100644
--- a/index.html
+++ b/index.html
@@ -54,6 +54,11 @@ Welcome. Pick a texture!
+
+ Dalmatian spots
+
+
+
Dyson sphere
diff --git a/online/dalmatian-spots.html b/online/dalmatian-spots.html
new file mode 100644
index 0000000..05e6e18
--- /dev/null
+++ b/online/dalmatian-spots.html
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/dalmatian-spots.js b/src/dalmatian-spots.js
new file mode 100644
index 0000000..713e215
--- /dev/null
+++ b/src/dalmatian-spots.js
@@ -0,0 +1,51 @@
+
+// TSL-Textures: Dalmatian coat
+
+
+
+import { Color } from "three";
+import { exp, float, loop, mix, positionLocal, tslFn } from 'three/nodes';
+import { noise } from 'tsl-textures/tsl-utils.js';
+
+
+var dalmatianSpots = tslFn( ( params )=>{
+
+ var pos = positionLocal.mul( exp( params.scale ) ).add( params.seed ).sub( 1000 ).toVar( );
+
+ var k = float( 1 ).toVar();
+
+ var d = float( 1.5 ).sub( params.density ).mul( 2 ).toVar();
+ var count = params.density.mul( 5 ).add( 5 ).toVar();
+
+ loop( count, ()=> {
+
+ k.mulAssign( noise( pos ).abs().pow( d ).mul( 100 ).sub( 50 ).clamp( 0, 1 ).oneMinus() );
+ pos.assign( pos.mul( 1.01 ) );
+ k.mulAssign( noise( pos.yzx ).abs().pow( d ).mul( 100 ).sub( 50 ).clamp( 0, 1 ).oneMinus() );
+ pos.assign( pos.mul( 1.01 ) );
+ k.mulAssign( noise( pos.zxy ).abs().pow( d ).mul( 100 ).sub( 50 ).clamp( 0, 1 ).oneMinus() );
+ pos.assign( pos.mul( 1.01 ) );
+
+ } );
+
+ return mix( params.background, params.color, k.clamp( 0, 1 ) );
+
+} );
+
+
+dalmatianSpots.defaults = {
+ $name: 'Dalmatian spots',
+ $width: 260,
+
+ scale: 2,
+ density: 0.6,
+
+ color: new Color( 0xFFFFFF ),
+ background: new Color( 0x000000 ),
+
+ seed: 0,
+};
+
+
+
+export { dalmatianSpots };