singe/testScripts/scene27.singe

121 lines
4.4 KiB
Text

-- The Khronos Sponza atrium, packed with util/packGlb.py from the glTF-Sample-Models 2.0 Sponza.
-- A warm sun falls through the roof opening onto the atrium floor with hard shadows, braziers along the nave
-- add pools of firelight with particle flames and smoke, each crackling from where it stands (the
-- listener is the camera), and dust drifts in the sunbeams; the camera walks the ground floor,
-- crosses the atrium, climbs to the gallery, then passes the columns.
local font = fontLoad("Singe/FreeSansBold.ttf", 28)
local frames = 0
fontSelect(font)
sceneEnable(true)
sceneSetBackground(120, 150, 200, 255)
sceneSetAmbient(120, 126, 150)
sceneSetShadowSize(2048)
sceneSetBloom(1.2, 0.25)
local model = modelLoad("testScripts/Models/Sponza.glb")
local sponza = modelInstance(model)
-- The sun: high and warm so it falls through the roof opening onto the atrium floor.
local sun = lightNew(LIGHT_DIRECTIONAL)
nodeSetPosition(sun, 5, 22, 4)
nodeLookAt(sun, -2, 0, -1.5)
lightSetIntensity(sun, 4.5)
lightSetColor(sun, 255, 236, 205)
lightSetShadow(sun, true)
-- Braziers: warm point lights along the nave, the two nearest the camera path casting shadows,
-- each with a flame and a thread of smoke.
local fire = materialNew()
materialSetColor(fire, 60, 40, 30)
local crackle = soundLoad("testScripts/crackle.wav")
local braziers = {}
for i, p in ipairs({ { 6.5, 1.1, -2.2 }, { 6.5, 1.1, 2.2 }, { -6.5, 1.1, -2.2 }, { -6.5, 1.1, 2.2 }, { 0, 1.1, -2.4 }, { 0, 1.1, 2.4 } }) do
local bowl = nodeNew()
nodeSetMesh(bowl, meshCylinder(0.35, 0.25, 12), fire)
nodeSetPosition(bowl, p[1], p[2] - 0.15, p[3])
local glowNode = nodeNew()
nodeSetPosition(glowNode, p[1], p[2] + 0.35, p[3])
local lamp = lightNew(LIGHT_POINT)
nodeSetParent(lamp, glowNode)
lightSetColor(lamp, 255, 170, 80)
lightSetIntensity(lamp, 6)
lightSetRange(lamp, 12)
lightSetShadow(lamp, i <= 2)
local flame = emitterNew(glowNode)
emitterSetBlend(flame, PARTICLE_ADD)
emitterSetRate(flame, 60)
emitterSetLife(flame, 0.4, 0.8)
emitterSetSpeed(flame, 0.5, 1.1)
emitterSetDirection(flame, 0, 1, 0)
emitterSetSpread(flame, 18)
emitterSetSize(flame, 0.22, 0.04, 0.15)
emitterSetColor(flame, 255, 190, 90, 255, 255, 60, 0, 0)
emitterSetRadius(flame, 0.1)
emitterStart(flame)
local smoke = emitterNew(glowNode)
emitterSetRate(smoke, 12)
emitterSetLife(smoke, 2.5, 4)
emitterSetSpeed(smoke, 0.4, 0.7)
emitterSetDirection(smoke, 0, 1, 0)
emitterSetSpread(smoke, 12)
emitterSetSize(smoke, 0.15, 0.8, 0.15)
emitterSetColor(smoke, 90, 80, 75, 90, 50, 45, 45, 0)
emitterSetSpin(smoke, -25, 25)
emitterSetLit(smoke, true)
emitterSetSoftness(smoke, 0.4)
emitterStart(smoke)
local channel = soundPlay(crackle, -1)
if channel >= 0 then
soundSetNode(channel, glowNode)
soundSetRange(channel, 1.5, 14)
end
braziers[i] = glowNode
end
-- Dust in the sunbeams over the atrium floor.
local air = nodeNew()
nodeSetPosition(air, 0, 3, 0)
local dust = emitterNew(air)
emitterSetRate(dust, 40)
emitterSetLife(dust, 5, 8)
emitterSetSpeed(dust, 0.05, 0.25)
emitterSetSpread(dust, 180)
emitterSetSize(dust, 0.05, 0.05)
emitterSetColor(dust, 255, 240, 210, 0, 255, 240, 210, 190)
emitterSetRadius(dust, 5)
emitterSetMax(dust, 400)
emitterStart(dust)
emitterBurst(dust, 300)
local camera = nodeNew()
cameraSet(camera)
cameraSetPerspective(65, 0.05, 100)
local stops = {
{ 10, 1.6, 0, -10, 2.5, 0 }, -- Ground floor, along the nave past the braziers
{ 1.2, 1.6, 5.2, -1, 3.5, -5 }, -- Across the atrium toward the far arcade
{ -9, 5.5, -1, 6, 3, 1 }, -- From the upper gallery
{ 5, 1.2, -1.5, -8, 2, 1.5 }, -- Low, past the columns and a brazier
}
function onOverlayUpdate()
local stop = stops[math.min(#stops, math.floor(frames / 45) + 1)]
frames = frames + 1
nodeSetPosition(camera, stop[1], stop[2], stop[3])
nodeLookAt(camera, stop[4], stop[5], stop[6])
overlayClear()
fontPrint(20, 20, "Sponza, frame " .. frames)
if frames == 40 or frames == 85 or frames == 130 or frames == 175 then
singeScreenshot()
local total, drawn, calls, textureKB = sceneGetStats()
debugPrint(string.format("frame %d draws %d in view %d calls %d texture %d KB", frames, total, drawn, calls, textureKB))
for channel = 0, 5 do
local x, y, z, gain = soundGetPosition(channel)
debugPrint(string.format("frame %d brazier channel %d at %.1f %.1f %.1f gain %.2f", frames, channel, x, y, z, gain))
end
end
if frames == 180 then
singeQuit()
end
end