From 579c5ffa272bd0b72c53351cef0f5657c5392052 Mon Sep 17 00:00:00 2001 From: RandomityGuy <31925790+RandomityGuy@users.noreply.github.com> Date: Sat, 1 Jul 2023 23:28:30 +0530 Subject: [PATCH] reflection quality --- src/DifBuilder.hx | 11 ++++++++ src/InstanceManager.hx | 28 +++++++++++++++++++ src/Main.hx | 7 ++--- src/Marble.hx | 2 +- src/MarbleWorld.hx | 11 ++++++-- src/PreviewWorld.hx | 9 ++++-- src/Renderer.hx | 51 ++++++++++++++++++++++++---------- src/Settings.hx | 10 +++++-- src/gui/VideoOptionsGui.hx | 15 ++++++++++ src/shaders/CubemapRenderer.hx | 12 ++------ 10 files changed, 122 insertions(+), 34 deletions(-) diff --git a/src/DifBuilder.hx b/src/DifBuilder.hx index 836ba000..b874a3b0 100644 --- a/src/DifBuilder.hx +++ b/src/DifBuilder.hx @@ -958,6 +958,16 @@ class DifBuilder { var retrievefunc = shaderMaterialDict[exactName]; shaderWorker.addTask(fwd -> { retrievefunc(shad -> { + var zPass = material.mainPass.clone(); + zPass.removeShader(material.textureShader); + var tx = zPass.getShader(h3d.shader.Texture); + zPass.removeShader(tx); + zPass.setColorMask(false, false, false, false); + zPass.depthWrite = true; + zPass.setPassName("zPass"); + material.addPass(zPass); + + material.mainPass.depthTest = LessEqual; material.mainPass.removeShader(material.textureShader); material.mainPass.addShader(shad); var thisprops:Dynamic = material.getDefaultProps(); @@ -965,6 +975,7 @@ class DifBuilder { material.props = thisprops; material.shadows = false; material.receiveShadows = true; + material.mainPass.setPassName("interior"); fwd(); }); }); diff --git a/src/InstanceManager.hx b/src/InstanceManager.hx index 7763e3e0..a293bb36 100644 --- a/src/InstanceManager.hx +++ b/src/InstanceManager.hx @@ -241,6 +241,34 @@ class InstanceManager { minfo.meshbatch.material.addPass(gpass); } + var zPass = mat.getPass("zPass"); + if (zPass != null) { + var gpass = zPass.clone(); + gpass.enableLights = false; + gpass.depthTest = zPass.depthTest; + gpass.blendSrc = zPass.blendSrc; + gpass.blendDst = zPass.blendDst; + gpass.blendOp = zPass.blendOp; + gpass.blendAlphaSrc = zPass.blendAlphaSrc; + gpass.blendAlphaDst = zPass.blendAlphaDst; + gpass.blendAlphaOp = zPass.blendAlphaOp; + gpass.colorMask = zPass.colorMask; + minfoshaders = []; + + for (shader in gpass.getShaders()) { + minfoshaders.push(shader); + } + for (shader in minfoshaders) + gpass.removeShader(shader); + var addshaders = []; + for (shader in zPass.getShaders()) { + addshaders.push(shader); + } + for (shader in addshaders) + gpass.addShader(shader); + + minfo.meshbatch.material.addPass(gpass); + } // var dtsshader = mat.mainPass.getShader(DtsTexture); // if (dtsshader != null) { // minfo.meshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader); diff --git a/src/Main.hx b/src/Main.hx index c195cbe2..0232562b 100644 --- a/src/Main.hx +++ b/src/Main.hx @@ -128,10 +128,9 @@ class Main extends hxd.App { override function update(dt:Float) { super.update(dt); + ProfilerUI.begin(); + ProfilerUI.measure("updateBegin"); if (loaded) { - ProfilerUI.begin(); - ProfilerUI.measure("updateBegin"); - // try { // timeAccumulator += dt; // while (timeAccumulator > 1 / 60) { @@ -154,9 +153,9 @@ class Main extends hxd.App { if (loaded) { ProfilerUI.measure("renderBegin"); marbleGame.render(e); - ProfilerUI.end(); } super.render(e); + ProfilerUI.end(); } static function main() { diff --git a/src/Marble.hx b/src/Marble.hx index 4111c25a..14b06b50 100644 --- a/src/Marble.hx +++ b/src/Marble.hx @@ -336,7 +336,7 @@ class Marble extends GameObject { mat.receiveShadows = false; // mat.mainPass.culling = None; - if (Settings.optionsSettings.reflectiveMarble) { + if (Settings.optionsSettings.reflectionDetail > 0) { var csky = level != null ? level.sky : (@:privateAccess MarbleGame.instance.previewWorld.sky); this.cubemapRenderer = new CubemapRenderer(MarbleGame.instance.scene, csky); diff --git a/src/MarbleWorld.hx b/src/MarbleWorld.hx index 0e83056e..2e1b587b 100644 --- a/src/MarbleWorld.hx +++ b/src/MarbleWorld.hx @@ -201,6 +201,8 @@ class MarbleWorld extends Scheduler { var oobSchedule:Float; var oobSchedule2:Float; + var _cubemapNeedsUpdate:Bool = false; + var lock:Bool = false; public function new(scene:Scene, scene2d:h2d.Scene, mission:Mission, record:Bool = false) { @@ -1045,6 +1047,7 @@ class MarbleWorld extends Scheduler { for (marble in marbles) { marble.update(timeState, collisionWorld, this.pathedInteriors); } + _cubemapNeedsUpdate = true; if (this.rewinding) { // Update camera separately marble.camera.update(timeState.currentAttemptTime, realDt); @@ -1087,8 +1090,12 @@ class MarbleWorld extends Scheduler { if (this.playGui != null && _ready) this.playGui.render(e); if (this.marble != null && this.marble.cubemapRenderer != null && _ready) { - this.marble.cubemapRenderer.position.load(this.marble.getAbsPos().getPosition()); - this.marble.cubemapRenderer.render(e, 0.002); + ProfilerUI.measure("renderCubemap"); + if (_cubemapNeedsUpdate) { + this.marble.cubemapRenderer.position.load(this.marble.getAbsPos().getPosition()); + this.marble.cubemapRenderer.render(e); + _cubemapNeedsUpdate = false; + } } } diff --git a/src/PreviewWorld.hx b/src/PreviewWorld.hx index 978cd2ca..65f82781 100644 --- a/src/PreviewWorld.hx +++ b/src/PreviewWorld.hx @@ -73,6 +73,7 @@ class PreviewWorld extends Scheduler { var itrAddTime:Float = 0; var _loadToken = 0; + var _cubemapNeedsUpdate:Bool = false; public function new(scene:Scene) { this.scene = scene; @@ -595,14 +596,18 @@ class PreviewWorld extends Scheduler { for (marb in marbles) { marb.update(timeState, this.collisionWorld, []); } + _cubemapNeedsUpdate = true; this.instanceManager.render(); } public function render(e:h3d.Engine) { for (marble in marbles) { if (marble != null && marble.cubemapRenderer != null) { - marble.cubemapRenderer.position.load(marble.getAbsPos().getPosition()); - marble.cubemapRenderer.render(e, 0.002); + if (_cubemapNeedsUpdate) { + marble.cubemapRenderer.position.load(marble.getAbsPos().getPosition()); + marble.cubemapRenderer.render(e); + _cubemapNeedsUpdate = false; + } } } } diff --git a/src/Renderer.hx b/src/Renderer.hx index 1089d973..6b8e5a32 100644 --- a/src/Renderer.hx +++ b/src/Renderer.hx @@ -8,6 +8,8 @@ import h3d.Vector; import shaders.Blur; import h3d.pass.ScreenFx; import h3d.mat.DepthBuffer; +import src.ProfilerUI; +import src.Settings; class Renderer extends h3d.scene.Renderer { var def(get, never):h3d.pass.Base; @@ -62,12 +64,8 @@ class Renderer extends h3d.scene.Renderer { } override function getPassByName(name:String):h3d.pass.Base { - if (name == "alpha" - || name == "additive" - || name == "glowPre" - || name == "glow" - || name == "refract" - || name == "glowPreNoRender") + if (name == "alpha" || name == "additive" || name == "glowPre" || name == "glow" || name == "refract" || name == "glowPreNoRender" + || name == "interior" || name == "zPass") return defaultPass; return super.getPassByName(name); } @@ -99,13 +97,32 @@ class Renderer extends h3d.scene.Renderer { // ctx.engine.pushTarget(backBuffers[0]); // ctx.engine.clear(0, 1); - renderPass(defaultPass, get("sky")); - renderPass(defaultPass, get("skyshape"), backToFront); - renderPass(defaultPass, get("default")); - renderPass(defaultPass, get("glowPre")); + if (!cubemapPass) + ProfilerUI.measure("sky"); + if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 1) { + renderPass(defaultPass, get("sky")); + renderPass(defaultPass, get("skyshape"), backToFront); + } + if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 2) { + if (!cubemapPass) + ProfilerUI.measure("interiorZPass"); + renderPass(defaultPass, get("zPass")); + if (!cubemapPass) + ProfilerUI.measure("interior"); + renderPass(defaultPass, get("interior")); + } + if (!cubemapPass) + ProfilerUI.measure("render"); + if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 3) { + renderPass(defaultPass, get("default")); + } + if (!cubemapPass) + ProfilerUI.measure("glow"); + if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 4) + renderPass(defaultPass, get("glowPre")); // Glow pass - if (!cubemapPass) { + if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 4) { var glowObjects = get("glow"); if (!glowObjects.isEmpty()) { ctx.engine.pushTarget(glowBuffer); @@ -119,17 +136,23 @@ class Renderer extends h3d.scene.Renderer { copyPass.render(); } } + if (!cubemapPass) + ProfilerUI.measure("refract"); // Refraction pass - if (!cubemapPass) { + if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 4) { var refractObjects = get("refract"); if (!refractObjects.isEmpty()) { h3d.pass.Copy.run(backBuffer, sfxBuffer); renderPass(defaultPass, refractObjects); } } + if (!cubemapPass) + ProfilerUI.measure("alpha"); - renderPass(defaultPass, get("alpha"), backToFront); - renderPass(defaultPass, get("additive")); + if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 4) { + renderPass(defaultPass, get("alpha"), backToFront); + renderPass(defaultPass, get("additive")); + } ctx.engine.popTarget(); diff --git a/src/Settings.hx b/src/Settings.hx index 445008a7..5e3c3d67 100644 --- a/src/Settings.hx +++ b/src/Settings.hx @@ -36,7 +36,6 @@ typedef OptionsSettings = { var fovX:Int; var frameRateVis:Bool; var oobInsults:Bool; - var reflectiveMarble:Bool; var marbleIndex:Int; var marbleCategoryIndex:Int; var marbleSkin:String; @@ -45,6 +44,7 @@ typedef OptionsSettings = { var cameraDistance:Float; var rewindEnabled:Bool; var rewindTimescale:Float; + var reflectionDetail:Int; } typedef ControlsSettings = { @@ -120,7 +120,6 @@ class Settings { fovX: 90, frameRateVis: true, oobInsults: true, - reflectiveMarble: true, marbleIndex: 0, marbleCategoryIndex: 0, marbleSkin: "base", @@ -129,6 +128,7 @@ class Settings { cameraDistance: 2.5, rewindEnabled: false, rewindTimescale: 1.0, + reflectionDetail: 3, vsync: #if js true #end #if hl false @@ -384,6 +384,12 @@ class Settings { optionsSettings.fovX = 90; if (optionsSettings.rewindEnabled == false #if js || optionsSettings.rewindEnabled == null #end) optionsSettings.rewindEnabled = false; + if (optionsSettings.rewindTimescale == 0 #if js || optionsSettings.rewindTimescale == null #end) + optionsSettings.rewindTimescale = 1; + #if js + if (optionsSettings.reflectionDetail == null) + optionsSettings.reflectionDetail = 2; + #end controlsSettings = json.controls; if (json.touch != null) { touchSettings = json.touch; diff --git a/src/gui/VideoOptionsGui.hx b/src/gui/VideoOptionsGui.hx index ae1aab69..324d20f0 100644 --- a/src/gui/VideoOptionsGui.hx +++ b/src/gui/VideoOptionsGui.hx @@ -153,6 +153,21 @@ class VideoOptionsGui extends GuiImage { } innerCtrl.addChild(fovOpt); + yPos += 60; + + var rfOpt = new GuiXboxOptionsList(1, "Reflection Detail", ["None", "Sky Only", "Level and Sky", "Level, Sky and Items", "Everything"], 0.35); + + rfOpt.vertSizing = Bottom; + rfOpt.horizSizing = Right; + rfOpt.position = new Vector(380, yPos); + rfOpt.extent = new Vector(815, 94); + rfOpt.setCurrentOption(Settings.optionsSettings.reflectionDetail); + rfOpt.onChangeFunc = (idx) -> { + Settings.optionsSettings.reflectionDetail = idx; + return true; + } + innerCtrl.addChild(rfOpt); + 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 a43c0a7d..f99cf386 100644 --- a/src/shaders/CubemapRenderer.hx +++ b/src/shaders/CubemapRenderer.hx @@ -17,6 +17,7 @@ class CubemapRenderer { var camera:Camera; var scene:Scene; var nextFaceToRender:Int; + var facesPerRender:Int = 2; public function new(scene:Scene, sky:Sky) { this.scene = scene; @@ -28,14 +29,13 @@ class CubemapRenderer { this.nextFaceToRender = 0; } - public function render(e:Engine, budget:Float = 1e8) { + public function render(e:Engine) { var scenecam = scene.camera; scene.camera = camera; - var start = haxe.Timer.stamp(); var renderedFaces = 0; Renderer.cubemapPass = true; - for (i in 0...6) { + for (i in 0...facesPerRender) { var index = (nextFaceToRender + i) % 6; e.pushTarget(cubemap, index); @@ -45,12 +45,6 @@ class CubemapRenderer { e.popTarget(); renderedFaces++; - var time = haxe.Timer.stamp(); - var elapsed = time - start; - var elapsedPerFace = elapsed / renderedFaces; - - if (elapsedPerFace * (renderedFaces + 1) >= budget) - break; } Renderer.cubemapPass = false; scene.camera = scenecam;