Page 1 of 1
A Procedural Graphics System
Posted: Tue Sep 30, 2025 2:56 am
by Hutchboy
Hi,
I am attaching a Procedural Graphics System stack and a user guide. In the user guide I talk a bit about changing the resolution of the image, but I have it hard wired for now at 800 x 800 pixels. The user guide should open directly in your browser; I've tested it with Safari, FireFox and Chrome successfully.
This has some similarities to the Minimum Drawing Library ( available here in the forums ) but I am interested in creating procedural art so I wanted a "playground" I could easily expand (next version is in work).
- Mike
[ 10/1/2025. Removed files and uploaded new versions below]
Re: A Procedural Graphics System
Posted: Tue Sep 30, 2025 8:26 pm
by Hutchboy
Hi,
The attached version 1.2.0 of the Procedural Graphics System adds some noise generators. These are fairly slow generators in an 800 x 800 pixel image, but not too bad. There is a small status update msg in the lower left corner that will show you progress for these generators so you know something is happening. I am running out of card real estate for controls for the next phase development so I will probably expand the stack width size to accommodate. I will hold off a bit before updating the user guide, probably for the next phase. Look up any terms that may seem unfamiliar for now (lacunarity!?) .
Note: for each generator type I changed the code to just disable/dim the unnecessary controls for that type. The first version hid them but that was too jarring.
- Mike
[10/1/25. Removed files and uploaded new revisions below]
Re: A Procedural Graphics System
Posted: Wed Oct 01, 2025 2:51 pm
by bobcole
@Hutchboy (Mike)
This is a fascinating project.
I am curious as to the meaning of Scale, Octaves, Persistence and Lacunarity at the top of the window.
I am enjoying your efforts.
Bob
Re: A Procedural Graphics System
Posted: Wed Oct 01, 2025 6:50 pm
by bn
Hutchboy wrote: ↑Tue Sep 30, 2025 8:26 pm
The attached version 1.2.0 of the Procedural Graphics System adds some noise generators. These are fairly slow generators in an 800 x 800 pixel image, but not too bad.
Mike,
Firstly thank you for this elaborate and well written stack.
I took the liberty to change some code in your version 1.2.0 to improve speed a bit. It makes linear gradients about 10%+ faster.
1. I changed handler
applyInterpolation to:
Code: Select all
function applyInterpolation @pRatio, @pMethod
note the @ sign. This handler is called very often and the referencing by @ speeds things up nicely.
In handler createLinearGradient I call it this way since tRatio is now changed in handler
applyInterpolation
Code: Select all
get applyInterpolation(tRatio, pInterpolation) # changed
The whole handler
applyInterpolation
Code: Select all
-- APPLY INTERPOLATION TO RATIO
function applyInterpolation @pRatio, @pMethod
local tResult
switch pMethod
case "linear"
put pRatio into pRatio
break
case "easein"
-- Quadratic ease-in: ratio^2
put pRatio * pRatio into pRatio
break
case "easeout"
-- Quadratic ease-out: 1 - (1-ratio)^2
put 1 - ((1 - pRatio) * (1 - pRatio)) into pRatio
break
default
put pRatio into tResult
end switch
--return pRatio
end applyInterpolation
Furthermore I changed handler
createLinearGradient in the switch statement: (speeds up a little bit)
Code: Select all
-- CREATE LINEAR GRADIENT (ORIGINAL - NOW WITH INTERPOLATION)
on createLinearGradient pWidth, pHeight, pStartColor, pEndColor, pDirection, pInterpolation
local tData, tX, tY, tRatio
local tStartR, tStartG, tStartB
local tEndR, tEndG, tEndB
local tR, tG, tB
local tPixelColor
local tMaxDimension
-- Parse start color
put item 1 of pStartColor into tStartR
put item 2 of pStartColor into tStartG
put item 3 of pStartColor into tStartB
-- Parse end color
put item 1 of pEndColor into tEndR
put item 2 of pEndColor into tEndG
put item 3 of pEndColor into tEndB
-- Determine maximum dimension for diagonal
if pDirection is "diagonal" then
put sqrt(pWidth^2 + pHeight^2) into tMaxDimension
end if
-- Calculate ratio based on direction
switch pDirection
case "horizontal"
-- Generate pixel data
repeat with tY = 0 to pHeight - 1
repeat with tX = 0 to pWidth - 1
-- Apply interpolation
put tX / (pWidth - 1) into tRatio
get applyInterpolation(tRatio, pInterpolation) # changed
-- Interpolate RGB values
put round(tStartR + (tEndR - tStartR) * tRatio) into tR
put round(tStartG + (tEndG - tStartG) * tRatio) into tG
put round(tStartB + (tEndB - tStartB) * tRatio) into tB
-- Encode pixel in ARGB format (alpha = 0 for opaque)
put binaryEncode("CCCC", 0, tR, tG, tB) after tData -- Append to image data ## changed
end repeat
end repeat
break
case "vertical"
-- Generate pixel data
repeat with tY = 0 to pHeight - 1
repeat with tX = 0 to pWidth - 1
put tY / (pHeight - 1) into tRatio
-- Apply interpolation
get applyInterpolation(tRatio, pInterpolation) # changed
-- Interpolate RGB values
put round(tStartR + (tEndR - tStartR) * tRatio) into tR
put round(tStartG + (tEndG - tStartG) * tRatio) into tG
put round(tStartB + (tEndB - tStartB) * tRatio) into tB
-- Encode pixel in ARGB format (alpha = 0 for opaque)
put binaryEncode("CCCC", 0, tR, tG, tB) after tData -- Append to image data # changed
end repeat
end repeat
break
case "diagonal"
-- Generate pixel data
repeat with tY = 0 to pHeight - 1
repeat with tX = 0 to pWidth - 1
put sqrt(tX^2 + tY^2) / tMaxDimension into tRatio
if tRatio > 1 then put 1 into tRatio
-- Apply interpolation
get applyInterpolation(tRatio, pInterpolation) --into tRatio
-- Interpolate RGB values
put round(tStartR + (tEndR - tStartR) * tRatio) into tR
put round(tStartG + (tEndG - tStartG) * tRatio) into tG
put round(tStartB + (tEndB - tStartB) * tRatio) into tB
-- Encode pixel in ARGB format (alpha = 0 for opaque)
put binaryEncode("CCCC", 0, tR, tG, tB) after tData -- Append to image data # changed
end repeat
end repeat
break
default
put tX / (pWidth - 1) into tRatio
-- Generate pixel data
repeat with tY = 0 to pHeight - 1
repeat with tX = 0 to pWidth - 1
-- Apply interpolation
get applyInterpolation(tRatio, pInterpolation) # changed
-- Interpolate RGB values
put round(tStartR + (tEndR - tStartR) * tRatio) into tR
put round(tStartG + (tEndG - tStartG) * tRatio) into tG
put round(tStartB + (tEndB - tStartB) * tRatio) into tB
-- Encode pixel in ARGB format (alpha = 0 for opaque)
put binaryEncode("CCCC", 0, tR, tG, tB) after tData -- Append to image data # changed
end repeat
end repeat
end switch
-- Resize and apply image
lock screen -- saves about 10 to 20 milliseconds # changed
set the width of img "img_display" to pWidth
set the height of img "img_display" to pHeight
set the imageData of img "img_display" to tData
-- Center image in display area
centerImageInDisplay
-- Store for export
put tData into gLastGeneratedImage
end createLinearGradient
The other
create... handlers could be adapted for "get applyInterpolation(tRatio, pInterpolation) --into tRatio"
Again thanks for this nice example.
Kind regards
Bernd
Re: A Procedural Graphics System
Posted: Thu Oct 02, 2025 1:12 am
by Hutchboy
Hi,
Attached is version 1.4 of my Procedural Graphics System. This version adds new features, enlarges the stack size to 1400 x 900, and removes the restriction on changing the resolution to ranges from a minimum of 200 pixels to a max of 800. I've added an "Reset" button that will return everything to the defaults and clear the image.
I have also updated the user guide to bring it up to date with this release.
[bn...Thanks, I will review and incorporate your speed up recommendations in the next phase]
-Mike