sandboxels/mods/xVS_cal_wasm.c

72 lines
2.5 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// xVS_cal_wasm.c
#include <emscripten.h>
#include <stdint.h>
#define CLAMP(x, low, high) ((x) < (low) ? (low) : ((x) > (high) ? (high) : (x)))
// === LIGHT PROPAGATION ===
EMSCRIPTEN_KEEPALIVE
void propagate_lightmap_f32(
const float* in_r, const float* in_g, const float* in_b,
float* out_r, float* out_g, float* out_b,
int width, int height, float falloff
) {
const int dx[4] = {1, -1, 0, 0};
const int dy[4] = {0, 0, 1, -1};
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
float sum_r = 0, sum_g = 0, sum_b = 0;
int count = 0;
for (int d = 0; d < 4; ++d) {
int nx = x + dx[d];
int ny = y + dy[d];
if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
int nidx = ny * width + nx;
sum_r += in_r[nidx];
sum_g += in_g[nidx];
sum_b += in_b[nidx];
count++;
}
}
int idx = y * width + x;
if (count > 0) {
float factor = falloff / count;
out_r[idx] = CLAMP(sum_r * factor, 0.0f, 765.0f);
out_g[idx] = CLAMP(sum_g * factor, 0.0f, 765.0f);
out_b[idx] = CLAMP(sum_b * factor, 0.0f, 765.0f);
} else {
out_r[idx] = out_g[idx] = out_b[idx] = 0.0f;
}
}
}
}
// === SHADOW OCCLUSION (blocker count only) ===
// Input: 1D array of element IDs (0 = empty, 1 = transparent, 2+ = opaque)
// Output: blocker count per pixel
EMSCRIPTEN_KEEPALIVE
void compute_blockers_u8(
const uint8_t* grid, // width × height
uint8_t* blockers_out, // same size
int width, int height,
const int8_t* coords, // [dx0,dy0,dx1,dy1,...] length = 2*N
int coord_count // N
) {
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
uint8_t blockers = 0;
for (int i = 0; i < coord_count; ++i) {
int nx = x + coords[i * 2];
int ny = y + coords[i * 2 + 1];
if (nx < 0 || nx >= width || ny < 0 || ny >= height) {
blockers++;
} else {
uint8_t val = grid[ny * width + nx];
if (val >= 2) blockers++; // opaque
}
}
blockers_out[y * width + x] = blockers;
}
}
}