Jump to content

Fix Your Alpha-masked Vegetation Textures


This is a very common mistake I see in 3D models. Probably the majority of the time, artists will use either black or white for the background in a masked vegetation texture.

before.thumb.jpg.2ef969c00a7d404dcdc9dd6c17f22833.jpg

This often goes unnoticed because support for viewing alpha channels is almost universally bad in all paint programs and image viewers. Here is what the image looks like with the alpha channel active:

MI_YMC_Grass_01_BaseColor_fixed.thumb.png.8770ceb6ec0b9f8aabf6a8587c6b42da.png

Although Leadwerks is smart enough to weight pixels by their alpha value when creating the downsampled mipmap chain, the linear filter the GPU uses will still show the background color on the edge of the solid area. This results in a strange darkening or lightening of your vegetation. If you see the vegetation getting darker with distance, the background of the transparent area is probably black. If you see flickering white pixels, the transparent area is probably white.

The script below will downsample the image, using the alpha-weighted technique Leadwerks uses, and then apply the blurred color to the transparent background of the original image, resulting in an image that looks like this:

after.thumb.jpg.0062d5797e11ee94ec056989f1ada67b.jpg

This will eliminate the artifacts you are seeing in your masked vegetation and provide clear but smooth alpha-masked surfaces, free of pixelation.

local file = RequestFile("Open File", CurrentDir().."/")
if file == "" then return end

local pixmap = LoadPixmap(file)
if pixmap == nil then return end

local mipmaps = pixmap:BuildMipchain()
local n = #mipmaps - 3
if n < 1 then n = 1 end

local x, y, rgba, r, g, b, a
local changed = false

for x = 0, pixmap.size.x - 1 do
    for y = 0, pixmap.size.y - 1 do
        rgba = pixmap:Sample(iVec2(x, y))
        if rgba.a < 1.0 then
            background = mipmaps[n]:Sample((x + 0.5) / pixmap.size.x, (y + 0.5) / pixmap.size.y)
            rgba.r = Mix(background.r, rgba.r, rgba.a)
            rgba.g = Mix(background.g, rgba.g, rgba.a)
            rgba.b = Mix(background.b, rgba.b, rgba.a)
            pixmap:WritePixel(x, y, rgba)
            changed = true
        end
    end
end

if changed then
    pixmap:Save(StripExt(file).."_fixed."..ExtractExt(file))
else
    Print("No transparent pixels")
end

 

  • Like 2

0 Comments


Recommended Comments

There are no comments to display.

Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...