mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2026-04-27 05:01:38 +00:00
marble reflections for future
This commit is contained in:
parent
dbeb6b7c60
commit
35b353f535
5 changed files with 133 additions and 19 deletions
|
|
@ -1,5 +1,7 @@
|
||||||
package src;
|
package src;
|
||||||
|
|
||||||
|
import shaders.MarbleReflection;
|
||||||
|
import shaders.CubemapRenderer;
|
||||||
import h3d.shader.AlphaMult;
|
import h3d.shader.AlphaMult;
|
||||||
import shaders.DtsTexture;
|
import shaders.DtsTexture;
|
||||||
import collision.gjk.GJK;
|
import collision.gjk.GJK;
|
||||||
|
|
@ -195,21 +197,10 @@ class Marble extends GameObject {
|
||||||
|
|
||||||
var teleporting:Bool = false;
|
var teleporting:Bool = false;
|
||||||
|
|
||||||
|
public var cubemapRenderer:CubemapRenderer;
|
||||||
|
|
||||||
public function new() {
|
public function new() {
|
||||||
super();
|
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.velocity = new Vector();
|
||||||
this.omega = new Vector();
|
this.omega = new Vector();
|
||||||
|
|
@ -244,6 +235,23 @@ class Marble extends GameObject {
|
||||||
|
|
||||||
public function init(level:MarbleWorld, onFinish:Void->Void) {
|
public function init(level:MarbleWorld, onFinish:Void->Void) {
|
||||||
this.level = level;
|
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 = new DtsObject();
|
||||||
this.forcefield.dtsPath = "data/shapes/images/glow_bounce.dts";
|
this.forcefield.dtsPath = "data/shapes/images/glow_bounce.dts";
|
||||||
this.forcefield.useInstancing = true;
|
this.forcefield.useInstancing = true;
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ import triggers.DestinationTrigger;
|
||||||
import shapes.Nuke;
|
import shapes.Nuke;
|
||||||
import shapes.Magnet;
|
import shapes.Magnet;
|
||||||
import src.Replay;
|
import src.Replay;
|
||||||
import hxd.impl.Air3File.FileSeek;
|
|
||||||
import gui.Canvas;
|
import gui.Canvas;
|
||||||
import hxd.snd.Channel;
|
import hxd.snd.Channel;
|
||||||
import hxd.res.Sound;
|
import hxd.res.Sound;
|
||||||
|
|
@ -230,6 +229,9 @@ class MarbleWorld extends Scheduler {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function postInit() {
|
public function postInit() {
|
||||||
|
// Add the sky at the last so that cubemap reflections work
|
||||||
|
this.scene.addChild(this.sky);
|
||||||
|
|
||||||
this._ready = true;
|
this._ready = true;
|
||||||
this.playGui.init(this.scene2d);
|
this.playGui.init(this.scene2d);
|
||||||
var musicFileName = 'data/sound/' + this.mission.missionInfo.music;
|
var musicFileName = 'data/sound/' + this.mission.missionInfo.music;
|
||||||
|
|
@ -295,10 +297,10 @@ class MarbleWorld extends Scheduler {
|
||||||
sky.dmlPath = ResourceLoader.getProperFilepath(skyElement.materiallist);
|
sky.dmlPath = ResourceLoader.getProperFilepath(skyElement.materiallist);
|
||||||
|
|
||||||
worker.addTask(fwd -> sky.init(cast this, fwd));
|
worker.addTask(fwd -> sky.init(cast this, fwd));
|
||||||
worker.addTask(fwd -> {
|
// worker.addTask(fwd -> {
|
||||||
scene.addChild(sky);
|
// scene.addChild(sky);
|
||||||
return fwd();
|
// return fwd();
|
||||||
});
|
// });
|
||||||
|
|
||||||
worker.run();
|
worker.run();
|
||||||
}
|
}
|
||||||
|
|
@ -1014,6 +1016,10 @@ class MarbleWorld extends Scheduler {
|
||||||
asyncLoadResources();
|
asyncLoadResources();
|
||||||
if (this.playGui != null && _ready)
|
if (this.playGui != null && _ready)
|
||||||
this.playGui.render(e);
|
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() {
|
function asyncLoadResources() {
|
||||||
|
|
|
||||||
57
src/shaders/CubemapRenderer.hx
Normal file
57
src/shaders/CubemapRenderer.hx
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
43
src/shaders/MarbleReflection.hx
Normal file
43
src/shaders/MarbleReflection.hx
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -35,7 +35,7 @@ class EasterEgg extends PowerUp {
|
||||||
public override function init(level:src.MarbleWorld, onFinish:() -> Void) {
|
public override function init(level:src.MarbleWorld, onFinish:() -> Void) {
|
||||||
super.init(level, () -> {
|
super.init(level, () -> {
|
||||||
ResourceLoader.load("sound/easter.wav").entry.load(() -> {
|
ResourceLoader.load("sound/easter.wav").entry.load(() -> {
|
||||||
ResourceLoader.load("data/sound/easterfound.wav").entry.load(onFinish);
|
ResourceLoader.load("sound/easterfound.wav").entry.load(onFinish);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue