Ray-caster: sort fragments while shading
This commit is contained in:
parent
e80adf831d
commit
4afc82034b
@ -138,16 +138,34 @@ void main() {
|
||||
const int SPHERE_MAX_INTERNAL = 6;
|
||||
vec2 depth_pairs [SPHERE_MAX_INTERNAL];
|
||||
taggedFrag frags [2*SPHERE_MAX_INTERNAL];
|
||||
int frag_cnt = 0;
|
||||
for (int i = 0; i < sphere_cnt; ++i) {
|
||||
vec2 hit_depths = sphere_cast(sphere_list[i], dir);
|
||||
if (hit_depths[0] > 0.) {
|
||||
frags[frag_cnt] = sphere_shading(sphere_list[i], hit_depths[0] * dir, color_list[i], i);
|
||||
++frag_cnt;
|
||||
}
|
||||
if (hit_depths[1] > 0.) {
|
||||
frags[frag_cnt] = sphere_shading(sphere_list[i], hit_depths[1] * dir, color_list[i], i);
|
||||
++frag_cnt;
|
||||
int layer_cnt = 0;
|
||||
for (int id = 0; id < sphere_cnt; ++id) {
|
||||
// find out where the ray hits the sphere
|
||||
vec2 hit_depths = sphere_cast(sphere_list[id], dir);
|
||||
|
||||
// insertion-sort the fragments we hit into the fragment list
|
||||
for (int side = 0; side < 2; ++side) {
|
||||
if (hit_depths[side] > 0.) {
|
||||
for (int layer = layer_cnt; layer >= 0; --layer) {
|
||||
if (layer < 1 || frags[layer-1].pt.z >= -hit_depths[side]) {
|
||||
// we're not as close to the screen as the fragment
|
||||
// before the empty slot, so insert here
|
||||
frags[layer] = sphere_shading(
|
||||
sphere_list[id],
|
||||
hit_depths[side] * dir,
|
||||
color_list[id],
|
||||
id
|
||||
);
|
||||
break;
|
||||
} else {
|
||||
// we're closer to the screen than the fragment before
|
||||
// the empty slot, so move that fragment into the empty
|
||||
// slot
|
||||
frags[layer] = frags[layer-1];
|
||||
}
|
||||
}
|
||||
++layer_cnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,29 +174,16 @@ void main() {
|
||||
if (debug_mode) {
|
||||
// at the bottom of the screen, show the color scale instead of the
|
||||
// layer count
|
||||
if (gl_FragCoord.y < 10.) frag_cnt = int(8. * gl_FragCoord.x / resolution.x);
|
||||
if (gl_FragCoord.y < 10.) layer_cnt = int(8. * gl_FragCoord.x / resolution.x);
|
||||
|
||||
// convert number to color
|
||||
ivec3 bits = frag_cnt / ivec3(1, 2, 4);
|
||||
ivec3 bits = layer_cnt / ivec3(1, 2, 4);
|
||||
outColor = vec4(mod(vec3(bits), 2.), 1.);
|
||||
return;
|
||||
}
|
||||
|
||||
// sort the fragments by depth, using an insertion sort
|
||||
for (int take = 1; take < frag_cnt; ++take) {
|
||||
taggedFrag pulled = frags[take];
|
||||
for (int put = take; put >= 0; --put) {
|
||||
if (put < 1 || frags[put-1].pt.z >= pulled.pt.z) {
|
||||
frags[put] = pulled;
|
||||
break;
|
||||
} else {
|
||||
frags[put] = frags[put-1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// highlight intersections and cusps
|
||||
for (int i = frag_cnt-1; i >= 1; --i) {
|
||||
for (int i = layer_cnt-1; i >= 1; --i) {
|
||||
// intersections
|
||||
taggedFrag frag0 = frags[i];
|
||||
taggedFrag frag1 = frags[i-1];
|
||||
@ -201,7 +206,7 @@ void main() {
|
||||
|
||||
// composite the sphere fragments
|
||||
vec3 color = vec3(0.);
|
||||
for (int i = frag_cnt-1; i >= layer_threshold; --i) {
|
||||
for (int i = layer_cnt-1; i >= layer_threshold; --i) {
|
||||
if (frags[i].pt.z < 0.) {
|
||||
vec4 frag_color = frags[i].color;
|
||||
color = mix(color, frag_color.rgb, frag_color.a);
|
||||
|
Loading…
Reference in New Issue
Block a user