Skip to content

Instantly share code, notes, and snippets.

@headjoe3
Last active October 3, 2021 14:02
Show Gist options
  • Save headjoe3/be2c59eb8235d85ad4359a5a0a4d48de to your computer and use it in GitHub Desktop.
Save headjoe3/be2c59eb8235d85ad4359a5a0a4d48de to your computer and use it in GitHub Desktop.
UIGradient Pixel Rendering
--[[
Optimized pixel rendering by Hexcede
Version 1.0
How do I use it?
The only function contained on the PixOptimize module is the Generate function. It takes a 2D array of pixels and returns a Frame containing the generated image.
How does it work?
This works by using UI gradients to render pixels instead of individual frames. It splits the image into 1x20 (could be increased in the future if Roblox supports ColorSequences with >20 values) strips which are colored using a single UIGradient instance.
What are some current problems with this method?
Due to the interpolation of UIGradients slight visual artifacting WILL occur. The perlin noise debug mode included in the demo script shows this artificting best.
What benefits might you get if you were to use this method?
This module can reduce the number of frames used to render an image up to 20 times which can reduce lag up to 20 times and allow for up to 20x taller images
© Hexcede 2020
Feel free to use this code for any purpose as long as this snippet and the copyright above is kept with my code! I just like my code to be credited ;D
That doesn't mean you need to credit me in your place though unless you want to!
--]]
local pixOptimize = {}
pixOptimize.COLOR_SEQUENCE_MAX_LENGTH = 18 -- Currently this is 20, however it could be changed in the future maybe!
-- Alpha, color, etc is a number from 0-1. Alpha of 0 is fully opaque.
-- Pixels is in the format: {[x] = {[y] = {Color = Color3, Alpha/Transparency = number}}}
function pixOptimize:Generate(pixels)
local rows = Instance.new("Frame")
rows.BackgroundTransparency = 1
pixels = pixels or {}
rows.Size = UDim2.new(0, #pixels, 0, #(pixels[1] or {}))
local rowCounter = 0
local pixId = 0
local area = rows.AbsoluteSize.X * rows.AbsoluteSize.Y
for x=1, #pixels do
local col = pixels[x] or {}
local row
local gradient
local colors
local transparencies
local function doCleanup(reallocate)
if gradient then
table.insert(colors, ColorSequenceKeypoint.new((#colors-1)/(self.COLOR_SEQUENCE_MAX_LENGTH), Color3.fromRGB(255, 0, 0)))
table.insert(transparencies, NumberSequenceKeypoint.new((#transparencies-1)/(self.COLOR_SEQUENCE_MAX_LENGTH), 1))
if reallocate and #colors < self.COLOR_SEQUENCE_MAX_LENGTH then
for i=#colors, self.COLOR_SEQUENCE_MAX_LENGTH - 1 do
table.insert(colors, ColorSequenceKeypoint.new(i/(self.COLOR_SEQUENCE_MAX_LENGTH - 1), Color3.new()))
end
end
if reallocate and #transparencies < self.COLOR_SEQUENCE_MAX_LENGTH then
for i=#transparencies, self.COLOR_SEQUENCE_MAX_LENGTH - 1 do
table.insert(transparencies, NumberSequenceKeypoint.new(i/(self.COLOR_SEQUENCE_MAX_LENGTH - 1), 1))
end
end
gradient.Color = ColorSequence.new(colors)
gradient.Transparency = NumberSequence.new(transparencies)
gradient.Parent = row
end
if row then
row.Parent = rows
end
end
for y=1, #col do
local pix = col[y] or {Color = Color3.new(), Alpha = 1}
pixId = pixId + 1
if (y-1)%self.COLOR_SEQUENCE_MAX_LENGTH == 0 then
doCleanup()
rowCounter = rowCounter + 1
row = Instance.new("Frame")
row.BorderSizePixel = 0
row.Size = UDim2.new(0, 1, 0, self.COLOR_SEQUENCE_MAX_LENGTH)
row.Position = UDim2.new(0, x - 1, 0, y - 1)
gradient = Instance.new("UIGradient")
gradient.Rotation = 90 -- Gradient top to bottom, 0 is left to right
colors = table.create(self.COLOR_SEQUENCE_MAX_LENGTH+2)
table.insert(colors, ColorSequenceKeypoint.new(0, Color3.fromRGB(255, 0, 0)))
transparencies = table.create(self.COLOR_SEQUENCE_MAX_LENGTH+2)
table.insert(transparencies, NumberSequenceKeypoint.new(0, 1))
end
table.insert(colors, ColorSequenceKeypoint.new(((y-0.5)%self.COLOR_SEQUENCE_MAX_LENGTH)/(self.COLOR_SEQUENCE_MAX_LENGTH), pix.Color))
table.insert(transparencies, NumberSequenceKeypoint.new(((y-0.5)%self.COLOR_SEQUENCE_MAX_LENGTH)/(self.COLOR_SEQUENCE_MAX_LENGTH), pix.Alpha or pix.Transparency))
end
doCleanup(true)
end
return rows, rowCounter
end
return pixOptimize
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment