speed up gfx, colored lighting is out for now
This commit is contained in:
parent
3c3e961995
commit
01e6059dd1
17 changed files with 1055 additions and 250 deletions
|
|
@ -2,15 +2,105 @@
|
|||
#include "pxl8_shader.h"
|
||||
#include "pxl8_shader_builtins.h"
|
||||
|
||||
u8 pxl8_shader_lit(
|
||||
pxl8_shader_ctx* ctx,
|
||||
void pxl8_shader_lit(
|
||||
const pxl8_shader_ctx* ctx,
|
||||
const pxl8_shader_bindings* bindings,
|
||||
const pxl8_shader_uniforms* uniforms
|
||||
const pxl8_shader_uniforms* uniforms,
|
||||
u8* colors_out
|
||||
) {
|
||||
#if defined(PXL8_SIMD_SSE) || defined(PXL8_SIMD_NEON)
|
||||
f32 uv_x[4], uv_y[4], color_f[4];
|
||||
i32 px[4], py[4];
|
||||
pxl8_f32_simd_store(uv_x, ctx->v_uv.x);
|
||||
pxl8_f32_simd_store(uv_y, ctx->v_uv.y);
|
||||
pxl8_f32_simd_store(color_f, ctx->v_color);
|
||||
pxl8_i32_simd_store(px, ctx->x);
|
||||
pxl8_i32_simd_store(py, ctx->y);
|
||||
|
||||
u8 tex_idx[4];
|
||||
for (u32 i = 0; i < ctx->color_count; i++) {
|
||||
if (bindings && bindings->atlas) {
|
||||
tex_idx[i] = pxl8_sample_indexed(bindings, (pxl8_vec2){{ uv_x[i], uv_y[i] }});
|
||||
} else {
|
||||
if (uniforms && uniforms->dither) {
|
||||
tex_idx[i] = pxl8_gfx_dither(color_f[i], (u32)px[i], (u32)py[i]);
|
||||
} else {
|
||||
f32 clamped = pxl8_clamp(color_f[i], 0.0f, 255.0f);
|
||||
tex_idx[i] = (u8)(clamped);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pxl8_f32_simd light = ctx->v_light;
|
||||
|
||||
if (uniforms) {
|
||||
pxl8_f32_simd ambient = pxl8_f32_simd_set((f32)uniforms->ambient / 255.0f);
|
||||
light = pxl8_f32_simd_max(light, ambient);
|
||||
|
||||
if (uniforms->celestial_intensity > 0.0f) {
|
||||
pxl8_vec3_simd cel_dir = pxl8_vec3_simd_set(uniforms->celestial_dir);
|
||||
pxl8_f32_simd ndotl = pxl8_f32_simd_sub(
|
||||
pxl8_f32_simd_zero(),
|
||||
pxl8_vec3_simd_dot(ctx->v_normal, cel_dir)
|
||||
);
|
||||
pxl8_f32_simd cel_contrib = pxl8_f32_simd_mul(
|
||||
pxl8_f32_simd_max(ndotl, pxl8_f32_simd_zero()),
|
||||
pxl8_f32_simd_set(uniforms->celestial_intensity)
|
||||
);
|
||||
light = pxl8_f32_simd_add(light, cel_contrib);
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < uniforms->lights_count; i++) {
|
||||
const pxl8_light* l = &uniforms->lights[i];
|
||||
pxl8_vec3_simd light_pos = pxl8_vec3_simd_set(l->position);
|
||||
pxl8_vec3_simd to_light = pxl8_vec3_simd_sub(light_pos, ctx->v_world);
|
||||
pxl8_f32_simd dist_sq = pxl8_vec3_simd_dot(to_light, to_light);
|
||||
|
||||
pxl8_f32_simd in_range = pxl8_f32_simd_cmpgt(
|
||||
pxl8_f32_simd_set(l->radius_sq), dist_sq
|
||||
);
|
||||
if (!pxl8_f32_simd_movemask(in_range)) continue;
|
||||
|
||||
pxl8_f32_simd inv_dist = pxl8_f32_simd_rsqrt(dist_sq);
|
||||
pxl8_vec3_simd light_dir = pxl8_vec3_simd_scale(to_light, inv_dist);
|
||||
pxl8_f32_simd ndotl = pxl8_vec3_simd_dot(ctx->v_normal, light_dir);
|
||||
ndotl = pxl8_f32_simd_max(ndotl, pxl8_f32_simd_zero());
|
||||
|
||||
pxl8_f32_simd falloff = pxl8_f32_simd_sub(
|
||||
pxl8_f32_simd_set(1.0f),
|
||||
pxl8_f32_simd_mul(dist_sq, pxl8_f32_simd_set(l->inv_radius_sq))
|
||||
);
|
||||
falloff = pxl8_f32_simd_max(falloff, pxl8_f32_simd_zero());
|
||||
|
||||
pxl8_f32_simd strength = pxl8_f32_simd_mul(
|
||||
pxl8_f32_simd_mul(pxl8_f32_simd_set(l->intensity), falloff),
|
||||
ndotl
|
||||
);
|
||||
|
||||
light = pxl8_f32_simd_add(light, strength);
|
||||
}
|
||||
}
|
||||
|
||||
light = pxl8_f32_simd_clamp(light, pxl8_f32_simd_zero(), pxl8_f32_simd_set(1.0f));
|
||||
pxl8_f32_simd light_f = pxl8_f32_simd_mul(light, pxl8_f32_simd_set(255.0f));
|
||||
|
||||
f32 light_arr[4];
|
||||
pxl8_f32_simd_store(light_arr, light_f);
|
||||
|
||||
for (u32 i = 0; i < ctx->color_count; i++) {
|
||||
u8 light_u8;
|
||||
if (uniforms && uniforms->dither) {
|
||||
light_u8 = pxl8_gfx_dither(light_arr[i], (u32)px[i], (u32)py[i]);
|
||||
} else {
|
||||
light_u8 = (u8)light_arr[i];
|
||||
}
|
||||
colors_out[i] = pxl8_colormap_lookup(bindings, tex_idx[i], light_u8);
|
||||
}
|
||||
|
||||
#else
|
||||
u8 tex_idx = 0;
|
||||
if (bindings && bindings->atlas) {
|
||||
tex_idx = pxl8_sample_indexed(bindings, ctx->v_uv);
|
||||
if (pxl8_unlikely(tex_idx == 0)) return 0;
|
||||
} else {
|
||||
if (uniforms && uniforms->dither) {
|
||||
tex_idx = pxl8_gfx_dither(ctx->v_color, (u32)ctx->x, (u32)ctx->y);
|
||||
|
|
@ -35,11 +125,6 @@ u8 pxl8_shader_lit(
|
|||
}
|
||||
}
|
||||
|
||||
f32 dyn_strength = 0.0f;
|
||||
f32 dyn_r = 0.0f;
|
||||
f32 dyn_g = 0.0f;
|
||||
f32 dyn_b = 0.0f;
|
||||
|
||||
for (u32 i = 0; i < uniforms->lights_count; i++) {
|
||||
const pxl8_light* l = &uniforms->lights[i];
|
||||
f32 lx = l->position.x - ctx->v_world.x;
|
||||
|
|
@ -58,28 +143,9 @@ u8 pxl8_shader_lit(
|
|||
|
||||
f32 falloff = 1.0f - dist_sq * l->inv_radius_sq;
|
||||
if (falloff <= 0.0f) continue;
|
||||
if (uniforms->dither && falloff < 0.33f) {
|
||||
f32 threshold = (PXL8_BAYER_4X4[((u32)ctx->y & 3) * 4 + ((u32)ctx->x & 3)] + 0.5f) * (1.0f / 16.0f);
|
||||
if (falloff < threshold * 0.33f) continue;
|
||||
}
|
||||
|
||||
f32 strength = ((f32)l->intensity / 255.0f) * falloff * ndotl;
|
||||
if (strength <= 0.0f) continue;
|
||||
|
||||
dyn_strength += strength;
|
||||
dyn_r += strength * (f32)l->r;
|
||||
dyn_g += strength * (f32)l->g;
|
||||
dyn_b += strength * (f32)l->b;
|
||||
}
|
||||
|
||||
if (dyn_strength > 0.0f) {
|
||||
f32 inv = pxl8_fast_rcp(dyn_strength);
|
||||
u8 r = (u8)pxl8_clamp(dyn_r * inv, 0.0f, 255.0f);
|
||||
u8 g = (u8)pxl8_clamp(dyn_g * inv, 0.0f, 255.0f);
|
||||
u8 b = (u8)pxl8_clamp(dyn_b * inv, 0.0f, 255.0f);
|
||||
u8 a = (u8)pxl8_clamp(dyn_strength * 255.0f, 0.0f, 255.0f);
|
||||
ctx->out_light_color = (u32)r | ((u32)g << 8) | ((u32)b << 16) | ((u32)a << 24);
|
||||
light += dyn_strength;
|
||||
f32 strength = l->intensity * falloff * ndotl;
|
||||
light += strength;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -92,15 +158,6 @@ u8 pxl8_shader_lit(
|
|||
light_u8 = pxl8_gfx_dither(light_f, (u32)ctx->x, (u32)ctx->y);
|
||||
}
|
||||
|
||||
u8 shaded = pxl8_colormap_lookup(bindings, tex_idx, light_u8);
|
||||
|
||||
if (uniforms && uniforms->emissive) {
|
||||
u32 rgb = 0x00FFFFFF;
|
||||
if (bindings && bindings->palette) {
|
||||
rgb = bindings->palette[tex_idx] & 0x00FFFFFF;
|
||||
}
|
||||
pxl8_set_light_tint(ctx, rgb, 1.0f);
|
||||
}
|
||||
|
||||
return shaded;
|
||||
colors_out[0] = pxl8_colormap_lookup(bindings, tex_idx, light_u8);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue