mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2025-10-30 08:11:25 +00:00
shader optim
This commit is contained in:
parent
df0477a5c3
commit
dc0f2df246
20 changed files with 622 additions and 11 deletions
|
|
@ -16,7 +16,7 @@ import src.GameObject;
|
||||||
import h3d.scene.Scene;
|
import h3d.scene.Scene;
|
||||||
import h3d.scene.Object;
|
import h3d.scene.Object;
|
||||||
import h3d.scene.Mesh;
|
import h3d.scene.Mesh;
|
||||||
import h3d.scene.MeshBatch;
|
import src.MeshBatch;
|
||||||
import src.MarbleGame;
|
import src.MarbleGame;
|
||||||
import src.ProfilerUI;
|
import src.ProfilerUI;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ import collision.SphereCollisionEntity;
|
||||||
import src.Sky;
|
import src.Sky;
|
||||||
import h3d.scene.Mesh;
|
import h3d.scene.Mesh;
|
||||||
import src.InstanceManager;
|
import src.InstanceManager;
|
||||||
import h3d.scene.MeshBatch;
|
import src.MeshBatch;
|
||||||
import src.DtsObject;
|
import src.DtsObject;
|
||||||
import src.PathedInterior;
|
import src.PathedInterior;
|
||||||
import hxd.Key;
|
import hxd.Key;
|
||||||
|
|
|
||||||
440
src/MeshBatch.hx
Normal file
440
src/MeshBatch.hx
Normal file
|
|
@ -0,0 +1,440 @@
|
||||||
|
package src;
|
||||||
|
|
||||||
|
import h3d.scene.RenderContext;
|
||||||
|
import h3d.Matrix;
|
||||||
|
import h3d.scene.MultiMaterial;
|
||||||
|
import hxsl.ShaderList;
|
||||||
|
|
||||||
|
private class BatchData {
|
||||||
|
public var paramsCount:Int;
|
||||||
|
public var maxInstance:Int;
|
||||||
|
public var matIndex:Int;
|
||||||
|
public var indexCount:Int;
|
||||||
|
public var indexStart:Int;
|
||||||
|
public var instanceBuffers:Array<h3d.impl.InstanceBuffer>;
|
||||||
|
public var buffers:Array<h3d.Buffer> = [];
|
||||||
|
public var data:hxd.FloatBuffer;
|
||||||
|
public var params:hxsl.RuntimeShader.AllocParam;
|
||||||
|
public var shader:hxsl.BatchShader;
|
||||||
|
public var shaders:Array<hxsl.Shader>;
|
||||||
|
public var pass:h3d.mat.Pass;
|
||||||
|
public var next:BatchData;
|
||||||
|
|
||||||
|
public function new() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MeshBatchPart {
|
||||||
|
public var indexStart:Int;
|
||||||
|
public var indexCount:Int;
|
||||||
|
public var baseVertex:Int;
|
||||||
|
public var bounds:h3d.col.Bounds;
|
||||||
|
|
||||||
|
public function new() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
h3d.scene.MeshBatch allows to draw multiple meshed in a single draw call.
|
||||||
|
See samples/MeshBatch.hx for an example.
|
||||||
|
**/
|
||||||
|
class MeshBatch extends MultiMaterial {
|
||||||
|
static var modelViewID = hxsl.Globals.allocID("global.modelView");
|
||||||
|
static var modelViewTransposeID = hxsl.Globals.allocID("global.modelViewTranspose");
|
||||||
|
static var modelViewInverseID = hxsl.Globals.allocID("global.modelViewInverse");
|
||||||
|
static var MAX_BUFFER_ELEMENTS = 4096;
|
||||||
|
|
||||||
|
var instanced:h3d.prim.Instanced;
|
||||||
|
var dataPasses:BatchData;
|
||||||
|
var needUpload = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set if shader list or shader constants has changed, before calling begin()
|
||||||
|
**/
|
||||||
|
public var shadersChanged = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
The number of instances on this batch
|
||||||
|
**/
|
||||||
|
public var instanceCount(default, null):Int = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If set, use this position in emitInstance() instead MeshBatch absolute position
|
||||||
|
**/
|
||||||
|
public var worldPosition:Matrix;
|
||||||
|
|
||||||
|
var invWorldPosition:Matrix;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Tells the mesh batch to draw only a subpart of the primitive
|
||||||
|
**/
|
||||||
|
public var primitiveSubPart:MeshBatchPart;
|
||||||
|
|
||||||
|
var primitiveSubBytes:haxe.io.Bytes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
If set, exact bounds will be recalculated during emitInstance (default true)
|
||||||
|
**/
|
||||||
|
public var calcBounds = true;
|
||||||
|
|
||||||
|
var instancedParams:hxsl.Cache.BatchInstanceParams;
|
||||||
|
|
||||||
|
public function new(primitive, ?material, ?parent) {
|
||||||
|
instanced = new h3d.prim.Instanced();
|
||||||
|
instanced.commands = new h3d.impl.InstanceBuffer();
|
||||||
|
instanced.setMesh(primitive);
|
||||||
|
super(instanced, material == null ? null : [material], parent);
|
||||||
|
for (p in this.material.getPasses())
|
||||||
|
@:privateAccess p.batchMode = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
override function onRemove() {
|
||||||
|
super.onRemove();
|
||||||
|
cleanPasses();
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanPasses() {
|
||||||
|
var alloc = hxd.impl.Allocator.get();
|
||||||
|
while (dataPasses != null) {
|
||||||
|
dataPasses.pass.removeShader(dataPasses.shader);
|
||||||
|
for (b in dataPasses.buffers)
|
||||||
|
alloc.disposeBuffer(b);
|
||||||
|
if (dataPasses.instanceBuffers != null) {
|
||||||
|
for (b in dataPasses.instanceBuffers)
|
||||||
|
b.dispose();
|
||||||
|
}
|
||||||
|
alloc.disposeFloats(dataPasses.data);
|
||||||
|
dataPasses = dataPasses.next;
|
||||||
|
}
|
||||||
|
if (instanced.commands != null)
|
||||||
|
instanced.commands.dispose();
|
||||||
|
shadersChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function initShadersMapping() {
|
||||||
|
var scene = getScene();
|
||||||
|
if (scene == null)
|
||||||
|
return;
|
||||||
|
cleanPasses();
|
||||||
|
for (index in 0...materials.length) {
|
||||||
|
var mat = materials[index];
|
||||||
|
if (mat == null)
|
||||||
|
continue;
|
||||||
|
var matInfo = @:privateAccess instanced.primitive.getMaterialIndexes(index);
|
||||||
|
for (p in mat.getPasses())
|
||||||
|
@:privateAccess {
|
||||||
|
var ctx = scene.renderer.getPassByName(p.name);
|
||||||
|
if (ctx == null)
|
||||||
|
throw "Could't find renderer pass " + p.name;
|
||||||
|
|
||||||
|
var manager = cast(ctx, shaders.RendererDefaultPass).manager;
|
||||||
|
var shaders = p.getShadersRec();
|
||||||
|
var rt = manager.compileShaders(shaders, false);
|
||||||
|
var shader = manager.shaderCache.makeBatchShader(rt, shaders, instancedParams);
|
||||||
|
|
||||||
|
var b = new BatchData();
|
||||||
|
b.indexCount = matInfo.count;
|
||||||
|
b.indexStart = matInfo.start;
|
||||||
|
b.paramsCount = shader.paramsSize;
|
||||||
|
b.maxInstance = Std.int(MAX_BUFFER_ELEMENTS / b.paramsCount);
|
||||||
|
if (b.maxInstance <= 0)
|
||||||
|
throw "Mesh batch shaders needs at least one perInstance parameter";
|
||||||
|
b.params = shader.params;
|
||||||
|
b.shader = shader;
|
||||||
|
b.pass = p;
|
||||||
|
b.matIndex = index;
|
||||||
|
b.shaders = [null /*link shader*/];
|
||||||
|
p.dynamicParameters = true;
|
||||||
|
p.batchMode = true;
|
||||||
|
|
||||||
|
b.next = dataPasses;
|
||||||
|
dataPasses = b;
|
||||||
|
|
||||||
|
var sl = shaders;
|
||||||
|
while (sl != null) {
|
||||||
|
b.shaders.push(sl.s);
|
||||||
|
sl = sl.next;
|
||||||
|
}
|
||||||
|
shader.Batch_Count = b.maxInstance * b.paramsCount;
|
||||||
|
shader.Batch_HasOffset = primitiveSubPart != null;
|
||||||
|
shader.constBits = (shader.Batch_Count << 1) | (shader.Batch_HasOffset ? 1 : 0);
|
||||||
|
shader.updateConstants(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add batch shaders
|
||||||
|
var p = dataPasses;
|
||||||
|
while (p != null) {
|
||||||
|
@:privateAccess p.pass.addSelfShader(p.shader);
|
||||||
|
p = p.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function begin(emitCountTip = -1, resizeDown = false) {
|
||||||
|
instanceCount = 0;
|
||||||
|
instanced.initBounds();
|
||||||
|
if (shadersChanged) {
|
||||||
|
initShadersMapping();
|
||||||
|
shadersChanged = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (emitCountTip < 0)
|
||||||
|
emitCountTip = 128;
|
||||||
|
var p = dataPasses;
|
||||||
|
var alloc = hxd.impl.Allocator.get();
|
||||||
|
while (p != null) {
|
||||||
|
var size = emitCountTip * p.paramsCount * 4;
|
||||||
|
if (p.data == null || p.data.length < size || (resizeDown && p.data.length > size << 1)) {
|
||||||
|
if (p.data != null)
|
||||||
|
alloc.disposeFloats(p.data);
|
||||||
|
p.data = alloc.allocFloats(size);
|
||||||
|
}
|
||||||
|
p = p.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncData(batch:BatchData) {
|
||||||
|
var startPos = batch.paramsCount * instanceCount << 2;
|
||||||
|
// in case we are bigger than emitCountTip
|
||||||
|
if (startPos + (batch.paramsCount << 2) > batch.data.length)
|
||||||
|
batch.data.grow(batch.data.length << 1);
|
||||||
|
|
||||||
|
var p = batch.params;
|
||||||
|
var buf = batch.data;
|
||||||
|
var shaders = batch.shaders;
|
||||||
|
|
||||||
|
var calcInv = false;
|
||||||
|
while (p != null) {
|
||||||
|
var pos = startPos + p.pos;
|
||||||
|
inline function addMatrix(m:h3d.Matrix) {
|
||||||
|
buf[pos++] = m._11;
|
||||||
|
buf[pos++] = m._21;
|
||||||
|
buf[pos++] = m._31;
|
||||||
|
buf[pos++] = m._41;
|
||||||
|
buf[pos++] = m._12;
|
||||||
|
buf[pos++] = m._22;
|
||||||
|
buf[pos++] = m._32;
|
||||||
|
buf[pos++] = m._42;
|
||||||
|
buf[pos++] = m._13;
|
||||||
|
buf[pos++] = m._23;
|
||||||
|
buf[pos++] = m._33;
|
||||||
|
buf[pos++] = m._43;
|
||||||
|
buf[pos++] = m._14;
|
||||||
|
buf[pos++] = m._24;
|
||||||
|
buf[pos++] = m._34;
|
||||||
|
buf[pos++] = m._44;
|
||||||
|
}
|
||||||
|
if (p.perObjectGlobal != null) {
|
||||||
|
if (p.perObjectGlobal.gid == modelViewID) {
|
||||||
|
addMatrix(worldPosition != null ? worldPosition : absPos);
|
||||||
|
} else if (p.perObjectGlobal.gid == modelViewInverseID) {
|
||||||
|
if (worldPosition == null)
|
||||||
|
addMatrix(getInvPos());
|
||||||
|
else {
|
||||||
|
if (!calcInv) {
|
||||||
|
calcInv = true;
|
||||||
|
if (invWorldPosition == null)
|
||||||
|
invWorldPosition = new h3d.Matrix();
|
||||||
|
invWorldPosition.initInverse(worldPosition);
|
||||||
|
}
|
||||||
|
addMatrix(invWorldPosition);
|
||||||
|
}
|
||||||
|
} else if (p.perObjectGlobal.gid == modelViewTransposeID) {
|
||||||
|
var m = worldPosition != null ? worldPosition : absPos;
|
||||||
|
m.transpose();
|
||||||
|
addMatrix(m);
|
||||||
|
m.transpose();
|
||||||
|
} else
|
||||||
|
throw "Unsupported global param " + p.perObjectGlobal.path;
|
||||||
|
p = p.next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var curShader = shaders[p.instance];
|
||||||
|
switch (p.type) {
|
||||||
|
case TVec(size, _):
|
||||||
|
var v:h3d.Vector = curShader.getParamValue(p.index);
|
||||||
|
switch (size) {
|
||||||
|
case 2:
|
||||||
|
buf[pos++] = v.x;
|
||||||
|
buf[pos++] = v.y;
|
||||||
|
case 3:
|
||||||
|
buf[pos++] = v.x;
|
||||||
|
buf[pos++] = v.y;
|
||||||
|
buf[pos++] = v.z;
|
||||||
|
default:
|
||||||
|
buf[pos++] = v.x;
|
||||||
|
buf[pos++] = v.y;
|
||||||
|
buf[pos++] = v.z;
|
||||||
|
buf[pos++] = v.w;
|
||||||
|
}
|
||||||
|
case TFloat:
|
||||||
|
buf[pos++] = curShader.getParamFloatValue(p.index);
|
||||||
|
case TMat4:
|
||||||
|
var m:h3d.Matrix = curShader.getParamValue(p.index);
|
||||||
|
addMatrix(m);
|
||||||
|
default:
|
||||||
|
throw "Unsupported batch type " + p.type;
|
||||||
|
}
|
||||||
|
p = p.next;
|
||||||
|
}
|
||||||
|
needUpload = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
override function addBoundsRec(b:h3d.col.Bounds, relativeTo:h3d.Matrix) {
|
||||||
|
var old = primitive;
|
||||||
|
primitive = null;
|
||||||
|
super.addBoundsRec(b, relativeTo);
|
||||||
|
primitive = old;
|
||||||
|
if (primitive == null || flags.has(FIgnoreBounds))
|
||||||
|
return;
|
||||||
|
// already transformed in absolute
|
||||||
|
var bounds = primitive.getBounds();
|
||||||
|
if (relativeTo == null)
|
||||||
|
b.add(bounds);
|
||||||
|
else
|
||||||
|
b.addTransform(bounds, relativeTo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function emitInstance() {
|
||||||
|
if (worldPosition == null)
|
||||||
|
syncPos();
|
||||||
|
var ps = primitiveSubPart;
|
||||||
|
if (ps != null)
|
||||||
|
@:privateAccess {
|
||||||
|
// instanced.tmpBounds.load(primitiveSubPart.bounds);
|
||||||
|
// instanced.tmpBounds.transform(worldPosition == null ? absPos : worldPosition);
|
||||||
|
// instanced.bounds.add(instanced.tmpBounds);
|
||||||
|
|
||||||
|
if (primitiveSubBytes == null) {
|
||||||
|
primitiveSubBytes = haxe.io.Bytes.alloc(128);
|
||||||
|
instanced.commands = null;
|
||||||
|
}
|
||||||
|
if (primitiveSubBytes.length < (instanceCount + 1) * 20) {
|
||||||
|
var next = haxe.io.Bytes.alloc(Std.int(primitiveSubBytes.length * 3 / 2));
|
||||||
|
next.blit(0, primitiveSubBytes, 0, instanceCount * 20);
|
||||||
|
primitiveSubBytes = next;
|
||||||
|
}
|
||||||
|
var p = instanceCount * 20;
|
||||||
|
primitiveSubBytes.setInt32(p, ps.indexCount);
|
||||||
|
primitiveSubBytes.setInt32(p + 4, 1);
|
||||||
|
primitiveSubBytes.setInt32(p + 8, ps.indexStart);
|
||||||
|
primitiveSubBytes.setInt32(p + 12, ps.baseVertex);
|
||||||
|
primitiveSubBytes.setInt32(p + 16, 0);
|
||||||
|
} else if (calcBounds)
|
||||||
|
instanced.addInstanceBounds(worldPosition == null ? absPos : worldPosition);
|
||||||
|
var p = dataPasses;
|
||||||
|
while (p != null) {
|
||||||
|
syncData(p);
|
||||||
|
p = p.next;
|
||||||
|
}
|
||||||
|
instanceCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function disposeBuffers() {
|
||||||
|
if (instanceCount == 0)
|
||||||
|
return;
|
||||||
|
var p = dataPasses;
|
||||||
|
var alloc = hxd.impl.Allocator.get();
|
||||||
|
while (p != null) {
|
||||||
|
for (b in p.buffers)
|
||||||
|
b.dispose();
|
||||||
|
p = p.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override function sync(ctx:RenderContext) {
|
||||||
|
super.sync(ctx);
|
||||||
|
if (instanceCount == 0)
|
||||||
|
return;
|
||||||
|
var p = dataPasses;
|
||||||
|
var alloc = hxd.impl.Allocator.get();
|
||||||
|
var psBytes = primitiveSubBytes;
|
||||||
|
while (p != null) {
|
||||||
|
var index = 0;
|
||||||
|
var start = 0;
|
||||||
|
while (start < instanceCount) {
|
||||||
|
var upload = needUpload;
|
||||||
|
var buf = p.buffers[index];
|
||||||
|
var count = instanceCount - start;
|
||||||
|
if (count > p.maxInstance)
|
||||||
|
count = p.maxInstance;
|
||||||
|
if (buf == null || buf.isDisposed()) {
|
||||||
|
buf = alloc.allocBuffer(MAX_BUFFER_ELEMENTS, 4, UniformDynamic);
|
||||||
|
p.buffers[index] = buf;
|
||||||
|
upload = true;
|
||||||
|
}
|
||||||
|
if (upload)
|
||||||
|
buf.uploadVector(p.data, start * p.paramsCount * 4, count * p.paramsCount);
|
||||||
|
if (psBytes != null) {
|
||||||
|
if (p.instanceBuffers == null)
|
||||||
|
p.instanceBuffers = [];
|
||||||
|
var buf = p.instanceBuffers[index];
|
||||||
|
if (buf == null /*|| buf.isDisposed()*/) {
|
||||||
|
buf = new h3d.impl.InstanceBuffer();
|
||||||
|
var sub = psBytes.sub(start * 20, count * 20);
|
||||||
|
for (i in 0...count)
|
||||||
|
sub.setInt32(i * 20 + 16, i);
|
||||||
|
buf.setBuffer(count, sub);
|
||||||
|
p.instanceBuffers[index] = buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
start += count;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
while (p.buffers.length > index)
|
||||||
|
alloc.disposeBuffer(p.buffers.pop());
|
||||||
|
p = p.next;
|
||||||
|
}
|
||||||
|
if (psBytes != null) {
|
||||||
|
var prim = cast(primitive, h3d.prim.MeshPrimitive);
|
||||||
|
var offsets = @:privateAccess prim.getBuffer("Batch_Start");
|
||||||
|
if (offsets == null || offsets.vertices < instanceCount || offsets.isDisposed()) {
|
||||||
|
if (offsets != null)
|
||||||
|
offsets.dispose();
|
||||||
|
var tmp = haxe.io.Bytes.alloc(4 * instanceCount);
|
||||||
|
for (i in 0...instanceCount)
|
||||||
|
tmp.setFloat(i << 2, i);
|
||||||
|
offsets = new h3d.Buffer(instanceCount, 1);
|
||||||
|
offsets.uploadBytes(tmp, 0, instanceCount);
|
||||||
|
@:privateAccess prim.addBuffer("Batch_Start", offsets);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
needUpload = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
override function draw(ctx:RenderContext) {
|
||||||
|
var p = dataPasses;
|
||||||
|
while (true) {
|
||||||
|
if (p.pass == ctx.drawPass.pass) {
|
||||||
|
var bufferIndex = ctx.drawPass.index & 0xFFFF;
|
||||||
|
p.shader.Batch_Buffer = p.buffers[bufferIndex];
|
||||||
|
if (p.instanceBuffers == null) {
|
||||||
|
var count = instanceCount - p.maxInstance * bufferIndex;
|
||||||
|
instanced.commands.setCommand(count, p.indexCount, p.indexStart);
|
||||||
|
} else
|
||||||
|
instanced.commands = p.instanceBuffers[bufferIndex];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p = p.next;
|
||||||
|
}
|
||||||
|
ctx.uploadParams();
|
||||||
|
var prev = ctx.drawPass.index;
|
||||||
|
ctx.drawPass.index >>= 16;
|
||||||
|
super.draw(ctx);
|
||||||
|
ctx.drawPass.index = prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
override function emit(ctx:RenderContext) {
|
||||||
|
if (instanceCount == 0)
|
||||||
|
return;
|
||||||
|
var p = dataPasses;
|
||||||
|
while (p != null) {
|
||||||
|
var pass = p.pass;
|
||||||
|
// check that the pass is still enable
|
||||||
|
var material = materials[p.matIndex];
|
||||||
|
if (material != null && material.getPass(pass.name) != null) {
|
||||||
|
for (i in 0...p.buffers.length)
|
||||||
|
ctx.emitPass(pass, this).index = i | (p.matIndex << 16);
|
||||||
|
}
|
||||||
|
p = p.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package src;
|
package src;
|
||||||
|
|
||||||
|
import shaders.RendererDefaultPass;
|
||||||
import hxd.Window;
|
import hxd.Window;
|
||||||
import src.ResourceLoader;
|
import src.ResourceLoader;
|
||||||
import shaders.GammaRamp;
|
import shaders.GammaRamp;
|
||||||
|
|
@ -38,7 +39,7 @@ class Renderer extends h3d.scene.Renderer {
|
||||||
|
|
||||||
public function new() {
|
public function new() {
|
||||||
super();
|
super();
|
||||||
defaultPass = new h3d.pass.Default("default");
|
defaultPass = new RendererDefaultPass("default");
|
||||||
allPasses = [defaultPass, depth, normal, shadow];
|
allPasses = [defaultPass, depth, normal, shadow];
|
||||||
blurShader = new ScreenFx<Blur>(new Blur());
|
blurShader = new ScreenFx<Blur>(new Blur());
|
||||||
copyPass = new h3d.pass.Copy();
|
copyPass = new h3d.pass.Copy();
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ class DefaultCubemapMaterial extends hxsl.Shader {
|
||||||
};
|
};
|
||||||
@global var global:{
|
@global var global:{
|
||||||
@perObject var modelView:Mat4;
|
@perObject var modelView:Mat4;
|
||||||
|
@perObject var modelViewTranspose:Mat4;
|
||||||
@perObject var modelViewInverse:Mat4;
|
@perObject var modelViewInverse:Mat4;
|
||||||
};
|
};
|
||||||
@input var input:{
|
@input var input:{
|
||||||
|
|
@ -58,7 +59,7 @@ class DefaultCubemapMaterial extends hxsl.Shader {
|
||||||
outNormal = input.normal;
|
outNormal = input.normal;
|
||||||
// outNormal.x *= -1;
|
// outNormal.x *= -1;
|
||||||
|
|
||||||
var inLightVec = vec3(-0.5732, 0.27536, -0.77176) * transposeMat3(mat3(global.modelView));
|
var inLightVec = vec3(-0.5732, 0.27536, -0.77176) * mat3(global.modelViewTranspose);
|
||||||
// inLightVec.x *= -1;
|
// inLightVec.x *= -1;
|
||||||
outLightVec.xyz = -inLightVec * objToTangentSpace;
|
outLightVec.xyz = -inLightVec * objToTangentSpace;
|
||||||
// var cubeVertPos = input.position * cubeTrans;
|
// var cubeVertPos = input.position * cubeTrans;
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ class DefaultCubemapNormalMaterial extends hxsl.Shader {
|
||||||
@global var global:{
|
@global var global:{
|
||||||
@perObject var modelView:Mat4;
|
@perObject var modelView:Mat4;
|
||||||
@perObject var modelViewInverse:Mat4;
|
@perObject var modelViewInverse:Mat4;
|
||||||
|
@perObject var modelViewTranspose:Mat4;
|
||||||
};
|
};
|
||||||
@input var input:{
|
@input var input:{
|
||||||
var position:Vec3;
|
var position:Vec3;
|
||||||
|
|
@ -44,7 +45,7 @@ class DefaultCubemapNormalMaterial extends hxsl.Shader {
|
||||||
function vertex() {
|
function vertex() {
|
||||||
calculatedUV = input.uv;
|
calculatedUV = input.uv;
|
||||||
outLightVec = vec4(0);
|
outLightVec = vec4(0);
|
||||||
var inLightVec = vec3(-0.5732, 0.27536, -0.77176) * transposeMat3(mat3(global.modelView));
|
var inLightVec = vec3(-0.5732, 0.27536, -0.77176) * mat3(global.modelViewTranspose);
|
||||||
// inLightVec.x *= -1;
|
// inLightVec.x *= -1;
|
||||||
var eyePos = camera.position * mat3x4(global.modelViewInverse);
|
var eyePos = camera.position * mat3x4(global.modelViewInverse);
|
||||||
// eyePos.x *= -1;
|
// eyePos.x *= -1;
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ class DefaultCubemapNormalNoSpecMaterial extends hxsl.Shader {
|
||||||
@global var global:{
|
@global var global:{
|
||||||
@perObject var modelView:Mat4;
|
@perObject var modelView:Mat4;
|
||||||
@perObject var modelViewInverse:Mat4;
|
@perObject var modelViewInverse:Mat4;
|
||||||
|
@perObject var modelViewTranspose:Mat4;
|
||||||
};
|
};
|
||||||
@input var input:{
|
@input var input:{
|
||||||
var position:Vec3;
|
var position:Vec3;
|
||||||
|
|
@ -38,7 +39,7 @@ class DefaultCubemapNormalNoSpecMaterial extends hxsl.Shader {
|
||||||
}
|
}
|
||||||
function vertex() {
|
function vertex() {
|
||||||
calculatedUV = input.uv;
|
calculatedUV = input.uv;
|
||||||
var inLightVec = vec3(-0.5732, 0.27536, -0.77176) * transposeMat3(mat3(global.modelView));
|
var inLightVec = vec3(-0.5732, 0.27536, -0.77176) * mat3(global.modelViewTranspose);
|
||||||
// inLightVec.x *= -1;
|
// inLightVec.x *= -1;
|
||||||
var pN = input.normal;
|
var pN = input.normal;
|
||||||
// pN.x *= -1;
|
// pN.x *= -1;
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ class DefaultDiffuseMaterial extends hxsl.Shader {
|
||||||
@global var global:{
|
@global var global:{
|
||||||
@perObject var modelView:Mat4;
|
@perObject var modelView:Mat4;
|
||||||
@perObject var modelViewInverse:Mat4;
|
@perObject var modelViewInverse:Mat4;
|
||||||
|
@perObject var modelViewTranspose:Mat4;
|
||||||
};
|
};
|
||||||
@input var input:{
|
@input var input:{
|
||||||
var position:Vec3;
|
var position:Vec3;
|
||||||
|
|
@ -28,7 +29,7 @@ class DefaultDiffuseMaterial extends hxsl.Shader {
|
||||||
function vertex() {
|
function vertex() {
|
||||||
calculatedUV = input.uv;
|
calculatedUV = input.uv;
|
||||||
var objToTangentSpace = mat3(input.t, input.b, input.n);
|
var objToTangentSpace = mat3(input.t, input.b, input.n);
|
||||||
var inLightVec = vec3(-0.5732, 0.27536, -0.77176) * transposeMat3(mat3(global.modelView));
|
var inLightVec = vec3(-0.5732, 0.27536, -0.77176) * mat3(global.modelViewTranspose);
|
||||||
// inLightVec.x *= -1;
|
// inLightVec.x *= -1;
|
||||||
var n = input.normal;
|
var n = input.normal;
|
||||||
// n.x *= -1;
|
// n.x *= -1;
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ class DefaultMaterial extends hxsl.Shader {
|
||||||
@global var global:{
|
@global var global:{
|
||||||
@perObject var modelView:Mat4;
|
@perObject var modelView:Mat4;
|
||||||
@perObject var modelViewInverse:Mat4;
|
@perObject var modelViewInverse:Mat4;
|
||||||
|
@perObject var modelViewTranspose:Mat4;
|
||||||
};
|
};
|
||||||
@input var input:{
|
@input var input:{
|
||||||
var position:Vec3;
|
var position:Vec3;
|
||||||
|
|
@ -46,7 +47,7 @@ class DefaultMaterial extends hxsl.Shader {
|
||||||
}
|
}
|
||||||
var objToTangentSpace = mat3(input.t, input.b, input.n);
|
var objToTangentSpace = mat3(input.t, input.b, input.n);
|
||||||
outLightVec = vec4(0);
|
outLightVec = vec4(0);
|
||||||
var inLightVec = vec3(-0.5732, 0.27536, -0.77176) * transposeMat3(mat3(global.modelView));
|
var inLightVec = vec3(-0.5732, 0.27536, -0.77176) * mat3(global.modelViewTranspose);
|
||||||
// inLightVec.x *= -1;
|
// inLightVec.x *= -1;
|
||||||
var eyePos = camera.position * mat3x4(global.modelViewInverse);
|
var eyePos = camera.position * mat3x4(global.modelViewInverse);
|
||||||
// eyePos.x *= -1;
|
// eyePos.x *= -1;
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ class DefaultNormalMaterial extends hxsl.Shader {
|
||||||
@global var global:{
|
@global var global:{
|
||||||
@perObject var modelView:Mat4;
|
@perObject var modelView:Mat4;
|
||||||
@perObject var modelViewInverse:Mat4;
|
@perObject var modelViewInverse:Mat4;
|
||||||
|
@perObject var modelViewTranspose:Mat4;
|
||||||
};
|
};
|
||||||
@input var input:{
|
@input var input:{
|
||||||
var position:Vec3;
|
var position:Vec3;
|
||||||
|
|
@ -42,7 +43,7 @@ class DefaultNormalMaterial extends hxsl.Shader {
|
||||||
function vertex() {
|
function vertex() {
|
||||||
calculatedUV = input.uv;
|
calculatedUV = input.uv;
|
||||||
outLightVec = vec4(0);
|
outLightVec = vec4(0);
|
||||||
var inLightVec = vec3(-0.5732, 0.27536, -0.77176) * transposeMat3(mat3(global.modelView));
|
var inLightVec = vec3(-0.5732, 0.27536, -0.77176) * mat3(global.modelViewTranspose);
|
||||||
// inLightVec.x *= -1;
|
// inLightVec.x *= -1;
|
||||||
var eyePos = camera.position * mat3x4(global.modelViewInverse);
|
var eyePos = camera.position * mat3x4(global.modelViewInverse);
|
||||||
// eyePos.x *= -1;
|
// eyePos.x *= -1;
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ class NoiseTileMaterial extends hxsl.Shader {
|
||||||
@global var global:{
|
@global var global:{
|
||||||
@perObject var modelView:Mat4;
|
@perObject var modelView:Mat4;
|
||||||
@perObject var modelViewInverse:Mat4;
|
@perObject var modelViewInverse:Mat4;
|
||||||
|
@perObject var modelViewTranspose:Mat4;
|
||||||
};
|
};
|
||||||
@input var input:{
|
@input var input:{
|
||||||
var position:Vec3;
|
var position:Vec3;
|
||||||
|
|
@ -42,7 +43,7 @@ class NoiseTileMaterial extends hxsl.Shader {
|
||||||
calculatedUV = input.uv;
|
calculatedUV = input.uv;
|
||||||
var objToTangentSpace = mat3(input.t, input.b, input.n);
|
var objToTangentSpace = mat3(input.t, input.b, input.n);
|
||||||
outLightVec = vec4(0);
|
outLightVec = vec4(0);
|
||||||
var inLightVec = vec3(-0.5732, 0.27536, -0.77176) * transposeMat3(mat3(global.modelView));
|
var inLightVec = vec3(-0.5732, 0.27536, -0.77176) * mat3(global.modelViewTranspose);
|
||||||
// inLightVec.x *= -1;
|
// inLightVec.x *= -1;
|
||||||
var eyePos = camera.position * mat3x4(global.modelViewInverse);
|
var eyePos = camera.position * mat3x4(global.modelViewInverse);
|
||||||
// eyePos.x *= -1;
|
// eyePos.x *= -1;
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ class RefractMaterial extends hxsl.Shader {
|
||||||
@global var global:{
|
@global var global:{
|
||||||
@perObject var modelView:Mat4;
|
@perObject var modelView:Mat4;
|
||||||
@perObject var modelViewInverse:Mat4;
|
@perObject var modelViewInverse:Mat4;
|
||||||
|
@perObject var modelViewTranspose:Mat4;
|
||||||
};
|
};
|
||||||
@input var input:{
|
@input var input:{
|
||||||
var position:Vec3;
|
var position:Vec3;
|
||||||
|
|
@ -44,7 +45,7 @@ class RefractMaterial extends hxsl.Shader {
|
||||||
calculatedUV = input.uv;
|
calculatedUV = input.uv;
|
||||||
var objToTangentSpace = mat3(input.t, input.b, input.n);
|
var objToTangentSpace = mat3(input.t, input.b, input.n);
|
||||||
outLightVec = vec4(0);
|
outLightVec = vec4(0);
|
||||||
var inLightVec = vec3(-0.5732, 0.27536, -0.77176) * transposeMat3(mat3(global.modelView));
|
var inLightVec = vec3(-0.5732, 0.27536, -0.77176) * mat3(global.modelViewTranspose);
|
||||||
// inLightVec.x *= -1;
|
// inLightVec.x *= -1;
|
||||||
var eyePos = camera.position * mat3x4(global.modelViewInverse);
|
var eyePos = camera.position * mat3x4(global.modelViewInverse);
|
||||||
// eyePos.x *= -1;
|
// eyePos.x *= -1;
|
||||||
|
|
|
||||||
155
src/shaders/RendererDefaultPass.hx
Normal file
155
src/shaders/RendererDefaultPass.hx
Normal file
|
|
@ -0,0 +1,155 @@
|
||||||
|
package shaders;
|
||||||
|
|
||||||
|
import h3d.pass.PassObject;
|
||||||
|
import h3d.pass.ShaderManager;
|
||||||
|
import h3d.pass.Base;
|
||||||
|
import h3d.pass.SortByMaterial;
|
||||||
|
|
||||||
|
@:build(hxsl.Macros.buildGlobals())
|
||||||
|
@:access(h3d.mat.Pass)
|
||||||
|
class RendererDefaultPass extends Base {
|
||||||
|
var manager:ShaderManager;
|
||||||
|
var globals(get, never):hxsl.Globals;
|
||||||
|
var defaultSort = new SortByMaterial().sort;
|
||||||
|
|
||||||
|
inline function get_globals()
|
||||||
|
return manager.globals;
|
||||||
|
|
||||||
|
@global("camera.view") var cameraView:h3d.Matrix = ctx.camera.mcam;
|
||||||
|
@global("camera.zNear") var cameraNear:Float = ctx.camera.zNear;
|
||||||
|
@global("camera.zFar") var cameraFar:Float = ctx.camera.zFar;
|
||||||
|
@global("camera.proj") var cameraProj:h3d.Matrix = ctx.camera.mproj;
|
||||||
|
@global("camera.position") var cameraPos:h3d.Vector = ctx.camera.pos;
|
||||||
|
@global("camera.projDiag") var cameraProjDiag:h3d.Vector = new h3d.Vector(ctx.camera.mproj._11, ctx.camera.mproj._22, ctx.camera.mproj._33,
|
||||||
|
ctx.camera.mproj._44);
|
||||||
|
@global("camera.projFlip") var cameraProjFlip:Float = ctx.engine.driver.hasFeature(BottomLeftCoords)
|
||||||
|
&& ctx.engine.getCurrentTarget() != null ? -1 : 1;
|
||||||
|
@global("camera.viewProj") var cameraViewProj:h3d.Matrix = ctx.camera.m;
|
||||||
|
@global("camera.inverseViewProj") var cameraInverseViewProj:h3d.Matrix = ctx.camera.getInverseViewProj();
|
||||||
|
@global("global.time") var globalTime:Float = ctx.time;
|
||||||
|
@global("global.pixelSize") var pixelSize:h3d.Vector = getCurrentPixelSize();
|
||||||
|
@global("global.modelView") var globalModelView:h3d.Matrix;
|
||||||
|
@global("global.modelViewInverse") var globalModelViewInverse:h3d.Matrix;
|
||||||
|
@global("global.modelViewTranspose") var globalModelViewTranspose:h3d.Matrix;
|
||||||
|
|
||||||
|
public function new(name) {
|
||||||
|
super(name);
|
||||||
|
manager = new ShaderManager(getOutputs());
|
||||||
|
initGlobals();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCurrentPixelSize() {
|
||||||
|
var t = ctx.engine.getCurrentTarget();
|
||||||
|
return new h3d.Vector(2 / (t == null ? ctx.engine.width : t.width), 2 / (t == null ? ctx.engine.height : t.height));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOutputs():Array<hxsl.Output> {
|
||||||
|
return [Value("output.color")];
|
||||||
|
}
|
||||||
|
|
||||||
|
override function compileShader(p:h3d.mat.Pass) {
|
||||||
|
var o = @:privateAccess new h3d.pass.PassObject();
|
||||||
|
o.pass = p;
|
||||||
|
setupShaders(new h3d.pass.PassList(o));
|
||||||
|
return manager.compileShaders(o.shaders, p.batchMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
function processShaders(p:h3d.pass.PassObject, shaders:hxsl.ShaderList) {
|
||||||
|
var p = ctx.extraShaders;
|
||||||
|
while (p != null) {
|
||||||
|
shaders = ctx.allocShaderList(p.s, shaders);
|
||||||
|
p = p.next;
|
||||||
|
}
|
||||||
|
return shaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
@:access(h3d.scene)
|
||||||
|
function setupShaders(passes:h3d.pass.PassList) {
|
||||||
|
var lightInit = false;
|
||||||
|
for (p in passes) {
|
||||||
|
var shaders = p.pass.getShadersRec();
|
||||||
|
shaders = processShaders(p, shaders);
|
||||||
|
if (p.pass.enableLights && ctx.lightSystem != null) {
|
||||||
|
if (!lightInit) {
|
||||||
|
ctx.lightSystem.initGlobals(globals);
|
||||||
|
lightInit = true;
|
||||||
|
}
|
||||||
|
shaders = ctx.lightSystem.computeLight(p.obj, shaders);
|
||||||
|
}
|
||||||
|
p.shader = manager.compileShaders(shaders, p.pass.batchMode);
|
||||||
|
p.shaders = shaders;
|
||||||
|
var t = p.shader.fragment.textures;
|
||||||
|
if (t == null || t.type.match(TArray(_)))
|
||||||
|
p.texture = 0;
|
||||||
|
else {
|
||||||
|
var t:h3d.mat.Texture = manager.getParamValue(t, shaders, true);
|
||||||
|
p.texture = t == null ? 0 : t.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline function log(str:String) {
|
||||||
|
ctx.engine.driver.log(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawObject(p:h3d.pass.PassObject) {
|
||||||
|
ctx.drawPass = p;
|
||||||
|
ctx.engine.selectMaterial(p.pass);
|
||||||
|
@:privateAccess p.obj.draw(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static public dynamic function onShaderError(e:Dynamic, p:PassObject) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
@:access(h3d.scene)
|
||||||
|
override function draw(passes:h3d.pass.PassList, ?sort:h3d.pass.PassList->Void) {
|
||||||
|
if (passes.isEmpty())
|
||||||
|
return;
|
||||||
|
#if sceneprof h3d.impl.SceneProf.begin("draw", ctx.frame); #end
|
||||||
|
for (g in ctx.sharedGlobals)
|
||||||
|
globals.fastSet(g.gid, g.value);
|
||||||
|
setGlobals();
|
||||||
|
setupShaders(passes);
|
||||||
|
if (sort == null)
|
||||||
|
defaultSort(passes);
|
||||||
|
else
|
||||||
|
sort(passes);
|
||||||
|
ctx.currentManager = manager;
|
||||||
|
var buf = ctx.shaderBuffers, prevShader = null;
|
||||||
|
for (p in passes) {
|
||||||
|
#if sceneprof h3d.impl.SceneProf.mark(p.obj); #end
|
||||||
|
globalModelView = p.obj.absPos;
|
||||||
|
if (p.shader.hasGlobal(globalModelViewTranspose_id.toInt())) {
|
||||||
|
globalModelViewTranspose = globalModelView.clone();
|
||||||
|
globalModelViewTranspose.transpose();
|
||||||
|
}
|
||||||
|
if (p.shader.hasGlobal(globalModelViewInverse_id.toInt()))
|
||||||
|
globalModelViewInverse = p.obj.getInvPos();
|
||||||
|
if (prevShader != p.shader) {
|
||||||
|
prevShader = p.shader;
|
||||||
|
try {
|
||||||
|
ctx.engine.selectShader(p.shader);
|
||||||
|
} catch (e:Dynamic) {
|
||||||
|
onShaderError(e, p);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (buf == null)
|
||||||
|
buf = ctx.shaderBuffers = new h3d.shader.Buffers(p.shader);
|
||||||
|
else
|
||||||
|
buf.grow(p.shader);
|
||||||
|
manager.fillGlobals(buf, p.shader);
|
||||||
|
ctx.engine.uploadShaderBuffers(buf, Globals);
|
||||||
|
}
|
||||||
|
if (!p.pass.dynamicParameters) {
|
||||||
|
manager.fillParams(buf, p.shader, p.shaders);
|
||||||
|
ctx.engine.uploadShaderBuffers(buf, Params);
|
||||||
|
ctx.engine.uploadShaderBuffers(buf, Textures);
|
||||||
|
ctx.engine.uploadShaderBuffers(buf, Buffers);
|
||||||
|
}
|
||||||
|
drawObject(p);
|
||||||
|
}
|
||||||
|
#if sceneprof h3d.impl.SceneProf.end(); #end
|
||||||
|
ctx.nextPass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -14,6 +14,7 @@ class ClassicGlass extends hxsl.Shader {
|
||||||
};
|
};
|
||||||
@global var global:{
|
@global var global:{
|
||||||
@perObject var modelView:Mat4;
|
@perObject var modelView:Mat4;
|
||||||
|
@perObject var modelViewTranspose:Mat4;
|
||||||
@perObject var modelViewInverse:Mat4;
|
@perObject var modelViewInverse:Mat4;
|
||||||
};
|
};
|
||||||
@input var input:{
|
@input var input:{
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ class ClassicGlassPureSphere extends hxsl.Shader {
|
||||||
};
|
};
|
||||||
@global var global:{
|
@global var global:{
|
||||||
@perObject var modelView:Mat4;
|
@perObject var modelView:Mat4;
|
||||||
|
@perObject var modelViewTranspose:Mat4;
|
||||||
@perObject var modelViewInverse:Mat4;
|
@perObject var modelViewInverse:Mat4;
|
||||||
};
|
};
|
||||||
@input var input:{
|
@input var input:{
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ class ClassicMarb extends hxsl.Shader {
|
||||||
};
|
};
|
||||||
@global var global:{
|
@global var global:{
|
||||||
@perObject var modelView:Mat4;
|
@perObject var modelView:Mat4;
|
||||||
|
@perObject var modelViewTranspose:Mat4;
|
||||||
@perObject var modelViewInverse:Mat4;
|
@perObject var modelViewInverse:Mat4;
|
||||||
};
|
};
|
||||||
@input var input:{
|
@input var input:{
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ class ClassicMarb2 extends hxsl.Shader {
|
||||||
};
|
};
|
||||||
@global var global:{
|
@global var global:{
|
||||||
@perObject var modelView:Mat4;
|
@perObject var modelView:Mat4;
|
||||||
|
@perObject var modelViewTranspose:Mat4;
|
||||||
@perObject var modelViewInverse:Mat4;
|
@perObject var modelViewInverse:Mat4;
|
||||||
};
|
};
|
||||||
@input var input:{
|
@input var input:{
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ class ClassicMarb3 extends hxsl.Shader {
|
||||||
};
|
};
|
||||||
@global var global:{
|
@global var global:{
|
||||||
@perObject var modelView:Mat4;
|
@perObject var modelView:Mat4;
|
||||||
|
@perObject var modelViewTranspose:Mat4;
|
||||||
@perObject var modelViewInverse:Mat4;
|
@perObject var modelViewInverse:Mat4;
|
||||||
};
|
};
|
||||||
@input var input:{
|
@input var input:{
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ class ClassicMetal extends hxsl.Shader {
|
||||||
};
|
};
|
||||||
@global var global:{
|
@global var global:{
|
||||||
@perObject var modelView:Mat4;
|
@perObject var modelView:Mat4;
|
||||||
|
@perObject var modelViewTranspose:Mat4;
|
||||||
@perObject var modelViewInverse:Mat4;
|
@perObject var modelViewInverse:Mat4;
|
||||||
};
|
};
|
||||||
@input var input:{
|
@input var input:{
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ class CrystalMarb extends hxsl.Shader {
|
||||||
};
|
};
|
||||||
@global var global:{
|
@global var global:{
|
||||||
@perObject var modelView:Mat4;
|
@perObject var modelView:Mat4;
|
||||||
|
@perObject var modelViewTranspose:Mat4;
|
||||||
@perObject var modelViewInverse:Mat4;
|
@perObject var modelViewInverse:Mat4;
|
||||||
};
|
};
|
||||||
@input var input:{
|
@input var input:{
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue