Skip to content

Commit 8011e61

Browse files
committed
fix atlas sampling artifacts (closes #23)
1 parent e6ee8cf commit 8011e61

17 files changed

+227
-249
lines changed

shaders/composite.frag

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
layout(location = 0) in vec2 i_uv;
66
layout(location = 0) out vec4 o_color;
7-
layout(set = 2, binding = 0) uniform sampler2D s_atlas;
7+
layout(set = 2, binding = 0) uniform sampler2DArray s_atlas;
88
layout(set = 2, binding = 1) uniform sampler2D s_position;
99
layout(set = 2, binding = 2) uniform sampler2D s_uv;
1010
layout(set = 2, binding = 3) uniform usampler2D s_voxel;
@@ -26,7 +26,7 @@ layout(set = 3, binding = 2) uniform t_shadow_matrix
2626
void main()
2727
{
2828
const vec3 position = texture(s_position, i_uv).xyz;
29-
const vec2 uv = texture(s_uv, i_uv).xy;
29+
const vec3 uv = texture(s_uv, i_uv).xyz;
3030
const uint voxel = texture(s_voxel, i_uv).x;
3131
if (length(uv) == 0)
3232
{

shaders/helpers.glsl

+19-32
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,19 @@ const vec3 normals[6] = vec3[6]
1616
vec3 get_position(
1717
const uint voxel)
1818
{
19-
return vec3(voxel >> VOXEL_X_OFFSET & VOXEL_X_MASK,
19+
return vec3(
20+
voxel >> VOXEL_X_OFFSET & VOXEL_X_MASK,
2021
voxel >> VOXEL_Y_OFFSET & VOXEL_Y_MASK,
2122
voxel >> VOXEL_Z_OFFSET & VOXEL_Z_MASK);
2223
}
2324

24-
vec2 get_atlas(
25-
const vec2 position)
26-
{
27-
return vec2(
28-
position.x / ATLAS_WIDTH * ATLAS_FACE_WIDTH,
29-
position.y / ATLAS_HEIGHT * ATLAS_FACE_HEIGHT);
30-
}
31-
32-
vec2 get_uv(
25+
vec3 get_uv(
3326
const uint voxel)
3427
{
35-
return get_atlas(vec2(
28+
return vec3(
3629
voxel >> VOXEL_U_OFFSET & VOXEL_U_MASK,
37-
voxel >> VOXEL_V_OFFSET & VOXEL_V_MASK));
30+
voxel >> VOXEL_V_OFFSET & VOXEL_V_MASK,
31+
voxel >> VOXEL_FACE_OFFSET & VOXEL_FACE_MASK);
3832
}
3933

4034
uint get_direction(
@@ -80,10 +74,10 @@ float get_fog(
8074
}
8175

8276
vec4 get_color(
83-
const sampler2D atlas,
77+
const sampler2DArray atlas,
8478
const sampler2D shadowmap,
8579
const vec3 position,
86-
const vec2 uv,
80+
const vec3 uv,
8781
const vec3 normal,
8882
const vec3 player_position,
8983
const vec3 shadow_position,
@@ -98,37 +92,30 @@ vec4 get_color(
9892
shadow_uv.x = shadow_position.x * 0.5 + 0.5;
9993
shadow_uv.y = 1.0 - (shadow_position.y * 0.5 + 0.5);
10094
shadow_uv.z = shadow_position.z;
101-
float a;
102-
float b;
103-
float c;
95+
float ao = ssao * 0.4;
96+
float ambient = 0.2;
97+
float directional = 0.0;
10498
const float angle = dot(normal, -shadow_vector);
10599
const float depth = shadow_uv.z - 0.001;
106-
if (shadowed && ((angle < 0.0) || (
107-
all(greaterThanEqual(shadow_uv, vec3(0.0))) &&
108-
all(lessThanEqual(shadow_uv, vec3(1.0))) &&
109-
(depth > texture(shadowmap, shadow_uv.xy).x))))
110-
{
111-
a = ssao * 0.2;
112-
b = 0.3;
113-
c = 0.0;
114-
}
115-
else
100+
if (!shadowed || (angle > 0.0 && (
101+
all(lessThanEqual(shadow_uv, vec3(0.0))) ||
102+
all(greaterThanEqual(shadow_uv, vec3(1.0))) ||
103+
(depth < texture(shadowmap, shadow_uv.xy).x))))
116104
{
117-
a = ssao * 0.4;
118-
b = 0.3;
119-
c = max(angle, 0.0) * 1.2;
105+
directional = max(angle, 0.0) * 1.2;
120106
}
121107
if (!occluded)
122108
{
123-
a = 0.7;
109+
ao = 0.7;
124110
}
125111
vec4 color = texture(atlas, uv);
126112
color.a = clamp(color.a + alpha, 0.0, 1.0);
127-
const vec4 composite = vec4(color.xyz * (a + b + c), color.a);
113+
const float light = ao + ambient + directional;
128114
const float dy = position.y - player_position.y;
129115
const float dx = distance(position.xz, player_position.xz);
130116
const float pitch = atan(dy, dx);
131117
const vec4 sky = vec4(get_sky(pitch), 1.0);
118+
const vec4 composite = vec4(color.xyz * light, color.a);
132119
return mix(composite, sky, fog);
133120
}
134121

shaders/opaque.frag

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
layout(location = 0) in flat uint i_voxel;
44
layout(location = 1) in vec4 i_position;
5-
layout(location = 2) in vec2 i_uv;
5+
layout(location = 2) in vec3 i_uv;
66
layout(location = 0) out vec4 o_position;
7-
layout(location = 1) out vec2 o_uv;
7+
layout(location = 1) out vec3 o_uv;
88
layout(location = 2) out uint o_voxel;
9-
layout(set = 2, binding = 0) uniform sampler2D s_atlas;
9+
layout(set = 2, binding = 0) uniform sampler2DArray s_atlas;
1010

1111
void main()
1212
{

shaders/opaque.vert

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
layout(location = 0) in uint i_voxel;
66
layout(location = 0) out flat uint o_voxel;
77
layout(location = 1) out vec4 o_position;
8-
layout(location = 2) out vec2 o_uv;
8+
layout(location = 2) out vec3 o_uv;
99
layout(set = 1, binding = 0) uniform t_position
1010
{
1111
ivec3 u_position;

shaders/random.frag

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#version 450
22

33
layout(location = 0) in vec2 i_uv;
4-
layout(location = 0) out float o_random;
4+
layout(location = 0) out vec2 o_random;
55

66
void main()
77
{
8-
o_random = fract(sin(dot(i_uv, vec2(12.9898, 78.233))) * 43758.5453);
8+
o_random.x = fract(sin(dot(i_uv * 1.0, vec2(12.9898, 78.233))) * 43758.5453);
9+
o_random.y = fract(sin(dot(i_uv * 2.0, vec2(12.9898, 78.233))) * 43758.5453);
10+
o_random = o_random * 2.0 - 1.0;
911
}

shaders/ssao.frag

+19-19
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,22 @@ layout(set = 2, binding = 3) uniform sampler2D s_random;
1212
bool test(
1313
const uint direction,
1414
const vec3 position,
15-
const vec3 neighbor)
15+
const vec2 uv)
1616
{
17+
const vec3 neighbor_position = texture(s_position, uv).xyz;
18+
const vec2 neighbor_uv = texture(s_uv, uv).xy;
19+
if (length(neighbor_uv) == 0)
20+
{
21+
return false;
22+
}
1723
switch (direction)
1824
{
19-
case 4: return position.y < neighbor.y;
20-
case 5: return position.y > neighbor.y;
21-
case 2: return position.x < neighbor.x;
22-
case 3: return position.x > neighbor.x;
23-
case 0: return position.z < neighbor.z;
24-
case 1: return position.z > neighbor.z;
25+
case 4: return position.y < neighbor_position.y;
26+
case 5: return position.y > neighbor_position.y;
27+
case 2: return position.x < neighbor_position.x;
28+
case 3: return position.x > neighbor_position.x;
29+
case 0: return position.z < neighbor_position.z;
30+
case 1: return position.z > neighbor_position.z;
2531
}
2632
return false;
2733
}
@@ -36,22 +42,16 @@ void main()
3642
}
3743
const vec4 position = texture(s_position, i_uv);
3844
const uint direction = get_direction(voxel);
39-
const vec2 size = 1.0 / textureSize(s_voxel, 0) * (1.0 / position.w) * 75.0;
45+
const vec2 scale = 75.0 / (textureSize(s_voxel, 0) * position.w);
4046
float ssao = 0.0;
4147
int kernel = 2;
42-
for (int x = -kernel; x <= kernel; ++x)
48+
for (int x = -kernel; x <= kernel; x++)
4349
{
44-
for (int y = -kernel; y <= kernel; ++y)
50+
for (int y = -kernel; y <= kernel; y++)
4551
{
46-
const vec2 origin = i_uv + vec2(x, y) * size;
47-
const vec2 random = origin + vec2(texture(s_random, origin).x) * 0.01;
48-
const uint neighbor_voxel = texture(s_voxel, random).x;
49-
const uint neighbor_direction = get_direction(neighbor_voxel);
50-
const vec3 neighbor_position = texture(s_position, random).xyz;
51-
const vec2 neighbor_uv = texture(s_uv, random).xy;
52-
if (length(neighbor_uv) == 0 ||
53-
direction != neighbor_direction ||
54-
test(neighbor_direction, position.xyz, neighbor_position))
52+
const vec2 origin = i_uv + vec2(x, y) * scale;
53+
const vec2 offset = texture(s_random, origin).xy * scale;
54+
if (test(direction, position.xyz, origin + offset))
5555
{
5656
ssao += 1.0;
5757
}

shaders/transparent.frag

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33
#include "helpers.glsl"
44

55
layout(location = 0) in vec3 i_position;
6-
layout(location = 1) in vec2 i_uv;
6+
layout(location = 1) in vec3 i_uv;
77
layout(location = 2) in flat vec3 i_normal;
88
layout(location = 3) in vec4 i_shadow_position;
99
layout(location = 4) in flat uint i_shadowed;
1010
layout(location = 5) in flat uint i_occluded;
1111
layout(location = 6) in float i_fog;
1212
layout(location = 7) in vec2 i_fragment;
1313
layout(location = 0) out vec4 o_color;
14-
layout(set = 2, binding = 0) uniform sampler2D s_atlas;
14+
layout(set = 2, binding = 0) uniform sampler2DArray s_atlas;
1515
layout(set = 2, binding = 1) uniform sampler2D s_shadowmap;
1616
layout(set = 2, binding = 2) uniform sampler2D s_position;
1717
layout(set = 3, binding = 0) uniform t_shadow_vector

shaders/transparent.vert

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
layout(location = 0) in uint i_voxel;
66
layout(location = 0) out vec3 o_position;
7-
layout(location = 1) out vec2 o_uv;
7+
layout(location = 1) out vec3 o_uv;
88
layout(location = 2) out flat vec3 o_normal;
99
layout(location = 3) out vec4 o_shadow_position;
1010
layout(location = 4) out flat uint o_shadowed;

shaders/ui.frag

+5-8
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#include "helpers.glsl"
44

55
layout(location = 0) out vec4 o_color;
6-
layout(set = 2, binding = 0) uniform sampler2D s_atlas;
6+
layout(set = 2, binding = 0) uniform sampler2DArray s_atlas;
77
layout(set = 3, binding = 0) uniform t_viewport
88
{
99
ivec2 u_viewport;
@@ -12,9 +12,9 @@ layout(set = 3, binding = 1) uniform t_corner
1212
{
1313
ivec2 u_corner;
1414
};
15-
layout(set = 3, binding = 2) uniform t_block
15+
layout(set = 3, binding = 2) uniform t_face
1616
{
17-
ivec2 u_block;
17+
uint u_face;
1818
};
1919

2020
void main()
@@ -31,11 +31,8 @@ void main()
3131
{
3232
const float x = (position.x - block_start.x) / block_width;
3333
const float y = (position.y - block_start.y) / block_width;
34-
const vec2 uv = get_atlas(u_block);
35-
const float c = uv.x + x / ATLAS_X_FACES;
36-
const float d = uv.y + (1.0 - y) / ATLAS_Y_FACES;
37-
o_color = texture(s_atlas, vec2(c, d));
38-
o_color.xyz *= 1.25;
34+
o_color = texture(s_atlas, vec3(x, 1.0 - y, u_face));
35+
o_color.xyz *= 1.5;
3936
return;
4037
}
4138
const float cross_width = 8 * scale;

0 commit comments

Comments
 (0)