bad not working transparency

This commit is contained in:
2026-03-17 23:06:32 -03:00
parent a3d5bc6b70
commit 6e6dd08af7
7 changed files with 104 additions and 36 deletions
+1
View File
@@ -8,3 +8,4 @@ import "./stone.ts";
import "./log.ts";
import "./sand.ts";
import "./snow.ts";
import "./glass.ts";
+2
View File
@@ -3,4 +3,6 @@ import { BlockRegistry, EverythingRegistry } from "$/common/everything_registry.
EverythingRegistry.register<BlockRegistry>("blocks", "bworld:water", {
textures: "bworld:water",
has_collision: false,
transparent: true,
alpha: 0.8,
});
+9 -4
View File
@@ -28,8 +28,10 @@ export interface Chunk {
blocks: Int16Array;
generated: boolean;
dirty: boolean;
vertex_buffer?: WebGLBuffer;
vertex_count?: number;
opaque_vertex_buffer?: WebGLBuffer;
opaque_vertex_count?: number;
transparent_vertex_buffer?: WebGLBuffer;
transparent_vertex_count?: number;
}
export class Dimension extends Component {
@@ -193,8 +195,11 @@ export class Dimension extends Component {
}
delete_chunk_mesh(chunk: Chunk) {
if (chunk.vertex_buffer) {
gl.deleteBuffer(chunk.vertex_buffer);
if (chunk.opaque_vertex_buffer) {
gl.deleteBuffer(chunk.opaque_vertex_buffer);
}
if (chunk.transparent_vertex_buffer) {
gl.deleteBuffer(chunk.transparent_vertex_buffer);
}
}
+1 -1
View File
@@ -116,7 +116,7 @@ export class PlayerControlsSystem extends System {
x: block.x + offset.x,
y: block.y + offset.y,
z: block.z + offset.z,
id: "bworld:dirt",
id: "bworld:glass",
});
}
}
+30 -7
View File
@@ -11,7 +11,7 @@ const worker = new Worker(new URL("./workers/chunk_mesh_worker.js", import.meta.
});
worker.onmessage = (event) => {
const { vertices, count, chunk_x, chunk_z } = event.data;
const { opaque_vertices, opaque_count, transparent_vertices, transparent_count, chunk_x, chunk_z } = event.data;
const chunk = gdimension.get_chunk(chunk_x, chunk_z);
if (!chunk) {
console.error("bad");
@@ -19,13 +19,24 @@ worker.onmessage = (event) => {
}
gdimension.delete_chunk_mesh(chunk);
chunk.dirty = false;
chunk.vertex_buffer = gl.createBuffer();
chunk.vertex_count = count / 9;
gl.bindBuffer(gl.ARRAY_BUFFER, chunk.vertex_buffer);
chunk.opaque_vertex_buffer = gl.createBuffer();
chunk.opaque_vertex_count = opaque_count / 9;
gl.bindBuffer(gl.ARRAY_BUFFER, chunk.opaque_vertex_buffer);
gl.bufferData(
gl.ARRAY_BUFFER,
vertices.subarray(0, count),
opaque_vertices.subarray(0, opaque_count),
gl.STATIC_DRAW,
);
chunk.transparent_vertex_buffer = gl.createBuffer();
chunk.transparent_vertex_count = transparent_count / 9;
gl.bindBuffer(gl.ARRAY_BUFFER, chunk.transparent_vertex_buffer);
gl.bufferData(
gl.ARRAY_BUFFER,
transparent_vertices.subarray(0, transparent_count),
gl.STATIC_DRAW,
);
};
@@ -70,12 +81,24 @@ export function render_dimension(dimension: Dimension, camera: Camera) {
for (const chunk of dimension.chunks) {
render_chunk_opaque(chunk);
}
for (const chunk of dimension.chunks) {
render_chunk_transparent(chunk);
}
}
function render_chunk_opaque(chunk: Chunk) {
if (!chunk.vertex_buffer || !chunk.vertex_count) {
if (!chunk.opaque_vertex_buffer || !chunk.opaque_vertex_count) {
return;
}
flush_buffer(chunk.vertex_buffer, chunk.vertex_count);
flush_buffer(chunk.opaque_vertex_buffer, chunk.opaque_vertex_count);
}
function render_chunk_transparent(chunk: Chunk) {
if (!chunk.transparent_vertex_buffer || !chunk.transparent_vertex_count) {
return;
}
flush_buffer(chunk.transparent_vertex_buffer, chunk.transparent_vertex_count);
}
+58 -23
View File
@@ -29,8 +29,18 @@ const FACE_PUSHING_FUNCTIONS = {
self.onmessage = (event) => {
const { chunk_x, chunk_z, padded_chunk, blocks_registry, textures_info, image } = event.data;
const [vertices, count] = make_chunk_mesh(chunk_x, chunk_z, padded_chunk, blocks_registry, textures_info, image);
self.postMessage({ vertices, count, chunk_x, chunk_z }, [vertices.buffer]);
const [opaque_vertices, opaque_count, transparent_vertices, transparent_count] = make_chunk_mesh(
chunk_x,
chunk_z,
padded_chunk,
blocks_registry,
textures_info,
image,
);
self.postMessage(
{ opaque_vertices, opaque_count, transparent_vertices, transparent_count, chunk_x, chunk_z },
[opaque_vertices.buffer, transparent_vertices.buffer],
);
};
function make_chunk_mesh(
@@ -40,9 +50,11 @@ function make_chunk_mesh(
blocks_registry: BlockRegistry[],
textures_info: TexturesInfo,
image: Texture,
): [Float32Array, number] {
let vertices = new Float32Array(2048);
let count = 0;
): [Float32Array, number, Float32Array, number] {
let opaque_vertices = new Float32Array(2048);
let opaque_count = 0;
let transparent_vertices = new Float32Array(2048);
let transparent_count = 0;
const size = CHUNK_SIZE + 2;
const layer = size * size;
@@ -119,30 +131,53 @@ function make_chunk_mesh(
if (faces[side]) {
const region = textures_info[texture_ids[side]];
vertices = ensure_capacity(vertices, count + (6 * 6 * 9));
count = FACE_PUSHING_FUNCTIONS[side](
vertices,
count,
image,
wx,
y,
wz,
region.x * TEXTURE_SIZE,
region.y * TEXTURE_SIZE,
TEXTURE_SIZE,
TEXTURE_SIZE,
1,
1,
1,
1,
);
if (block_info.transparent) {
transparent_vertices = ensure_capacity(
transparent_vertices,
transparent_count + (6 * 6 * 9),
);
transparent_count = FACE_PUSHING_FUNCTIONS[side](
transparent_vertices,
transparent_count,
image,
wx,
y,
wz,
region.x * TEXTURE_SIZE,
region.y * TEXTURE_SIZE,
TEXTURE_SIZE,
TEXTURE_SIZE,
1,
1,
1,
block_info.alpha ?? 1,
);
} else {
opaque_vertices = ensure_capacity(opaque_vertices, opaque_count + (6 * 6 * 9));
opaque_count = FACE_PUSHING_FUNCTIONS[side](
opaque_vertices,
opaque_count,
image,
wx,
y,
wz,
region.x * TEXTURE_SIZE,
region.y * TEXTURE_SIZE,
TEXTURE_SIZE,
TEXTURE_SIZE,
1,
1,
1,
1,
);
}
}
}
}
}
}
return [vertices, count];
return [opaque_vertices, opaque_count, transparent_vertices, transparent_count];
}
function ensure_capacity(
+3 -1
View File
@@ -62,8 +62,10 @@ interface TextureFront {
export interface BlockRegistry<T = unknown | undefined> {
textures: string | TextureSideTopBottom | TextureFront;
has_collision: boolean;
transparent?: boolean;
alpha?: number;
has_collision: boolean;
drop_table?: string;
on_create?(dimension: Dimension, block: Block<T>): void;