HELP - EditableImage only showing one color

  1. What do you want to achieve?

I want to make it so the editable image displays a height map from black to white based on a randomly generated number.

  1. What is the issue? Include screenshots / videos if possible!

The issue is that the image is only showing a single color at once, almost like it’s ignoring the math.random()

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

I’ve tried switching from draw rectangles to write pixels, and back, and I’ve searched on the developer hub for solutions, but I couldn’t find any posts on the topic.

			EditableImage:Resize(Vector2.new(1024, 1024))
			local image_size = EditableImage.Size

			-- Create an array to store pixel data
			local pixel_data = {}

			-- Loop through each pixel in the image
			for y = 0, image_size.Y - 1 do
				for x = 0, image_size.X - 1 do
					-- Generate a floating-point random number between 0 and 1 for depth
					local num = math.random(0.0000, 1.0000)

					-- Use grayscale value for the depth
					local vertex_color = Color3.new(num, num, num)

					-- Add the color data (R, G, B, A) to the pixel array, converted to [0, 255] range
					table.insert(pixel_data, math.floor(vertex_color.R * 255))  -- Red
					table.insert(pixel_data, math.floor(vertex_color.G * 255))  -- Green
					table.insert(pixel_data, math.floor(vertex_color.B * 255))  -- Blue
					table.insert(pixel_data, 255)  -- Alpha (fully opaque)
				end
			end

			EditableImage:WritePixels(Vector2.new(0, 0), image_size, pixel_data)

If the full context for generating the plain mesh itself is needed, I’ll send the full script.

A few things are incorrect with your script.
math.random() will only return a whole number, a solution is to use Random and :NextNumber() without any arguments.

local random = Random.new()
local num = random:NextNumber() -- will return between 0 and 1, including decimals

Next, you are inserting pixels that are equivalent to the actual RGB values. :WritePixels() accepts R,G,B,A as you are aware, though those values are meant to be between 0 and 1. To fix this, you can just remove the math.floor() and * 255 you have. If you want to keep a certain amount of decimals, you can just do something like this:

local num = random:NextNumber() -- 0.295129102
num = math.floor(num * 10000)/10000 -- 0.2951

After this, you can just insert these values into the pixel_data table and it should be all grayscale values.

1 Like

The reply above my own should be the solution to your problem.

I’m replying as I wish to add that math.random() (without any parameters given) returns a decimal number between 0 and 1, meaning that you can just remove the 0.0000 and 1.0000 to get the desired randomness, rather than having to use Random:NextNumber()

I think it may have something to do with the way the plain was scripted, because even after making all of these changes, the entire plain is only ever turning one color.

This is my code I wrote to create the plain:

parts[part] = {}
			parts[part].editablemesh = EditableMesh
			local Vertices = {}
			for y = 1, HEIGHT do
				local raw = {}
				for x = 1, WIDTH do
					local vertex_position = (Vector3.new(x-1, 0, y-1) - Vector3.new(WIDTH / 2, 0, HEIGHT / 2)) * Offset
					local vertex_id = EditableMesh:AddVertex(vertex_position)

					-- Precompute a random phase offset and store it along with the vertex
					local phaseOffset = Vector3.new(math.random() * PhaseScale, 0, math.random() * PhaseScale)
					-- Precompute a random speed variation and store it along with the vertex
					local speedVariation = 1 + (math.random() - 0.5) * 0.1

					raw[x] = {vertex_id, vertex_position, phaseOffset, speedVariation}
				end
				Vertices[y] = raw
			end

			for y = 1, HEIGHT-1 do
				for x = 1, WIDTH-1 do
					local vertex_1 = Vertices[y][x][1] :: number 
					local vertex_2 = Vertices[y+1][x][1] :: number
					local vertex_3 = Vertices[y][x+1][1] :: number

					local vertex_4 = Vertices[y+1][x+1][1] :: number

					local triangle_1 = EditableMesh:AddTriangle(vertex_1, vertex_2, vertex_3)
					local triangle_2 = EditableMesh:AddTriangle(vertex_2, vertex_4, vertex_3)
				end
			end
			parts[part].verticies = Vertices

I can’t seem to figure out why.

It’s how Roblox tries to project an EditableImage on to a Mesh with an EditableMesh thats the issue. I believe that’s why they are creating the method :DrawProjectionImage(), which is currently disabled.

There are still a few potential solutions. If you have a flat plane, and will NOT be modifying the actual height of the EditableMesh, you can just use a SurfaceGUI with it’s adornee property set to the Mesh. The EditableImage should be parented to an ImageLabel inside of SurfaceGUI.

If you are modifying the height of the EditableMesh, rather than using an EditableImage, you can use vertex coloring on the EditableMesh using :SetFaceColors(). SetFaceColors takes in a FaceId which you can get from :GetFaces() and a table of Colors created using :AddColor().

Example:

-- This sets each quad(2 tris) to a whole color, as if it were an EditableImage
local faces = EditableMesh:GetFaces()
for index, faceId in pairs(faces) do
	if index % 2 == 0 then
		local previousFaceColors = EditableMesh:GetFaceColors(faces[index-1])
		EditableMesh:SetFaceColors(faceId, previousFaceColors)
	else
		local randomColor = math.random()
		local newColor = EditableMesh:AddColor(Color3.new(randomColor, randomColor, randomColor), 1)
		EditableMesh:SetFaceColors(faceId, {newColor, newColor, newColor})
	end	
end

The only other solution is to use :SetUV() if you are really adamant on using an EditableImage. I haven’t messed with it enough to be able to provide with the information on how to use it in your situation, but I know it will let you use EditableImage on your EditableMesh. THIS POST has an example place you can download and search for :SetUV() in, but keep in mind you’ll have to make your own way of setting UVs as this is based on its own EditableMeshes and situation.

There probably is a different/better solution than what I provided, but hopefully this can help provide some solution to your question.