Using LÖVE 11.4.
main.lua
Code: Select all
cmp = love.graphics.newShader("compute.cmp")
test = false
MAX = 10
SIZE = 16
function sendData(input,weight,bias,output) -- float[]
-- input = Image[y ]
-- weight = Image[x,y]
-- bias = Image[x ]
-- output = int (x )
local screen = love.graphics.getCanvas() -- for end output
local level = output
local weightMap = love.graphics.newCanvas(#weight,#weight[1],{format="rgba32f"}) -- x,y
local weightMaper = weightMap:newImageData()
local biasMap = love.graphics.newCanvas(#weight,1,{format="rgba32f"}) -- x
local biasMaper = biasMap:newImageData()
local intakeMap = love.graphics.newCanvas(#weight[1],1,{format="rgba32f"}) -- y
local intakeMaper = intakeMap:newImageData()
print("dimensions:(" .. #weight .. "|" .. #weight[1] .. ")")
print("dimension#:(" .. #bias .. "|" .. #input ..")")
if type(output) == "number" then
level = love.graphics.newCanvas(output,1,{format="rgba32f"})
end
local f = 0
for i=0,#bias - 1,1 do
f = bias [i + 1]
print("bias:(" .. i .. "):" .. f)
biasMaper:setPixel(i,0,f,f,f,1)
end
for i=0,#input - 1,1 do
f = input[i + 1]
print("input:(" .. i .. "):" .. f)
intakeMaper:setPixel(i,0,f,f,f,1)
end
for i=0,#weight - 1,1 do
for j=0,#weight[1] - 1,1 do
f = weight[i + 1][j + 1]
-- print("weights:(" .. i .. "|" .. j .. "):" .. f)
weightMaper:setPixel( i,j, f,f,f,1)
end
end
weightMap :release() -- free space
biasMap :release()
intakeMap :release()
weightMap = love.graphics.newImage(weightMaper) -- make Image
intakeMap = love.graphics.newImage(intakeMaper) -- for display and
biasMap = love.graphics.newImage(biasMaper ) -- data use
-- better display
weightMap :setFilter("nearest","nearest")
biasMap :setFilter("nearest","nearest")
intakeMap :setFilter("nearest","nearest")
-- sending data to Shader
cmp:send("height" ,#weight [1])
cmp:send("weights",weightMap )
cmp:send("intake" ,intakeMap )
cmp:send("bias" ,biasMap )
love.graphics.rectangle("fill", 0, 0, 500, 500)
love.graphics.draw(intakeMap , 0, 0, 0,SIZE,SIZE)
love.graphics.draw(biasMap ,#weight * SIZE + SIZE * 2,SIZE * 2,math.pi * 0.5,SIZE,SIZE)
love.graphics.draw(weightMap , 0,SIZE * 2, 0,SIZE,SIZE)
-- love.graphics.draw()
weightMap :release() -- free space
biasMap :release()
intakeMap :release()
weightMaper:release()
biasMaper :release()
intakeMaper:release()
-- use output buffer use Shader and compute!
love.graphics.setCanvas(level)
love.graphics.setShader(cmp)
love.graphics.rectangle("fill",0,0,#weight * 2,5)
love.graphics.setCanvas()
love.graphics.setShader()
-- data collector
local outp = {}
local data = level:newImageData()
local r,g,b,a
-- display purpeses
level:setFilter("nearest","nearest")
love.graphics.setCanvas(screen)
love.graphics.draw(level,#weight * SIZE + SIZE * 4,SIZE * 2,math.pi * 0.5,SIZE,SIZE) -- display output
-- collector
for i=0,#weight - 1,1 do
r,g,b,a = data:getPixel(i,0)
print("Data:(" .. i .. "):(" .. r .. "," .. g .. "," .. b .. "," .. a ..")")
outp[i + 1] = r
end
data:release() -- free
return outp
end
function smallLog(value)
for k,v in pairs(value) do
print(k .. "\t|" .. v)
end
end
function love.load()
-- setupDisplay-buffer
screen = love.graphics.newCanvas(800,500)
-- no Crash?
cmp:send("bias" ,love.graphics.newCanvas(1,1,{format="rgba32f"}))
cmp:send("intake" ,love.graphics.newCanvas(1,1,{format="rgba32f"}))
cmp:send("weights",love.graphics.newCanvas(1,1,{format="rgba32f"}))
cmp:send("height" ,0)
end
function love.update(dt)
end
function love.draw()
love.graphics.setCanvas(screen)
if test then
-- test
smallLog(
sendData({0,.4,.8,.0},{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}},{0,.2,.4,.8},4)
)
test = false
end
-- drawing things
love.graphics.setCanvas()
love.graphics.setColor(1,1,1)
love.graphics.draw(screen,0,0,0,1,1)
end
function love.keypressed( key, scancode, isrepeat )
if key == "space" then
test = true
end
end
function love.mousepressed( x, y, button, istouch, presses )
-- get Pixel value
local s = screen:newImageData()
print(s:getPixel(x,y))
s:release()
end
compute.cmp
Code: Select all
// uniform vec2 size;
// #define BUFFER_SIZE 100
uniform int height = 0;
uniform Image bias;
// x output
uniform Image intake;
// y input
uniform Image weights;
// x is output y is input
// x + M * y
/*layout(std430,binding = 1) buffer moin
{};/**/
float activation(float value){
return 1 / (1 + exp(-value));
}
vec3 activation(vec3 value){
return 1 / (1 + exp(-value));
}
vec4 effect( vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords ){
// x is for the output array
// y is for the input array
int x = int(floor(screen_coords.x));
int y = 0;
// vec3 col = bias[x].rgb;
// for(;y < height;y++){
// col += Texel(intake,vec2(y,0)).rgb * Texel(weights,vec2(x,y)).rgb;
// }
// return vec4(activation(col),1);
float col = Texel(bias,vec2(x,0)).r;
for(;y < height;y++){
col += Texel(intake,vec2(y,0)).r * Texel(weights,vec2(x,y)).r;
}
return vec4(
activation(col),
Texel(intake,vec2(x,0)).r,
Texel(bias,vec2(x,0)).r,
1);
}
On the CPU side the textures are normal and in the Shader x is diffrent.
If there are any questions, let me know, and if I make "bad" Code let me know.