A Procedural Graphics System

A place for you to show off what you have made with LiveCode

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Post Reply
Hutchboy
Posts: 135
Joined: Wed Aug 01, 2018 2:57 pm
Contact:

A Procedural Graphics System

Post by Hutchboy » Tue Sep 30, 2025 2:56 am

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]
Last edited by Hutchboy on Thu Oct 02, 2025 1:14 am, edited 1 time in total.

Hutchboy
Posts: 135
Joined: Wed Aug 01, 2018 2:57 pm
Contact:

Re: A Procedural Graphics System

Post by Hutchboy » Tue Sep 30, 2025 8:26 pm

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]
Last edited by Hutchboy on Thu Oct 02, 2025 1:15 am, edited 1 time in total.

bobcole
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 170
Joined: Tue Feb 23, 2010 10:53 pm

Re: A Procedural Graphics System

Post by bobcole » Wed Oct 01, 2025 2:51 pm

@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

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4179
Joined: Sun Jan 07, 2007 9:12 pm

Re: A Procedural Graphics System

Post by bn » Wed Oct 01, 2025 6:50 pm

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

Hutchboy
Posts: 135
Joined: Wed Aug 01, 2018 2:57 pm
Contact:

Re: A Procedural Graphics System

Post by Hutchboy » Thu Oct 02, 2025 1:12 am

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
Attachments
procedural_graphics_guide_v2.html.zip
(8.15 KiB) Downloaded 8 times
Procedural Graphics System v1.4.0.livecode.zip
(26.18 KiB) Downloaded 9 times

Post Reply