render_3d.frag.glsl (3775B)
1 /* See LICENSE for license details. */ 2 layout(location = 0) in vec3 normal; 3 layout(location = 1) in vec3 texture_coordinate; 4 layout(location = 0) out vec4 out_colour; 5 6 layout(std430, buffer_reference, buffer_reference_align = 64) readonly buffer InputVec2 { 7 vec2 values[]; 8 }; 9 10 layout(std430, buffer_reference, buffer_reference_align = 64) readonly buffer InputFloat { 11 float values[]; 12 }; 13 14 /* input: h [0,360] | s,v [0, 1] * 15 * output: rgb [0,1] */ 16 vec3 hsv2rgb(vec3 hsv) 17 { 18 vec3 k = mod(vec3(5, 3, 1) + hsv.x / 60, 6); 19 k = max(min(min(k, 4 - k), 1), 0); 20 return hsv.z - hsv.z * hsv.y * k; 21 } 22 23 /* NOTE(rnp): adapted from: https://iquilezles.org/articles/distfunctions */ 24 float sdf_wire_box_outside(vec3 p, vec3 b, float e) 25 { 26 p = abs(p) - b; 27 vec3 q = abs(p + e) - e; 28 float result = min(min(length(max(vec3(p.x, q.y, q.z), 0.0)), 29 length(max(vec3(q.x, p.y, q.z), 0.0))), 30 length(max(vec3(q.x, q.y, p.z), 0.0))); 31 return result; 32 } 33 34 uint32_t texture_dimension(uvec3 points) 35 { 36 points = uvec3(greaterThan(points, uvec3(1))); 37 return points.x + points.y + points.z; 38 } 39 40 uint32_t input_index(vec3 uv) 41 { 42 uv *= vec3(input_size_x - 1, input_size_y - 1, input_size_z - 1); 43 uint32_t result = input_size_y * input_size_x * uint32_t(uv.z) + 44 input_size_x * uint32_t(uv.y) + 45 uint32_t(uv.x); 46 result = min(result, input_size_z * input_size_y * input_size_x - 1); 47 return result; 48 } 49 50 float sample_value(vec3 p) 51 { 52 float result; 53 if (input_data != 0) { 54 uint32_t index = input_index(texture_coordinate); 55 switch (data_kind) { 56 case DataKind_Float32:{ result = length(InputFloat(input_data).values[index]); }break; 57 case DataKind_Float32Complex:{ result = length(InputVec2(input_data).values[index]); }break; 58 } 59 } 60 61 float threshold_val = pow(10.0f, threshold / 20.0f); 62 result = clamp(result, 0.0f, threshold_val); 63 result = result / threshold_val; 64 result = pow(result, gamma); 65 66 if (db_cutoff > 0) { 67 result = 20 * log(result) / log(10); 68 result = clamp(result, -db_cutoff, 0) / -db_cutoff; 69 result = 1 - result; 70 } 71 72 return result; 73 } 74 75 float grad(float x) 76 { 77 float h = length(fwidth(texture_coordinate.xy)); 78 float s1 = sample_value(vec3(x + h, 0, 0)); 79 float s2 = sample_value(vec3(x - h, 0, 0)); 80 return (s1 - s2) / (2.0f * h); 81 } 82 83 void main(void) 84 { 85 uint32_t dimension = texture_dimension(uvec3(input_size_x, input_size_y, input_size_z)); 86 87 if (dimension == 3) { 88 // TODO(rnp): add slice offset passed in as a uniform 89 } 90 91 float data = sample_value(texture_coordinate); 92 //float t = test_texture_coordinate.y; 93 //smp = smp * smoothstep(-0.4, 1.1, t) * u_gain; 94 95 vec3 p = 2.0f * texture_coordinate - 1.0f; 96 97 switch (dimension) { 98 case 1:{ 99 100 float df = mix(grad(texture_coordinate.x), dFdx(data), 101 smoothstep(0.0f, 0.55f, abs(texture_coordinate.x - 0.5f))); 102 float de = abs(data - texture_coordinate.y) / sqrt(1.0f + df * df); 103 104 float eps = length(fwidth(texture_coordinate.xy)); 105 float thickness = 4.f; 106 107 float alpha = smoothstep((0.5f * thickness + 2.0f) * eps, (0.5f * thickness + 0.0f) * eps, de); 108 out_colour = vec4(bounding_box_colour.xyz, alpha); 109 }break; 110 111 case 0: // NOTE(rnp): 0 is a special case for X-Plane Rendering 112 case 2: 113 case 3: 114 { 115 float t = clamp(sdf_wire_box_outside(p, vec3(1.0f), bounding_box_fraction) / bounding_box_fraction, 0, 1); 116 117 out_colour = vec4(t * vec3(data) + (1 - t) * bounding_box_colour.xyz, 1); 118 //if (u_solid_bb) out_colour = u_bb_colour; 119 }break; 120 } 121 122 //out_colour = vec4(textureQueryLod(u_texture, texture_coordinate).y, 0, 0, 1); 123 //out_colour = vec4(abs(normal), 1); 124 //out_colour = vec4(1, 1, 1, smp); 125 //out_colour = vec4(smp * abs(normal), 1); 126 }