Many techniques in image processing work off of noise: randomized pixel values that you can add to an image, subtract from an image, blend into an image, or otherwise use as the grist for some image filter. Creating noise for use in creating a tileset is no different, but it has certain requirements.
I am creating 32x16 diamond, and I want them to join seamlessly. I cannot tile a patch of 16x16 noise, because that would repeat in the space of a single diamond. I cannot tile a patch of 32x16 noise, bececause that would only repeat every other tile (imagine a black-and-white checker board pattern). What I really need is a diamond-shaped patch of noise.
It so happens that I can produce the results I want by starting with a 16x16 patch of noise, and then doubling it to 32x16, and then skewing it, and then looping it back on itself, like so:
Creating such 'tileable' noise was something I saw myself needing to do so regularly that I created a GIMP script to automate the process. It takes a single parameter (the height of the noise rectangle to generate), generates a rectangle using the above process (strictly, using a process that gives equivalent results), and tiles it to the image size. The source code is below:
(define (script-fu-diagonal-noise image layer height) (let* ( (width (* 2 height)) ) (gimp-context-push) (gimp-undo-push-group-start image) ; Implementation start ; (gimp-layer-resize-to-image-size layer) ; Produce a square patch of noise ; (gimp-image-select-rectangle image CHANNEL-OP-REPLACE 0 0 (/ width 2) height) (plug-in-randomize-hurl RUN-NONINTERACTIVE image layer 100.0 1.0 TRUE 0) (plug-in-colors-channel-mixer RUN-NONINTERACTIVE image layer FALSE 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0) ; Copy top left to bottom right ; (gimp-image-select-rectangle image CHANNEL-OP-REPLACE 0 0 (/ width 2) (/ height 2)) (gimp-edit-copy layer) (let* ((floater (car (gimp-edit-paste layer FALSE)))) (gimp-layer-translate floater (/ width 2) (/ height 2)) (gimp-floating-sel-anchor floater) ) ; Copy bottom left to top right ; (gimp-image-select-rectangle image CHANNEL-OP-REPLACE 0 (/ height 2) (/ width 2) (/ height 2)) (gimp-edit-copy layer) (let* ((floater (car (gimp-edit-paste layer FALSE)))) (gimp-layer-translate floater (/ width 2) (/ height -2)) (gimp-floating-sel-anchor floater) ) ; Clip layer to noise size, tile it, and reset the alpha channel ; (gimp-layer-resize layer width height 0 0) (plug-in-tile RUN-NONINTERACTIVE image layer (car (gimp-image-width image)) (car (gimp-image-height image)) FALSE) (gimp-layer-flatten layer) ; Implemenation end ; (gimp-undo-push-group-end image) (gimp-context-pop) (gimp-displays-flush) ) ) (script-fu-register "script-fu-diagonal-noise" "Diagonal Noise" "Fills a layer with uniformly-distributed grayscale noise that has a repeating diagonal grain. The period of the noise's repeating pattern will be twice as large as it is high." "The Unary Heap" "The Unary Heap" "2014-07-15" "RGB*" SF-IMAGE "Image" 0 SF-DRAWABLE "Drawable" 0 SF-VALUE "Height" "16" ) (script-fu-menu-register "script-fu-diagonal-noise" "<Image>/Filters/UnaryHeap" )
If you run the script, you will get results similar to the following:
No comments:
Post a Comment