optimize materials

This commit is contained in:
RandomityGuy 2024-06-28 23:10:52 +05:30
parent aa91022a77
commit dfa953d63c
4 changed files with 433 additions and 385 deletions

View file

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

View file

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

View file

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

View file

@ -4,36 +4,103 @@ import h3d.prim.*;
import h3d.col.Point;
class Polygon extends MeshPrimitive {
public var points:Array<Point>;
public var normals:Array<Point>;
public var tangents:Array<Point>;
public var bitangents:Array<Point>;
public var texMatNormals:Array<Point>;
public var uvs:Array<UV>;
public var idx:hxd.IndexBuffer;
public var points:Array<Float>;
public var normals:Array<Float>;
public var tangents:Array<Float>;
public var bitangents:Array<Float>;
public var texMatNormals:Array<Float>;
public var uvs:Array<Float>;
public var indexStarts:Array<Int>;
public var indexCounts:Array<Int>;
var currentMaterial:Int = 0;
var curTris = 0;
var bounds:h3d.col.Bounds;
var scaled = 1.;
var translatedX = 0.;
var translatedY = 0.;
var translatedZ = 0.;
public function new(points, ?idx) {
this.points = points;
this.idx = idx;
public function new() {
this.indexStarts = [0];
this.indexCounts = [];
this.points = [];
this.uvs = [];
this.normals = [];
this.tangents = [];
this.bitangents = [];
this.texMatNormals = [];
}
override function getBounds() {
if (bounds == null) {
var b = new h3d.col.Bounds();
for (p in points)
b.addPoint(p);
var i = 0;
while (i < points.length) {
b.addPoint(new h3d.col.Point(points[i], points[i + 1], points[i + 2]));
i += 3;
}
bounds = b;
}
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) {
dispose();
@ -67,140 +134,84 @@ class Polygon extends MeshPrimitive {
}
var buf = new hxd.FloatBuffer();
for (k in 0...points.length) {
var p = points[k];
buf.push(p.x);
buf.push(p.y);
buf.push(p.z);
for (k in 0...Std.int(points.length / 3)) {
buf.push(points[k * 3]);
buf.push(points[k * 3 + 1]);
buf.push(points[k * 3 + 2]);
if (normals != null) {
var n = normals[k];
buf.push(n.x);
buf.push(n.y);
buf.push(n.z);
buf.push(normals[k * 3]);
buf.push(normals[k * 3 + 1]);
buf.push(normals[k * 3 + 2]);
}
if (tangents != null) {
var t = tangents[k];
buf.push(t.x);
buf.push(t.y);
buf.push(t.z);
buf.push(tangents[k * 3]);
buf.push(tangents[k * 3 + 1]);
buf.push(tangents[k * 3 + 2]);
}
if (bitangents != null) {
var t = bitangents[k];
buf.push(t.x);
buf.push(t.y);
buf.push(t.z);
buf.push(bitangents[k * 3]);
buf.push(bitangents[k * 3 + 1]);
buf.push(bitangents[k * 3 + 2]);
}
if (texMatNormals != null) {
var t = texMatNormals[k];
buf.push(t.x);
buf.push(t.y);
buf.push(t.z);
buf.push(texMatNormals[k * 3]);
buf.push(texMatNormals[k * 3 + 1]);
buf.push(texMatNormals[k * 3 + 2]);
}
if (uvs != null) {
var t = uvs[k];
buf.push(t.u);
buf.push(t.v);
buf.push(uvs[k * 2]);
buf.push(uvs[k * 2 + 1]);
}
}
var flags:Array<h3d.Buffer.BufferFlag> = [];
if (idx == null)
flags.push(Triangles);
flags.push(Triangles);
if (normals == null || tangents != null)
flags.push(RawFormat);
buffer = h3d.Buffer.ofFloats(buf, size, flags);
for (i in 0...names.length)
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() {
// make per-point normal
normals = new Array();
for (i in 0...points.length)
normals[i] = new Point();
normals[i] = 0;
var pos = 0;
for (i in 0...triCount()) {
var i0, i1, i2;
if (idx == null) {
i0 = pos++;
i1 = pos++;
i2 = pos++;
} else {
i0 = idx[pos++];
i1 = idx[pos++];
i2 = idx[pos++];
}
var p0 = points[i0];
var p1 = points[i1];
var p2 = points[i2];
i0 = pos++;
i1 = pos++;
i2 = pos++;
var p0 = new h3d.Vector(points[3 * i0], points[3 * i0 + 1], points[3 * i0 + 2]);
var p1 = new h3d.Vector(points[3 * i1], points[3 * i1 + 1], points[3 * i1 + 2]);
var p2 = new h3d.Vector(points[3 * i2], points[3 * i2 + 1], points[3 * i2 + 2]);
// this is the per-face normal
var n = p1.sub(p0).cross(p2.sub(p0));
// add it to each point
normals[i0].x += n.x;
normals[i0].y += n.y;
normals[i0].z += n.z;
normals[i1].x += n.x;
normals[i1].y += n.y;
normals[i1].z += n.z;
normals[i2].x += n.x;
normals[i2].y += n.y;
normals[i2].z += n.z;
normals[3 * i0] += n.x;
normals[3 * i0 + 1] += n.y;
normals[3 * i0 + 2] += n.z;
normals[3 * i1] += n.x;
normals[3 * i1 + 1] += n.y;
normals[3 * i1 + 2] += n.z;
normals[3 * i2] += n.x;
normals[3 * i2 + 1] += n.y;
normals[3 * i2 + 2] += n.z;
}
// normalize all normals
for (n in normals)
for (k in 0...Std.int(points.length / 3)) {
var n = new h3d.Vector(normals[k * 3], normals[k * 3 + 1], normals[k * 3 + 2]);
n.normalize();
normals[k * 3] = n.x;
normals[k * 3 + 1] = n.y;
normals[k * 3 + 2] = n.z;
}
}
public function addTangents() {
@ -210,26 +221,21 @@ class Polygon extends MeshPrimitive {
addUVs();
tangents = [];
for (i in 0...points.length)
tangents[i] = new Point();
tangents[i] = 0;
var pos = 0;
for (i in 0...triCount()) {
var i0, i1, i2;
if (idx == null) {
i0 = pos++;
i1 = pos++;
i2 = pos++;
} else {
i0 = idx[pos++];
i1 = idx[pos++];
i2 = idx[pos++];
}
var p0 = points[i0];
var p1 = points[i1];
var p2 = points[i2];
var uv0 = uvs[i0];
var uv1 = uvs[i1];
var uv2 = uvs[i2];
var n = normals[i0];
i0 = pos++;
i1 = pos++;
i2 = pos++;
var p0 = new h3d.Vector(points[3 * i0], points[3 * i0 + 1], points[3 * i0 + 2]);
var p1 = new h3d.Vector(points[3 * i1], points[3 * i1 + 1], points[3 * i1 + 2]);
var p2 = new h3d.Vector(points[3 * i2], points[3 * i2 + 1], points[3 * i2 + 2]);
var uv0 = new UV(uvs[2 * i0], uvs[2 * i0 + 1]);
var uv1 = new UV(uvs[2 * i1], uvs[2 * i1 + 1]);
var uv2 = new UV(uvs[2 * i2], uvs[2 * i2 + 1]);
var n = new h3d.Vector(normals[3 * i0], normals[3 * i0 + 1], normals[3 * i0 + 2]);
var k0 = p1.sub(p0);
var k1 = p2.sub(p0);
@ -242,36 +248,33 @@ class Polygon extends MeshPrimitive {
t.normalize();
// add it to each point
tangents[i0].x += t.x;
tangents[i0].y += t.y;
tangents[i0].z += t.z;
tangents[i1].x += t.x;
tangents[i1].y += t.y;
tangents[i1].z += t.z;
tangents[i2].x += t.x;
tangents[i2].y += t.y;
tangents[i2].z += t.z;
tangents[3 * i0] += t.x;
tangents[3 * i0 + 1] += t.y;
tangents[3 * i0 + 2] += t.z;
tangents[3 * i1] += t.x;
tangents[3 * i1 + 1] += t.y;
tangents[3 * i1 + 2] += t.z;
tangents[3 * i2] += t.x;
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() {
uvs = [];
for (i in 0...points.length)
uvs[i] = new UV(points[i].x, points[i].y);
}
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;
for (k in 0...Std.int(points.length / 3)) {
uvs[k * 2] = points[k * 3];
uvs[k * 2 + 1] = points[k * 3 + 1];
}
}
@ -279,38 +282,25 @@ class Polygon extends MeshPrimitive {
var n = super.triCount();
if (n != 0)
return n;
return Std.int((idx == null ? points.length : idx.length) / 3);
return Std.int(points.length / 9);
}
override function vertexCount() {
return points.length;
}
override function getCollider():h3d.col.Collider {
var vertexes = new haxe.ds.Vector<hxd.impl.Float32>(points.length * 3);
var indexes = new haxe.ds.Vector<Int>(idx.length);
var vid = 0;
for (p in points) {
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 selectMaterial(material:Int) {
currentMaterial = material;
}
override function getMaterialIndexes(material:Int):{count:Int, start:Int} {
return {start: indexStarts[material] * 3, count: indexCounts[material] * 3};
}
override function render(engine:h3d.Engine) {
if (buffer == null || buffer.isDisposed())
alloc(engine);
var bufs = getBuffers(engine);
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());
engine.renderMultiBuffers(bufs, engine.mem.triIndexes, indexStarts[currentMaterial], indexCounts[currentMaterial]);
}
}