This commit is contained in:
wan-may 2025-03-20 00:11:15 -03:00
parent 5adca6b4fa
commit b1e4ea12c1
22 changed files with 553 additions and 56 deletions

View File

@ -12,6 +12,10 @@ local sky
local bell
local contempra
local terrain
local spike
local water
local building
local veil
local light = require( "level.light" )
function t.start()
@ -21,10 +25,14 @@ function t.start()
depth = true,
}
veil = require( "models.veil" )
building = require( "models.building" )
-- water = require( "models.water" )
sky = require( "models.sky" )
bell = require( "models.bell" )
contempra = require( "models.contempra" )
terrain = require( "models.terrain" )
spike = require( "models.spike" )
end
function t.debug()
@ -41,7 +49,7 @@ local function matte( )
end
end
function t.draw( view, proj )
function t.draw( view, proj, player )
if isDebugging then
end
@ -56,9 +64,12 @@ function t.draw( view, proj )
love.graphics.setMeshCullMode( "back" )
sky.draw( view, proj, light )
terrain.draw( view, proj )
terrain.draw( view, proj, light )
building.draw( view, proj, light )
bell.draw( view, proj, light )
contempra.draw( view, proj, light )
spike.draw( view, proj, light )
veil.draw( view, proj )
love.graphics.pop()

View File

@ -111,7 +111,7 @@ do
local c, s = math.cos( 2*math.pi / 7 ), -math.sin( 2*math.pi / 7 )
local x, z = 1, 0
local r = 15
local r = 40
for i = 1, 7 do
bells[i] = { i / 2, r * x, r * z, (i-1)/6 }
x, z = c*x+s*z, c*z-s*x
@ -128,6 +128,7 @@ t.mesh = bellMesh
function t.draw( view, proj, light )
local s = t.shader
love.graphics.setColor(1,1,1,1)
s:send( "view", "column", view )
s:send( "proj", "column", proj )
s:send("light", light )

BIN
src/models/building.bin Normal file

Binary file not shown.

96
src/models/building.gltf Normal file
View File

@ -0,0 +1,96 @@
{
"asset":{
"generator":"Khronos glTF Blender I/O v4.2.70",
"version":"2.0"
},
"scene":0,
"scenes":[
{
"name":"Scene",
"nodes":[
0
]
}
],
"nodes":[
{
"mesh":0,
"name":"Building",
"translation":[
0,
1,
0
]
}
],
"meshes":[
{
"name":"Building",
"primitives":[
{
"attributes":{
"POSITION":0,
"NORMAL":1
},
"indices":2
}
]
}
],
"accessors":[
{
"bufferView":0,
"componentType":5126,
"count":643,
"max":[
10.494050979614258,
2.4390439987182617,
10.381834983825684
],
"min":[
-9.749046325683594,
-0.9988071918487549,
-10.38186264038086
],
"type":"VEC3"
},
{
"bufferView":1,
"componentType":5126,
"count":643,
"type":"VEC3"
},
{
"bufferView":2,
"componentType":5123,
"count":999,
"type":"SCALAR"
}
],
"bufferViews":[
{
"buffer":0,
"byteLength":7716,
"byteOffset":0,
"target":34962
},
{
"buffer":0,
"byteLength":7716,
"byteOffset":7716,
"target":34962
},
{
"buffer":0,
"byteLength":1998,
"byteOffset":15432,
"target":34963
}
],
"buffers":[
{
"byteLength":17432,
"uri":"building.bin"
}
]
}

View File

@ -0,0 +1,94 @@
local dkjson = require( "lib.dkjson" )
local love = assert( love )
local shader = require( "shaders.flat" )
local mat = require( "mat4" )
local attributeNames = {
POSITION = "VertexPosition",
NORMAL = "VertexNormal",
}
local types = {
["SCALAR"] = 1,
["VEC3"] = 3,
}
local componentTypes = {
[5121] = "byte",
[5123] = "unorm16",
[5126] = "float",
}
local elementComponentTypes = {
[5123] = "uint16",
[5126] = "uint32",
}
local asset
local buffer
do
local fd = assert( love.filesystem.newFileData( "models/building.gltf" ) )
asset = dkjson.decode( fd:getString() )
buffer = love.filesystem.newFileData( "models/building.bin" )
end
--load all the bufferViews
local bufferViews = {}
for i, view in pairs( asset.bufferViews ) do
bufferViews[i] = love.data.newByteData( buffer, view.byteOffset, view.byteLength )
end
local function attributeFormat( attributeName, accessor )
return {attributeNames[attributeName], componentTypes[accessor.componentType], types[accessor.type] }
end
local function lgMesh( primitive )
assert( not( primitive.mode ) ) --triangles only
local finalMesh
for name, accIdx in pairs( primitive.attributes ) do
local acc = asset.accessors[accIdx+1]
local mesh = love.graphics.newMesh(
{attributeFormat(name, acc)}, --vertexformat
acc.count,
"triangles",
"static"
)
local bfv = bufferViews[1+acc.bufferView]
mesh:setVertices( bfv )
if finalMesh then
finalMesh:attachAttribute( attributeNames[name], mesh )
else
finalMesh = mesh
end
end
do
local acc = asset.accessors[1+primitive.indices]
local bfv = bufferViews[1+acc.bufferView]
finalMesh:setVertexMap(bfv, elementComponentTypes[acc.componentType] )
end
return finalMesh
end
local obj = {}
local mesh = lgMesh( asset.meshes[1].primitives[1] )
local id = mat.TRS(2,2,2,0,0,0,0,2,0)
function obj.draw( view, proj, light )
love.graphics.setMeshCullMode( "none" )
shader:send( "view", "column", view )
shader:send( "proj", "column", proj )
shader:send( "light", light )
love.graphics.setShader( shader )
love.graphics.setColor( 0.05,0.05,0.1,1.0 )
shader:send( "mdl", "column", id )
love.graphics.draw( mesh )
end
return obj

View File

@ -115,7 +115,6 @@ local colors = setmetatable(
)
function obj.draw( view, proj, light )
love.graphics.setMeshCullMode( "none" ) --debug
shader:send( "view", "column", view )
shader:send( "proj", "column", proj )
shader:send( "light", light )

0
src/models/gltf.lua Normal file
View File

BIN
src/models/spike.bin Normal file

Binary file not shown.

104
src/models/spike.gltf Normal file
View File

@ -0,0 +1,104 @@
{
"asset":{
"generator":"Khronos glTF Blender I/O v4.2.70",
"version":"2.0"
},
"scene":0,
"scenes":[
{
"name":"Scene",
"nodes":[
0
]
}
],
"nodes":[
{
"mesh":0,
"name":"Spike"
}
],
"meshes":[
{
"name":"Spike",
"primitives":[
{
"attributes":{
"POSITION":0,
"NORMAL":1,
"TEXCOORD_0":2
},
"indices":3
}
]
}
],
"accessors":[
{
"bufferView":0,
"componentType":5126,
"count":48,
"max":[
1,
1,
1
],
"min":[
-1,
0,
-1
],
"type":"VEC3"
},
{
"bufferView":1,
"componentType":5126,
"count":48,
"type":"VEC3"
},
{
"bufferView":2,
"componentType":5126,
"count":48,
"type":"VEC2"
},
{
"bufferView":3,
"componentType":5123,
"count":48,
"type":"SCALAR"
}
],
"bufferViews":[
{
"buffer":0,
"byteLength":576,
"byteOffset":0,
"target":34962
},
{
"buffer":0,
"byteLength":576,
"byteOffset":576,
"target":34962
},
{
"buffer":0,
"byteLength":384,
"byteOffset":1152,
"target":34962
},
{
"buffer":0,
"byteLength":96,
"byteOffset":1536,
"target":34963
}
],
"buffers":[
{
"byteLength":1632,
"uri":"spike.bin"
}
]
}

View File

@ -35,9 +35,9 @@ local filterTypes = {
local asset
local buffer
do
local fd = assert( love.filesystem.newFileData( "models/bell.gltf" ) )
local fd = assert( love.filesystem.newFileData( "models/spike.gltf" ) )
asset = dkjson.decode( fd:getString() )
buffer = love.filesystem.newFileData( "models/bell.bin" )
buffer = love.filesystem.newFileData( "models/spike.bin" )
end
--load all the bufferViews
@ -70,43 +70,76 @@ local function lgMesh( primitive )
local finalMesh
for name, accIdx in pairs( primitive.attributes ) do
local acc = asset.accessors[accIdx+1]
local mesh = love.graphics.newMesh(
{attributeFormat(name, acc)}, --vertexformat
acc.count,
"triangles",
"static"
)
local bfv = bufferViews[1+acc.bufferView]
mesh:setVertices( bfv )
if finalMesh then
finalMesh:attachAttribute( attributeNames[name], mesh )
else
finalMesh = mesh
end
end
do
local acc = asset.accessors[1+primitive.indices]
local bfv = bufferViews[1+acc.bufferView]
finalMesh:setVertexMap(bfv, elementComponentTypes[acc.componentType] )
end
if primitive.material then finalMesh:setTexture( lgTexture( primitive.material ) ) end
return finalMesh
end
local spike = lgMesh( asset.meshes[1].primitives[1] )
local spikeInstanceMesh = {}
spike:setTexture( love.graphics.newImage( "tex/rock.png", { mipmaps = true } ) )
local spikes = {}
local spikeCount = 4096
do
function spikes.draw( view, proj, light )
local function rad(x,z)
return x*x+z*z
end
local spikes = {}
local inner, outer = 25, 100
for n = 1, spikeCount do
local r, a = math.sqrt( math.random() * (outer*outer-inner*inner)+outer*outer ), 2 * math.pi * math.random()
local x, z = r*math.cos(a),r*math.sin(a)
local h = 2 + 10 * math.random()
spikes[n] = { x, -1, z, h, 0 }
n=n+1
end
local spikeInstanceMesh = love.graphics.newMesh(
{{"spikeInstance", "float", 4},
{"spikeOrientation", "float", 1 },
}, --vertexformat
spikes,
nil,
"static"
)
spike:attachAttribute( "spikeInstance", spikeInstanceMesh, "perinstance" )
spike:attachAttribute( "spikeOrientation", spikeInstanceMesh, "perinstance" )
end
local spikes = {}
function spikes.draw( view, proj, light )
love.graphics.setColor( 1,1,1,1)
shader:send( "view", "column", view )
shader:send( "proj", "column", proj )
shader:send( "light", light )
love.graphics.setShader( shader )
love.graphics.drawInstanced( spike, spikeCount )
end
return spikes

View File

@ -1,69 +1,116 @@
local love = assert( love )
local ffi = require( "ffi" )
local sideLength = 256
local sideLength = 128 --VERTICES in a side
local vertexCount = sideLength * sideLength
local vertices = love.data.newByteData( 4 * vertexCount )
local vertexMap = love.data.newByteData( 2 * vertexCount )
local vertices = love.data.newByteData( 4 * 2 * vertexCount )
local height = love.graphics.newImage( "tex/terrain.png" )
local heightMap = love.image.newImageData( "tex/terrain.jpg" )
local heightTex = love.graphics.newImage( heightMap, {linear = true} )
heightTex:setWrap( "repeat", "repeat" )
local mesh = love.graphics.newMesh(
{{"VertexPosition", "float", 1 }},
{{"VertexPosition", "float", 2 }},
vertexCount,
"strip",
"triangles",
"static"
)
mesh:setTexture( height )
--set vertices
do
local p = vertexMap:getFFIPointer()
local ptr = ffi.cast( "uint16_t *", p)
for i = 0, vertexCount - 1 do
ptr[i] = i
end
mesh:setVertexMap( vertexMap, "uint16" )
do local _ = p end --keep alive?
local p = vertices:getFFIPointer()
local ptr = ffi.cast( "float*", p )
local i = 0
for x = 0, sideLength-1 do for y = 0, sideLength-1 do
ptr[i],ptr[i+1] = x - sideLength / 2 ,y - sideLength / 2
i=i+2
end end
mesh:setVertices( vertices )
do local _ = p end
end
--set vertex map
do
local ptr = {}
local n = 1
local s = sideLength
for x = 1, sideLength - 1 do for y = 0, sideLength - 2 do
local i = y*s+x
--print( x, y, i, i+1, i+s, i+s+1 )
ptr[n],ptr[n+1],ptr[n+2] = i,i+1,i+s
n=n+3
ptr[n],ptr[n+1],ptr[n+2] = i+1,s+i+1,i+s
n=n+3
end end
mesh:setVertexMap( ptr )
end
local shader = love.graphics.newShader[[
#pragma glsl3
#define fog vec4( 0.85, 0.85, 1.0, 1.0 )
#define fog vec4( 0.6, 0.6, 0.7, 1.0 )
#define fogHigh vec4( 1.0, 1.0, 0.9, 1.0 )
#define fogFalloff 0.03
varying vec2 uv;
varying vec3 world;
varying vec3 normal;
varying float depth;
//varying vec3 normal;
varying vec4 world;
#ifdef VERTEX
uniform sampler2D height;
uniform mat4 view;
uniform mat4 proj;
// attribute vec3 VertexNormal;
vec4 position( mat4 _, vec4 pos ){
//normal = VertexNormal;
world = pos;
vec4 eye = view * world;
depth = -eye.z;
pos = pos.xzyw;
float y = Texel( height, pos.xz / 256.0 ).r - 0.5;
uv = 0.25 * (pos.xz + vec2(y, sin( y ) ));
pos.y += y;
world = pos.xyz;
vec4 eye = view*pos;
depth = clamp( -eye.z * fogFalloff, 0.0, 1.0 );
normal = vec3( 0.0, 1.0, 0.0 ) + 1.5 * pos.y ;
return proj*eye;
}
#endif
#ifdef PIXEL
//uniform vec3 light;
uniform vec3 light;
vec4 effect( vec4 color, Image tex, vec2 texuv, vec2 scruv) {
// vec3 norm = normalize( normal );
// vec3 toLight = normalize( light - world.xyz );
// float diff = max( dot( norm, light ), 0.5 );
// vec4 mainColor = vec4( diff * color.rgb, color.a );
return mix( mix( color * Texel( tex, texuv ), fog,
clamp( depth / 80.0, 0.0, 1.0)), fogHigh,
clamp( world.y / 20.0, 0.0, 1.0)) ;
vec3 albedo = 0.2 * Texel( tex, uv ).rgb;
//diffuse light
vec3 norm = normalize( normal );
vec3 toLight = normalize( light - world.xyz );
float diff = max( dot( norm, light ), 0.1 );
vec4 d = vec4( diff * albedo, 1.0 );
return mix( color * d , fog, depth );
}
#endif
]]
local obj = { height = height }
--set texture
do
local tex = love.graphics.newImage( "tex/rock.png", {mipmaps = true} )
tex:setWrap( "repeat", "repeat" )
mesh:setTexture( tex )
end
function obj.draw( view, proj )
shader:send( "height", heightTex )
local obj = {}
local function worldSpaceToTexCoord( x, z )
return x, z
end
function obj.getHeight( x, z )
return heightMap:getPixel( worldSpaceToTexCoord(x,z) )[1]
end
function obj.draw( view, proj, light )
shader:send( "view", "column", view )
shader:send( "proj", "column", proj )
shader:send( "light", light )
love.graphics.setShader( shader )
love.graphics.draw( mesh )
end

43
src/models/veil.lua Normal file
View File

@ -0,0 +1,43 @@
local lg = love.graphics
local mesh = lg.newMesh(
{{"VertexPosition", "float", 3}},
{
{-1,-1,-1}, --A
{-1,-1, 1}, --B
{-1, 1,-1}, --H
{-1, 1, 1}, --G
{ 1,-1,-1}, --D
{ 1,-1, 1}, --C
{ 1, 1,-1}, --E
{ 1, 1, 1}, --F
},
"triangles",
"static")
mesh:setVertexMap{
1, 2, 3,
2, 3, 4,
3, 4, 7,
4, 7, 8,
7, 5, 8,
5, 8, 6,
8, 4, 6,
4, 6, 2,
6, 2, 5,
2, 5, 1,
5, 1, 7,
1, 7, 3,
}
local shader = require( "shaders.veil" )
local function draw( view, proj )
lg.push( "all" )
lg.setMeshCullMode( "none" )
--get view matrix without translation
shader:send( "proj", "column", proj )
shader:send( "view", "column", view )
lg.setShader( shader )
lg.draw( mesh )
lg.pop()
end
return { draw = draw }

View File

@ -27,7 +27,7 @@ end
function t.draw()
world.draw( player.view, player.proj )
world.draw( player.view, player.proj, player.x, player.z )
local y = 0
for k, v in pairs(love.graphics.getStats()) do

View File

@ -13,7 +13,7 @@ return love.graphics.newShader[[
uniform mat4 view;
uniform mat4 proj;
vec4 position( mat4 _, vec4 pos ){
normal = (view*vec4(VertexNormal,1.0)).rgb;
normal = VertexNormal;
instanceColor = bellInstance.a;
pos.xyz *= bellInstance.r;
pos.xz += bellInstance.gb;
@ -32,15 +32,17 @@ return love.graphics.newShader[[
float y = texuv.y;
y = max( 0.1,
1.4 * pow( 0.9*y*(1.0-0.9*y) , 0.25));
texel.rgb *= y;
texel.gb *= 0.5 * instanceColor + 0.75;
vec3 albedo = texel.rgb * y;
albedo.gb *= 0.5 * instanceColor + 0.75;
//diffuse light
vec3 norm = normalize( normal );
vec3 toLight = normalize( light - world.xyz );
float diff = max( dot( norm, light ), 0.1 );
vec4 mainColor = vec4( diff * texel.rgb, texel.a );
float diff = max( dot( norm, light ), 0.5 );
vec4 mainColor = vec4( diff * albedo, texel.a );
return color * mix( mix( mainColor,
fog, clamp( depth / 80.0, 0.0, 1.0)),

View File

@ -0,0 +1,46 @@
return love.graphics.newShader[[
#define fog vec4( 0.6, 0.6, 0.7, 1.0 )
#define fogHigh vec4( 0.7, 0.7, 0.6, 1.0 )
#define sunDir 0.1 * vec3( 0.9, 0.2, 0.5 )
varying float depth;
varying vec3 normal;
varying vec4 world;
#ifdef VERTEX
//per instance: (uniform) x, y, z, height
attribute vec4 spikeInstance;
attribute float spikeOrientation;
attribute vec3 VertexNormal;
uniform mat4 view;
uniform mat4 proj;
vec4 position( mat4 _, vec4 pos ){
normal = VertexNormal;
pos.xz *= 0.25;
pos.y *= spikeInstance.w;
pos.xyz += spikeInstance.xyz;
world = pos;
vec4 eye = view * pos;
depth = -eye.z;
return proj*eye;
}
#endif
#ifdef PIXEL
uniform vec3 light;
vec4 effect( vec4 color, Image tex, vec2 texuv, vec2 scruv) {
vec2 uv = vec2(texuv.x, texuv.y/10.0);
vec4 texel = Texel( tex, uv );
//diffuse light
vec3 norm = normalize( normal );
vec3 toLight = normalize( light - world.xyz );
float diff = max( dot( norm, light ), 0.1 );
vec4 mainColor = vec4( diff * texel.rgb, texel.a );
return color * mix( mix( mainColor,
fog, clamp( depth / 80.0, 0.0, 1.0)),
fogHigh, clamp(world.y / 20.0, 0.0, 1.0));
}
#endif
]]

21
src/shaders/veil.lua Normal file
View File

@ -0,0 +1,21 @@
return love.graphics.newShader[[
#define fog vec4( 0.85, 0.85, 1.0, 1.0 )
#define blue vec4( 0.6, 0.6, 0.7, 0.0 )
varying float d;
#ifdef VERTEX
uniform mat4 view;
uniform mat4 proj;
vec4 position( mat4 _, vec4 pos ){
pos.xyz *= 16.0;
vec4 eye = view*pos;
d = clamp( -eye.z / 16.0 - 0.4, 0.0, 1.0 );
return proj*eye;
}
#endif
#ifdef PIXEL
vec4 effect( vec4 color, Image _, vec2 __, vec2 ___) {
return mix( blue, fog, d);
}
#endif
]]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 598 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 579 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 573 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 605 KiB