Implement transparency fading stuff for dts

This commit is contained in:
RandomityGuy 2021-06-06 23:42:40 +05:30
parent 5279ba0247
commit cb12352f4f
8 changed files with 134 additions and 12 deletions

View file

@ -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) {

View file

@ -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<CollisionEntity>;
var mountPointNodes:Array<Int>;
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;
}
}
}
}
}

View file

@ -4,4 +4,5 @@ import h3d.scene.Object;
class GameObject extends Object {
public var identifier:String;
public var currentOpacity:Float = 1;
}

View file

@ -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<Object>;
var instances:Array<MeshInstance>;
var meshbatch:MeshBatch;
var ?transparencymeshbatch:MeshBatch;
var mesh:Mesh;
}
typedef MeshInstance = {
var emptyObj:Object;
var gameObject:GameObject;
}
class InstanceManager {
var objects:Map<String, Array<MeshBatchInfo>> = 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);

View file

@ -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) {

View file

@ -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;
}

39
src/shaders/DtsTexture.hx Normal file
View file

@ -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;
}
}

View file

@ -9,5 +9,6 @@ class SuperSpeed extends DtsObject {
this.isCollideable = false;
this.isTSStatic = false;
this.identifier = "SuperSpeed";
this.useInstancing = true;
}
}