reepblue Posted September 8 Share Posted September 8 This extension is for those who have existing materials that were made for the Blinn-Phong shading (diffuse+normal+specular) such as the textures for Leadwerks. Right click on an image with a specular suffix in the name and a "Convert Specular to Metal-Roughness" option will show up. This will take the spec sheet, insert the existing pixels in the blue channel, then swap the pixels and store that copy into the green channel. (This seems to take a bit) The result will be a blue and green texture. In your material, you then can use the Metalness and Roughness spinners to adjust the values. I find setting the Metalness to 0.1 is what you want for most non-metal textures to mimic the specular effect. For things that are metal, well that's up to you to tweak and find out. It really helps if you know how the material should look. The only thing you might need to consider is any roughness map you've made if you came from Leadwerks. That mask wasn't really conventional, and you may want to look into packing that yourself with the Channel Packing Tool to get the desired look. SpecMapToMetalRoughness.lua 3 Quote Cyclone - Ultra Game System - Component Preprocessor - Tex2TGA - Darkness Awaits Template (Leadwerks) If you like my work, consider supporting me on Patreon! Link to comment Share on other sites More sharing options...
reepblue Posted September 20 Author Share Posted September 20 Quick patch: local extension = {} extension.currentsuffix = "" extension.suffix = "metalroughness" function extension.IsSpecMap(file) if file == nil then return false end if FileType(file) == 0 then return false end -- Check the file extention, make sure it's an image. local ext = ExtractExt(string.lower(file)) if ext ~= "tga" and ext ~= "png" and ext ~= "jpg" and ext ~= "bmp" then return false end -- Check to see if the file has a specular suffix at the end if Right(StripExt(file), 8) == string.lower("specular") then extension.currentsuffix = string.lower("specular") elseif Right(StripExt(file), 4) == string.lower("spec") then extension.currentsuffix = string.lower("spec") elseif Right(StripExt(file), 1) == string.lower("s") then extension.currentsuffix = string.lower("s") else extension.currentsuffix = "" return false end -- Return true if all conditions met! return true end function extension.StorePixelsInChannel(src, dst, channel) if src then local sz = src.size if src.blocksize ~= 1 then src = src:Convert(TEXTURE_RGBA) if src == nil then Print("Error: Failed to convert pixmap format") return false end end if src.size ~= sz then src = src:Resize(sz.x, sz.y) end if not src:CopyChannel(channel, dst, channel) then Print("Error: Pixmap:CopyChannel failed on channel "..tostring(n)) end end end function extension.ConvertSpecToMetalRoughness(file) local pixmap = LoadPixmap(file) if pixmap==nil then Print("Error: Failed to generate texture \"" .. file .. "\"") return false end if pixmap.blocksize ~= 1 then pixmap = pixmap:Convert(TEXTURE_RGBA) end -- Define the channels local roughnesschannel = 2 -- Green local specchannel = 3 -- blue local dst = CreatePixmap(pixmap.size.x, pixmap.size.x) dst:Fill(Rgba(0,0,0,255)) -- Store the spec in the blue channel. extension.StorePixelsInChannel(pixmap, dst, specchannel) -- Roughness is the specular but we invert the colors. (This is also really slow) local roughness = CreatePixmap(pixmap.size.x, pixmap.size.y) roughness:Fill(Rgba(0,0,0,255)) Print("Swapping colors from the specular map. This might take a while...") for x = 0, pixmap.size.x - 1 do for y = 0, pixmap.size.y - 1 do local rgba = pixmap:ReadPixel(x, y) local r = 255-Red(rgba) local g = 255-Green(rgba) local b = 255-Blue(rgba) rgba = Rgba(r, g, b, 255) roughness:WritePixel(x, y, rgba) end end extension.StorePixelsInChannel(roughness, dst, roughnesschannel) roughness = nil -- Save as a DDS texture local d = StripExt(file) local name = Left(d, Len(d) - Len(extension.currentsuffix)) local output = name .. extension.suffix .. ".dds" --Build mipmap chain local mipchain = dst:BuildMipchain() local ddsformat = TEXTURE_BC7--Everything else local blocksize = 4 local count = #mipchain local block = dst.blocksize --Convert to desired compression format if ddsformat ~= 0 then local mipchain2 = {} local n for n = 1, #mipchain do if mipchain[n].size.x < blocksize or mipchain[n].size.y < blocksize then break else mipchain2[n] = mipchain[n]:Convert(ddsformat) if mipchain2[n] == nil then Print("Error: Failed to convert \""..path.."\" to format "..tostring(ddsformat)) return false end end end mipchain = mipchain2 end --Save the texture return SaveTexture(output, TEXTURE_2D, mipchain) end function extension.hook(event, extension) if event.id == EVENT_WIDGETACTION then if event.source == extension.menu[1] then if program.assetbrowser.selectedfile then if program.assetbrowser.selectedfile.package == nil then Print("Converting \""..StripDir(program.assetbrowser.selectedfile.path).."\"") if extension.ConvertSpecToMetalRoughness(program.assetbrowser.selectedfile.path) then extension.currentsuffix = "" Print("Done!") end collectgarbage() end end end elseif event.id == EVENT_WIDGETOPEN then if event.source == program.assetbrowser.filepopupmenu then --Hide the menu items if they exist if extension.menu ~= nil then extension.menu[1]:SetHidden(true) extension.menu[2]:SetHidden(true) end if program.assetbrowser.selectedfile then if program.assetbrowser.selectedfile.package == nil then if extension.IsSpecMap(program.assetbrowser.selectedfile.path) then --Create menu items if needed if extension.menu == nil then widget = Widget(event.source) extension.menu = {} extension.menu[1] = CreateMenu("Convert Specular to Metal-Roughness", widget) extension.menu[2] = CreateMenu("", widget) extension.menu[2]:SetParent(widget, 0) extension.menu[1]:SetParent(widget, 0) ListenEvent(EVENT_WIDGETACTION, extension.menu[1], extension.hook, extension) end --Show the menu item and divider extension.menu[1]:SetHidden(false) extension.menu[2]:SetHidden(false) end end end end end end ListenEvent(EVENT_WIDGETOPEN, program.assetbrowser.filepopupmenu, extension.hook, extension) Quote Cyclone - Ultra Game System - Component Preprocessor - Tex2TGA - Darkness Awaits Template (Leadwerks) If you like my work, consider supporting me on Patreon! Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.