From e7f0fb57a3c850336cb78fab1162c71ec79aadf7 Mon Sep 17 00:00:00 2001 From: RandomityGuy <31925790+RandomityGuy@users.noreply.github.com> Date: Sun, 2 Jul 2023 14:02:15 +0530 Subject: [PATCH] optimize graphics stuff --- src/MarbleWorld.hx | 2 ++ src/PreviewWorld.hx | 1 + src/Renderer.hx | 43 +++++++++++++++++++++++++++------- src/Settings.hx | 4 ++++ src/gui/VideoOptionsGui.hx | 38 ++++++++++++++++++++++++++++++ src/shaders/CubemapRenderer.hx | 10 +++++++- 6 files changed, 88 insertions(+), 10 deletions(-) diff --git a/src/MarbleWorld.hx b/src/MarbleWorld.hx index 67d8ee73..99180d44 100644 --- a/src/MarbleWorld.hx +++ b/src/MarbleWorld.hx @@ -92,6 +92,7 @@ import src.Gamepad; import modes.GameMode; import modes.NullMode; import modes.GameMode.GameModeFactory; +import src.Renderer; class MarbleWorld extends Scheduler { public var collisionWorld:CollisionWorld; @@ -1052,6 +1053,7 @@ class MarbleWorld extends Scheduler { marble.update(timeState, collisionWorld, this.pathedInteriors); } _cubemapNeedsUpdate = true; + Renderer.dirtyBuffers = true; if (this.rewinding) { // Update camera separately marble.camera.update(timeState.currentAttemptTime, realDt); diff --git a/src/PreviewWorld.hx b/src/PreviewWorld.hx index 65f82781..98d141f5 100644 --- a/src/PreviewWorld.hx +++ b/src/PreviewWorld.hx @@ -597,6 +597,7 @@ class PreviewWorld extends Scheduler { marb.update(timeState, this.collisionWorld, []); } _cubemapNeedsUpdate = true; + Renderer.dirtyBuffers = true; this.instanceManager.render(); } diff --git a/src/Renderer.hx b/src/Renderer.hx index 6b8e5a32..ec70099d 100644 --- a/src/Renderer.hx +++ b/src/Renderer.hx @@ -28,6 +28,12 @@ class Renderer extends h3d.scene.Renderer { var copyPass:h3d.pass.Copy; var backBuffer:h3d.mat.Texture; + public static var dirtyBuffers:Bool = true; + + var depthBuffer:DepthBuffer; + + static var pixelRatio:Float = 1; + public static var cubemapPass:Bool = false; public function new() { @@ -61,6 +67,14 @@ class Renderer extends h3d.scene.Renderer { glowBuffer.dispose(); glowBuffer = null; } + if (depthBuffer != null) { + depthBuffer.dispose(); + depthBuffer = null; + } + pixelRatio = 1; + #if js + pixelRatio = js.Browser.window.devicePixelRatio / Math.min(Settings.optionsSettings.maxPixelRatio, js.Browser.window.devicePixelRatio); + #end } override function getPassByName(name:String):h3d.pass.Base { @@ -72,7 +86,9 @@ class Renderer extends h3d.scene.Renderer { override function render() { if (backBuffer == null) { - backBuffer = ctx.textures.allocTarget("backBuffer", ctx.engine.width, ctx.engine.height); + depthBuffer = new DepthBuffer(cast ctx.engine.width / pixelRatio, cast ctx.engine.height / pixelRatio, Depth24Stencil8); + backBuffer = ctx.textures.allocTarget("backBuffer", cast ctx.engine.width / pixelRatio, cast ctx.engine.height / pixelRatio, false); + backBuffer.depthBuffer = depthBuffer; } ctx.engine.pushTarget(backBuffer); ctx.engine.clear(0, 1); @@ -86,8 +102,10 @@ class Renderer extends h3d.scene.Renderer { if (has("normal")) renderPass(normal, get("normal")); - if (glowBuffer == null) - glowBuffer = ctx.textures.allocTarget("glowBuffer", ctx.engine.width, ctx.engine.height); + if (glowBuffer == null) { + glowBuffer = ctx.textures.allocTarget("glowBuffer", cast ctx.engine.width / pixelRatio, cast ctx.engine.height / pixelRatio); + glowBuffer.depthBuffer = depthBuffer; + } if (growBufferTemps == null) { growBufferTemps = [ ctx.textures.allocTarget("gb1", 320, 320, false), @@ -125,11 +143,13 @@ class Renderer extends h3d.scene.Renderer { if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 4) { var glowObjects = get("glow"); if (!glowObjects.isEmpty()) { - ctx.engine.pushTarget(glowBuffer); - ctx.engine.clear(0); - renderPass(defaultPass, glowObjects); - bloomPass(ctx); - ctx.engine.popTarget(); + if (dirtyBuffers) { + ctx.engine.pushTarget(glowBuffer); + ctx.engine.clear(0); + renderPass(defaultPass, glowObjects); + bloomPass(ctx); + ctx.engine.popTarget(); + } copyPass.shader.texture = growBufferTemps[0]; copyPass.pass.blend(One, One); copyPass.pass.depth(false, Always); @@ -142,7 +162,9 @@ class Renderer extends h3d.scene.Renderer { if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 4) { var refractObjects = get("refract"); if (!refractObjects.isEmpty()) { - h3d.pass.Copy.run(backBuffer, sfxBuffer); + if (dirtyBuffers) { + h3d.pass.Copy.run(backBuffer, sfxBuffer); + } renderPass(defaultPass, refractObjects); } } @@ -154,6 +176,9 @@ class Renderer extends h3d.scene.Renderer { renderPass(defaultPass, get("additive")); } + if (!cubemapPass && dirtyBuffers) + dirtyBuffers = false; + ctx.engine.popTarget(); copyPass.pass.blend(One, Zero); diff --git a/src/Settings.hx b/src/Settings.hx index 5e3c3d67..ce085f3a 100644 --- a/src/Settings.hx +++ b/src/Settings.hx @@ -45,6 +45,7 @@ typedef OptionsSettings = { var rewindEnabled:Bool; var rewindTimescale:Float; var reflectionDetail:Int; + var maxPixelRatio:Float; } typedef ControlsSettings = { @@ -129,6 +130,7 @@ class Settings { rewindEnabled: false, rewindTimescale: 1.0, reflectionDetail: 3, + maxPixelRatio: 1, vsync: #if js true #end #if hl false @@ -390,6 +392,8 @@ class Settings { if (optionsSettings.reflectionDetail == null) optionsSettings.reflectionDetail = 2; #end + if (optionsSettings.maxPixelRatio == 0 #if js || optionsSettings.maxPixelRatio == null #end) + optionsSettings.maxPixelRatio = 1; controlsSettings = json.controls; if (json.touch != null) { touchSettings = json.touch; diff --git a/src/gui/VideoOptionsGui.hx b/src/gui/VideoOptionsGui.hx index 324d20f0..dc43621a 100644 --- a/src/gui/VideoOptionsGui.hx +++ b/src/gui/VideoOptionsGui.hx @@ -168,6 +168,44 @@ class VideoOptionsGui extends GuiImage { } innerCtrl.addChild(rfOpt); + yPos += 60; + + #if js + var pxOpt = new GuiXboxOptionsList(1, "Pixel Ratio", ["Max 0.5", "Max 1", "Max 1.5", "Max 2", "Max Infinity"], 0.35); + + var curPixelRatioIndex = 1; + if (Settings.optionsSettings.maxPixelRatio == 0.5) + curPixelRatioIndex = 0; + else if (Settings.optionsSettings.maxPixelRatio == 1) + curPixelRatioIndex = 1; + else if (Settings.optionsSettings.maxPixelRatio == 1.5) + curPixelRatioIndex = 2; + else if (Settings.optionsSettings.maxPixelRatio == 2) + curPixelRatioIndex = 3; + else if (Settings.optionsSettings.maxPixelRatio == 100) + curPixelRatioIndex = 4; + + pxOpt.vertSizing = Bottom; + pxOpt.horizSizing = Right; + pxOpt.position = new Vector(380, yPos); + pxOpt.extent = new Vector(815, 94); + pxOpt.setCurrentOption(curPixelRatioIndex); + pxOpt.onChangeFunc = (idx) -> { + if (idx == 0) + Settings.optionsSettings.maxPixelRatio = 0.5; + else if (idx == 1) + Settings.optionsSettings.maxPixelRatio = 1; + else if (idx == 2) + Settings.optionsSettings.maxPixelRatio = 1.5; + else if (idx == 3) + Settings.optionsSettings.maxPixelRatio = 2; + else if (idx == 4) + Settings.optionsSettings.maxPixelRatio = 100; + return true; + } + innerCtrl.addChild(pxOpt); + #end + var bottomBar = new GuiControl(); bottomBar.position = new Vector(0, 590); bottomBar.extent = new Vector(640, 200); diff --git a/src/shaders/CubemapRenderer.hx b/src/shaders/CubemapRenderer.hx index f99cf386..7f7036e0 100644 --- a/src/shaders/CubemapRenderer.hx +++ b/src/shaders/CubemapRenderer.hx @@ -23,7 +23,7 @@ class CubemapRenderer { this.scene = scene; this.sky = sky; this.cubemap = new Texture(128, 128, [Cube, Dynamic, Target], h3d.mat.Data.TextureFormat.RGB8); - this.cubemap.depthBuffer = new h3d.mat.DepthBuffer(128, 128, h3d.mat.DepthBuffer.DepthFormat.Depth24); + this.cubemap.depthBuffer = new h3d.mat.DepthBuffer(128, 128, h3d.mat.DepthBuffer.DepthFormat.Depth16); this.camera = new Camera(90, 1, 1, 0.02, scene.camera.zFar); this.position = new Vector(); this.nextFaceToRender = 0; @@ -33,10 +33,12 @@ class CubemapRenderer { var scenecam = scene.camera; scene.camera = camera; + var start = haxe.Timer.stamp(); var renderedFaces = 0; Renderer.cubemapPass = true; for (i in 0...facesPerRender) { var index = (nextFaceToRender + i) % 6; + Renderer.dirtyBuffers = true; e.pushTarget(cubemap, index); this.camera.setCubeMap(index, position); @@ -45,6 +47,12 @@ class CubemapRenderer { e.popTarget(); renderedFaces++; + var time = haxe.Timer.stamp(); + var elapsed = time - start; + var elapsedPerFace = elapsed / renderedFaces; + + if (elapsedPerFace * (renderedFaces + 1) >= 0.002) + break; } Renderer.cubemapPass = false; scene.camera = scenecam;