;; Water pattern - This is a script for The GIMP to generate a highlight pattern such as those found on the bottom of pools ;; Copyright (C) 2010 William Morrison ;; ;; This program is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . (define (script-fu-wavetank srcimg srclayer scalex scaley blend-num numframes displace? highlights? displacestrength) (let* ((blend-mode 5) (img 0) (layer 0) (templayer 0) (cloud1 0) (cloud2 0) (newlayer1 0) (newlayer2 0) (displacelayer 0) ;variables for layers and the image (count 1) (array (cons-array 6 'byte)) (xsize (car (gimp-drawable-width srclayer))) (ysize (car (gimp-drawable-height srclayer))) (shiftx (/ xsize numframes)) (shifty (/ ysize numframes)));variables for other stuff ;these are the values used for applying the curves filter. (aset array 0 0) (aset array 1 255) (aset array 2 64) (aset array 3 64) (aset array 4 255) (aset array 5 0) (set! blend-mode (cond ((= blend-num 0) 5) ((= blend-num 1) 7) ((= blend-num 2) 4) ((= blend-num 3) 16) ) ) ;Create the new image based on the dimensions of the source layer (set! img (car (gimp-image-new xsize ysize 0))) (gimp-image-undo-freeze img) ;generates the source layers for the image and the solid noise (set! layer (car (gimp-layer-new-from-drawable srclayer img))) (set! cloud1 (car (gimp-layer-new img xsize ysize 0 "Frame" 100 0))) (set! cloud2 (car (gimp-layer-new img xsize ysize 0 "diff" 100 6))) (gimp-image-add-layer img layer -1) (gimp-image-add-layer img cloud1 -1) (gimp-image-add-layer img cloud2 -1) ;Adds the solid noise (plug-in-solid-noise 1 img cloud1 1 0 (rand 2100000000) 1 scalex scaley) (plug-in-solid-noise 1 img cloud2 1 0 (rand 2100000000) 1 scalex scaley) (plug-in-normalize 1 img cloud1) (plug-in-normalize 1 img cloud2) (while (< count numframes) ;Duplicates and adds source layers (set! templayer (car (gimp-layer-new-from-drawable layer img))) (set! newlayer1 (car (gimp-layer-new-from-drawable cloud1 img))) (set! newlayer2 (car (gimp-layer-new-from-drawable cloud2 img))) (gimp-image-add-layer img templayer -1) (gimp-image-add-layer img newlayer1 -1) (gimp-image-add-layer img newlayer2 -1) ;Offsets and merges layers, and creates the displace map (gimp-drawable-offset newlayer2 1 0 (* count shiftx) (* count shifty)) (gimp-drawable-offset newlayer1 1 0 (- 0 (* count shiftx)) (- 0 (* count shifty))) (set! newlayer1 (car (gimp-image-merge-down img newlayer2 0))) (cond ((= displace? 1) (set! displacelayer (car (gimp-layer-new-from-drawable newlayer1 img))) )) (gimp-curves-spline newlayer1 0 6 array) ;merges the highlights onto the source image (cond ((= highlights? 1) (gimp-layer-set-mode newlayer1 blend-mode) (set! templayer (car (gimp-image-merge-down img newlayer1 0))) ) (else (gimp-image-remove-layer img newlayer1) ) ) (gimp-drawable-set-name templayer "Frame") ;displaces the final result according to the displacement map (cond ((= displace? 1) (plug-in-displace 1 img templayer (* xsize displacestrength) (* ysize displacestrength) 1 1 displacelayer displacelayer 1) )) (set! count (+ 1 count)) ) ;The following section is the same as the body of the while loop, but acts on the original source layers (set! cloud1 (car (gimp-image-merge-down img cloud2 0))) (cond ((= displace? 1) (set! displacelayer (car (gimp-layer-new-from-drawable cloud1 img))) )) (gimp-curves-spline cloud1 0 6 array) (cond ((= highlights? 1) (gimp-layer-set-mode cloud1 blend-mode) (set! layer (car (gimp-image-merge-down img cloud1 0))) ) (else (gimp-image-remove-layer img cloud1) ) ) (gimp-drawable-set-name layer "Frame#0") (cond ((= displace? 1) (plug-in-displace 1 img layer (* xsize displacestrength) (* ysize displacestrength) 1 1 displacelayer displacelayer 1) )) (gimp-image-undo-thaw img) ; Create and update the display (gimp-display-new img) (gimp-displays-flush) ) ) (script-fu-register "script-fu-wavetank" "Wave Tank..." "Generates an animation as if the active layer were on the bottom of a ripple tank." "Will Morrison" "Will Morrison" "2010" "RGB*" SF-IMAGE "Image" 0 SF-DRAWABLE "Active Layer" 0 ; SF-ADJUSTMENT "Image X size" '(800 1 2048 1 50 0 1) ; SF-ADJUSTMENT "Image Y size" '(600 1 2048 1 50 0 1) SF-ADJUSTMENT "Horizontal scale" '(2 0.1 16 0.1 1 1 0) SF-ADJUSTMENT "Vertical scale" '(5 0.1 16 0.1 1 1 0) SF-OPTION "Blend Mode" '("Overlay" "Addition" "Screen" "Dodge") SF-ADJUSTMENT "Number of frames" '(50 1 400 1 10 0 1) SF-TOGGLE "Use Displace Map" 0 SF-TOGGLE "Use Highlights" 1 SF-ADJUSTMENT "Displace strength" '(0.01 0 1 0.01 0.1 3 0) ) (script-fu-menu-register "script-fu-wavetank" "/Filters/Will's Script Pack")