mirror of
https://github.com/tanema/light_world.lua.git
synced 2024-12-24 20:24:19 +00:00
refactored into a normal map library which made body a bit smaller
This commit is contained in:
parent
ae7f8f7b80
commit
b1c366e236
71
lib/body.lua
71
lib/body.lua
@ -1,6 +1,6 @@
|
||||
local _PACKAGE = (...):match("^(.+)[%./][^%./]+") or ""
|
||||
local class = require(_PACKAGE.."/class")
|
||||
local height_map_conv = require(_PACKAGE..'/height_map_conv')
|
||||
local normal_map = require(_PACKAGE..'/normal_map')
|
||||
local vector = require(_PACKAGE..'/vector')
|
||||
local shadowLength = 100000
|
||||
|
||||
@ -299,83 +299,22 @@ end
|
||||
|
||||
-- set height map
|
||||
function body:setHeightMap(heightMap, strength)
|
||||
self:setNormalMap(height_map_conv.toNormalMap(heightMap, strength))
|
||||
self:setNormalMap(normal_map.fromHeightMap(heightMap, strength))
|
||||
end
|
||||
|
||||
-- generate flat normal map
|
||||
function body:generateNormalMapFlat(mode)
|
||||
local imgData = self.img:getData()
|
||||
local imgNormalData = love.image.newImageData(self.imgWidth, self.imgHeight)
|
||||
local color
|
||||
|
||||
if mode == "top" then
|
||||
color = {127, 127, 255}
|
||||
elseif mode == "front" then
|
||||
color = {127, 0, 127}
|
||||
elseif mode == "back" then
|
||||
color = {127, 255, 127}
|
||||
elseif mode == "left" then
|
||||
color = {31, 0, 223}
|
||||
elseif mode == "right" then
|
||||
color = {223, 0, 127}
|
||||
end
|
||||
|
||||
for i = 0, self.imgHeight - 1 do
|
||||
for k = 0, self.imgWidth - 1 do
|
||||
local r, g, b, a = imgData:getPixel(k, i)
|
||||
if a > 0 then
|
||||
imgNormalData:setPixel(k, i, color[1], color[2], color[3], 255)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self:setNormalMap(love.graphics.newImage(imgNormalData))
|
||||
self:setNormalMap(normal_map.generateFlat(self.img, mode))
|
||||
end
|
||||
|
||||
-- generate faded normal map
|
||||
function body:generateNormalMapGradient(horizontalGradient, verticalGradient)
|
||||
local imgData = self.img:getData()
|
||||
local imgNormalData = love.image.newImageData(self.imgWidth, self.imgHeight)
|
||||
local dx = 255.0 / self.imgWidth
|
||||
local dy = 255.0 / self.imgHeight
|
||||
local nx
|
||||
local ny
|
||||
local nz
|
||||
|
||||
for i = 0, self.imgWidth - 1 do
|
||||
for k = 0, self.imgHeight - 1 do
|
||||
local r, g, b, a = imgData:getPixel(i, k)
|
||||
if a > 0 then
|
||||
if horizontalGradient == "gradient" then
|
||||
nx = i * dx
|
||||
elseif horizontalGradient == "inverse" then
|
||||
nx = 255 - i * dx
|
||||
else
|
||||
nx = 127
|
||||
end
|
||||
|
||||
if verticalGradient == "gradient" then
|
||||
ny = 127 - k * dy * 0.5
|
||||
nz = 255 - k * dy * 0.5
|
||||
elseif verticalGradient == "inverse" then
|
||||
ny = 127 + k * dy * 0.5
|
||||
nz = 127 - k * dy * 0.25
|
||||
else
|
||||
ny = 255
|
||||
nz = 127
|
||||
end
|
||||
|
||||
imgNormalData:setPixel(i, k, nx, ny, nz, 255)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self:setNormalMap(love.graphics.newImage(imgNormalData))
|
||||
self:setNormalMap(normal_map.generateGradient(self.img, horizontalGradient, verticalGradient))
|
||||
end
|
||||
|
||||
-- generate normal map
|
||||
function body:generateNormalMap(strength)
|
||||
self:setNormalMap(height_map_conv.toNormalMap(self.img, strength))
|
||||
self:setNormalMap(normal_map.fromHeightMap(self.img, strength))
|
||||
end
|
||||
|
||||
-- set material
|
||||
|
@ -1,50 +0,0 @@
|
||||
height_map = {}
|
||||
|
||||
function height_map.toNormalMap(heightMap, strength)
|
||||
local imgData = heightMap:getData()
|
||||
local imgData2 = love.image.newImageData(heightMap:getWidth(), heightMap:getHeight())
|
||||
local red, green, blue, alpha
|
||||
local x, y
|
||||
local matrix = {}
|
||||
matrix[1] = {}
|
||||
matrix[2] = {}
|
||||
matrix[3] = {}
|
||||
strength = strength or 1.0
|
||||
|
||||
for i = 0, heightMap:getHeight() - 1 do
|
||||
for k = 0, heightMap:getWidth() - 1 do
|
||||
for l = 1, 3 do
|
||||
for m = 1, 3 do
|
||||
if k + (l - 1) < 1 then
|
||||
x = heightMap:getWidth() - 1
|
||||
elseif k + (l - 1) > heightMap:getWidth() - 1 then
|
||||
x = 1
|
||||
else
|
||||
x = k + l - 1
|
||||
end
|
||||
|
||||
if i + (m - 1) < 1 then
|
||||
y = heightMap:getHeight() - 1
|
||||
elseif i + (m - 1) > heightMap:getHeight() - 1 then
|
||||
y = 1
|
||||
else
|
||||
y = i + m - 1
|
||||
end
|
||||
|
||||
local red, green, blue, alpha = imgData:getPixel(x, y)
|
||||
matrix[l][m] = red
|
||||
end
|
||||
end
|
||||
|
||||
red = (255 + ((matrix[1][2] - matrix[2][2]) + (matrix[2][2] - matrix[3][2])) * strength) / 2.0
|
||||
green = (255 + ((matrix[2][2] - matrix[1][1]) + (matrix[2][3] - matrix[2][2])) * strength) / 2.0
|
||||
blue = 192
|
||||
|
||||
imgData2:setPixel(k, i, red, green, blue)
|
||||
end
|
||||
end
|
||||
|
||||
return love.graphics.newImage(imgData2)
|
||||
end
|
||||
|
||||
return height_map
|
@ -25,7 +25,7 @@ local _PACKAGE = (...):match("^(.+)[%./][^%./]+") or ""
|
||||
local class = require(_PACKAGE..'/class')
|
||||
local Light = require(_PACKAGE..'/light')
|
||||
local Body = require(_PACKAGE..'/body')
|
||||
local height_map_conv = require(_PACKAGE..'/height_map_conv')
|
||||
local normal_map = require(_PACKAGE..'/normal_map')
|
||||
|
||||
local light_world = class()
|
||||
|
||||
@ -456,7 +456,7 @@ end
|
||||
|
||||
-- new refraction from height map
|
||||
function light_world:newRefractionHeightMap(heightMap, x, y, strength)
|
||||
local normal = height_map_conv.toNormalMap(heightMap, strength)
|
||||
local normal = normal_map.fromHeightMap(heightMap, strength)
|
||||
self.isRefraction = true
|
||||
return self.newRefraction(p, normal, x, y)
|
||||
end
|
||||
@ -469,7 +469,7 @@ end
|
||||
|
||||
-- new reflection from height map
|
||||
function light_world:newReflectionHeightMap(heightMap, x, y, strength)
|
||||
local normal = height_map_conv.toNormalMap(heightMap, strength)
|
||||
local normal = normal_map.fromHeightMap(heightMap, strength)
|
||||
self.isReflection = true
|
||||
return self.newReflection(p, normal, x, y)
|
||||
end
|
||||
|
123
lib/normal_map.lua
Normal file
123
lib/normal_map.lua
Normal file
@ -0,0 +1,123 @@
|
||||
normal_map = {}
|
||||
|
||||
function normal_map.fromHeightMap(heightMap, strength)
|
||||
local imgData = heightMap:getData()
|
||||
local imgData2 = love.image.newImageData(heightMap:getWidth(), heightMap:getHeight())
|
||||
local red, green, blue, alpha
|
||||
local x, y
|
||||
local matrix = {}
|
||||
matrix[1] = {}
|
||||
matrix[2] = {}
|
||||
matrix[3] = {}
|
||||
strength = strength or 1.0
|
||||
|
||||
for i = 0, heightMap:getHeight() - 1 do
|
||||
for k = 0, heightMap:getWidth() - 1 do
|
||||
for l = 1, 3 do
|
||||
for m = 1, 3 do
|
||||
if k + (l - 1) < 1 then
|
||||
x = heightMap:getWidth() - 1
|
||||
elseif k + (l - 1) > heightMap:getWidth() - 1 then
|
||||
x = 1
|
||||
else
|
||||
x = k + l - 1
|
||||
end
|
||||
|
||||
if i + (m - 1) < 1 then
|
||||
y = heightMap:getHeight() - 1
|
||||
elseif i + (m - 1) > heightMap:getHeight() - 1 then
|
||||
y = 1
|
||||
else
|
||||
y = i + m - 1
|
||||
end
|
||||
|
||||
local red, green, blue, alpha = imgData:getPixel(x, y)
|
||||
matrix[l][m] = red
|
||||
end
|
||||
end
|
||||
|
||||
red = (255 + ((matrix[1][2] - matrix[2][2]) + (matrix[2][2] - matrix[3][2])) * strength) / 2.0
|
||||
green = (255 + ((matrix[2][2] - matrix[1][1]) + (matrix[2][3] - matrix[2][2])) * strength) / 2.0
|
||||
blue = 192
|
||||
|
||||
imgData2:setPixel(k, i, red, green, blue)
|
||||
end
|
||||
end
|
||||
|
||||
return love.graphics.newImage(imgData2)
|
||||
end
|
||||
|
||||
function normal_map.generateFlat(img, mode)
|
||||
local imgData = img:getData()
|
||||
local imgNormalData = love.image.newImageData(img:getWidth(), img:getHeight())
|
||||
local color
|
||||
|
||||
if mode == "top" then
|
||||
color = {127, 127, 255}
|
||||
elseif mode == "front" then
|
||||
color = {127, 0, 127}
|
||||
elseif mode == "back" then
|
||||
color = {127, 255, 127}
|
||||
elseif mode == "left" then
|
||||
color = {31, 0, 223}
|
||||
elseif mode == "right" then
|
||||
color = {223, 0, 127}
|
||||
end
|
||||
|
||||
for i = 0, self.imgHeight - 1 do
|
||||
for k = 0, self.imgWidth - 1 do
|
||||
local r, g, b, a = imgData:getPixel(k, i)
|
||||
if a > 0 then
|
||||
imgNormalData:setPixel(k, i, color[1], color[2], color[3], 255)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return love.graphics.newImage(imgNormalData)
|
||||
end
|
||||
|
||||
function normal_map.generateGradient(img, horizontalGradient, verticalGradient)
|
||||
horizontalGradient = horizontalGradient or "gradient"
|
||||
verticalGradient = verticalGradient or horizontalGradient
|
||||
|
||||
local imgData = img:getData()
|
||||
local imgWidth, imgHeight = img:getWidth(), img:getHeight()
|
||||
local imgNormalData = love.image.newImageData(imgWidth, imgHeight)
|
||||
local dx = 255.0 / imgWidth
|
||||
local dy = 255.0 / imgHeight
|
||||
local nx
|
||||
local ny
|
||||
local nz
|
||||
|
||||
for i = 0, imgWidth - 1 do
|
||||
for k = 0, imgHeight - 1 do
|
||||
local r, g, b, a = imgData:getPixel(i, k)
|
||||
if a > 0 then
|
||||
if horizontalGradient == "gradient" then
|
||||
nx = i * dx
|
||||
elseif horizontalGradient == "inverse" then
|
||||
nx = 255 - i * dx
|
||||
else
|
||||
nx = 127
|
||||
end
|
||||
|
||||
if verticalGradient == "gradient" then
|
||||
ny = 127 - k * dy * 0.5
|
||||
nz = 255 - k * dy * 0.5
|
||||
elseif verticalGradient == "inverse" then
|
||||
ny = 127 + k * dy * 0.5
|
||||
nz = 127 - k * dy * 0.25
|
||||
else
|
||||
ny = 255
|
||||
nz = 127
|
||||
end
|
||||
|
||||
imgNormalData:setPixel(i, k, nx, ny, nz, 255)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return love.graphics.newImage(imgNormalData)
|
||||
end
|
||||
|
||||
return normal_map
|
Loading…
Reference in New Issue
Block a user