everything I could before the deadline
This commit is contained in:
parent
1ddffb71e4
commit
3f65959321
|
@ -33,9 +33,12 @@ IT WON'T BE LONG NOW, BEFORE WE GO TO OUR REWARD.
|
||||||
|
|
||||||
TETÉLESTAI
|
TETÉLESTAI
|
||||||
]],
|
]],
|
||||||
phoneRing = "THE PHONE RINGS IMPATIENTLY",
|
phoneRing = [[THE RED CONTEMPRA PHONE,
|
||||||
|
THE KING'S INCORPOREAL FORM,
|
||||||
|
RINGS IMPATIENTLY.]],
|
||||||
|
ringBell = "[%s]: RING BELLS",
|
||||||
phonePickup = "[%s]: PICK UP", --use key
|
phonePickup = "[%s]: PICK UP", --use key
|
||||||
phoneRedial = "[%s]: *69", --use key
|
phoneRedial = "[%s]: *69", --use key
|
||||||
phoneClue = "🔔🔔🔔🔔🔔🔔🔔",
|
phoneClue = [[ZIMINIAR WILL BARGAIN. PLAY THIS TUNE TO ACCEPT.]],
|
||||||
phoneWin = "WHAT IS WANTED",
|
phoneWin = "WHAT IS WANTED",
|
||||||
}
|
}
|
|
@ -9,11 +9,29 @@ local light = {}
|
||||||
light[1], light[2], light[3] = normal( 1.0, 1.0, 0.0 ) --direction TO the light btw
|
light[1], light[2], light[3] = normal( 1.0, 1.0, 0.0 ) --direction TO the light btw
|
||||||
light.target = 1
|
light.target = 1
|
||||||
|
|
||||||
|
local targets = {}
|
||||||
local c, s, p = math.cos, math.sin, 2*math.pi
|
local c, s, p = math.cos, math.sin, 2*math.pi
|
||||||
|
do
|
||||||
|
local c, s = c( p * 2 / 7 ), s( p * 2 / 7 )
|
||||||
|
local x, y, z = 1, 1, 0
|
||||||
|
for i = 1, 7 do
|
||||||
|
x, z = c*x-z*s,s*x+z*c
|
||||||
|
y = 1 + 0.5 * s
|
||||||
|
targets[i] = { x, y, z }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function light.setTarget( i )
|
function light.setTarget( i )
|
||||||
light.target = light.target + 1
|
light.target = i
|
||||||
i = i - 1
|
end
|
||||||
light[1], light[2], light[3] = normal( c(i*p/7), 1, s(i*p/7) )
|
|
||||||
|
function light.update( enteringCircle )
|
||||||
|
if enteringCircle then light.setTarget( enteringCircle ) end
|
||||||
|
if not light.target then return end
|
||||||
|
for i = 1, 3 do
|
||||||
|
light[i] = 0.999 * light[i] + 0.001 * targets[ light.target ][i]
|
||||||
|
end
|
||||||
|
light[1], light[2], light[3] = normal( light[1], light[2], light[3] )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,29 +22,38 @@ function t.start()
|
||||||
stencil = false,
|
stencil = false,
|
||||||
depth = true,
|
depth = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
-- water = require( "models.water" )
|
-- water = require( "models.water" )
|
||||||
sky = require( "models.sky" )
|
sky = require( "models.sky" )
|
||||||
bell = require( "models.bell" )
|
bell = require( "models.bell" )
|
||||||
|
t.bell = bell
|
||||||
contempra = require( "models.contempra" )
|
contempra = require( "models.contempra" )
|
||||||
|
t.phone = contempra
|
||||||
|
t.phone.ring()
|
||||||
terrain = require( "models.terrain" )
|
terrain = require( "models.terrain" )
|
||||||
spike = require( "models.spike" )
|
spike = require( "models.spike" )
|
||||||
|
|
||||||
|
local n = 1
|
||||||
|
t.circles = {}
|
||||||
|
local function addCircles( obj )
|
||||||
|
for i, circle in ipairs( obj.circles ) do
|
||||||
|
t.circles[n] = circle
|
||||||
|
n=n+1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
addCircles( contempra )
|
||||||
|
addCircles( bell )
|
||||||
|
addCircles( spike )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function t.debug()
|
function t.debug()
|
||||||
isDebugging = true
|
isDebugging = true
|
||||||
end
|
end
|
||||||
|
|
||||||
local function matte( )
|
local text = love.graphics.newText( love.graphics.getFont() )
|
||||||
local list = drawLists.matte
|
|
||||||
local shader = shaders.matte
|
|
||||||
love.graphics.setShader( shader )
|
|
||||||
for mesh in pairs( list ) do
|
|
||||||
shader:send( "mdl", "column", meshes[mesh])
|
|
||||||
love.graphics.draw( mesh )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function t.draw( view, proj, x, z )
|
function t.draw( view, proj, x, z )
|
||||||
|
|
||||||
if isDebugging then
|
if isDebugging then
|
||||||
|
@ -52,13 +61,15 @@ function t.draw( view, proj, x, z )
|
||||||
|
|
||||||
|
|
||||||
love.graphics.push( "all" )
|
love.graphics.push( "all" )
|
||||||
|
|
||||||
|
love.graphics.setColor( 1,1,1,1 )
|
||||||
love.graphics.setScissor( 0, 0, love.graphics.getDimensions() )
|
love.graphics.setScissor( 0, 0, love.graphics.getDimensions() )
|
||||||
love.graphics.setCanvas( canvas )
|
love.graphics.setCanvas( canvas )
|
||||||
love.graphics.clear()
|
love.graphics.clear()
|
||||||
love.graphics.setDepthMode( "less", true )
|
love.graphics.setDepthMode( "less", true )
|
||||||
love.graphics.replaceTransform( tf )
|
love.graphics.replaceTransform( tf )
|
||||||
love.graphics.setMeshCullMode( "back" )
|
love.graphics.setMeshCullMode( "back" )
|
||||||
|
|
||||||
sky.draw( view, proj, light )
|
sky.draw( view, proj, light )
|
||||||
terrain.draw( view, proj, light )
|
terrain.draw( view, proj, light )
|
||||||
bell.draw( view, proj, light )
|
bell.draw( view, proj, light )
|
||||||
|
@ -70,24 +81,37 @@ function t.draw( view, proj, x, z )
|
||||||
love.graphics.setColor( 1, 1, 1, 1 )
|
love.graphics.setColor( 1, 1, 1, 1 )
|
||||||
love.graphics.draw( canvas[1] )
|
love.graphics.draw( canvas[1] )
|
||||||
|
|
||||||
if isDebugging then
|
|
||||||
isDebugging = false
|
if t.msg then
|
||||||
io.flush()
|
text:set( t.msg )
|
||||||
|
text:setf( t.msg, text:getWidth(), "center" )
|
||||||
|
end
|
||||||
|
local textx = 0.5 * (love.graphics.getWidth() - text:getWidth())
|
||||||
|
local w = text:getWidth()
|
||||||
|
if w > 0 then
|
||||||
|
love.graphics.setColor( 0,0,0,0.9 )
|
||||||
|
love.graphics.rectangle( "fill", textx - 10, 0, w + 20, text:getHeight() + 20 )
|
||||||
|
love.graphics.setColor( 1,0,0,1 )
|
||||||
|
love.graphics.draw( text, textx, 10 )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function t.update( player )
|
function t.update( player )
|
||||||
|
|
||||||
|
local msg
|
||||||
|
light.update( player.enteringCircle )
|
||||||
|
|
||||||
|
msg = bell.update( player.enteringCircle, player.leavingCircle, player.x, player.z )
|
||||||
|
local phoneMsg = contempra.update( player )
|
||||||
|
msg = msg or phoneMsg
|
||||||
|
t.msg = msg or ""
|
||||||
end
|
end
|
||||||
|
|
||||||
function t.transposeBells( i, j )
|
function t.transposeBells( i, j )
|
||||||
return bell.transpose( i, j )
|
return bell.transpose( i, j )
|
||||||
end
|
end
|
||||||
|
|
||||||
function t.targetLight( i )
|
|
||||||
return light.setTarget( i )
|
|
||||||
end
|
|
||||||
|
|
||||||
function t.pickupPhone()
|
function t.pickupPhone()
|
||||||
return contempra.pickup()
|
return contempra.pickup()
|
||||||
end
|
end
|
||||||
|
@ -96,4 +120,8 @@ function t.ring( idx )
|
||||||
return bell.ring( idx )
|
return bell.ring( idx )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function t.ringAll( i )
|
||||||
|
return bell.ringAll( i )
|
||||||
|
end
|
||||||
|
|
||||||
return t
|
return t
|
|
@ -3,6 +3,7 @@ local love = assert( love )
|
||||||
local lg = assert( love.graphics )
|
local lg = assert( love.graphics )
|
||||||
local math = math
|
local math = math
|
||||||
local mat = require( "mat4" )
|
local mat = require( "mat4" )
|
||||||
|
local strings = require( "i18n" )
|
||||||
|
|
||||||
|
|
||||||
local attributeNames = {
|
local attributeNames = {
|
||||||
|
@ -107,19 +108,33 @@ local bellMesh = lgMesh( asset.meshes[1].primitives[1] )
|
||||||
-- scale, x, z, colorparam
|
-- scale, x, z, colorparam
|
||||||
local bells = {}
|
local bells = {}
|
||||||
local bellInstanceMesh
|
local bellInstanceMesh
|
||||||
local ringSource = love.audio.newSource( "sfx/bellC2.ogg", "static" )
|
local rings = { poly = false }
|
||||||
|
do
|
||||||
|
rings[true] = love.audio.newSource( "sfx/bellC2.ogg", "static" )
|
||||||
|
rings[false] = love.audio.newSource( "sfx/bellC2.ogg", "static" )
|
||||||
|
end
|
||||||
|
rings[true]:setVolume( 0.1 )
|
||||||
|
rings[false]:setVolume( 0.1 )
|
||||||
|
|
||||||
|
local function getPitch( size )
|
||||||
|
return 5.0 / size
|
||||||
|
end
|
||||||
|
|
||||||
do
|
do
|
||||||
local c, s = math.cos( 2*math.pi / 7 ), -math.sin( 2*math.pi / 7 )
|
local c, s = math.cos( 2*math.pi / 7 ), -math.sin( 2*math.pi / 7 )
|
||||||
local x, z = math.cos(math.pi/7), -math.sin( math.pi/7 )
|
local x, z = math.cos(math.pi/7), -math.sin( math.pi/7 )
|
||||||
local pitches = { 0, 5, 8, 12, 10, 22, 25 }
|
local pitches = { 0, 5, 8, 10, 12, 22, 26 }
|
||||||
for i = 1, #pitches do
|
for i = 1, #pitches do
|
||||||
pitches[i] = math.pow( 2.0, pitches[i] / 12.0 )
|
pitches[i] = math.pow( 2.0, pitches[i] / 12.0 )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local bellMt = { __index = { get = function(t)
|
||||||
|
return t[2], t[3], t[1]
|
||||||
|
end }}
|
||||||
|
|
||||||
local r = 20
|
local r = 20
|
||||||
for i = 1, 7 do
|
for i = 1, 7 do
|
||||||
bells[i] = { 5.0 / pitches[i], r * x, r * z, (i-1)/6 }
|
bells[i] = setmetatable({ 5.0 / pitches[i], r * x, r * z, (i-1)/6 }, bellMt )
|
||||||
x, z = c*x+s*z, c*z-s*x
|
x, z = c*x+s*z, c*z-s*x
|
||||||
end
|
end
|
||||||
bellInstanceMesh = lg.newMesh({{"bellInstance","float",4}}, bells, nil, "static" )
|
bellInstanceMesh = lg.newMesh({{"bellInstance","float",4}}, bells, nil, "static" )
|
||||||
|
@ -131,6 +146,8 @@ local t = {}
|
||||||
|
|
||||||
t.shader = require( "shaders.bell" )
|
t.shader = require( "shaders.bell" )
|
||||||
t.mesh = bellMesh
|
t.mesh = bellMesh
|
||||||
|
t.timer = 0
|
||||||
|
|
||||||
|
|
||||||
function t.draw( view, proj, light )
|
function t.draw( view, proj, light )
|
||||||
local s = t.shader
|
local s = t.shader
|
||||||
|
@ -142,19 +159,111 @@ function t.draw( view, proj, light )
|
||||||
lg.drawInstanced( t.mesh, 7 )
|
lg.drawInstanced( t.mesh, 7 )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local queue = {}
|
||||||
|
function t.queue( i, ticks )
|
||||||
|
local time = ticks + (queue.time or t.timer)
|
||||||
|
local q = queue
|
||||||
|
while q.next do
|
||||||
|
q = q.next
|
||||||
|
end
|
||||||
|
q.time = time
|
||||||
|
q.bell = i
|
||||||
|
q.next = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function t.transpose( i, j )
|
function t.transpose( i, j )
|
||||||
print( "transposing:", i, j )
|
|
||||||
io.flush()
|
io.flush()
|
||||||
bells[i][1], bells[j][1] = bells[j][1], bells[i][1]
|
bells[i][1], bells[j][1] = bells[j][1], bells[i][1]
|
||||||
bellInstanceMesh:setVertices( bells )
|
bellInstanceMesh:setVertices( bells )
|
||||||
bellMesh:attachAttribute( "bellInstance", bellInstanceMesh,
|
bellMesh:attachAttribute( "bellInstance", bellInstanceMesh,
|
||||||
"perinstance" )
|
"perinstance" )
|
||||||
|
t.ring( i )
|
||||||
|
t.queue( j, 100 )
|
||||||
end
|
end
|
||||||
|
|
||||||
function t.ring( i )
|
function t.ring( i )
|
||||||
ringSource:stop()
|
local b = rings.poly
|
||||||
ringSource:setPitch( bells[i][1] )
|
b = not( b )
|
||||||
ringSource:play()
|
rings.poly = b
|
||||||
|
rings[b]:stop()
|
||||||
|
rings[b]:setPitch( getPitch( bells[i][1] ) )
|
||||||
|
rings[b]:setPosition( bells[i][2], 0, bells[i][3] )
|
||||||
|
rings[b]:play()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function t.ringAll( i )
|
||||||
|
local b = i
|
||||||
|
for j = 0, 6 do
|
||||||
|
t.queue( b, j * 100 )
|
||||||
|
b = b + 1
|
||||||
|
if b > 7 then b = 1 end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function t.nearBell(x, z)
|
||||||
|
for i, bell in ipairs( bells ) do
|
||||||
|
local bx, bz, br = bell:get()
|
||||||
|
if (x-bx)*(x-bx)+(z-bz)*(z-bz) < 2 * (br*br) then
|
||||||
|
return i
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
t.solution = {
|
||||||
|
bells[7],
|
||||||
|
bells[6],
|
||||||
|
bells[4],
|
||||||
|
bells[5],
|
||||||
|
bells[3],
|
||||||
|
bells[2],
|
||||||
|
bells[1]
|
||||||
|
}
|
||||||
|
function t.checkWin( i )
|
||||||
|
local idx = i
|
||||||
|
for j = 1, 7 do
|
||||||
|
idx = idx + 1
|
||||||
|
if idx > 7 then idx = 1 end
|
||||||
|
local bell = t.solution[j]
|
||||||
|
if bell ~= bells[idx] then return false end
|
||||||
|
end
|
||||||
|
t.winTime = t.timer + 700
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local trans = {}
|
||||||
|
function t.update( enteringCircle, leavingCircle, x, z )
|
||||||
|
t.timer = t.timer + 1
|
||||||
|
|
||||||
|
if t.winTime and t.timer > t.winTime then
|
||||||
|
local strings = require( "i18n" )
|
||||||
|
local slideshow = require( "scenes.slideshow" )
|
||||||
|
return slideshow.play( strings.win, love.event.quit, "tex/win.jpg", "sfx/mus.ogg" )
|
||||||
|
end
|
||||||
|
|
||||||
|
if queue.time and (queue.time <= t.timer) then
|
||||||
|
t.ring( queue.bell )
|
||||||
|
queue = queue.next or {}
|
||||||
|
end
|
||||||
|
|
||||||
|
if enteringCircle then trans[1] = enteringCircle end
|
||||||
|
if leavingCircle then trans[2] = leavingCircle end
|
||||||
|
if trans[1] and trans[2] then
|
||||||
|
t.transpose( trans[1], trans[2] )
|
||||||
|
trans[1], trans[2] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if t.winTime then
|
||||||
|
return strings.phoneWin
|
||||||
|
end
|
||||||
|
|
||||||
|
t.near = t.nearBell( x, z )
|
||||||
|
if t.near then
|
||||||
|
return strings.ringBell:format(strings.keyUse)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
t.circles = bells
|
||||||
|
t.near = false
|
||||||
|
|
||||||
return t
|
return t
|
|
@ -2,6 +2,7 @@ local dkjson = require( "lib.dkjson" )
|
||||||
local love = assert( love )
|
local love = assert( love )
|
||||||
local shader = require( "shaders.flat" )
|
local shader = require( "shaders.flat" )
|
||||||
local mat = require( "mat4" )
|
local mat = require( "mat4" )
|
||||||
|
local strings = require( "i18n" )
|
||||||
|
|
||||||
local attributeNames = {
|
local attributeNames = {
|
||||||
POSITION = "VertexPosition",
|
POSITION = "VertexPosition",
|
||||||
|
@ -127,16 +128,16 @@ end
|
||||||
function obj.draw( view, proj, light, x, z )
|
function obj.draw( view, proj, light, x, z )
|
||||||
if veilAlpha( x, z ) > 0.0 then
|
if veilAlpha( x, z ) > 0.0 then
|
||||||
love.graphics.setDepthMode( "less", false )
|
love.graphics.setDepthMode( "less", false )
|
||||||
local s = shaders.Veil
|
local s = shaders.Veil
|
||||||
love.graphics.setShader( s )
|
love.graphics.setShader( s )
|
||||||
s:send( "view", "column", view )
|
s:send( "view", "column", view )
|
||||||
s:send( "proj", "column", proj )
|
s:send( "proj", "column", proj )
|
||||||
love.graphics.setColor( 0, 0, 0, veilAlpha( x, z ) )
|
love.graphics.setColor( 0, 0, 0, veilAlpha( x, z ) )
|
||||||
love.graphics.draw( meshes.Veil )
|
love.graphics.draw( meshes.Veil )
|
||||||
love.graphics.setBlendMode( "alpha" )
|
love.graphics.setBlendMode( "alpha" )
|
||||||
love.graphics.setDepthMode( "less", true )
|
love.graphics.setDepthMode( "less", true )
|
||||||
end
|
end
|
||||||
|
|
||||||
shader:send( "view", "column", view )
|
shader:send( "view", "column", view )
|
||||||
shader:send( "proj", "column", proj )
|
shader:send( "proj", "column", proj )
|
||||||
shader:send( "light", light )
|
shader:send( "light", light )
|
||||||
|
@ -151,12 +152,56 @@ function obj.draw( view, proj, light, x, z )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function obj.update( player )
|
local phoneRing = love.audio.newSource( "sfx/phoneRing.ogg", "static" )
|
||||||
|
local phoneMessage = love.audio.newSource( "sfx/phoneMessage.ogg", "static" )
|
||||||
|
phoneRing:setPosition( 0, 0, 0 )
|
||||||
|
phoneRing:setAirAbsorption( 10 )
|
||||||
|
phoneRing:setLooping( true )
|
||||||
|
phoneRing:setVolume( 0.05 )
|
||||||
|
phoneRing:setPitch( 0.9 )
|
||||||
|
if love.audio.isEffectsSupported() then
|
||||||
|
love.audio.setEffect( "phonervb", {type = "reverb", volume = 1, decaytime = 20, density = 0.5, gain = 0.8 })
|
||||||
|
phoneRing:setEffect( "phonervb" )
|
||||||
end
|
end
|
||||||
|
phoneMessage:setPosition( 0,0,0 )
|
||||||
|
phoneMessage:setVolume( 0.2 )
|
||||||
|
phoneMessage:stop()
|
||||||
|
|
||||||
|
function obj.update( player )
|
||||||
|
obj.pickedUp = phoneMessage:isPlaying()
|
||||||
|
obj.canPickup = (player.r < 2) and not( obj.pickedUp )
|
||||||
|
if player.r > 2 then
|
||||||
|
return obj.isRinging and strings.phoneRing
|
||||||
|
elseif obj.pickedUp then
|
||||||
|
return strings.phoneClue
|
||||||
|
else
|
||||||
|
return obj.canPickup and strings.phonePickup:format( strings.keyUse )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function obj.pickup( )
|
function obj.pickup( )
|
||||||
obj.pickedUp = true
|
obj.pickedUp = true
|
||||||
|
obj.isRinging = false
|
||||||
|
phoneMessage:play()
|
||||||
|
phoneRing:stop()
|
||||||
|
end
|
||||||
|
|
||||||
|
function obj.ring()
|
||||||
|
obj.isRinging = true
|
||||||
|
phoneRing:play()
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
obj.circles = {}
|
||||||
|
local circleMT = {__index = { get = function(t) return t.x, t.z, t.r end } }
|
||||||
|
local x, z = 1, 0
|
||||||
|
local c, s = math.cos( 2 * math.pi / 7 ), math.sin( 2 * math.pi / 7 )
|
||||||
|
for i = 1, 7 do
|
||||||
|
obj.circles[i] = setmetatable( {x = 10 * x, z = 10 * z, r = 1} , circleMT )
|
||||||
|
x, z = x*c+s*z,-s*x+c*z
|
||||||
|
end
|
||||||
|
obj.circles[8] = setmetatable( {x = 0, z = 0, r = 1.5 }, circleMT )
|
||||||
end
|
end
|
||||||
|
|
||||||
return obj
|
return obj
|
|
@ -3,6 +3,7 @@ local math = math
|
||||||
local mat = require( "mat4" )
|
local mat = require( "mat4" )
|
||||||
local dkjson = require( "lib.dkjson" )
|
local dkjson = require( "lib.dkjson" )
|
||||||
local shader = require( "shaders.spike" )
|
local shader = require( "shaders.spike" )
|
||||||
|
local terrainHeight = require( "models.terrain" ).getHeight
|
||||||
|
|
||||||
local attributeNames = {
|
local attributeNames = {
|
||||||
POSITION = "VertexPosition",
|
POSITION = "VertexPosition",
|
||||||
|
@ -104,35 +105,36 @@ local spike = lgMesh( asset.meshes[1].primitives[1] )
|
||||||
spike:setTexture( love.graphics.newImage( "tex/rock.png", { mipmaps = true } ) )
|
spike:setTexture( love.graphics.newImage( "tex/rock.png", { mipmaps = true } ) )
|
||||||
|
|
||||||
local spikeCount = 4096
|
local spikeCount = 4096
|
||||||
|
local obj = {}
|
||||||
do
|
do
|
||||||
|
|
||||||
local function rad(x,z)
|
local function rad(x,z)
|
||||||
return x*x+z*z
|
return x*x+z*z
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local spikeMT = { __index = { get = function( t ) return t[1], t[3], 1 end }}
|
||||||
|
|
||||||
local spikes = {}
|
local spikes = {}
|
||||||
local inner, outer = 25, 100
|
obj.circles = spikes
|
||||||
|
local inner, outer = 35, 250
|
||||||
for n = 1, spikeCount do
|
for n = 1, spikeCount do
|
||||||
local r, a = math.sqrt( math.random() * (outer*outer-inner*inner)+outer*outer ), 2 * math.pi * math.random()
|
local r, a = math.sqrt( math.random() * (outer*outer-inner*inner)+inner*inner ), 2 * math.pi * math.random()
|
||||||
local x, z = r*math.cos(a),r*math.sin(a)
|
local x, z = r*math.cos(a),r*math.sin(a)
|
||||||
local h = 2 + 10 * math.random()
|
local h = 12 + 10 * math.random()
|
||||||
spikes[n] = { x, -1, z, h, 0 }
|
spikes[n] = setmetatable({ x, terrainHeight(x, z, -0.5), z, h }, spikeMT )
|
||||||
n=n+1
|
n=n+1
|
||||||
end
|
end
|
||||||
local spikeInstanceMesh = love.graphics.newMesh(
|
local spikeInstanceMesh = love.graphics.newMesh(
|
||||||
{{"spikeInstance", "float", 4},
|
{{"spikeInstance", "float", 4},
|
||||||
{"spikeOrientation", "float", 1 },
|
|
||||||
}, --vertexformat
|
}, --vertexformat
|
||||||
spikes,
|
spikes,
|
||||||
nil,
|
nil,
|
||||||
"static"
|
"static"
|
||||||
)
|
)
|
||||||
spike:attachAttribute( "spikeInstance", spikeInstanceMesh, "perinstance" )
|
spike:attachAttribute( "spikeInstance", spikeInstanceMesh, "perinstance" )
|
||||||
spike:attachAttribute( "spikeOrientation", spikeInstanceMesh, "perinstance" )
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local spikes = {}
|
function obj.draw( view, proj, light )
|
||||||
function spikes.draw( view, proj, light )
|
|
||||||
love.graphics.setColor( 1,1,1,1)
|
love.graphics.setColor( 1,1,1,1)
|
||||||
shader:send( "view", "column", view )
|
shader:send( "view", "column", view )
|
||||||
shader:send( "proj", "column", proj )
|
shader:send( "proj", "column", proj )
|
||||||
|
@ -142,4 +144,4 @@ function spikes.draw( view, proj, light )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
return spikes
|
return obj
|
|
@ -21,7 +21,7 @@ do
|
||||||
local ptr = ffi.cast( "float*", p )
|
local ptr = ffi.cast( "float*", p )
|
||||||
local i = 0
|
local i = 0
|
||||||
for x = 0, sideLength-1 do for y = 0, sideLength-1 do
|
for x = 0, sideLength-1 do for y = 0, sideLength-1 do
|
||||||
ptr[i],ptr[i+1] = x - sideLength / 2 ,y - sideLength / 2
|
ptr[i],ptr[i+1] = 4 * (x - sideLength / 2) , 4 * (y - sideLength / 2)
|
||||||
i=i+2
|
i=i+2
|
||||||
end end
|
end end
|
||||||
mesh:setVertices( vertices )
|
mesh:setVertices( vertices )
|
||||||
|
@ -45,13 +45,14 @@ do
|
||||||
end
|
end
|
||||||
|
|
||||||
local shader = love.graphics.newShader[[
|
local shader = love.graphics.newShader[[
|
||||||
#define fog vec4( 0.6, 0.6, 0.7, 1.0 )
|
#define fog vec4( 0.9, 0.9, 1.0, 1.0 )
|
||||||
#define fogHigh vec4( 1.0, 1.0, 0.9, 1.0 )
|
#define fogHigh vec4( 1.0, 1.0, 0.85, 1.0 )
|
||||||
#define fogFalloff 0.03
|
#define fogFalloff 0.03
|
||||||
varying vec2 uv;
|
varying vec2 uv;
|
||||||
varying vec3 world;
|
varying vec3 world;
|
||||||
varying vec3 normal;
|
varying vec3 normal;
|
||||||
varying float depth;
|
varying float depth;
|
||||||
|
varying float h;
|
||||||
#ifdef VERTEX
|
#ifdef VERTEX
|
||||||
uniform sampler2D height;
|
uniform sampler2D height;
|
||||||
uniform mat4 view;
|
uniform mat4 view;
|
||||||
|
@ -65,11 +66,12 @@ local shader = love.graphics.newShader[[
|
||||||
pos = pos.xzyw;
|
pos = pos.xzyw;
|
||||||
float y = Texel( height, pos.xz / 256.0 ).r - 0.5;
|
float y = Texel( height, pos.xz / 256.0 ).r - 0.5;
|
||||||
uv = 0.25 * (pos.xz + vec2(y, sin( y ) ));
|
uv = 0.25 * (pos.xz + vec2(y, sin( y ) ));
|
||||||
float r = dot( pos.xz, pos.xz );
|
float r = length( pos.xz );
|
||||||
pos.y = sigmoid( r / 50.0 - 20.0 ) * ( 1.0 + y ) * 0.05 * r / (sqrt( r ) + 1) - 0.01;
|
pos.y = sigmoid( r / 10.0 - 6.0 ) * ( 2.0 + y ) * 0.1 * (r*r) / (r + 1) - 0.01;
|
||||||
|
|
||||||
world = pos.xyz;
|
world = pos.xyz;
|
||||||
vec4 eye = view*pos;
|
vec4 eye = view*pos;
|
||||||
|
h = clamp( world.y, 0.0, 1.0 );
|
||||||
depth = clamp( -eye.z * fogFalloff, 0.0, 1.0 );
|
depth = clamp( -eye.z * fogFalloff, 0.0, 1.0 );
|
||||||
|
|
||||||
normal = vec3( 0.0, 1.0, 0.0 ) + 1.5 * pos.y ;
|
normal = vec3( 0.0, 1.0, 0.0 ) + 1.5 * pos.y ;
|
||||||
|
@ -87,7 +89,7 @@ local shader = love.graphics.newShader[[
|
||||||
vec3 norm = normalize( normal );
|
vec3 norm = normalize( normal );
|
||||||
vec3 toLight = normalize( light - world.xyz );
|
vec3 toLight = normalize( light - world.xyz );
|
||||||
float diff = max( dot( norm, light ), 0.1 );
|
float diff = max( dot( norm, light ), 0.1 );
|
||||||
vec4 d = vec4( diff * albedo, 1.0 );
|
vec4 d = vec4( diff * albedo * h, 1.0 );
|
||||||
|
|
||||||
return mix( color * d , fog, depth );
|
return mix( color * d , fog, depth );
|
||||||
}
|
}
|
||||||
|
@ -109,8 +111,21 @@ local function worldSpaceToTexCoord( x, z )
|
||||||
return x, z
|
return x, z
|
||||||
end
|
end
|
||||||
|
|
||||||
function obj.getHeight( x, z )
|
local function sigmoid( x )
|
||||||
return heightMap:getPixel( worldSpaceToTexCoord(x,z) )[1]
|
return 1.0 / ( 1.0 + math.exp( -x ) )
|
||||||
|
end
|
||||||
|
|
||||||
|
local function sqDistance( x, y, a, b )
|
||||||
|
return (x-a)*(x-a)+(y-b)*(y-b)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function getWorldSpace( x, z )
|
||||||
|
return x / 4 + sideLength / 2 , z / 4 + sideLength / 2
|
||||||
|
end
|
||||||
|
|
||||||
|
function obj.getHeight( x, z, y )
|
||||||
|
local r = math.sqrt( sqDistance( x, z, 0, 0 ) )
|
||||||
|
return sigmoid( r / 10.0 - 6.0 ) * ( 2.0 + y ) * 0.1 * (r*r) / (r + 1) - 0.01
|
||||||
end
|
end
|
||||||
|
|
||||||
function obj.draw( view, proj, light )
|
function obj.draw( view, proj, light )
|
||||||
|
|
131
src/player.lua
131
src/player.lua
|
@ -3,6 +3,8 @@ local math = assert( math )
|
||||||
local mat = require( "mat4" )
|
local mat = require( "mat4" )
|
||||||
local sfx = require( "sfx" )
|
local sfx = require( "sfx" )
|
||||||
|
|
||||||
|
local getHeight = require( "models.terrain" ).getHeight
|
||||||
|
|
||||||
local maxPitch = math.pi / 2
|
local maxPitch = math.pi / 2
|
||||||
|
|
||||||
local function logistic( x )
|
local function logistic( x )
|
||||||
|
@ -12,10 +14,11 @@ end
|
||||||
local player = {
|
local player = {
|
||||||
turnRate = 0,
|
turnRate = 0,
|
||||||
rate = 0.01, --tick rate
|
rate = 0.01, --tick rate
|
||||||
speed = 2, --movement speed m/s
|
speed = 3, --movement speed m/s
|
||||||
x = 0,
|
x = 35,
|
||||||
y = 1.5,
|
y = 1.5,
|
||||||
z = 3,
|
z = 75,
|
||||||
|
r = 4,
|
||||||
vx = 0,
|
vx = 0,
|
||||||
vz = 0,
|
vz = 0,
|
||||||
yaw = 1.5,
|
yaw = 1.5,
|
||||||
|
@ -25,7 +28,7 @@ local player = {
|
||||||
view = mat.id(),
|
view = mat.id(),
|
||||||
proj = mat.id(),
|
proj = mat.id(),
|
||||||
footstepTimer = 0,
|
footstepTimer = 0,
|
||||||
footstepStride = 0.5 --seconds before taking a step
|
footstepStride = 0.8 --seconds before taking a step
|
||||||
}
|
}
|
||||||
|
|
||||||
function player:updateDesiredDirection( forward, left, right, back )
|
function player:updateDesiredDirection( forward, left, right, back )
|
||||||
|
@ -38,10 +41,8 @@ function player:updateDesiredDirection( forward, left, right, back )
|
||||||
self.desx, self.desz = x * c + z * s, -x * s + z * c
|
self.desx, self.desz = x * c + z * s, -x * s + z * c
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function player:setFOV( fov )
|
function player:setFOV( fov )
|
||||||
self.proj = mat.projection( 0.05, 100, math.rad( fov or 90 ) )
|
self.proj = mat.projection( 0.05, 500, math.rad( fov or 90 ) )
|
||||||
end
|
end
|
||||||
|
|
||||||
function player:setTurnRate( sensitivity )
|
function player:setTurnRate( sensitivity )
|
||||||
|
@ -51,7 +52,7 @@ end
|
||||||
function player:turn( dx, dy )
|
function player:turn( dx, dy )
|
||||||
self.yaw = self.yaw + dx * self.turnRate
|
self.yaw = self.yaw + dx * self.turnRate
|
||||||
self.pitch = math.min( maxPitch, math.max( -maxPitch,
|
self.pitch = math.min( maxPitch, math.max( -maxPitch,
|
||||||
self.pitch + dy * self.turnRate ))
|
self.pitch + dy * self.turnRate ))
|
||||||
end
|
end
|
||||||
|
|
||||||
local function sqDistance( x, y, a, b )
|
local function sqDistance( x, y, a, b )
|
||||||
|
@ -71,39 +72,83 @@ local function distanceToSegment( ix, iy, fx, fy, cx, cy )
|
||||||
return sqDistance( cx, cy, u*ix+t*fx,u*iy+t*fy )
|
return sqDistance( cx, cy, u*ix+t*fx,u*iy+t*fy )
|
||||||
end
|
end
|
||||||
|
|
||||||
--collide in 2D on the xz-plane.
|
local function inCircle( x, y, cx, cy, cr )
|
||||||
local function collide( ix, iz, fx, fz, circles, lines )
|
return sqDistance( x, y, cx, cy ) < (cr * cr)
|
||||||
local x, z = ix, iz
|
|
||||||
for _, circle in pairs( circles ) do
|
|
||||||
if distanceToSegment( ix, iz, fx, fz, circle.x, circle.z ) <
|
|
||||||
circle.r * circle.r then
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for _, line in pairs( lines ) do
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
return x, z, fx, fz
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function player:update()
|
--collide in 2D on the xz-plane.
|
||||||
self.vx = self.desx * self.speed
|
local function collide( ix, iz, fx, fz, circles )
|
||||||
self.vz = self.desz * self.speed
|
local x, z = ix, iz
|
||||||
|
for _, circle in pairs( circles ) do
|
||||||
self.x = self.x + self.vx * self.rate
|
local cx, cz, cr = circle:get()
|
||||||
self.z = self.z + self.vz * self.rate
|
if inCircle( fx, fz, cx, cz, cr ) then
|
||||||
|
fx, fz = x, z
|
||||||
|
io.flush()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local function getSection( x, z )
|
||||||
|
local s = math.atan2( z, x )
|
||||||
|
s = ( s < 0 ) and s + 2.0 * math.pi or s
|
||||||
|
s = 0.5 * s / math.pi
|
||||||
|
local section = 1 + math.modf( s * 7, 1 )
|
||||||
|
print( section )
|
||||||
|
io.flush()
|
||||||
|
return section
|
||||||
|
end
|
||||||
|
|
||||||
|
local function enteringRing( x, z, fx, fz )
|
||||||
|
local fd = sqDistance( fx, fz, 0, 0 )
|
||||||
|
if fd < 90 and (sqDistance( x, z, 0, 0 ) > 90) then
|
||||||
|
return getSection( x, z )
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local function leavingRing( x, z, fx, fz )
|
||||||
|
local fd = sqDistance( fx, fz, 0, 0 )
|
||||||
|
if fd > 50 and (sqDistance( x, z, 0, 0 ) < 50) then
|
||||||
|
return getSection( x, z )
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function player:update( circles )
|
||||||
|
|
||||||
|
self.vx = 0.1 * self.desx * self.speed + 0.9 * self.vx
|
||||||
|
self.vz = 0.1 * self.desz * self.speed + 0.9 * self.vz
|
||||||
|
|
||||||
|
|
||||||
|
local fx, fz = self.x + self.vx * self.rate, self.z + self.vz * self.rate
|
||||||
|
|
||||||
|
self.enteringCircle, self.leavingCircle = enteringRing( self.x, self.z, fx, fz ), leavingRing( self.x, self.z, fx, fz )
|
||||||
|
|
||||||
|
if collide( self.x, self.z, fx, fz, circles ) then
|
||||||
|
self.vx, self.vz = -2.0 * self.vx, -2.0 * self.vz
|
||||||
|
else
|
||||||
|
self.x, self.z = fx, fz
|
||||||
|
end
|
||||||
|
local r = math.sqrt( sqDistance( self.x, self.z, 0, 0 ) )
|
||||||
|
self.r = r
|
||||||
|
self.y = 1.5 + getHeight( self.x, self.z, 0.2 )
|
||||||
|
--1.5 + logistic( -( r / 10.0 - 6.0 ) ) * ( 1.0 + 0 ) * 0.1 * (r*r) / (r + 1) - 0.01
|
||||||
|
|
||||||
self.view = mat.view( self.x, self.y, self.z, self.yaw, self.pitch )
|
self.view = mat.view( self.x, self.y, self.z, self.yaw, self.pitch )
|
||||||
|
|
||||||
self:footstep()
|
self:footstep()
|
||||||
|
|
||||||
|
sfx.setPosition( self.x, self.y, self.z )
|
||||||
|
sfx.setOrientation( self.yaw )
|
||||||
end
|
end
|
||||||
|
|
||||||
function player:isMoving()
|
function player:isMoving()
|
||||||
return
|
return
|
||||||
self.vx > 0.01 or self.vz > 0.01 or
|
self.vx > 0.1 or self.vz > 0.1 or
|
||||||
self.vx < 0.01 or self.vz < 0.01
|
self.vx <-0.1 or self.vz < -0.1
|
||||||
end
|
end
|
||||||
|
|
||||||
function player:footstep()
|
function player:footstep()
|
||||||
|
@ -126,16 +171,16 @@ function player:tostring()
|
||||||
pitch:%3.2f
|
pitch:%3.2f
|
||||||
desx: %3.2f
|
desx: %3.2f
|
||||||
desz: %3.2f
|
desz: %3.2f
|
||||||
]]):format(
|
]]):format(
|
||||||
player.x,
|
player.x,
|
||||||
player.y,
|
player.y,
|
||||||
player.z,
|
player.z,
|
||||||
player.vx,
|
player.vx,
|
||||||
player.vz,
|
player.vz,
|
||||||
player.yaw,
|
player.yaw,
|
||||||
player.pitch,
|
player.pitch,
|
||||||
player.desx,
|
player.desx,
|
||||||
player.desz
|
player.desz
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ local mat = require( "mat4" )
|
||||||
local t = {}
|
local t = {}
|
||||||
|
|
||||||
local frameStart = love.timer.getTime()
|
local frameStart = love.timer.getTime()
|
||||||
|
|
||||||
local rockTexture = love.graphics.newImage( "tex/rock.png", { mipmaps = true } )
|
local rockTexture = love.graphics.newImage( "tex/rock.png", { mipmaps = true } )
|
||||||
rockTexture:setWrap( "repeat", "repeat" )
|
rockTexture:setWrap( "repeat", "repeat" )
|
||||||
function t.play()
|
function t.play()
|
||||||
|
@ -15,12 +14,6 @@ function t.play()
|
||||||
player:setTurnRate( settings.mouseSensitivity.val )
|
player:setTurnRate( settings.mouseSensitivity.val )
|
||||||
player:setFOV( settings.FOV.val )
|
player:setFOV( settings.FOV.val )
|
||||||
world.start()
|
world.start()
|
||||||
|
|
||||||
--[[local spike = require( "models/spike" )
|
|
||||||
spike:setTexture( rockTexture )
|
|
||||||
renderer.add( spike )
|
|
||||||
renderer.update( spike, mat.TRS( 0.3, 12, 0.3, 0, 0, 0, 4, 0, 3) )]]
|
|
||||||
|
|
||||||
local scene = require( "scene" )
|
local scene = require( "scene" )
|
||||||
return scene.load( t )
|
return scene.load( t )
|
||||||
end
|
end
|
||||||
|
@ -28,15 +21,6 @@ end
|
||||||
function t.draw()
|
function t.draw()
|
||||||
|
|
||||||
world.draw( player.view, player.proj, player.x, player.z )
|
world.draw( player.view, player.proj, player.x, player.z )
|
||||||
|
|
||||||
local y = 0
|
|
||||||
for k, v in pairs(love.graphics.getStats()) do
|
|
||||||
love.graphics.print( k, 0, y )
|
|
||||||
love.graphics.print( v, 200, y )
|
|
||||||
y = y + 16
|
|
||||||
end
|
|
||||||
|
|
||||||
love.graphics.print( player:tostring(), 0, y )
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,10 +39,10 @@ function t.update( dt )
|
||||||
updateTimeRemaining = updateTimeRemaining + dt
|
updateTimeRemaining = updateTimeRemaining + dt
|
||||||
while updateTimeRemaining >= player.rate do
|
while updateTimeRemaining >= player.rate do
|
||||||
updateTimeRemaining = updateTimeRemaining - player.rate
|
updateTimeRemaining = updateTimeRemaining - player.rate
|
||||||
player:update()
|
player:update( world.circles )
|
||||||
|
world.update( player )
|
||||||
end
|
end
|
||||||
|
io.flush()
|
||||||
world.update( player )
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function t.mousepressed( x, y, button, isTouch, presses )
|
function t.mousepressed( x, y, button, isTouch, presses )
|
||||||
|
@ -72,24 +56,8 @@ function t.keypressed( key, code, isrepeat )
|
||||||
love.mouse.setVisible( true )
|
love.mouse.setVisible( true )
|
||||||
end
|
end
|
||||||
if code == settings.keyUse.val then
|
if code == settings.keyUse.val then
|
||||||
|
if world.bell.near then return world.bell.ringAll( world.bell.near ) end
|
||||||
end
|
if world.phone.canPickup then return world.phone.pickup() end
|
||||||
if code == "2" then
|
|
||||||
local strings = require( "i18n" )
|
|
||||||
local slideshow = require( "scenes.slideshow" )
|
|
||||||
return slideshow.play( strings.win, love.event.quit, "tex/win.jpg" )
|
|
||||||
end
|
|
||||||
if code == "3" then
|
|
||||||
return world.targetLight( math.random( 1, 7 ) )
|
|
||||||
end
|
|
||||||
if code == "4" then
|
|
||||||
return world.pickupPhone()
|
|
||||||
end
|
|
||||||
if code == "1" then
|
|
||||||
return world.transposeBells( 2, 7 )
|
|
||||||
end
|
|
||||||
if code == "5" then
|
|
||||||
return world.ring( 2 )
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
26
src/sfx.lua
26
src/sfx.lua
|
@ -1,6 +1,28 @@
|
||||||
|
local love = love
|
||||||
local sfx = {}
|
local sfx = {}
|
||||||
|
|
||||||
function sfx.playFootstep()
|
love.audio.setDistanceModel( "linear" )
|
||||||
--print( "step" )
|
|
||||||
|
local footsteps = {}
|
||||||
|
for i, file in pairs( love.filesystem.getDirectoryItems( "sfx/footsteps" ) ) do
|
||||||
|
footsteps[i] = love.audio.newSource( "sfx/footsteps/"..file, "static" )
|
||||||
|
footsteps[i]:setVolume( 0.02 )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local stepIdx = 1
|
||||||
|
function sfx.playFootstep()
|
||||||
|
footsteps[ stepIdx ]:stop()
|
||||||
|
stepIdx = math.random( 1, #footsteps )
|
||||||
|
footsteps[ stepIdx ]:play()
|
||||||
|
end
|
||||||
|
|
||||||
|
function sfx.setPosition( x, y, z )
|
||||||
|
return love.audio.setPosition( x, y, z )
|
||||||
|
end
|
||||||
|
|
||||||
|
function sfx.setOrientation( yaw )
|
||||||
|
local x, z = math.cos( yaw ), math.sin( yaw )
|
||||||
|
return love.audio.setOrientation( x, 0, z, 0, 1, 0 )
|
||||||
|
end
|
||||||
|
|
||||||
return sfx
|
return sfx
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,5 +1,5 @@
|
||||||
return love.graphics.newShader[[
|
return love.graphics.newShader[[
|
||||||
#define fog vec4( 0.85, 0.85, 1.0, 1.0 )
|
#define fog vec4( 0.9, 0.9, 1.0, 1.0 )
|
||||||
#define fogHigh vec4( 1.0, 1.0, 0.85, 1.0 )
|
#define fogHigh vec4( 1.0, 1.0, 0.85, 1.0 )
|
||||||
#define sunDir 0.1 * vec3( 0.9, 0.2, 0.5 )
|
#define sunDir 0.1 * vec3( 0.9, 0.2, 0.5 )
|
||||||
varying float depth;
|
varying float depth;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
return love.graphics.newShader[[
|
return love.graphics.newShader[[
|
||||||
#define fog vec4( 0.85, 0.85, 1.0, 1.0 )
|
#define fog vec4( 0.9, 0.9, 1.0, 1.0 )
|
||||||
#define fogHigh vec4( 1.0, 1.0, 0.9, 1.0 )
|
#define fogHigh vec4( 1.0, 1.0, 0.85, 1.0 )
|
||||||
varying float depth;
|
varying float depth;
|
||||||
varying vec3 normal;
|
varying vec3 normal;
|
||||||
varying vec4 world;
|
varying vec4 world;
|
||||||
|
@ -24,10 +24,10 @@ return love.graphics.newShader[[
|
||||||
vec3 toLight = normalize( light - world.xyz );
|
vec3 toLight = normalize( light - world.xyz );
|
||||||
float diff = max( dot( norm, light ), 0.1 );
|
float diff = max( dot( norm, light ), 0.1 );
|
||||||
|
|
||||||
vec4 mainColor = vec4( diff * color.rgb, color.a );
|
vec4 mainColor = vec4( diff * color.rgb * world.y, color.a );
|
||||||
|
|
||||||
return mix( mix( mainColor, fog,
|
return mix( mix( mainColor, fog,
|
||||||
clamp( depth / 80.0, 0.0, 1.0)), fogHigh,
|
clamp( depth / 50.0, 0.0, 1.0)), fogHigh,
|
||||||
clamp( world.y / 20.0, 0.0, 1.0)) ;
|
clamp( world.y / 20.0, 0.0, 1.0)) ;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -14,10 +14,13 @@ varying vec3 viewDir;
|
||||||
#ifdef PIXEL
|
#ifdef PIXEL
|
||||||
uniform vec3 light;
|
uniform vec3 light;
|
||||||
vec4 effect( vec4 color, Image _, vec2 __, vec2 ___) {
|
vec4 effect( vec4 color, Image _, vec2 __, vec2 ___) {
|
||||||
float d = dot( normalize( viewDir ), light );
|
vec3 view = normalize( viewDir );
|
||||||
d = 0.5+0.5*d;
|
float d = dot( view, light );
|
||||||
d = pow(d, 45);
|
float e = 0.504 +0.5*d;
|
||||||
return mix( blue, mix( yellow, color, d * 2 ) , d );
|
e = pow(e, 40);
|
||||||
|
float b = d < 0.995 ? 1.0 : 0.0;
|
||||||
|
vec4 black = vec4(b,b,b,1.0);
|
||||||
|
return black * mix( blue, mix( yellow, color, d * 2 ) , e ) + 0.2 * pow( (1.0 - dot( view, vec3( 0, 1, 0 ) )), 7 );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
]]
|
]]
|
|
@ -1,6 +1,6 @@
|
||||||
return love.graphics.newShader[[
|
return love.graphics.newShader[[
|
||||||
#define fog vec4( 0.6, 0.6, 0.7, 1.0 )
|
#define fog vec4( 0.9, 0.9, 1.0, 1.0 )
|
||||||
#define fogHigh vec4( 0.7, 0.7, 0.6, 1.0 )
|
#define fogHigh vec4( 1.0, 1.0, 0.85, 1.0 )
|
||||||
#define sunDir 0.1 * vec3( 0.9, 0.2, 0.5 )
|
#define sunDir 0.1 * vec3( 0.9, 0.2, 0.5 )
|
||||||
varying float depth;
|
varying float depth;
|
||||||
varying vec3 normal;
|
varying vec3 normal;
|
||||||
|
@ -8,15 +8,14 @@ return love.graphics.newShader[[
|
||||||
#ifdef VERTEX
|
#ifdef VERTEX
|
||||||
//per instance: (uniform) x, y, z, height
|
//per instance: (uniform) x, y, z, height
|
||||||
attribute vec4 spikeInstance;
|
attribute vec4 spikeInstance;
|
||||||
attribute float spikeOrientation;
|
|
||||||
attribute vec3 VertexNormal;
|
attribute vec3 VertexNormal;
|
||||||
uniform mat4 view;
|
uniform mat4 view;
|
||||||
uniform mat4 proj;
|
uniform mat4 proj;
|
||||||
vec4 position( mat4 _, vec4 pos ){
|
vec4 position( mat4 _, vec4 pos ){
|
||||||
normal = VertexNormal;
|
normal = VertexNormal;
|
||||||
pos.xz *= 0.25;
|
|
||||||
pos.y *= spikeInstance.w;
|
pos.y *= spikeInstance.w;
|
||||||
pos.xyz += spikeInstance.xyz;
|
pos.xy += spikeInstance.xy;
|
||||||
|
pos.z -= spikeInstance.z;
|
||||||
world = pos;
|
world = pos;
|
||||||
|
|
||||||
vec4 eye = view * pos;
|
vec4 eye = view * pos;
|
||||||
|
@ -39,7 +38,7 @@ return love.graphics.newShader[[
|
||||||
|
|
||||||
|
|
||||||
return color * mix( mix( mainColor,
|
return color * mix( mix( mainColor,
|
||||||
fog, clamp( depth / 80.0, 0.0, 1.0)),
|
fog, clamp( depth * 0.03 , 0.0, 1.0)),
|
||||||
fogHigh, clamp(world.y / 20.0, 0.0, 1.0));
|
fogHigh, clamp(world.y / 20.0, 0.0, 1.0));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue