marble reflections for future

This commit is contained in:
RandomityGuy 2022-11-16 23:41:50 +05:30
parent dbeb6b7c60
commit 35b353f535
5 changed files with 133 additions and 19 deletions

View file

@ -1,5 +1,7 @@
package src;
import shaders.MarbleReflection;
import shaders.CubemapRenderer;
import h3d.shader.AlphaMult;
import shaders.DtsTexture;
import collision.gjk.GJK;
@ -195,21 +197,10 @@ class Marble extends GameObject {
var teleporting:Bool = false;
public var cubemapRenderer:CubemapRenderer;
public function new() {
super();
var geom = Sphere.defaultUnitSphere();
geom.addUVs();
var marbleTexture = ResourceLoader.getFileEntry("data/shapes/balls/base.marble.png").toTexture();
var marbleMaterial = Material.create(marbleTexture);
marbleMaterial.shadows = false;
marbleMaterial.castShadows = true;
// marbleMaterial.mainPass.removeShader(marbleMaterial.textureShader);
// var dtsShader = new DtsTexture();
// dtsShader.texture = marbleTexture;
// dtsShader.currentOpacity = 1;
// marbleMaterial.mainPass.addShader(dtsShader);
var obj = new Mesh(geom, marbleMaterial, this);
obj.scale(_radius);
this.velocity = new Vector();
this.omega = new Vector();
@ -244,6 +235,23 @@ class Marble extends GameObject {
public function init(level:MarbleWorld, onFinish:Void->Void) {
this.level = level;
var geom = Sphere.defaultUnitSphere();
geom.addUVs();
var marbleTexture = ResourceLoader.getFileEntry("data/shapes/balls/base.marble.png").toTexture();
var marbleMaterial = Material.create(marbleTexture);
marbleMaterial.shadows = false;
marbleMaterial.castShadows = true;
// marbleMaterial.mainPass.removeShader(marbleMaterial.textureShader);
// var dtsShader = new DtsTexture();
// dtsShader.texture = marbleTexture;
// dtsShader.currentOpacity = 1;
// marbleMaterial.mainPass.addShader(dtsShader);
var obj = new Mesh(geom, marbleMaterial, this);
obj.scale(_radius);
this.cubemapRenderer = new CubemapRenderer(level.scene);
marbleMaterial.mainPass.addShader(new MarbleReflection(this.cubemapRenderer.cubemap));
this.forcefield = new DtsObject();
this.forcefield.dtsPath = "data/shapes/images/glow_bounce.dts";
this.forcefield.useInstancing = true;

View file

@ -9,7 +9,6 @@ import triggers.DestinationTrigger;
import shapes.Nuke;
import shapes.Magnet;
import src.Replay;
import hxd.impl.Air3File.FileSeek;
import gui.Canvas;
import hxd.snd.Channel;
import hxd.res.Sound;
@ -230,6 +229,9 @@ class MarbleWorld extends Scheduler {
}
public function postInit() {
// Add the sky at the last so that cubemap reflections work
this.scene.addChild(this.sky);
this._ready = true;
this.playGui.init(this.scene2d);
var musicFileName = 'data/sound/' + this.mission.missionInfo.music;
@ -295,10 +297,10 @@ class MarbleWorld extends Scheduler {
sky.dmlPath = ResourceLoader.getProperFilepath(skyElement.materiallist);
worker.addTask(fwd -> sky.init(cast this, fwd));
worker.addTask(fwd -> {
scene.addChild(sky);
return fwd();
});
// worker.addTask(fwd -> {
// scene.addChild(sky);
// return fwd();
// });
worker.run();
}
@ -1014,6 +1016,10 @@ class MarbleWorld extends Scheduler {
asyncLoadResources();
if (this.playGui != null && _ready)
this.playGui.render(e);
if (this.marble != null && this.marble.cubemapRenderer != null) {
this.marble.cubemapRenderer.position.load(this.marble.getAbsPos().getPosition());
this.marble.cubemapRenderer.render(e, 0.002);
}
}
function asyncLoadResources() {

View file

@ -0,0 +1,57 @@
package shaders;
import h3d.Vector;
import h3d.scene.Scene;
import h3d.Engine;
import h3d.Camera;
import h3d.mat.Texture;
class CubemapRenderer {
public var cubemap:Texture;
public var position:Vector;
var camera:Camera;
var scene:Scene;
var nextFaceToRender:Int;
public function new(scene:Scene) {
this.scene = scene;
this.cubemap = new Texture(128, 128, [Cube, Dynamic, Target]);
this.camera = new Camera(90, 1, 1);
this.position = new Vector();
this.nextFaceToRender = 0;
}
public function render(e:Engine, budget:Float = 1e8) {
var scenecam = scene.camera;
scene.camera = camera;
var start = haxe.Timer.stamp();
var renderedFaces = 0;
for (i in 0...6) {
var index = (nextFaceToRender + i) % 6;
e.pushTarget(cubemap, index);
this.camera.setCubeMap(index, position);
e.clear(0, 1);
scene.render(e);
e.popTarget();
renderedFaces++;
var time = haxe.Timer.stamp();
var elapsed = time - start;
var elapsedPerFace = elapsed / renderedFaces;
if (elapsedPerFace * (renderedFaces + 1) >= budget)
break;
}
scene.camera = scenecam;
this.nextFaceToRender += renderedFaces;
this.nextFaceToRender %= 6;
}
}

View file

@ -0,0 +1,43 @@
package shaders;
class MarbleReflection extends hxsl.Shader {
static var SRC = {
var pixelColor:Vec4;
var transformedNormal:Vec3;
@param var texture:SamplerCube;
@global var camera:{
var position:Vec3;
};
@input var input:{
var position:Vec3;
var normal:Vec3;
};
var pixelTransformedPosition:Vec3;
function fresnel(direction:Vec3, normal:Vec3, invert:Bool):Float {
var nDirection = normalize(direction);
var nNormal = normalize(normal);
var halfDirection = normalize(nNormal + nDirection);
var exponent = 5.0;
var cosine = dot(halfDirection, nDirection);
var product = max(cosine, 0.0);
var factor = invert ? 1.0 - pow(product, exponent) : pow(product, exponent);
return factor;
}
function fragment() {
var viewDir = normalize(camera.position - pixelTransformedPosition);
var fac = fresnel(viewDir, transformedNormal, true);
var incidentRay = normalize(pixelTransformedPosition - camera.position);
var reflectionRay = reflect(incidentRay, transformedNormal);
var refl = texture.get(reflectionRay);
pixelColor = mix(pixelColor, refl, fac * 0.7);
}
}
public function new(texture) {
super();
this.texture = texture;
}
}

View file

@ -35,7 +35,7 @@ class EasterEgg extends PowerUp {
public override function init(level:src.MarbleWorld, onFinish:() -> Void) {
super.init(level, () -> {
ResourceLoader.load("sound/easter.wav").entry.load(() -> {
ResourceLoader.load("data/sound/easterfound.wav").entry.load(onFinish);
ResourceLoader.load("sound/easterfound.wav").entry.load(onFinish);
});
});
}