Closed levlups closed 1 year ago
I'm lost, can you describe specifically what you want to do?
For reference, terrain meshes are merged together by chunk and by material - i.e. all voxel faces in a given chunk that share the same material will be part of the same mesh. So if you want to do something to an individual voxel face, the straightforward way would be to make a separate block material for that face, so it gets its own material. But I may be misunderstanding you.
you understood right , to make realistic shadow like minecraft i need a material per face ... ??? how would I do that ....
heres an example of code I was using id is the requestedID of the chunk , but its not precise
function pushAOColor(colors, ix, baseCol, ao, aoVals, revAoVal, id) {
var mult = (ao === 0) ? revAoVal : aoVals[ao - 1]
if (parseInt(id[1]) >= 0) {
mult = (ao === 0) ? revAoVal : aoVals[ao - 1]
} else {
mult = (ao === 0) ? revAoVal : aoVals[ao - 1]
mult -= 0.2
}
colors[ix] = baseCol[0] * mult
colors[ix + 1] = baseCol[1] * mult
colors[ix + 2] = baseCol[2] * mult
colors[ix + 3] = 1
}
fenomas if your still lost , tell me Ill make you a video to explain :)
Hmm, I'm still a bit lost but I guess you're tweaking the AO vertex colors based on the world position of the voxel face?
If that's right, then the requestedID of each chunk is just an identifier, so the engine and the client know if they're talking about the same chunk or not. If you want a kind of "is this voxel above or below y=0" test, then I guess you'd want to tweak terrain meshing so that the mesher knows each chunk's world x/y/z position, and then it can track the world position of each voxel as it meshes.
Is that what you're trying to do? If so, then look at the greedyMesher.mesh
call inside terrain mesher. If that call passed in chunk.x, chunk.y, chunk.z
along with its other params, then the mesher would know the world position of the chunk it's meshing, and it could pass internal xyz coords down to the AO logic.
Yes I did that already , but it's not enough , it needs to be more precise I'll make a video of exactly wath i need .Stay tuned lol.
heres the minecraft classic terrainmesher code if your attentive youll see a noa.getbrightness() function
function o() {
var e = i(188),
t = e.ID_MASK,
r = (e.VAR_MASK, e.SOLID_BIT),
o = e.OPAQUE_BIT,
s = e.OBJECT_BIT,
c = new Int16Array(256),
u = new Uint16Array(256);
function l(e, i, n, r, o, a) {
for (var s = n.shape[1], l = c, h = u, d = 0, p = n.data, m = n.index(e - 1, 0, 0), g = n.stride[0], _ = n.stride[1], v = n.stride[2], y = 0; y < s; ++y) {
var b = m;
m += v;
for (var E = 0; E < s; E++, d++, b += _) {
var T = p[b],
A = p[b + g],
x = f(T, A, E, y);
if (x) {
if (l[d] = x > 0 ? r(T & t, 2 * i) : -r(A & t, 2 * i + 1), 0 != l[d]) {
var S = a[0] + e + x,
C = a[1] + E,
P = a[2] + y;
1 == i && (S = a[0] + y, C = a[1] + e + x, P = a[2] + E), 2 == i && (S = a[0] + E, C = a[1] + y, P = a[2] + e + x), 0 == i && x > 0 && (S -= 1), 1 == i && x > 0 && (C -= 1), 2 == i && x > 0 && (P -= 1), noa.getBrightness(S, C, P) < 1 && (l[d] += 512 * x)
}
if (o) {
var R = x > 0 ? e : e - 1,
M = x > 0 ? e - 1 : e;
h[d] = o(n, R, M, E, y)
}
}
}
}
}
this.mesh = function(e, t, i, n, r, o, s) {
var h, f = [],
p = n && o === r[0];
n && (h = p ? v : y);
for (var m = 0; m < 3; ++m) {
var g = (m + 1) % 3,
_ = (m + 2) % 3,
b = e.transpose(m, g, _).lo(1, 1, 1).hi(e.shape[m] - 2, e.shape[g] - 2, e.shape[_] - 2),
E = b.shape[0] - 1,
T = b.shape[1],
A = b.shape[2];
c.length < T * A && (c = new Int16Array(T * A), u = new Uint16Array(T * A));
for (var x = 0; x <= E; ++x) l(x, m, b, t, h, s), a("built masks"), d(x, m, g, _, T, A, n, f, i, r, o, s), a("build submeshes")
}
return f
};
heres wath happen when you remove a block in minecraft classic
}), this.getBrightness = function(e, t, i) {
return e < 0 || t < 0 || i < 0 || e >= _ - 1 || i >= _ - 1 ? t >= v ? 1 : .6 : t >= T.lightDepths[e][i] + 1 ? 1 : .6
}, k.getBrightness = this.getBrightness, this.addBlockCheckLit = function(e, t, i) {
var n = this.lightDepths[e][i];
if (t >= n) {
if (Math.floor(t / g) != Math.floor(n / g)) {
var r = k.world.getBlockID(e, n, i);
k.world.setBlockID(0, e, n, i), k.world.setBlockID(r, e, n, i)
}
this.lightDepths[e][i] = t
}
}
heres the youtube video explanation
Hi, thanks for the video (and the kind words!). I understand the issue now.
First to explain, the core function of the terrain mesher is to merge together related terrain faces, to reduce the number of vertices in the overall world. You can see this in action if you compare what pieces of terrain look like in wireframe mode:
Normally this merging step happens after voxel materials and AO values (which are turned into vertex colors) have already been processed, so the terrain mesher only merges together faces where the corners all have the same values, so the merging isn't visible. But in your demo you're randomizing colors after the merging step, so that's why you see unpredictable changes.
Basically the point of all this is that for the engine to support lighting (in its current architecture, at least) lighting would need to be handled earlier in the meshing process - before or together with AO, so that later on the mesher only merges together voxels that have the same light level.
As for lighting itself, it's a big topic that basically hasn't been tackled yet - I think this has been discussed in other issues, but maybe I should make one big tracking issue for it. The simplest approach, which you could do immediately without waiting for any engine changes, would be to define two versions of your terrain blocks, a lighted version and an unlighted version. Then you'd just make the underground terrain out of unlit_dirt
voxels, and surface blocks out of lit_dirt
, and it would be game logic's job to know which one is correct in a given spot. The problem with this is that in real terrain you'd want some dirt blocks to be lit on one side and unlit on the other side, and it would be tedious to define lots of different variations.
For "real" engine-supported lighting, the short answer is that there are several possible approaches and I haven't currently started any of them yet.
I hope this clears stuff up!
in terrainMesher.js i was able to shade a particular chunk at will using the requestedID of chunk but if i use for example for ( var i=0;i<len0 ; i++) if ( i<10 ) shade... it doesnt work ,it breaks down its like the chunk meshes or AOs or... wath else merges together , is their a way to keep those faces separated so we can shade certain faces and not the whole chunk.???