|
@@ -112,7 +112,7 @@ class World extends Object {
|
|
|
/*
|
|
|
For each texture loaded, will call resolveNormalMap and have separate normal texture.
|
|
|
*/
|
|
|
- public var enableNormals = false;
|
|
|
+ public var enableNormalMaps = false;
|
|
|
/*
|
|
|
When enableSpecular=true, will store the specular value in the alpha channel instead of a different texture.
|
|
|
This will erase alpha value of transparent textures, so should only be used if specular is only on opaque models.
|
|
@@ -121,7 +121,10 @@ class World extends Object {
|
|
|
|
|
|
var worldStride : Int;
|
|
|
var bigTextureSize = 2048;
|
|
|
- var bigTextureBG = 0xFF8080FF;
|
|
|
+ var defaultDiffuseBG = 0;
|
|
|
+ var defaultNormalBG = 0x8080FF;
|
|
|
+ var defaultSpecularBG = 0;
|
|
|
+
|
|
|
var soilColor = 0x408020;
|
|
|
var chunks : Array<WorldChunk>;
|
|
|
var allChunks : Array<WorldChunk>;
|
|
@@ -151,14 +154,20 @@ class World extends Object {
|
|
|
}
|
|
|
|
|
|
function buildFormat() {
|
|
|
- return {
|
|
|
+ var r = {
|
|
|
fmt : [
|
|
|
new hxd.fmt.hmd.Data.GeometryFormat("position", DVec3),
|
|
|
new hxd.fmt.hmd.Data.GeometryFormat("normal", DVec3),
|
|
|
- new hxd.fmt.hmd.Data.GeometryFormat("uv", DVec2),
|
|
|
],
|
|
|
- defaults : [],
|
|
|
+ defaults : [null, new h3d.Vector(0,0,1)],
|
|
|
};
|
|
|
+ if(enableNormalMaps) {
|
|
|
+ r.fmt.push(new hxd.fmt.hmd.Data.GeometryFormat("tangent", DVec3));
|
|
|
+ r.defaults.push(new h3d.Vector(1,0,0));
|
|
|
+ }
|
|
|
+ r.fmt.push(new hxd.fmt.hmd.Data.GeometryFormat("uv", DVec2));
|
|
|
+ r.defaults.push(null);
|
|
|
+ return r;
|
|
|
}
|
|
|
|
|
|
function getBlend( r : hxd.res.Image ) : h3d.mat.BlendMode {
|
|
@@ -213,16 +222,25 @@ class World extends Object {
|
|
|
}
|
|
|
}
|
|
|
if( t == null ) {
|
|
|
- var b = new h3d.mat.BigTexture(bigTextures.length, bigTextureSize, bigTextureBG);
|
|
|
+ var b = new h3d.mat.BigTexture(bigTextures.length, bigTextureSize, defaultDiffuseBG);
|
|
|
btex = { diffuse : b, spec : null, normal : null };
|
|
|
bigTextures.unshift( btex );
|
|
|
t = b.add(rt);
|
|
|
if( t == null ) throw "Texture " + texturePath + " is too big";
|
|
|
}
|
|
|
|
|
|
+ inline function checkSize(res:hxd.res.Image) {
|
|
|
+ if(res != null) {
|
|
|
+ var size = res.getSize();
|
|
|
+ if(size.width != t.width || size.height != t.height)
|
|
|
+ throw 'Texture ${res.entry.path} has different size from diffuse (${size.width}x${size.height})';
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
var specTex = null;
|
|
|
if( enableSpecular ) {
|
|
|
var res = resolveSpecularTexture(texturePath, mat);
|
|
|
+ checkSize(res);
|
|
|
if( specularInAlpha ) {
|
|
|
if( res != null ) {
|
|
|
t.setAlpha(res);
|
|
@@ -230,23 +248,24 @@ class World extends Object {
|
|
|
}
|
|
|
} else {
|
|
|
if( btex.spec == null )
|
|
|
- btex.spec = new h3d.mat.BigTexture(-1, bigTextureSize, bigTextureBG);
|
|
|
+ btex.spec = new h3d.mat.BigTexture(-1, bigTextureSize, defaultSpecularBG);
|
|
|
if( res != null )
|
|
|
specTex = btex.spec.add(res);
|
|
|
else
|
|
|
- @:privateAccess btex.spec.allocPos(t.t.tex.width, t.t.tex.height); // keep UV in-sync
|
|
|
+ btex.spec.allocPos(t.width, t.height); // keep UV in-sync
|
|
|
}
|
|
|
}
|
|
|
|
|
|
var normalMap = null;
|
|
|
- if( enableNormals ) {
|
|
|
+ if( enableNormalMaps ) {
|
|
|
var res = resolveNormalMap(texturePath, mat);
|
|
|
+ checkSize(res);
|
|
|
if( btex.normal == null )
|
|
|
- btex.normal = new h3d.mat.BigTexture(-1, bigTextureSize, bigTextureBG);
|
|
|
+ btex.normal = new h3d.mat.BigTexture(-1, bigTextureSize, defaultNormalBG);
|
|
|
if( res != null )
|
|
|
normalMap = btex.normal.add(res);
|
|
|
else
|
|
|
- @:privateAccess btex.normal.allocPos(t.t.tex.width, t.t.tex.height); // keep UV in-sync
|
|
|
+ btex.normal.allocPos(t.width, t.height); // keep UV in-sync
|
|
|
}
|
|
|
|
|
|
var m = new WorldMaterial();
|
|
@@ -311,6 +330,9 @@ class World extends Object {
|
|
|
var vl = data.vertexes;
|
|
|
var p = 0;
|
|
|
var extra = model.stride - 8;
|
|
|
+ if(enableNormalMaps)
|
|
|
+ extra -= 3;
|
|
|
+
|
|
|
for( i in 0...m.vertexCount ) {
|
|
|
var x = vl[p++];
|
|
|
var y = vl[p++];
|
|
@@ -318,6 +340,12 @@ class World extends Object {
|
|
|
var nx = vl[p++];
|
|
|
var ny = vl[p++];
|
|
|
var nz = vl[p++];
|
|
|
+ var tx = 0., ty = 0., tz = 0.;
|
|
|
+ if(enableNormalMaps) {
|
|
|
+ tx = vl[p++];
|
|
|
+ ty = vl[p++];
|
|
|
+ tz = vl[p++];
|
|
|
+ }
|
|
|
var u = vl[p++];
|
|
|
var v = vl[p++];
|
|
|
|
|
@@ -337,6 +365,16 @@ class World extends Object {
|
|
|
model.buf.push(n.y * len);
|
|
|
model.buf.push(n.z * len);
|
|
|
|
|
|
+ if( enableNormalMaps ) {
|
|
|
+ var t = new h3d.Vector(tx, ty, tz);
|
|
|
+ var tlen = t.length();
|
|
|
+ t.transform3x3(pos);
|
|
|
+ var len = tlen * hxd.Math.invSqrt(n.lengthSq());
|
|
|
+ model.buf.push(t.x * len);
|
|
|
+ model.buf.push(t.y * len);
|
|
|
+ model.buf.push(t.z * len);
|
|
|
+ }
|
|
|
+
|
|
|
// uv
|
|
|
model.buf.push(u * wmat.t.su + wmat.t.du);
|
|
|
model.buf.push(v * wmat.t.sv + wmat.t.dv);
|