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 _PACKAGE = (...):match("^(.+)[%./][^%./]+") or ""
|
||||||
local class = require(_PACKAGE.."/class")
|
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 vector = require(_PACKAGE..'/vector')
|
||||||
local shadowLength = 100000
|
local shadowLength = 100000
|
||||||
|
|
||||||
@ -299,83 +299,22 @@ end
|
|||||||
|
|
||||||
-- set height map
|
-- set height map
|
||||||
function body:setHeightMap(heightMap, strength)
|
function body:setHeightMap(heightMap, strength)
|
||||||
self:setNormalMap(height_map_conv.toNormalMap(heightMap, strength))
|
self:setNormalMap(normal_map.fromHeightMap(heightMap, strength))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- generate flat normal map
|
-- generate flat normal map
|
||||||
function body:generateNormalMapFlat(mode)
|
function body:generateNormalMapFlat(mode)
|
||||||
local imgData = self.img:getData()
|
self:setNormalMap(normal_map.generateFlat(self.img, mode))
|
||||||
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))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- generate faded normal map
|
-- generate faded normal map
|
||||||
function body:generateNormalMapGradient(horizontalGradient, verticalGradient)
|
function body:generateNormalMapGradient(horizontalGradient, verticalGradient)
|
||||||
local imgData = self.img:getData()
|
self:setNormalMap(normal_map.generateGradient(self.img, horizontalGradient, verticalGradient))
|
||||||
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))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- generate normal map
|
-- generate normal map
|
||||||
function body:generateNormalMap(strength)
|
function body:generateNormalMap(strength)
|
||||||
self:setNormalMap(height_map_conv.toNormalMap(self.img, strength))
|
self:setNormalMap(normal_map.fromHeightMap(self.img, strength))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- set material
|
-- 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 class = require(_PACKAGE..'/class')
|
||||||
local Light = require(_PACKAGE..'/light')
|
local Light = require(_PACKAGE..'/light')
|
||||||
local Body = require(_PACKAGE..'/body')
|
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()
|
local light_world = class()
|
||||||
|
|
||||||
@ -456,7 +456,7 @@ end
|
|||||||
|
|
||||||
-- new refraction from height map
|
-- new refraction from height map
|
||||||
function light_world:newRefractionHeightMap(heightMap, x, y, strength)
|
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
|
self.isRefraction = true
|
||||||
return self.newRefraction(p, normal, x, y)
|
return self.newRefraction(p, normal, x, y)
|
||||||
end
|
end
|
||||||
@ -469,7 +469,7 @@ end
|
|||||||
|
|
||||||
-- new reflection from height map
|
-- new reflection from height map
|
||||||
function light_world:newReflectionHeightMap(heightMap, x, y, strength)
|
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
|
self.isReflection = true
|
||||||
return self.newReflection(p, normal, x, y)
|
return self.newReflection(p, normal, x, y)
|
||||||
end
|
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