├── demo.png ├── fizz.png ├── tiles.jpg ├── fisheye.png ├── ripple.png ├── spinning.png ├── README.md ├── fizz.svg ├── fisheye.svg ├── ripple.svg ├── spinning.svg ├── fizz.go ├── ripple.go ├── fisheye.go └── spinning.go /demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpickle/feDisplacementMaps/HEAD/demo.png -------------------------------------------------------------------------------- /fizz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpickle/feDisplacementMaps/HEAD/fizz.png -------------------------------------------------------------------------------- /tiles.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpickle/feDisplacementMaps/HEAD/tiles.jpg -------------------------------------------------------------------------------- /fisheye.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpickle/feDisplacementMaps/HEAD/fisheye.png -------------------------------------------------------------------------------- /ripple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpickle/feDisplacementMaps/HEAD/ripple.png -------------------------------------------------------------------------------- /spinning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unixpickle/feDisplacementMaps/HEAD/spinning.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # What is this? 2 | 3 | This repository contains some experiments with SVG's [feDisplacementMap](http://www.w3.org/TR/SVG11/filters.html#feDisplacementMapElement) filter operation. Filters that use feDisplacementMap can distort the pixels of an image using a sort of mask. 4 | 5 | In this repository, I use Go programs to generate masks, and then I see what they look like in SVG files. 6 | 7 | # Demo 8 | 9 | Here is an example of something you can do with feDisplacementMaps. The original image is a tiled floor, like this: 10 | 11 | ![tiles.jpg](tiles.jpg) 12 | 13 | And the distorted version looks like this: 14 | 15 | ![demo.png](demo.png) 16 | -------------------------------------------------------------------------------- /fizz.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 9 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /fisheye.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 9 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ripple.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 9 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /spinning.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 9 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /fizz.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "image" 6 | "image/color" 7 | "image/png" 8 | "math" 9 | "os" 10 | ) 11 | 12 | const Size = 512 13 | 14 | func main() { 15 | if len(os.Args) != 2 { 16 | fmt.Fprintln(os.Stderr, "Usage: fizz ") 17 | os.Exit(1) 18 | } 19 | 20 | image := image.NewRGBA(image.Rect(0, 0, Size, Size)) 21 | 22 | for x := 0; x < Size; x++ { 23 | for y := 0; y < Size; y++ { 24 | distanceVecX := float64(x - Size/2) 25 | distanceVecY := float64(y - Size/2) 26 | mag := math.Sqrt(math.Pow(distanceVecX, 2) + math.Pow(distanceVecY, 2)) 27 | distanceVecX /= mag 28 | distanceVecY /= mag 29 | pullFactor := math.Pow(-mag, 3) 30 | image.Set(x, y, color.RGBA{ 31 | R: uint8(pullFactor*distanceVecX + 128), 32 | G: uint8(pullFactor*distanceVecY + 128), 33 | B: 128, 34 | A: 255, 35 | }) 36 | } 37 | } 38 | 39 | out, err := os.Create(os.Args[1]) 40 | if err != nil { 41 | fmt.Fprintln(os.Stderr, err) 42 | os.Exit(1) 43 | } 44 | defer out.Close() 45 | png.Encode(out, image) 46 | } 47 | -------------------------------------------------------------------------------- /ripple.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "image" 6 | "image/color" 7 | "image/png" 8 | "math" 9 | "os" 10 | ) 11 | 12 | const Size = 512 13 | 14 | func main() { 15 | if len(os.Args) != 2 { 16 | fmt.Fprintln(os.Stderr, "Usage: ripple ") 17 | os.Exit(1) 18 | } 19 | 20 | image := image.NewRGBA(image.Rect(0, 0, Size, Size)) 21 | 22 | for x := 0; x < Size; x++ { 23 | for y := 0; y < Size; y++ { 24 | distanceVecX := float64(x - Size/2) 25 | distanceVecY := float64(y - Size/2) 26 | mag := math.Sqrt(math.Pow(distanceVecX, 2) + math.Pow(distanceVecY, 2)) 27 | distanceVecX /= mag 28 | distanceVecY /= mag 29 | pullFactor := 30 * math.Sin(mag/15) 30 | image.Set(x, y, color.RGBA{ 31 | R: uint8(pullFactor*distanceVecX + 128), 32 | G: uint8(pullFactor*distanceVecY + 128), 33 | B: 128, 34 | A: 255, 35 | }) 36 | } 37 | } 38 | 39 | out, err := os.Create(os.Args[1]) 40 | if err != nil { 41 | fmt.Fprintln(os.Stderr, err) 42 | os.Exit(1) 43 | } 44 | defer out.Close() 45 | png.Encode(out, image) 46 | } 47 | -------------------------------------------------------------------------------- /fisheye.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "image" 6 | "image/color" 7 | "image/png" 8 | "math" 9 | "os" 10 | ) 11 | 12 | const Size = 512 13 | 14 | func main() { 15 | if len(os.Args) != 2 { 16 | fmt.Fprintln(os.Stderr, "Usage: fisheye ") 17 | os.Exit(1) 18 | } 19 | 20 | image := image.NewRGBA(image.Rect(0, 0, Size, Size)) 21 | 22 | for x := 0; x < Size; x++ { 23 | for y := 0; y < Size; y++ { 24 | distanceVecX := float64(x - Size/2) 25 | distanceVecY := float64(y - Size/2) 26 | mag := math.Sqrt(math.Pow(distanceVecX, 2) + math.Pow(distanceVecY, 2)) 27 | maxMag := math.Sqrt2 * Size / 2 28 | displacement := (mag - maxMag/2) / (maxMag / 2) 29 | displacement /= maxMag / 128 30 | image.Set(x, y, color.RGBA{ 31 | R: uint8(displacement*distanceVecX + 128), 32 | G: uint8(displacement*distanceVecY + 128), 33 | B: 128, 34 | A: 255, 35 | }) 36 | } 37 | } 38 | 39 | out, err := os.Create(os.Args[1]) 40 | if err != nil { 41 | fmt.Fprintln(os.Stderr, err) 42 | os.Exit(1) 43 | } 44 | defer out.Close() 45 | png.Encode(out, image) 46 | } 47 | -------------------------------------------------------------------------------- /spinning.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "image" 6 | "image/color" 7 | "image/png" 8 | "math" 9 | "os" 10 | ) 11 | 12 | const Size = 512 13 | 14 | func main() { 15 | if len(os.Args) != 2 { 16 | fmt.Fprintln(os.Stderr, "Usage: spinning ") 17 | os.Exit(1) 18 | } 19 | 20 | image := image.NewRGBA64(image.Rect(0, 0, Size, Size)) 21 | 22 | for x := 0; x < Size; x++ { 23 | for y := 0; y < Size; y++ { 24 | distanceVecX := float64(x - Size/2) 25 | distanceVecY := float64(y - Size/2) 26 | mag := math.Sqrt(math.Pow(distanceVecX, 2) + math.Pow(distanceVecY, 2)) 27 | angle := mag / (Size / 3) 28 | newX := math.Cos(angle)*distanceVecX - math.Sin(angle)*distanceVecY 29 | newY := math.Sin(angle)*distanceVecX + math.Cos(angle)*distanceVecY 30 | diffX := newX - distanceVecX 31 | diffY := newY - distanceVecY 32 | diffScaler := float64(0x8000) / Size 33 | image.Set(x, y, color.RGBA64{ 34 | R: uint16(diffScaler*diffX + 0x8000), 35 | G: uint16(diffScaler*diffY + 0x8000), 36 | B: 0x8000, 37 | A: 0xffff, 38 | }) 39 | } 40 | } 41 | 42 | out, err := os.Create(os.Args[1]) 43 | if err != nil { 44 | fmt.Fprintln(os.Stderr, err) 45 | os.Exit(1) 46 | } 47 | defer out.Close() 48 | png.Encode(out, image) 49 | } 50 | --------------------------------------------------------------------------------