fixed that weird mesh seam bug

This commit is contained in:
2025-08-23 02:02:16 +10:00
parent 223afb5401
commit 8bec0fc69a
29 changed files with 370 additions and 95 deletions

143
Shaders/acerola.gdshader Normal file
View File

@@ -0,0 +1,143 @@
shader_type spatial;
render_mode skip_vertex_transform;
uniform bool billboard = false;
uniform sampler2D color_texture : source_color, filter_nearest, repeat_disable;
uniform vec3 tint : source_color = vec3(1);
uniform bool vertex_snapping = true;
uniform bool affine_texture_mapping = true;
group_uniforms Fog;
uniform bool add_fog = false;
uniform vec3 fog_color : source_color = vec3(0.42, 0.42, 0.45);
uniform vec2 fog_start_end = vec2(10, 100);
group_uniforms;
group_uniforms Light;
uniform bool add_dynamic_vertex_lighting = false;
uniform vec3 light_direction = vec3(0, 1, 0);
uniform float light_intensity = 1.0;
uniform vec3 ambient_light : source_color = vec3(0);
group_uniforms;
group_uniforms Dither;
uniform bool add_dither = true;
uniform float dither_spread = 1.0;
uniform float dither_gamma = 1.0;
group_uniforms;
varying vec4 clip_pos;
varying float FOG_FACTOR;
void vertex() {
mat4 model_matrix = MODEL_MATRIX;
if (billboard) {
mat4 mat_world = mat4(
normalize(INV_VIEW_MATRIX[0]),
vec4(0, 1, 0, 0),
normalize(INV_VIEW_MATRIX[2]),
MODEL_MATRIX[3]);
model_matrix = mat_world;
MODELVIEW_MATRIX = VIEW_MATRIX * mat_world;
MODELVIEW_NORMAL_MATRIX = mat3(MODELVIEW_MATRIX);
}
vec4 world_space = model_matrix * vec4(VERTEX, 1);
vec4 clip = PROJECTION_MATRIX * VIEW_MATRIX * world_space;
vec4 vertex = clip;
// Snap to nearest pixel
if (vertex_snapping) {
vertex.xy = round(clip.xy / clip.w * VIEWPORT_SIZE.xy) / VIEWPORT_SIZE.xy * clip.w;
}
POSITION = vertex;
// Need to hold on to clip.w to reverse perspective corrections
clip_pos = vertex;
// Calculate vertex distance from camera for fog
float view_distance = length(CAMERA_POSITION_WORLD - world_space.xyz);
FOG_FACTOR = (fog_start_end.y - (view_distance)) / (fog_start_end.y - fog_start_end.x);
FOG_FACTOR = 1.0 - clamp(FOG_FACTOR, 0.0, 1.0);
NORMAL = MODEL_NORMAL_MATRIX * NORMAL;
if (add_dynamic_vertex_lighting) {
float direct_light = clamp(dot(NORMAL, normalize(light_direction)), 0, 1);
vec3 light = ambient_light + direct_light * light_intensity;
COLOR.rgb *= clamp(light, vec3(0), vec3(1));
}
// Multiply by perspective correction to undo it in fragment shader
if (affine_texture_mapping) {
UV = UV * clip_pos.w;
COLOR *= clip_pos.w;
FOG_FACTOR *= clip_pos.w;
}
}
void fragment() {
vec2 uv = UV;
vec3 vertex_color = COLOR.rgb;
float fog_factor = FOG_FACTOR;
// Undo perspective correction
if (affine_texture_mapping) {
uv /= clip_pos.w;
vertex_color /= clip_pos.w;
fog_factor /= clip_pos.w;
}
vec3 texture_color = texture(color_texture, uv).rgb;
vec3 albedo = texture_color * vertex_color * tint;
vec3 fogged = albedo;
if (add_fog) {
fogged = mix(albedo, fog_color, fog_factor);
fogged = clamp(fogged, vec3(0), vec3(1));
}
vec3 quantized = fogged;
if (add_dither) {
int ps1_dither_matrix[16] = {
-4, 0, -3, 1,
2, -2, 3, -1,
-3, 1, -4, 0,
3, -1, 2, -2
};
// Index 1D dither matrix based on 2D screen coordinates
float noise = float(ps1_dither_matrix[(int(FRAGCOORD.x) % 4) + (int(FRAGCOORD.y) % 4) * 4]);
// Apply dithering and quantize 24 bit srgb to 15 bit srgb according to https://psx-spx.consoledev.net/graphicsprocessingunitgpu/
quantized = pow(fogged, vec3(1.0 / dither_gamma)); // Convert to srgb cause it imo looks better and is probably correct idk looks more correct than linear quantization
quantized = round(quantized * 255.0 + noise); // Convert to 0-255 and add dither noise
quantized = clamp(round(quantized), vec3(0), vec3(255)); // Clamp to 0-255 in case of overflow
quantized = clamp(quantized / 8.0, vec3(0), vec3(31)); // Convert to 0-31 range
quantized /= 31.0; // Convert back to 0-1 range
quantized = pow(quantized, vec3(dither_gamma)); // Convert back to linear
}
ALBEDO = quantized;
}
void light() {
DIFFUSE_LIGHT = vec3(1);
SPECULAR_LIGHT = vec3(0);
}