Skip to content

Commit

Permalink
Merge pull request #387 from RagnarokResearchLab/reduced-color-textures
Browse files Browse the repository at this point in the history
Implement color banding for diffuse texture images
  • Loading branch information
rdw-software authored Mar 18, 2024
2 parents 3b39259 + b6de33d commit e96fadd
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 2 deletions.
3 changes: 3 additions & 0 deletions Core/FileFormats/RagnarokMap.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ local RagnarokGRF = require("Core.FileFormats.RagnarokGRF")
local RagnarokRSW = require("Core.FileFormats.RagnarokRSW")

local C_Resources = require("Core.NativeClient.C_Resources")
local Texture = require("Core.NativeClient.WebGPU.Texture")

local NormalsVisualization = require("Core.NativeClient.DebugDraw.NormalsVisualization")

Expand Down Expand Up @@ -100,6 +101,8 @@ function RagnarokMap:LoadTerrainGeometry(mapID)
local textureImageBytes = self:FetchResourceByID(normalizedTextureImagePath)
local rgbaImageBytes, width, height = C_ImageProcessing.DecodeFileContents(textureImageBytes)

rgbaImageBytes, width, height = Texture:CreateReducedColorImage(rgbaImageBytes, width, height)

printf(
"[RagnarokMap] Loading GND ground mesh section %d with diffuse texture %s (%d x %d)",
sectionID,
Expand Down
39 changes: 39 additions & 0 deletions Core/NativeClient/WebGPU/Texture.lua
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,45 @@ function Texture:CreateTextureView(wgpuTexture, wgpuTextureViewDescriptor)
return webgpu.bindings.wgpu_texture_create_view(wgpuTexture, wgpuTextureViewDescriptor)
end

-- Should probably be replaced with an optimized version (via the ImageProcessing API)?
function Texture:CreateReducedColorImage(inputImageBytes, width, height, posterizationLevel)
posterizationLevel = posterizationLevel or 3

local numBytesWritten = 0
local rgbaImageBytes = buffer.new(width * height * 4)
local bufferStartPointer = rgbaImageBytes:reserve(width * height * 4)
local inputPixels = buffer.new():put(inputImageBytes):ref()
for pixelV = 0, height - 1, 1 do
for pixelU = 0, width - 1, 1 do
local writableAreaStartIndex = (pixelV * width + pixelU) * 4
local red = inputPixels[writableAreaStartIndex + 0]
local green = inputPixels[writableAreaStartIndex + 1]
local blue = inputPixels[writableAreaStartIndex + 2]
local alpha = inputPixels[writableAreaStartIndex + 3]

local posterizedRed = bit.rshift(red, posterizationLevel)
local posterizedGreen = bit.rshift(green, posterizationLevel)
local posterizedBlue = bit.rshift(blue, posterizationLevel)
local posterizedAlpha = bit.rshift(alpha, posterizationLevel)
posterizedRed = bit.lshift(posterizedRed, posterizationLevel)
posterizedGreen = bit.lshift(posterizedGreen, posterizationLevel)
posterizedBlue = bit.lshift(posterizedBlue, posterizationLevel)
posterizedAlpha = bit.lshift(posterizedAlpha, posterizationLevel)

bufferStartPointer[writableAreaStartIndex + 0] = posterizedRed
bufferStartPointer[writableAreaStartIndex + 1] = posterizedGreen
bufferStartPointer[writableAreaStartIndex + 2] = posterizedBlue
bufferStartPointer[writableAreaStartIndex + 3] = posterizedAlpha

numBytesWritten = numBytesWritten + 4
end
end

rgbaImageBytes:commit(numBytesWritten)

return rgbaImageBytes, width, height
end

Texture.__call = Texture.Construct
Texture.__index = Texture
setmetatable(Texture, Texture)
Expand Down
14 changes: 12 additions & 2 deletions Tests/FileFormats/RagnarokMap.spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ local RagnarokRSW = require("Core.FileFormats.RagnarokRSW")

local Texture = require("Core.NativeClient.WebGPU.Texture")

local openssl = require("openssl")
local digest = openssl.digest.digest

local function assertImageChecksumMatches(actualImageBytes, expectedImageBytes)
local checksum = digest("sha256", tostring(actualImageBytes))
expectedImageBytes = Texture:CreateReducedColorImage(expectedImageBytes, 256, 256)
local expectedChecksum = digest("sha256", tostring(expectedImageBytes))
assertEquals(checksum, expectedChecksum)
end

local function makeFileSystem(name)
local testFileSystem = {
ROOT_DIR = path.join("Tests", "Fixtures", "Borftopia"),
Expand Down Expand Up @@ -80,15 +90,15 @@ describe("RagnarokMap", function()
assertEquals(#map.meshes, 2 + 1)
assertEquals(#map.meshes, #groundMeshSections + #waterPlanes)

assertEquals(map.meshes[1].diffuseTextureImage.rgbaImageBytes, gradientTexture)
assertImageChecksumMatches(map.meshes[1].diffuseTextureImage.rgbaImageBytes, gradientTexture)
assertEquals(map.meshes[1].diffuseTextureImage.width, 256)
assertEquals(map.meshes[1].diffuseTextureImage.height, 256)
assertEquals(map.meshes[1].vertexPositions, groundMeshSections[1].vertexPositions)
assertEquals(map.meshes[1].vertexColors, groundMeshSections[1].vertexColors)
assertEquals(map.meshes[1].triangleConnections, groundMeshSections[1].triangleConnections)
assertEquals(map.meshes[1].diffuseTextureCoords, groundMeshSections[1].diffuseTextureCoords)

assertEquals(map.meshes[2].diffuseTextureImage.rgbaImageBytes, gridTexture)
assertImageChecksumMatches(map.meshes[2].diffuseTextureImage.rgbaImageBytes, gridTexture)
assertEquals(map.meshes[2].diffuseTextureImage.width, 256)
assertEquals(map.meshes[2].diffuseTextureImage.height, 256)
assertEquals(map.meshes[2].vertexPositions, groundMeshSections[2].vertexPositions)
Expand Down
11 changes: 11 additions & 0 deletions Tests/NativeClient/WebGPU/Texture.spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -204,4 +204,15 @@ describe("Texture", function()
end, Texture.ERROR_DIMENSIONS_EXCEEDING_LIMIT)
end)
end)

describe("CreateReducedColorImage", function()
it("should reduce the color depth of the texture image", function()
local testImage = "\255\192\128\000" .. "\007\007\007\007"
local reducedColorImage, width, height = Texture:CreateReducedColorImage(testImage, 2, 1)
local expectedimageBytes = "\248\192\128\000\000\000\000\000"
assertEquals(width, 2)
assertEquals(height, 1)
assertEquals(tostring(reducedColorImage), expectedimageBytes)
end)
end)
end)

0 comments on commit e96fadd

Please sign in to comment.