DogLua - Lua scripting for Project Dogwaffle:

Polar Texture Mapping

back: more Lua

 DogLua:   Overview - Downloading - Reference Guide - more Samples - Lua Browser
  see also:  GUI Server - more SDK Info

Polar Texture Mapping Correction

This script was created in response to an inquiry on the Bryce forum at Renderosity on how to create Polar map corrections on a rectangular texture map so that it can be properly mapped on a sphere without seams or pinching at the poles.  The thread can be found here:
This filter is a Lua version of the information and algorithm described by Paul Bourke at

image copyright 2001 Paul Bourke

You can download the Lua file here:


or you can copy-paste it into a text editor or Lua editor from the script shown to the right hre >

You can then save the script filet with the other Lua scripts (files ending in .lua)  in the "DogLuaScripts\" subfolder of your Project Dogwaffle installation.

Here's another example of what it does:

original image: 800x800 image containing a grid
(the grid was generated with this Grid script)

(click to enlarge)

Below is the resulting image after applying this polar mapping correction filter:

(click to enlarge)

cold lava (Dogwaffle filter)

cold lava, polar corrected

same with grid overlay for visual reference

-- File: polar_map_correction.lua
-- polar map correction, based on Paul Bourke's algo/details at
-- converted to Lua/gluas by Philip Staiger,
-- on November 8, 2006 in about 2 hours - that was fun!

-- also did a little bit of optimizations to reduce repetitive
-- calculations when indexing an array (using the 'indx' variable
-- Note: in gluas, width and height are built-in variables, set
-- automatically to the width and height of the image (in pixels of course)

PI =  3.1415926535           -- memories from college :-)
TWOPI = 2 * PI

local imageoutR = {height*width}   -- preallocate buffers of desired size
local imageoutG = {height*width}
local imageoutB = {height*width}

local x, y, r, g, b, a, x2

local i, j, theta, phi, phi2, indx

-- let's get busy
-- transform each pixel and temporarily store in the out buffers
   indx = 0                -- optimized for speed

   for y=0, height-1 do

        theta = PI * (y - (height-1)/2.0) / (height-1)

        for x=0, width-1 do

           phi  = TWOPI * (x - width/2.0) / width
           phi2 = phi * math.cos(theta)
           x2  = phi2 *  width / TWOPI +  width/2

           if ( ( x2 < 0 ) or ( x2 > width-1 ) ) then

    -- something bad happened - flag as red? - Should never happen
              r = 1.0
              g = 0.0
              b = 0.0
              r, g, b = get_rgb( x2, y )

           -- temporarily store the pixel in the out buffers
           imageoutR[indx] = r
           imageoutG[indx] = g
           imageoutB[indx] = b

           indx = indx + 1     -- optimized for speed
       progress( y / height)

--   finally send stored 'out' image back out to the imaging system

indx = 0                    -- optimized for better speed
for y = 0, height - 1 do
  for x = 0, width - 1 do

    r = imageoutR[indx]
    g = imageoutG[indx]
    b = imageoutB[indx]
    set_rgb(x, y, r, g, b)

    indx = indx + 1          -- optimized for better speed

  progress(y / height)