Revert "optimize materials"

This reverts commit dfa953d63c.
This commit is contained in:
RandomityGuy 2024-11-05 22:27:18 +05:30
parent 11d06784e4
commit 3bf6d913d9
4 changed files with 388 additions and 441 deletions

View file

@ -1,6 +1,5 @@
package src; package src;
import h3d.scene.MultiMaterial;
import shaders.DefaultCubemapMaterial; import shaders.DefaultCubemapMaterial;
import shaders.DefaultNormalMaterial; import shaders.DefaultNormalMaterial;
import shaders.DefaultMaterial; import shaders.DefaultMaterial;
@ -87,7 +86,7 @@ class TriangleEdge {
class DifCache { class DifCache {
var dif:Dif; var dif:Dif;
var difTriangles:Map<String, Array<DifBuilderTriangle>>; var difTriangles:Map<String, Array<DifBuilderTriangle>>;
var prim:Polygon; var prims:Map<String, Polygon>;
public function new() {} public function new() {}
} }
@ -895,7 +894,7 @@ class DifBuilder {
cache = new DifCache(); cache = new DifCache();
cache.difTriangles = mats; cache.difTriangles = mats;
cache.dif = dif; cache.dif = dif;
cache.prim = null; cache.prims = [];
buildNewCache = true; buildNewCache = true;
difCache.set(cachePath, cache); difCache.set(cachePath, cache);
} }
@ -950,16 +949,12 @@ class DifBuilder {
}); });
var time = Console.time(); var time = Console.time();
var prim:Polygon = null;
if (!buildNewCache && cache != null) {
prim = cache.prim;
} else {
prim = new Polygon();
cache.prim = prim;
}
var materials = [];
for (grp => tris in mats) { for (grp => tris in mats) {
if (buildNewCache || cache == null) { var prim:Polygon = null;
if (!buildNewCache && cache != null) {
prim = cache.prims.get(grp);
} else {
var points = []; var points = [];
var normals = []; var normals = [];
var uvs = []; var uvs = [];
@ -995,13 +990,15 @@ class DifBuilder {
n.push(new Point(-tri.n2.x, tri.n2.y, tri.n2.z)); n.push(new Point(-tri.n2.x, tri.n2.y, tri.n2.z));
n.push(new Point(-tri.n1.x, tri.n1.y, tri.n1.z)); n.push(new Point(-tri.n1.x, tri.n1.y, tri.n1.z));
} }
prim.appendPoints(points); prim = new Polygon(points);
prim.appendUVs(uvs); prim.uvs = uvs;
prim.appendNormals(normals); prim.normals = normals;
prim.appendTangents(t); prim.tangents = t;
prim.appendBitangents(b); prim.bitangents = b;
prim.appendTexMatNormals(n); prim.texMatNormals = n;
prim.nextMaterial(); if (buildNewCache) {
cache.prims.set(grp, prim);
}
} }
var texture:Texture; var texture:Texture;
@ -1029,7 +1026,7 @@ class DifBuilder {
thisprops.light = false; // We will calculate our own lighting thisprops.light = false; // We will calculate our own lighting
material.props = thisprops; material.props = thisprops;
material.shadows = false; material.shadows = false;
material.receiveShadows = false; material.receiveShadows = true;
material.mainPass.setPassName("interior"); material.mainPass.setPassName("interior");
fwd(); fwd();
}); });
@ -1040,26 +1037,20 @@ class DifBuilder {
texture.mipMap = Linear; texture.mipMap = Linear;
material.texture = texture; material.texture = texture;
material.shadows = false; material.shadows = false;
material.receiveShadows = false; material.receiveShadows = true;
} }
} else { } else {
Console.warn('Unable to load ${grp} texture for dif ${path}'); Console.warn('Unable to load ${grp} texture for dif ${path}');
material = Material.create(); material = Material.create();
material.shadows = false; material.shadows = false;
material.receiveShadows = false; material.receiveShadows = true;
} }
// material.mainPass.addShader(new h3d.shader.pbr.PropsValues(1, 0, 0, 1)); // material.mainPass.addShader(new h3d.shader.pbr.PropsValues(1, 0, 0, 1));
if (Debug.wireFrame) if (Debug.wireFrame)
material.mainPass.wireframe = true; material.mainPass.wireframe = true;
materials.push(material); var mesh = new Mesh(prim, material, itr);
} }
if (buildNewCache || cache == null) {
prim.endPrimitive();
}
var mesh = new MultiMaterial(prim, materials, itr);
var interval = Console.time() - time; var interval = Console.time() - time;
Console.log('Geometry build time ${interval}'); Console.log('Geometry build time ${interval}');

View file

@ -1,6 +1,5 @@
package src; package src;
import h3d.scene.MultiMaterial;
import h3d.col.Point; import h3d.col.Point;
import collision.CollisionWorld; import collision.CollisionWorld;
import shaders.EnvMap; import shaders.EnvMap;
@ -224,38 +223,33 @@ class DtsObject extends GameObject {
var vertexNormals = mesh.normals.map(v -> new Vector(-v.x, v.y, v.z)); var vertexNormals = mesh.normals.map(v -> new Vector(-v.x, v.y, v.z));
var geometry = this.generateMaterialGeometry(mesh, vertices, vertexNormals); var geometry = this.generateMaterialGeometry(mesh, vertices, vertexNormals);
var poly = new Polygon();
var usedMats = [];
for (k in 0...geometry.length) { for (k in 0...geometry.length) {
if (geometry[k].vertices.length == 0) if (geometry[k].vertices.length == 0)
continue; continue;
usedMats.push(materials[k]); var poly = new Polygon(geometry[k].vertices);
poly.normals = geometry[k].normals;
poly.uvs = geometry[k].uvs;
poly.tangents = geometry[k].tangents;
poly.bitangents = geometry[k].bitangents;
poly.texMatNormals = geometry[k].texNormals;
poly.appendPoints(geometry[k].vertices); var obj = new Mesh(poly, materials[k], this.graphNodes[i]);
poly.appendUVs(geometry[k].uvs); meshToIndex.set(obj, dts.objects.indexOf(object));
poly.appendNormals(geometry[k].normals);
poly.appendTangents(geometry[k].tangents);
poly.appendBitangents(geometry[k].bitangents);
poly.appendTexMatNormals(geometry[k].texNormals);
poly.nextMaterial();
} }
poly.endPrimitive();
var obj = new MultiMaterial(poly, usedMats, this.graphNodes[i]);
meshToIndex.set(obj, dts.objects.indexOf(object));
poly.endPrimitive();
} else { } else {
// var usedMats = []; var usedMats = [];
// for (prim in mesh.primitives) { for (prim in mesh.primitives) {
// if (!usedMats.contains(prim.matIndex)) { if (!usedMats.contains(prim.matIndex)) {
// usedMats.push(prim.matIndex); usedMats.push(prim.matIndex);
// } }
// } }
var obj = new Object(this.graphNodes[i]); for (k in usedMats) {
meshToIndex.set(obj, dts.objects.indexOf(object)); var obj = new Object(this.graphNodes[i]);
meshToIndex.set(obj, dts.objects.indexOf(object));
}
} }
} }
@ -1544,17 +1538,14 @@ class DtsObject extends GameObject {
var node = this.meshes[idx]; var node = this.meshes[idx];
if (node != null) { if (node != null) {
for (ch in node.getMeshes()) { for (ch in node.getMeshes()) {
var multimat = cast(ch, MultiMaterial); for (pass in ch.material.getPasses()) {
for (mat in multimat.materials) { var alphashader = pass.getShader(AlphaMult);
for (pass in ch.material.getPasses()) { if (alphashader != null)
var alphashader = pass.getShader(AlphaMult); alphashader.alpha = opacity * this.currentOpacity;
if (alphashader != null) else {
alphashader.alpha = opacity * this.currentOpacity; alphashader = new AlphaMult();
else { alphashader.alpha = opacity * this.currentOpacity;
alphashader = new AlphaMult(); pass.addShader(alphashader);
alphashader.alpha = opacity * this.currentOpacity;
pass.addShader(alphashader);
}
} }
} }
} }

View file

@ -1,7 +1,5 @@
package src; package src;
import h3d.mat.Material;
import h3d.scene.MultiMaterial;
import shaders.EnvMap; import shaders.EnvMap;
import h3d.shader.CubeMap; import h3d.shader.CubeMap;
import shaders.NormalMaterial; import shaders.NormalMaterial;
@ -29,8 +27,8 @@ class MeshBatchInfo {
var meshbatch:MeshBatch; var meshbatch:MeshBatch;
var transparencymeshbatch:MeshBatch; var transparencymeshbatch:MeshBatch;
var mesh:Mesh; var mesh:Mesh;
var dtsShaders:Array<DtsTexture>; var dtsShader:DtsTexture;
var glowPassDtsShaders:Array<DtsTexture>; var glowPassDtsShader:DtsTexture;
var baseBounds:h3d.col.Bounds; var baseBounds:h3d.col.Bounds;
public function new() {} public function new() {}
@ -158,43 +156,38 @@ class InstanceManager {
if (minfo.meshbatch != null) { if (minfo.meshbatch != null) {
minfo.meshbatch.begin(opaqueinstances.length); minfo.meshbatch.begin(opaqueinstances.length);
for (instance in opaqueinstances) { // Draw the opaque shit first for (instance in opaqueinstances) { // Draw the opaque shit first
// minfo.meshbatch.material.mainPass.getShader(DtsTexture); var dtsShader = minfo.dtsShader; // minfo.meshbatch.material.mainPass.getShader(DtsTexture);
var subOpacity = 1.0; var subOpacity = 1.0;
var noDraw = false; if (dtsShader != null) {
for (dtsShader in minfo.dtsShaders) { if (instance.gameObject.animateSubObjectOpacities) {
if (dtsShader != null) { subOpacity = instance.gameObject.getSubObjectOpacity(instance.emptyObj);
if (instance.gameObject.animateSubObjectOpacities) { if (subOpacity == 0)
subOpacity = instance.gameObject.getSubObjectOpacity(instance.emptyObj); continue; // Do not draw
if (subOpacity == 0) { // minfo.meshbatch.shadersChanged = true;
noDraw = true;
break;
}
// minfo.meshbatch.shadersChanged = true;
}
dtsShader.currentOpacity = instance.gameObject.currentOpacity * subOpacity;
} }
}
if (noDraw)
continue;
var transform = instance.emptyObj.getAbsPos();
// minfo.meshbatch.material.mainPass.depthWrite = minfo.mesh.material.mainPass.depthWrite;
// minfo.meshbatch.material.mainPass.depthTest = minfo.mesh.material.mainPass.depthTest;
// // minfo.meshbatch.shadersChanged = true;
// minfo.meshbatch.material.mainPass.setPassName(minfo.mesh.material.mainPass.name);
// minfo.meshbatch.material.mainPass.enableLights = minfo.mesh.material.mainPass.enableLights;
minfo.meshbatch.worldPosition = transform;
// minfo.meshbatch.material.mainPass.culling = minfo.mesh.material.mainPass.culling;
// minfo.meshbatch.material.mainPass.blendSrc = minfo.mesh.material.mainPass.blendSrc; dtsShader.currentOpacity = instance.gameObject.currentOpacity * subOpacity;
// minfo.meshbatch.material.mainPass.blendDst = minfo.mesh.material.mainPass.blendDst; }
// minfo.meshbatch.material.mainPass.blendOp = minfo.mesh.material.mainPass.blendOp; var transform = instance.emptyObj.getAbsPos();
// minfo.meshbatch.material.mainPass.blendAlphaSrc = minfo.mesh.material.mainPass.blendAlphaSrc; minfo.meshbatch.material.mainPass.depthWrite = minfo.mesh.material.mainPass.depthWrite;
// minfo.meshbatch.material.mainPass.blendAlphaDst = minfo.mesh.material.mainPass.blendAlphaDst; minfo.meshbatch.material.mainPass.depthTest = minfo.mesh.material.mainPass.depthTest;
// minfo.meshbatch.material.mainPass.blendAlphaOp = minfo.mesh.material.mainPass.blendAlphaOp; // minfo.meshbatch.shadersChanged = true;
minfo.meshbatch.material.mainPass.setPassName(minfo.mesh.material.mainPass.name);
minfo.meshbatch.material.mainPass.enableLights = minfo.mesh.material.mainPass.enableLights;
minfo.meshbatch.worldPosition = transform;
minfo.meshbatch.material.mainPass.culling = minfo.mesh.material.mainPass.culling;
minfo.meshbatch.material.mainPass.blendSrc = minfo.mesh.material.mainPass.blendSrc;
minfo.meshbatch.material.mainPass.blendDst = minfo.mesh.material.mainPass.blendDst;
minfo.meshbatch.material.mainPass.blendOp = minfo.mesh.material.mainPass.blendOp;
minfo.meshbatch.material.mainPass.blendAlphaSrc = minfo.mesh.material.mainPass.blendAlphaSrc;
minfo.meshbatch.material.mainPass.blendAlphaDst = minfo.mesh.material.mainPass.blendAlphaDst;
minfo.meshbatch.material.mainPass.blendAlphaOp = minfo.mesh.material.mainPass.blendAlphaOp;
// handle the glow pass too // handle the glow pass too
for (dtsShader in minfo.glowPassDtsShaders) { var glowPass = minfo.meshbatch.material.getPass("glow");
if (glowPass != null) {
dtsShader = minfo.glowPassDtsShader;
if (dtsShader != null) if (dtsShader != null)
dtsShader.currentOpacity = instance.gameObject.currentOpacity * subOpacity; dtsShader.currentOpacity = instance.gameObject.currentOpacity * subOpacity;
} }
@ -205,16 +198,15 @@ class InstanceManager {
if (minfo.transparencymeshbatch != null) { if (minfo.transparencymeshbatch != null) {
minfo.transparencymeshbatch.begin(transparentinstances.length); minfo.transparencymeshbatch.begin(transparentinstances.length);
for (instance in transparentinstances) { // Non opaque shit for (instance in transparentinstances) { // Non opaque shit
for (dtsShader in minfo.dtsShaders) { var dtsShader = minfo.dtsShader;
if (dtsShader != null) { if (dtsShader != null) {
dtsShader.currentOpacity = instance.gameObject.currentOpacity; dtsShader.currentOpacity = instance.gameObject.currentOpacity;
}
} }
// minfo.transparencymeshbatch.material.blendMode = Alpha; minfo.transparencymeshbatch.material.blendMode = Alpha;
// minfo.transparencymeshbatch.material.color.a = instance.gameObject.currentOpacity; // minfo.transparencymeshbatch.material.color.a = instance.gameObject.currentOpacity;
// minfo.transparencymeshbatch.material.mainPass.setPassName(minfo.mesh.material.mainPass.name); // minfo.transparencymeshbatch.material.mainPass.setPassName(minfo.mesh.material.mainPass.name);
// minfo.transparencymeshbatch.shadersChanged = true; // minfo.transparencymeshbatch.shadersChanged = true;
// minfo.transparencymeshbatch.material.mainPass.enableLights = minfo.mesh.material.mainPass.enableLights; minfo.transparencymeshbatch.material.mainPass.enableLights = minfo.mesh.material.mainPass.enableLights;
// minfo.transparencymeshbatch.material.mainPass.depthWrite = false; // minfo.transparencymeshbatch.material.mainPass.depthWrite = false;
// if (dtsShader != null) { // if (dtsShader != null) {
// dtsShader.currentOpacity = instance.gameObject.currentOpacity; // dtsShader.currentOpacity = instance.gameObject.currentOpacity;
@ -251,196 +243,159 @@ class InstanceManager {
var objs = getAllChildren(object); var objs = getAllChildren(object);
var minfos = []; var minfos = [];
for (obj in objs) { for (obj in objs) {
var isMesh = obj is MultiMaterial; var isMesh = obj is Mesh;
var minfo:MeshBatchInfo = new MeshBatchInfo(); var minfo:MeshBatchInfo = new MeshBatchInfo();
minfo.instances = [new MeshInstance(obj, object)]; minfo.instances = [new MeshInstance(obj, object)];
minfo.meshbatch = isMesh ? new MeshBatch(cast(cast(obj, MultiMaterial).primitive), null, scene) : null; minfo.meshbatch = isMesh ? new MeshBatch(cast(cast(obj, Mesh).primitive), cast(cast(obj, Mesh)).material.clone(), scene) : null;
minfo.mesh = isMesh ? cast obj : null; minfo.mesh = isMesh ? cast obj : null;
minfo.baseBounds = isMesh ? @:privateAccess cast(minfo.meshbatch.primitive, Instanced).baseBounds : null; minfo.baseBounds = isMesh ? @:privateAccess cast(minfo.meshbatch.primitive, Instanced).baseBounds : null;
minfo.dtsShaders = [];
minfo.glowPassDtsShaders = [];
if (isMesh) { if (isMesh) {
minfo.transparencymeshbatch = new MeshBatch(cast(cast(obj, MultiMaterial).primitive), null, scene); var mat = cast(obj, Mesh).material;
minfo.transparencymeshbatch.materials = []; var minfoshaders = [];
minfo.meshbatch.materials = []; for (shader in minfo.meshbatch.material.mainPass.getShaders()) {
for (mat in cast(obj, MultiMaterial).materials) { minfoshaders.push(shader);
var matclone:Material = cast mat.clone(); }
var minfoshaders = []; for (shader in minfoshaders)
for (shader in matclone.mainPass.getShaders()) { minfo.meshbatch.material.mainPass.removeShader(shader);
var addshaders = [];
for (shader in mat.mainPass.getShaders()) {
addshaders.push(shader);
}
for (shader in addshaders)
minfo.meshbatch.material.mainPass.addShader(shader);
var glowPass = mat.getPass("glow");
if (glowPass != null) {
var gpass = glowPass.clone();
gpass.enableLights = false;
gpass.depthTest = glowPass.depthTest;
gpass.blendSrc = glowPass.blendSrc;
gpass.blendDst = glowPass.blendDst;
gpass.blendOp = glowPass.blendOp;
gpass.blendAlphaSrc = glowPass.blendAlphaSrc;
gpass.blendAlphaDst = glowPass.blendAlphaDst;
gpass.blendAlphaOp = glowPass.blendAlphaOp;
if (glowPass.culling == None) {
gpass.culling = glowPass.culling;
}
minfoshaders = [];
for (shader in gpass.getShaders()) {
minfoshaders.push(shader); minfoshaders.push(shader);
} }
for (shader in minfoshaders) for (shader in minfoshaders)
matclone.mainPass.removeShader(shader); gpass.removeShader(shader);
var addshaders = []; var addshaders = [];
for (shader in mat.mainPass.getShaders()) { for (shader in glowPass.getShaders()) {
addshaders.push(shader); addshaders.push(shader);
} }
for (shader in addshaders) for (shader in addshaders)
matclone.mainPass.addShader(shader); gpass.addShader(shader);
var glowPass = mat.getPass("glow");
if (glowPass != null) {
var gpass = glowPass.clone();
gpass.enableLights = false;
gpass.depthTest = glowPass.depthTest;
gpass.blendSrc = glowPass.blendSrc;
gpass.blendDst = glowPass.blendDst;
gpass.blendOp = glowPass.blendOp;
gpass.blendAlphaSrc = glowPass.blendAlphaSrc;
gpass.blendAlphaDst = glowPass.blendAlphaDst;
gpass.blendAlphaOp = glowPass.blendAlphaOp;
if (glowPass.culling == None) {
gpass.culling = glowPass.culling;
}
minfoshaders = []; minfo.glowPassDtsShader = gpass.getShader(DtsTexture);
for (shader in gpass.getShaders()) { minfo.meshbatch.material.addPass(gpass);
minfoshaders.push(shader); }
} var refractPass = mat.getPass("refract");
for (shader in minfoshaders) if (refractPass != null) {
gpass.removeShader(shader); var gpass = refractPass.clone();
var addshaders = []; gpass.enableLights = false;
for (shader in glowPass.getShaders()) { gpass.depthTest = refractPass.depthTest;
addshaders.push(shader); gpass.blendSrc = refractPass.blendSrc;
} gpass.blendDst = refractPass.blendDst;
for (shader in addshaders) gpass.blendOp = refractPass.blendOp;
gpass.addShader(shader); gpass.blendAlphaSrc = refractPass.blendAlphaSrc;
minfo.glowPassDtsShaders.push(gpass.getShader(DtsTexture)); gpass.blendAlphaDst = refractPass.blendAlphaDst;
gpass.blendAlphaOp = refractPass.blendAlphaOp;
matclone.addPass(gpass); if (refractPass.culling == None) {
} else { gpass.culling = refractPass.culling;
minfo.glowPassDtsShaders.push(null);
} }
var refractPass = mat.getPass("refract");
if (refractPass != null) {
var gpass = refractPass.clone();
gpass.enableLights = false;
gpass.depthTest = refractPass.depthTest;
gpass.blendSrc = refractPass.blendSrc;
gpass.blendDst = refractPass.blendDst;
gpass.blendOp = refractPass.blendOp;
gpass.blendAlphaSrc = refractPass.blendAlphaSrc;
gpass.blendAlphaDst = refractPass.blendAlphaDst;
gpass.blendAlphaOp = refractPass.blendAlphaOp;
if (refractPass.culling == None) {
gpass.culling = refractPass.culling;
}
minfoshaders = [];
for (shader in gpass.getShaders()) {
minfoshaders.push(shader);
}
for (shader in minfoshaders)
gpass.removeShader(shader);
var addshaders = [];
for (shader in refractPass.getShaders()) {
addshaders.push(shader);
}
for (shader in addshaders)
gpass.addShader(shader);
matclone.addPass(gpass);
}
var zPass = mat.getPass("zPass");
if (zPass != null) {
var gpass = zPass.clone();
gpass.enableLights = false;
gpass.depthTest = zPass.depthTest;
gpass.blendSrc = zPass.blendSrc;
gpass.blendDst = zPass.blendDst;
gpass.blendOp = zPass.blendOp;
gpass.blendAlphaSrc = zPass.blendAlphaSrc;
gpass.blendAlphaDst = zPass.blendAlphaDst;
gpass.blendAlphaOp = zPass.blendAlphaOp;
gpass.colorMask = zPass.colorMask;
minfoshaders = [];
for (shader in gpass.getShaders()) {
minfoshaders.push(shader);
}
for (shader in minfoshaders)
gpass.removeShader(shader);
var addshaders = [];
for (shader in zPass.getShaders()) {
addshaders.push(shader);
}
for (shader in addshaders)
gpass.addShader(shader);
matclone.addPass(gpass);
}
matclone.mainPass.depthWrite = mat.mainPass.depthWrite;
matclone.mainPass.depthTest = mat.mainPass.depthTest;
// minfo.meshbatch.shadersChanged = true;
matclone.mainPass.setPassName(mat.mainPass.name);
matclone.mainPass.enableLights = mat.mainPass.enableLights;
matclone.mainPass.culling = mat.mainPass.culling;
matclone.mainPass.blendSrc = mat.mainPass.blendSrc;
matclone.mainPass.blendDst = mat.mainPass.blendDst;
matclone.mainPass.blendOp = mat.mainPass.blendOp;
matclone.mainPass.blendAlphaSrc = mat.mainPass.blendAlphaSrc;
matclone.mainPass.blendAlphaDst = mat.mainPass.blendAlphaDst;
matclone.mainPass.blendAlphaOp = mat.mainPass.blendAlphaOp;
minfo.dtsShaders.push(matclone.mainPass.getShader(DtsTexture));
for (p in matclone.getPasses())
@:privateAccess p.batchMode = true;
minfo.meshbatch.materials.push(matclone);
// 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.meshbatch.material.mainPass.culling = mat.mainPass.culling;
// minfo.meshbatch.material.mainPass.depthWrite = mat.mainPass.depthWrite;
// }
// var phongshader = mat.mainPass.getShader(PhongMaterial);
// if (phongshader != null) {
// minfo.meshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader);
// minfo.meshbatch.material.mainPass.addShader(phongshader);
// // minfo.meshbatch.material.mainPass.culling = mat.mainPass.culling;
// }
// var noiseshder = mat.mainPass.getShader(NoiseTileMaterial);
// if (noiseshder != null) {
// minfo.meshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader);
// minfo.meshbatch.material.mainPass.addShader(noiseshder);
// // minfo.meshbatch.material.mainPass.culling = mat.mainPass.culling;
// }
// var nmapshdr = mat.mainPass.getShader(NormalMaterial);
// if (nmapshdr != null) {
// minfo.meshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader);
// minfo.meshbatch.material.mainPass.addShader(nmapshdr);
// // minfo.meshbatch.material.mainPass.culling = mat.mainPass.culling;
// }
// var cubemapshdr = mat.mainPass.getShader(EnvMap);
// if (cubemapshdr != null) {
// minfo.meshbatch.material.mainPass.addShader(cubemapshdr);
// }
var matclonetransp:Material = cast mat.clone();
minfoshaders = []; minfoshaders = [];
for (shader in matclonetransp.mainPass.getShaders()) {
for (shader in gpass.getShaders()) {
minfoshaders.push(shader); minfoshaders.push(shader);
} }
for (shader in minfoshaders) for (shader in minfoshaders)
matclonetransp.mainPass.removeShader(shader); gpass.removeShader(shader);
matclonetransp.mainPass.removeShader(matclonetransp.textureShader); var addshaders = [];
for (shader in mat.mainPass.getShaders()) { for (shader in refractPass.getShaders()) {
matclonetransp.mainPass.addShader(shader); addshaders.push(shader);
} }
for (shader in addshaders)
gpass.addShader(shader);
for (p in matclonetransp.getPasses()) minfo.meshbatch.material.addPass(gpass);
@:privateAccess p.batchMode = true; }
var zPass = mat.getPass("zPass");
if (zPass != null) {
var gpass = zPass.clone();
gpass.enableLights = false;
gpass.depthTest = zPass.depthTest;
gpass.blendSrc = zPass.blendSrc;
gpass.blendDst = zPass.blendDst;
gpass.blendOp = zPass.blendOp;
gpass.blendAlphaSrc = zPass.blendAlphaSrc;
gpass.blendAlphaDst = zPass.blendAlphaDst;
gpass.blendAlphaOp = zPass.blendAlphaOp;
gpass.colorMask = zPass.colorMask;
minfoshaders = [];
matclonetransp.blendMode = Alpha; for (shader in gpass.getShaders()) {
matclonetransp.mainPass.enableLights = mat.mainPass.enableLights; minfoshaders.push(shader);
}
for (shader in minfoshaders)
gpass.removeShader(shader);
var addshaders = [];
for (shader in zPass.getShaders()) {
addshaders.push(shader);
}
for (shader in addshaders)
gpass.addShader(shader);
minfo.transparencymeshbatch.materials.push(matclonetransp); minfo.meshbatch.material.addPass(gpass);
}
minfo.dtsShader = minfo.meshbatch.material.mainPass.getShader(DtsTexture);
// 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.meshbatch.material.mainPass.culling = mat.mainPass.culling;
// minfo.meshbatch.material.mainPass.depthWrite = mat.mainPass.depthWrite;
// }
// var phongshader = mat.mainPass.getShader(PhongMaterial);
// if (phongshader != null) {
// minfo.meshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader);
// minfo.meshbatch.material.mainPass.addShader(phongshader);
// // minfo.meshbatch.material.mainPass.culling = mat.mainPass.culling;
// }
// var noiseshder = mat.mainPass.getShader(NoiseTileMaterial);
// if (noiseshder != null) {
// minfo.meshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader);
// minfo.meshbatch.material.mainPass.addShader(noiseshder);
// // minfo.meshbatch.material.mainPass.culling = mat.mainPass.culling;
// }
// var nmapshdr = mat.mainPass.getShader(NormalMaterial);
// if (nmapshdr != null) {
// minfo.meshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader);
// minfo.meshbatch.material.mainPass.addShader(nmapshdr);
// // minfo.meshbatch.material.mainPass.culling = mat.mainPass.culling;
// }
// var cubemapshdr = mat.mainPass.getShader(EnvMap);
// if (cubemapshdr != null) {
// minfo.meshbatch.material.mainPass.addShader(cubemapshdr);
// }
minfo.transparencymeshbatch = new MeshBatch(cast(cast(obj, Mesh).primitive), cast(cast(obj, Mesh)).material.clone(), scene);
minfoshaders = [];
for (shader in minfo.transparencymeshbatch.material.mainPass.getShaders()) {
minfoshaders.push(shader);
}
for (shader in minfoshaders)
minfo.transparencymeshbatch.material.mainPass.removeShader(shader);
minfo.transparencymeshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader);
for (shader in mat.mainPass.getShaders()) {
minfo.transparencymeshbatch.material.mainPass.addShader(shader);
} }
// minfo.transparencymeshbatch.material.mainPass.culling = mat.mainPass.culling; // minfo.transparencymeshbatch.material.mainPass.culling = mat.mainPass.culling;

View file

@ -4,103 +4,36 @@ import h3d.prim.*;
import h3d.col.Point; import h3d.col.Point;
class Polygon extends MeshPrimitive { class Polygon extends MeshPrimitive {
public var points:Array<Float>; public var points:Array<Point>;
public var normals:Array<Float>; public var normals:Array<Point>;
public var tangents:Array<Float>; public var tangents:Array<Point>;
public var bitangents:Array<Float>; public var bitangents:Array<Point>;
public var texMatNormals:Array<Float>; public var texMatNormals:Array<Point>;
public var uvs:Array<Float>; public var uvs:Array<UV>;
public var indexStarts:Array<Int>; public var idx:hxd.IndexBuffer;
public var indexCounts:Array<Int>;
var currentMaterial:Int = 0;
var curTris = 0;
var bounds:h3d.col.Bounds; var bounds:h3d.col.Bounds;
public function new() { var scaled = 1.;
this.indexStarts = [0]; var translatedX = 0.;
this.indexCounts = []; var translatedY = 0.;
this.points = []; var translatedZ = 0.;
this.uvs = [];
this.normals = []; public function new(points, ?idx) {
this.tangents = []; this.points = points;
this.bitangents = []; this.idx = idx;
this.texMatNormals = [];
} }
override function getBounds() { override function getBounds() {
if (bounds == null) { if (bounds == null) {
var b = new h3d.col.Bounds(); var b = new h3d.col.Bounds();
var i = 0; for (p in points)
while (i < points.length) { b.addPoint(p);
b.addPoint(new h3d.col.Point(points[i], points[i + 1], points[i + 2]));
i += 3;
}
bounds = b; bounds = b;
} }
return bounds; return bounds;
} }
public function appendPoints(pts:Array<Point>) {
for (p in pts) {
this.points.push(p.x);
this.points.push(p.y);
this.points.push(p.z);
}
curTris += Math.floor(pts.length / 3);
}
public function appendNormals(pts:Array<Point>) {
for (p in pts) {
this.normals.push(p.x);
this.normals.push(p.y);
this.normals.push(p.z);
}
}
public function appendTangents(pts:Array<Point>) {
for (p in pts) {
this.tangents.push(p.x);
this.tangents.push(p.y);
this.tangents.push(p.z);
}
}
public function appendBitangents(pts:Array<Point>) {
for (p in pts) {
this.bitangents.push(p.x);
this.bitangents.push(p.y);
this.bitangents.push(p.z);
}
}
public function appendTexMatNormals(pts:Array<Point>) {
for (p in pts) {
this.texMatNormals.push(p.x);
this.texMatNormals.push(p.y);
this.texMatNormals.push(p.z);
}
}
public function appendUVs(uvs:Array<UV>) {
for (uv in uvs) {
this.uvs.push(uv.u);
this.uvs.push(uv.v);
}
}
public function nextMaterial() {
indexStarts.push(Math.floor(this.points.length / 9));
indexCounts.push(curTris);
curTris = 0;
}
public function endPrimitive() {
indexCounts.push(curTris);
curTris = 0;
}
override function alloc(engine:h3d.Engine) { override function alloc(engine:h3d.Engine) {
dispose(); dispose();
@ -134,84 +67,140 @@ class Polygon extends MeshPrimitive {
} }
var buf = new hxd.FloatBuffer(); var buf = new hxd.FloatBuffer();
for (k in 0...Std.int(points.length / 3)) { for (k in 0...points.length) {
buf.push(points[k * 3]); var p = points[k];
buf.push(points[k * 3 + 1]); buf.push(p.x);
buf.push(points[k * 3 + 2]); buf.push(p.y);
buf.push(p.z);
if (normals != null) { if (normals != null) {
buf.push(normals[k * 3]); var n = normals[k];
buf.push(normals[k * 3 + 1]); buf.push(n.x);
buf.push(normals[k * 3 + 2]); buf.push(n.y);
buf.push(n.z);
} }
if (tangents != null) { if (tangents != null) {
buf.push(tangents[k * 3]); var t = tangents[k];
buf.push(tangents[k * 3 + 1]); buf.push(t.x);
buf.push(tangents[k * 3 + 2]); buf.push(t.y);
buf.push(t.z);
} }
if (bitangents != null) { if (bitangents != null) {
buf.push(bitangents[k * 3]); var t = bitangents[k];
buf.push(bitangents[k * 3 + 1]); buf.push(t.x);
buf.push(bitangents[k * 3 + 2]); buf.push(t.y);
buf.push(t.z);
} }
if (texMatNormals != null) { if (texMatNormals != null) {
buf.push(texMatNormals[k * 3]); var t = texMatNormals[k];
buf.push(texMatNormals[k * 3 + 1]); buf.push(t.x);
buf.push(texMatNormals[k * 3 + 2]); buf.push(t.y);
buf.push(t.z);
} }
if (uvs != null) { if (uvs != null) {
var t = uvs[k]; var t = uvs[k];
buf.push(uvs[k * 2]); buf.push(t.u);
buf.push(uvs[k * 2 + 1]); buf.push(t.v);
} }
} }
var flags:Array<h3d.Buffer.BufferFlag> = []; var flags:Array<h3d.Buffer.BufferFlag> = [];
flags.push(Triangles); if (idx == null)
flags.push(Triangles);
if (normals == null || tangents != null) if (normals == null || tangents != null)
flags.push(RawFormat); flags.push(RawFormat);
buffer = h3d.Buffer.ofFloats(buf, size, flags); buffer = h3d.Buffer.ofFloats(buf, size, flags);
for (i in 0...names.length) for (i in 0...names.length)
addBuffer(names[i], buffer, positions[i]); addBuffer(names[i], buffer, positions[i]);
if (idx != null)
indexes = h3d.Indexes.alloc(idx);
}
public function unindex() {
if (idx != null && points.length != idx.length) {
var p = [];
var used = [];
for (i in 0...idx.length)
p.push(points[idx[i]].clone());
if (normals != null) {
var n = [];
for (i in 0...idx.length)
n.push(normals[idx[i]].clone());
normals = n;
}
if (tangents != null) {
var t = [];
for (i in 0...idx.length)
t.push(tangents[idx[i]].clone());
tangents = t;
}
if (uvs != null) {
var t = [];
for (i in 0...idx.length)
t.push(uvs[idx[i]].clone());
uvs = t;
}
points = p;
idx = null;
}
}
public function translate(dx, dy, dz) {
translatedX += dx;
translatedY += dy;
translatedZ += dz;
for (p in points) {
p.x += dx;
p.y += dy;
p.z += dz;
}
}
public function scale(s:Float) {
scaled *= s;
for (p in points) {
p.x *= s;
p.y *= s;
p.z *= s;
}
} }
public function addNormals() { public function addNormals() {
// make per-point normal // make per-point normal
normals = new Array(); normals = new Array();
for (i in 0...points.length) for (i in 0...points.length)
normals[i] = 0; normals[i] = new Point();
var pos = 0; var pos = 0;
for (i in 0...triCount()) { for (i in 0...triCount()) {
var i0, i1, i2; var i0, i1, i2;
i0 = pos++; if (idx == null) {
i1 = pos++; i0 = pos++;
i2 = pos++; i1 = pos++;
var p0 = new h3d.Vector(points[3 * i0], points[3 * i0 + 1], points[3 * i0 + 2]); i2 = pos++;
var p1 = new h3d.Vector(points[3 * i1], points[3 * i1 + 1], points[3 * i1 + 2]); } else {
var p2 = new h3d.Vector(points[3 * i2], points[3 * i2 + 1], points[3 * i2 + 2]); i0 = idx[pos++];
i1 = idx[pos++];
i2 = idx[pos++];
}
var p0 = points[i0];
var p1 = points[i1];
var p2 = points[i2];
// this is the per-face normal // this is the per-face normal
var n = p1.sub(p0).cross(p2.sub(p0)); var n = p1.sub(p0).cross(p2.sub(p0));
// add it to each point // add it to each point
normals[3 * i0] += n.x; normals[i0].x += n.x;
normals[3 * i0 + 1] += n.y; normals[i0].y += n.y;
normals[3 * i0 + 2] += n.z; normals[i0].z += n.z;
normals[i1].x += n.x;
normals[3 * i1] += n.x; normals[i1].y += n.y;
normals[3 * i1 + 1] += n.y; normals[i1].z += n.z;
normals[3 * i1 + 2] += n.z; normals[i2].x += n.x;
normals[i2].y += n.y;
normals[3 * i2] += n.x; normals[i2].z += n.z;
normals[3 * i2 + 1] += n.y;
normals[3 * i2 + 2] += n.z;
} }
// normalize all normals // normalize all normals
for (k in 0...Std.int(points.length / 3)) { for (n in normals)
var n = new h3d.Vector(normals[k * 3], normals[k * 3 + 1], normals[k * 3 + 2]);
n.normalize(); n.normalize();
normals[k * 3] = n.x;
normals[k * 3 + 1] = n.y;
normals[k * 3 + 2] = n.z;
}
} }
public function addTangents() { public function addTangents() {
@ -221,21 +210,26 @@ class Polygon extends MeshPrimitive {
addUVs(); addUVs();
tangents = []; tangents = [];
for (i in 0...points.length) for (i in 0...points.length)
tangents[i] = 0; tangents[i] = new Point();
var pos = 0; var pos = 0;
for (i in 0...triCount()) { for (i in 0...triCount()) {
var i0, i1, i2; var i0, i1, i2;
i0 = pos++; if (idx == null) {
i1 = pos++; i0 = pos++;
i2 = pos++; i1 = pos++;
i2 = pos++;
var p0 = new h3d.Vector(points[3 * i0], points[3 * i0 + 1], points[3 * i0 + 2]); } else {
var p1 = new h3d.Vector(points[3 * i1], points[3 * i1 + 1], points[3 * i1 + 2]); i0 = idx[pos++];
var p2 = new h3d.Vector(points[3 * i2], points[3 * i2 + 1], points[3 * i2 + 2]); i1 = idx[pos++];
var uv0 = new UV(uvs[2 * i0], uvs[2 * i0 + 1]); i2 = idx[pos++];
var uv1 = new UV(uvs[2 * i1], uvs[2 * i1 + 1]); }
var uv2 = new UV(uvs[2 * i2], uvs[2 * i2 + 1]); var p0 = points[i0];
var n = new h3d.Vector(normals[3 * i0], normals[3 * i0 + 1], normals[3 * i0 + 2]); var p1 = points[i1];
var p2 = points[i2];
var uv0 = uvs[i0];
var uv1 = uvs[i1];
var uv2 = uvs[i2];
var n = normals[i0];
var k0 = p1.sub(p0); var k0 = p1.sub(p0);
var k1 = p2.sub(p0); var k1 = p2.sub(p0);
@ -248,33 +242,36 @@ class Polygon extends MeshPrimitive {
t.normalize(); t.normalize();
// add it to each point // add it to each point
tangents[3 * i0] += t.x; tangents[i0].x += t.x;
tangents[3 * i0 + 1] += t.y; tangents[i0].y += t.y;
tangents[3 * i0 + 2] += t.z; tangents[i0].z += t.z;
tangents[i1].x += t.x;
tangents[3 * i1] += t.x; tangents[i1].y += t.y;
tangents[3 * i1 + 1] += t.y; tangents[i1].z += t.z;
tangents[3 * i1 + 2] += t.z; tangents[i2].x += t.x;
tangents[i2].y += t.y;
tangents[3 * i2] += t.x; tangents[i2].z += t.z;
tangents[3 * i2 + 1] += t.y;
tangents[3 * i2 + 2] += t.z;
}
for (k in 0...Std.int(points.length / 3)) {
var n = new h3d.Vector(tangents[k * 3], tangents[k * 3 + 1], tangents[k * 3 + 2]);
n.normalize();
tangents[k * 3] = n.x;
tangents[k * 3 + 1] = n.y;
tangents[k * 3 + 2] = n.z;
} }
for (t in tangents)
t.normalize();
} }
public function addUVs() { public function addUVs() {
uvs = []; uvs = [];
for (k in 0...Std.int(points.length / 3)) { for (i in 0...points.length)
uvs[k * 2] = points[k * 3]; uvs[i] = new UV(points[i].x, points[i].y);
uvs[k * 2 + 1] = points[k * 3 + 1]; }
public function uvScale(su:Float, sv:Float) {
if (uvs == null)
throw "Missing UVs";
var m = new Map<UV, Bool>();
for (t in uvs) {
if (m.exists(t))
continue;
m.set(t, true);
t.u *= su;
t.v *= sv;
} }
} }
@ -282,25 +279,38 @@ class Polygon extends MeshPrimitive {
var n = super.triCount(); var n = super.triCount();
if (n != 0) if (n != 0)
return n; return n;
return Std.int(points.length / 9); return Std.int((idx == null ? points.length : idx.length) / 3);
} }
override function vertexCount() { override function vertexCount() {
return points.length; return points.length;
} }
override function selectMaterial(material:Int) { override function getCollider():h3d.col.Collider {
currentMaterial = material; var vertexes = new haxe.ds.Vector<hxd.impl.Float32>(points.length * 3);
} var indexes = new haxe.ds.Vector<Int>(idx.length);
var vid = 0;
override function getMaterialIndexes(material:Int):{count:Int, start:Int} { for (p in points) {
return {start: indexStarts[material] * 3, count: indexCounts[material] * 3}; vertexes[vid++] = p.x;
vertexes[vid++] = p.y;
vertexes[vid++] = p.z;
}
for (i in 0...idx.length)
indexes[i] = idx[i];
var poly = new h3d.col.Polygon();
poly.addBuffers(vertexes, indexes);
return poly;
} }
override function render(engine:h3d.Engine) { override function render(engine:h3d.Engine) {
if (buffer == null || buffer.isDisposed()) if (buffer == null || buffer.isDisposed())
alloc(engine); alloc(engine);
var bufs = getBuffers(engine); var bufs = getBuffers(engine);
engine.renderMultiBuffers(bufs, engine.mem.triIndexes, indexStarts[currentMaterial], indexCounts[currentMaterial]); if (indexes != null)
engine.renderMultiBuffers(bufs, indexes);
else if (buffer.flags.has(Quads))
engine.renderMultiBuffers(bufs, engine.mem.quadIndexes, 0, triCount());
else
engine.renderMultiBuffers(bufs, engine.mem.triIndexes, 0, triCount());
} }
} }