diff --git a/src/CameraController.hx b/src/CameraController.hx index 5f2f9927..9b0388ec 100644 --- a/src/CameraController.hx +++ b/src/CameraController.hx @@ -73,7 +73,6 @@ class CameraController extends Object { Sdl.warpMouseGlobal(cast this.screenWidth / 2, cast this.screenHeight / 2); default: } - trace(e); } function orbit(mouseX:Float, mouseY:Float) { diff --git a/src/DtsObject.hx b/src/DtsObject.hx index 321132d4..ba3d53cb 100644 --- a/src/DtsObject.hx +++ b/src/DtsObject.hx @@ -1,5 +1,9 @@ package src; +import shaders.DtsMaterial; +import shaders.DtsTexture; +import shaders.DtsMaterialSetup; +import h3d.shader.AlphaMult; import sys.io.File; import src.MarbleWorld; import src.GameObject; @@ -94,6 +98,7 @@ class DtsObject extends GameObject { var colliders:Array; var mountPointNodes:Array; + var alphaShader:AlphaMult; public function new() { super(); @@ -321,6 +326,11 @@ class DtsObject extends GameObject { var texture:Texture = ResourceLoader.getTexture(fullName); texture.wrap = Wrap.Repeat; material.texture = texture; + var dtsshader = new DtsTexture(); + dtsshader.texture = texture; + dtsshader.currentOpacity = 1; + material.mainPass.removeShader(material.textureShader); + material.mainPass.addShader(dtsshader); // TODO TRANSLUENCY SHIT } if (flags & 4 > 0) { @@ -338,6 +348,8 @@ class DtsObject extends GameObject { // } // ((flags & 32) || environmentMaterial) ? new Materia + material.mainPass.addShader(new AlphaMult()); + this.materials.push(material); } @@ -736,4 +748,27 @@ class DtsObject extends GameObject { } return this.getTransform().clone(); } + + public function setOpacity(opacity:Float) { + if (opacity == this.currentOpacity) + return; + this.currentOpacity = opacity; + + for (material in this.materials) { + if (this.currentOpacity != 1) { + material.blendMode = BlendMode.Alpha; + if (this.alphaShader == null) { + this.alphaShader = new AlphaMult(); + } + if (material.mainPass.getShader(AlphaMult) == null) { + material.mainPass.addShader(this.alphaShader); + } + this.alphaShader.alpha = this.currentOpacity; + } else { + if (alphaShader != null) { + alphaShader.alpha = this.currentOpacity; + } + } + } + } } diff --git a/src/GameObject.hx b/src/GameObject.hx index 98f7626b..205d20f2 100644 --- a/src/GameObject.hx +++ b/src/GameObject.hx @@ -4,4 +4,5 @@ import h3d.scene.Object; class GameObject extends Object { public var identifier:String; + public var currentOpacity:Float = 1; } diff --git a/src/InstanceManager.hx b/src/InstanceManager.hx index 254ea81e..8801eaf8 100644 --- a/src/InstanceManager.hx +++ b/src/InstanceManager.hx @@ -1,5 +1,8 @@ package src; +import shaders.DtsTexture; +import h3d.mat.Pass; +import h3d.shader.AlphaMult; import h2d.col.Matrix; import src.GameObject; import h3d.scene.Scene; @@ -8,11 +11,17 @@ import h3d.scene.Mesh; import h3d.scene.MeshBatch; typedef MeshBatchInfo = { - var instances:Array; + var instances:Array; var meshbatch:MeshBatch; + var ?transparencymeshbatch:MeshBatch; var mesh:Mesh; } +typedef MeshInstance = { + var emptyObj:Object; + var gameObject:GameObject; +} + class InstanceManager { var objects:Map> = new Map(); var scene:Scene; @@ -25,13 +34,29 @@ class InstanceManager { for (obj => meshes in objects) { for (minfo in meshes) { if (minfo.meshbatch != null) { - minfo.meshbatch.begin(minfo.instances.length); - for (instance in minfo.instances) { - var transform = instance.getAbsPos().clone(); + var opaqueinstances = minfo.instances.filter(x -> x.gameObject.currentOpacity == 1); + minfo.meshbatch.begin(opaqueinstances.length); + for (instance in opaqueinstances) { // Draw the opaque shit first + var transform = instance.emptyObj.getAbsPos().clone(); minfo.meshbatch.setTransform(transform); minfo.meshbatch.emitInstance(); } } + if (minfo.transparencymeshbatch != null) { + var transparentinstances = minfo.instances.filter(x -> x.gameObject.currentOpacity != 1); + minfo.transparencymeshbatch.begin(transparentinstances.length); + for (instance in transparentinstances) { // Non opaque shit + var dtsShader = minfo.transparencymeshbatch.material.mainPass.getShader(DtsTexture); + minfo.transparencymeshbatch.material.blendMode = Alpha; + if (dtsShader != null) { + dtsShader.currentOpacity = instance.gameObject.currentOpacity; + minfo.transparencymeshbatch.shadersChanged = true; + } + var transform = instance.emptyObj.getAbsPos().clone(); + minfo.transparencymeshbatch.setTransform(transform); + minfo.transparencymeshbatch.emitInstance(); + } + } } } } @@ -50,7 +75,7 @@ class InstanceManager { var objs = getAllChildren(object); var minfos = objects.get(object.identifier); for (i in 0...objs.length) { - minfos[i].instances.push(objs[i]); + minfos[i].instances.push({emptyObj: objs[i], gameObject: object}); } } else { // First time appending the thing so bruh @@ -60,10 +85,21 @@ class InstanceManager { for (obj in objs) { var isMesh = obj is Mesh; var minfo:MeshBatchInfo = { - instances: [obj], + instances: [{emptyObj: obj, gameObject: object}], meshbatch: isMesh ? new MeshBatch(cast(cast(obj, Mesh).primitive), cast(cast(obj, Mesh)).material.clone(), scene) : null, mesh: isMesh ? cast obj : null } + if (isMesh) { + var mat = cast(obj, Mesh).material; + var dtsshader = mat.mainPass.getShader(DtsTexture); + if (dtsshader != null) { + minfo.meshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader); + minfo.meshbatch.material.mainPass.addShader(dtsshader); + } + minfo.transparencymeshbatch = new MeshBatch(cast(cast(obj, Mesh).primitive), cast(cast(obj, Mesh)).material.clone(), scene); + minfo.transparencymeshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader); + minfo.transparencymeshbatch.material.mainPass.addShader(dtsshader); + } minfos.push(minfo); } objects.set(object.identifier, minfos); diff --git a/src/Main.hx b/src/Main.hx index 0a776690..c056bc98 100644 --- a/src/Main.hx +++ b/src/Main.hx @@ -1,5 +1,6 @@ package; +import shapes.SuperSpeed; import shapes.SignFinish; import shapes.Trapdoor; import shapes.AntiGravity; @@ -34,8 +35,8 @@ class Main extends hxd.App { override function init() { super.init(); - dtsObj = new SignFinish(); - dtsObj.z = 5; + dtsObj = new SuperSpeed(); + // dtsObj.z = 5; world = new MarbleWorld(s3d); @@ -86,6 +87,12 @@ class Main extends hxd.App { // world.addPathedInterior(pi); world.addDtsObject(dtsObj); + dtsObj.setOpacity(0.5); + + var dto = new SuperSpeed(); + world.addDtsObject(dto); + dto.setOpacity(1); + dto.z = 1; // for (i in 0...10) { // for (j in 0...10) { diff --git a/src/Sky.hx b/src/Sky.hx index 2a755179..4ecf506f 100644 --- a/src/Sky.hx +++ b/src/Sky.hx @@ -1,5 +1,7 @@ package src; +import h3d.shader.pbr.PropsValues; +import h3d.shader.AmbientLight; import h3d.scene.pbr.Environment; import src.Util; import src.MarbleWorld; @@ -25,13 +27,15 @@ class Sky extends Object { sky.addUVs(); var skyMesh = new h3d.scene.Mesh(sky, this); skyMesh.material.mainPass.culling = Front; - skyMesh.material.mainPass.setPassName("overlay"); + // This is such a hack + skyMesh.material.mainPass.addShader(new h3d.shader.pbr.PropsValues(1, 0, 0, 1)); + skyMesh.material.blendMode = None; skyMesh.scale(200); var env = new Environment(texture); env.compute(); var renderer = cast(level.scene.renderer, h3d.scene.pbr.Renderer); - // renderer.env = env; - skyMesh.material.mainPass.addShader(new h3d.shader.pbr.CubeLod(texture)); + var shad = new h3d.shader.pbr.CubeLod(texture); + skyMesh.material.mainPass.addShader(shad); skyMesh.material.shadows = false; } diff --git a/src/shaders/DtsTexture.hx b/src/shaders/DtsTexture.hx new file mode 100644 index 00000000..62adf5e2 --- /dev/null +++ b/src/shaders/DtsTexture.hx @@ -0,0 +1,39 @@ +package shaders; + +class DtsTexture extends hxsl.Shader { + static var SRC = { + @input var input:{ + var uv:Vec2; + }; + @const var additive:Bool; + @const var killAlpha:Bool; + @const var specularAlpha:Bool; + @range(0, 1) @param var killAlphaThreshold:Float; + @param var texture:Sampler2D; + @param var currentOpacity:Float; + var calculatedUV:Vec2; + var pixelColor:Vec4; + var specColor:Vec3; + function vertex() { + calculatedUV = input.uv; + } + function fragment() { + var c = texture.get(calculatedUV); + if (killAlpha && c.a - killAlphaThreshold < 0) + discard; + if (additive) + pixelColor += c; + else + pixelColor *= c; + if (specularAlpha) + specColor *= c.aaa; + pixelColor.a *= currentOpacity; + } + } + + public function new(?tex) { + super(); + this.texture = tex; + killAlphaThreshold = h3d.mat.Defaults.defaultKillAlphaThreshold; + } +} diff --git a/src/shapes/SuperSpeed.hx b/src/shapes/SuperSpeed.hx index a35bd419..a895b76e 100644 --- a/src/shapes/SuperSpeed.hx +++ b/src/shapes/SuperSpeed.hx @@ -9,5 +9,6 @@ class SuperSpeed extends DtsObject { this.isCollideable = false; this.isTSStatic = false; this.identifier = "SuperSpeed"; + this.useInstancing = true; } }