Alpha-to-coverage foliage

main
Phillip Trudeau-Tavara 9 months ago
parent 08df997396
commit bc1663006c

@ -838,7 +838,7 @@ sg_image load_image(MD_String8 path)
{
.width = png_width,
.height = png_height,
.pixel_format = SG_PIXELFORMAT_RGBA8,
.pixel_format = sapp_sgcontext().color_format,
.num_mipmaps = 1,
.data.subimage[0][0] =
{
@ -2646,11 +2646,13 @@ Shadow_State init_shadow_state();
static struct
{
sg_pass_action clear_everything_pass_action;
sg_pass_action threedee_msaa_pass_action;
sg_pass_action clear_depth_buffer_pass_action;
sg_pipeline twodee_pip;
sg_bindings bind;
sg_pipeline threedee_pip;
sg_pipeline threedee_alpha_blended_pip;
sg_pipeline armature_pip;
sg_bindings threedee_bind;
@ -2758,7 +2760,7 @@ void create_screenspace_gfx_state()
.render_target = true,
.width = sapp_width(),
.height = sapp_height(),
.pixel_format = SG_PIXELFORMAT_RGBA8,
.pixel_format = sapp_sgcontext().color_format,
.label = "outline-pass-render-target",
};
@ -2786,7 +2788,7 @@ void create_screenspace_gfx_state()
state.threedee_pass_resolve_image = sg_make_image(&desc);
desc.label = "threedee-pass-depth-render-target";
desc.pixel_format = sapp_depth_format();
desc.pixel_format = SG_PIXELFORMAT_DEPTH;
desc.sample_count = SAMPLE_COUNT;
state.threedee_pass_depth_image = sg_make_image(&desc);
@ -3367,30 +3369,38 @@ void init(void)
assert(desc);
shd = sg_make_shader(desc);
state.threedee_pip = sg_make_pipeline(&(sg_pipeline_desc){
.shader = shd,
.layout = {.attrs = {
[ATTR_threedee_vs_pos_in].format = SG_VERTEXFORMAT_FLOAT3,
[ATTR_threedee_vs_uv_in].format = SG_VERTEXFORMAT_FLOAT2,
}},
.depth = {
.pixel_format = sapp_depth_format(),
.compare = SG_COMPAREFUNC_LESS_EQUAL,
.write_enabled = true,
},
.sample_count = SAMPLE_COUNT,
.colors[0].blend = (sg_blend_state){
{
sg_pipeline_desc threedee_pip_desc = {
.shader = shd,
.layout = {.attrs = {
[ATTR_threedee_vs_pos_in].format = SG_VERTEXFORMAT_FLOAT3,
[ATTR_threedee_vs_uv_in].format = SG_VERTEXFORMAT_FLOAT2,
}},
.depth = {
.pixel_format = SG_PIXELFORMAT_DEPTH,
.compare = SG_COMPAREFUNC_LESS_EQUAL,
.write_enabled = true,
},
.alpha_to_coverage_enabled = true,
.sample_count = SAMPLE_COUNT,
.colors[0].blend.enabled = false,
.label = "threedee",
};
state.threedee_pip = sg_make_pipeline(&threedee_pip_desc);
threedee_pip_desc.depth.write_enabled = false;
threedee_pip_desc.alpha_to_coverage_enabled = false;
threedee_pip_desc.colors[0].blend = (sg_blend_state){
// allow transparency
.enabled = true,
.src_factor_rgb = SG_BLENDFACTOR_SRC_ALPHA,
.dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
.op_rgb = SG_BLENDOP_ADD,
.src_factor_alpha = SG_BLENDFACTOR_ONE,
.src_factor_alpha = SG_BLENDFACTOR_SRC_ALPHA,
.dst_factor_alpha = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
.op_alpha = SG_BLENDOP_ADD,
},
.label = "threedee",
});
state.threedee_alpha_blended_pip = sg_make_pipeline(&threedee_pip_desc);
}
desc = threedee_armature_shader_desc(sg_query_backend());
assert(desc);
@ -3400,7 +3410,7 @@ void init(void)
{
.shader = shd,
.depth = {
.pixel_format = sapp_depth_format(),
.pixel_format = SG_PIXELFORMAT_DEPTH,
.compare = SG_COMPAREFUNC_LESS_EQUAL,
.write_enabled = true
},
@ -3433,6 +3443,9 @@ void init(void)
};
state.clear_everything_pass_action = state.clear_depth_buffer_pass_action;
state.clear_everything_pass_action.colors[0] = (sg_color_attachment_action){ .load_action = SG_LOADACTION_CLEAR, .clear_value = { clearcol.r, clearcol.g, clearcol.b, 1.0f } };
state.threedee_msaa_pass_action = state.clear_everything_pass_action;
state.threedee_msaa_pass_action.colors[0].load_action = SG_LOADACTION_CLEAR;
state.threedee_msaa_pass_action.colors[0].store_action = SG_STOREACTION_DONTCARE;
state.sampler_linear = sg_make_sampler(&(sg_sampler_desc) {
.min_filter = SG_FILTER_LINEAR,
@ -3759,6 +3772,11 @@ void flush_quad_batch()
sg_apply_bindings(&state.bind);
cur_batch_params.tex_size = img_size(cur_batch_image);
cur_batch_params.screen_size = screen_size();
#if defined(SOKOL_GLCORE33) || defined(SOKOL_GLES3)
cur_batch_params.flip_and_swap_rgb = 0;
#else
cur_batch_params.flip_and_swap_rgb = 1;
#endif
sg_apply_uniforms(SG_SHADERSTAGE_FS, SLOT_threedee_twodee_fs_params, &SG_RANGE(cur_batch_params));
cur_batch_params.tex_size = V2(0,0); // unsure if setting the tex_size to something nonzero fucks up the batching so I'm just resetting it back here
assert(cur_batch_data_index % FLOATS_PER_VERTEX == 0);
@ -4877,7 +4895,7 @@ Shadow_State init_shadow_state() {
.render_target = true,
.width = SHADOW_MAP_DIMENSION,
.height = SHADOW_MAP_DIMENSION,
.pixel_format = SG_PIXELFORMAT_RGBA8,
.pixel_format = sapp_sgcontext().color_format,
.sample_count = 1,
.label = "shadow-map-color-image"
};
@ -4908,7 +4926,7 @@ Shadow_State init_shadow_state() {
.compare = SG_COMPAREFUNC_LESS_EQUAL,
.write_enabled = true,
},
.colors[0].pixel_format = SG_PIXELFORMAT_RGBA8,
.colors[0].pixel_format = sapp_sgcontext().color_format,
.label = "shadow-map-pipeline"
};
@ -5116,6 +5134,8 @@ void actually_draw_thing(DrawnThing *it, Mat4 light_space_matrix, bool for_outli
{
if(for_outline)
sg_apply_pipeline(state.outline_mesh_pip);
else if (it->alpha_blend)
sg_apply_pipeline(state.threedee_alpha_blended_pip);
else
sg_apply_pipeline(state.threedee_pip);
sg_bindings bindings = {0};
@ -5384,7 +5404,7 @@ void flush_all_drawn_things(Vec3 light_dir, Vec3 cam_pos, Vec3 cam_facing, Vec3
// actually draw, IMPORTANT after this drawn_this_frame is zeroed out!
{
sg_begin_pass(state.threedee_pass, &state.clear_everything_pass_action);
sg_begin_pass(state.threedee_pass, &state.threedee_msaa_pass_action);
// draw meshes
SLICE_ITER(DrawnThing, drawn_this_frame)

@ -295,11 +295,6 @@ void main() {
//col.rgb = vec3(desertness, 0, 0);
if(col.a < 0.1 && !alpha_blend)
{
discard;
}
else
{
vec3 normal = normalize(cross(dFdx(world_space_frag_pos.xyz), dFdy(world_space_frag_pos.xyz)));
@ -310,16 +305,13 @@ void main() {
float lighting_factor = shadow_factor * n_dot_l;
lighting_factor = lighting_factor * 0.5 + 0.5;
if(alpha_blend)
{
frag_color = vec4(col.rgb*lighting_factor, col.a);
}
else
if (!alpha_blend)
{
frag_color = vec4(col.rgb*lighting_factor, 1.0);
float _Cutoff = 0.75; // Change this! it is tuned for existing bushes and TreeLayer leaves 2023-08-23
col.a = (col.a - _Cutoff) / max(fwidth(col.a), 0.0001) + 0.5;
}
//frag_color = vec4(col.rgb, 1.0);
frag_color = vec4(col.rgb*lighting_factor, col.a);
}
}
@end
@ -385,6 +377,8 @@ uniform twodee_fs_params {
vec2 tex_size;
vec2 screen_size;
float flip_and_swap_rgb;
};
in vec2 uv;
@ -395,7 +389,10 @@ out vec4 frag_color;
void main() {
// clip space is from [-1,1] [left, right]of screen on X, and [-1,1] [bottom, top] of screen on Y
if(pos.x < clip_ul.x || pos.x > clip_lr.x || pos.y < clip_lr.y || pos.y > clip_ul.y) discard;
frag_color = texture(sampler2D(twodee_tex, fs_twodee_smp), uv) * tint;
vec2 real_uv = uv;
if (flip_and_swap_rgb > 0) real_uv.y = 1 - real_uv.y;
frag_color = texture(sampler2D(twodee_tex, fs_twodee_smp), real_uv) * tint;
if (flip_and_swap_rgb > 0) frag_color.rgb = frag_color.bgr;
if(frag_color.a <= alpha_clip_threshold)
{
discard;
@ -420,6 +417,8 @@ uniform twodee_fs_params {
vec2 tex_size;
vec2 screen_size;
float flip_and_swap_rgb;
};
in vec2 uv;
@ -430,13 +429,16 @@ out vec4 frag_color;
void main() {
// clip space is from [-1,1] [left, right]of screen on X, and [-1,1] [bottom, top] of screen on Y
if(pos.x < clip_ul.x || pos.x > clip_lr.x || pos.y < clip_lr.y || pos.y > clip_ul.y) discard;
vec2 real_uv = uv;
if (flip_and_swap_rgb > 0) real_uv.y = 1 - real_uv.y;
// 5-tap tent filter: centre, left, right, up, down
float c = texture(sampler2D(twodee_tex, fs_twodee_outline_smp), uv).a;
float l = texture(sampler2D(twodee_tex, fs_twodee_outline_smp), uv + vec2(-1, 0)/tex_size).a;
float r = texture(sampler2D(twodee_tex, fs_twodee_outline_smp), uv + vec2(+1, 0)/tex_size).a;
float u = texture(sampler2D(twodee_tex, fs_twodee_outline_smp), uv + vec2(0, +1)/tex_size).a;
float d = texture(sampler2D(twodee_tex, fs_twodee_outline_smp), uv + vec2(0, -1)/tex_size).a;
float c = texture(sampler2D(twodee_tex, fs_twodee_outline_smp), real_uv).a;
float l = texture(sampler2D(twodee_tex, fs_twodee_outline_smp), real_uv + vec2(-1, 0)/tex_size).a;
float r = texture(sampler2D(twodee_tex, fs_twodee_outline_smp), real_uv + vec2(+1, 0)/tex_size).a;
float u = texture(sampler2D(twodee_tex, fs_twodee_outline_smp), real_uv + vec2(0, +1)/tex_size).a;
float d = texture(sampler2D(twodee_tex, fs_twodee_outline_smp), real_uv + vec2(0, -1)/tex_size).a;
// if centre pixel is ~1, it is inside a shape.
// if centre pixel is ~0, it is outside a shape.
@ -478,6 +480,8 @@ uniform twodee_fs_params {
vec2 tex_size;
vec2 screen_size;
float flip_and_swap_rgb;
};
in vec2 uv;
@ -498,13 +502,17 @@ void main() {
// clip space is from [-1,1] [left, right]of screen on X, and [-1,1] [bottom, top] of screen on Y
if(pos.x < clip_ul.x || pos.x > clip_lr.x || pos.y < clip_lr.y || pos.y > clip_ul.y) discard;
vec4 col = texture(sampler2D(twodee_tex, fs_twodee_color_correction_smp), uv);
vec2 real_uv = uv;
if (flip_and_swap_rgb > 0) real_uv.y = 1 - real_uv.y;
vec4 col = texture(sampler2D(twodee_tex, fs_twodee_color_correction_smp), real_uv);
if (flip_and_swap_rgb > 0) col.rgb = col.bgr;
col.rgb = acesFilm(col.rgb);
// Film grain
vec2 uv = gl_FragCoord.xy / screen_size.xy;
float x = uv.x * uv.y * time * 24 + 100.0;
vec2 grain_uv = gl_FragCoord.xy / screen_size.xy;
float x = grain_uv.x * grain_uv.y * time * 24 + 100.0;
vec3 noise = vec3(mod((mod(x, 13.0) + 1.0) * (mod(x, 123.0) + 1.0), 0.01)) * 100.0;
col.rgb += (noise - 0.5) * 0.05;
col.rgb *= 0.95;

Loading…
Cancel
Save