@@ -97,15 +97,15 @@ vec3 get_obb_normal(vec3 ro, vec3 rd, uint id, float t) {
9797 return normalize(rotate_vector(n, tf.quat));
9898}
9999
100- bool trace_shadow (vec3 ro, vec3 rd, float max_t) {
100+ bool trace_shadow_fast (vec3 ro, vec3 rd, float max_t, int max_steps ) {
101101 float t_min, t_max; if (!intersect_aabb(ro, rd, vec3(WORLD_MIN), vec3(WORLD_MAX), t_min, t_max)) return false;
102102 t_min = max(t_min, 0.0); t_max = min(t_max, max_t);
103103 vec3 cell_p = (ro + rd * (t_min + 0.001) - WORLD_MIN) / CELL_SIZE;
104104 ivec3 cell = clamp(ivec3(floor(cell_p)), ivec3(0), ivec3(127));
105105 vec3 step = sign(rd), t_delta = abs(CELL_SIZE / rd), t_max_step;
106106 for(int i=0; i<3; ++i) t_max_step[i] = t_min + (rd[i]>0.0?floor(cell_p[i])+1.0-cell_p[i]:cell_p[i]-floor(cell_p[i])) * t_delta[i];
107107 uint64_t cached_mask = 0; ivec3 last_brick = ivec3(-1);
108- for (int i = 0; i < 24 ; ++i) {
108+ for (int i = 0; i < max_steps ; ++i) {
109109 ivec3 brick_p = cell >> 2;
110110 if (brick_p != last_brick) {
111111 cached_mask = all_bitmasks[pc.bitmask_id].bitmasks[brick_p.x + (brick_p.y << 5) + (brick_p.z << 10)];
@@ -161,16 +161,24 @@ float trace_ao(vec3 ro, vec3 n) {
161161 }
162162 return 1.0;
163163}
164+ vec3 get_sky(vec3 rd) {
165+ vec3 L = normalize(vec3(0.5, 1.0, 0.3));
166+ float sun = pow(max(dot(rd, L), 0.0), 128.0);
167+ vec3 sky = mix(vec3(0.1, 0.2, 0.4), vec3(0.4, 0.6, 0.9), max(rd.y, 0.0));
168+ return sky + vec3(1.0, 0.8, 0.5) * sun * 5.0; // Bright sun disk
169+ }
164170
165171void main() {
166172 uvec2 pixel = gl_GlobalInvocationID.xy;
167173 if (pixel.x >= uint(pc.res.x) || pixel.y >= uint(pc.res.y)) return;
168-
174+ uint seed = hash(pixel.x + pixel.y * uint(pc.res.x));
169175 vec2 uv = (vec2(pixel) / pc.res) * 2.0 - 1.0; uv.x *= pc.res.x / pc.res.y;
170176 vec3 rd = normalize(pc.cam_dir.xyz + pc.cam_right.xyz * uv.x + pc.cam_up.xyz * uv.y), ro = pc.cam_pos.xyz;
171- float t_min, t_max; vec3 color = vec3(0.005, 0.005, 0.01) + rd.y * 0.02;
177+ float t_min, t_max; vec3 color = get_sky(rd);
178+
172179 if (intersect_aabb(ro, rd, vec3(WORLD_MIN), vec3(WORLD_MAX), t_min, t_max)) {
173180 t_min = max(t_min, 0.0);
181+
174182 vec3 cell_p = (ro + rd * (t_min + 0.0001) - WORLD_MIN) / CELL_SIZE;
175183 ivec3 cell = clamp(ivec3(floor(cell_p)), ivec3(0), ivec3(127));
176184 vec3 step = sign(rd), t_delta = abs(CELL_SIZE / rd), t_max_step;
@@ -210,10 +218,19 @@ void main() {
210218 Material mat = all_mats[pc.mat_id].mats[hit_id]; vec3 L = normalize(vec3(0.5, 1.0, 0.3));
211219 float diff = max(dot(hit_n, L), 0.0);
212220 float ao = trace_ao(ro + rd * hit_t + hit_n * 0.01, hit_n);
213- color = mat.base_color.rgb * (diff * 0.8 + 0.2 * ao);
221+
222+ vec3 sky_color = get_sky(hit_n);
223+ color = mat.base_color.rgb * (diff * 1.5 + sky_color * 0.2 * ao);
214224 if (mat.emissive > 0.0) color += mat.base_color.rgb * mat.emissive;
215- if (pc.use_shadows == 1 && diff > 0.0) if (trace_shadow(ro + rd * hit_t + hit_n * 0.002, L, 20.0)) color *= 0.4;
225+ if (pc.use_shadows == 1 && diff > 0.0) {
226+ if (trace_shadow_fast(ro + rd * hit_t + hit_n * 0.01, L, 20.0, 48)) color *= 0.6;
227+ }
216228 }
217229 }
230+
231+ // ACES Tonemapping
232+ const float a = 2.51, b = 0.03, c = 2.43, d = 0.59, e = 0.14;
233+ color = clamp((color * (a * color + b)) / (color * (c * color + d) + e), 0.0, 1.0);
234+
218235 imageStore(all_images[pc.img_id], ivec2(pixel), vec4(color, 1.0));
219236}
0 commit comments