Last active
August 29, 2015 13:55
-
-
Save gokselgoktas/8779710 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const highp float EPSILON = .01; | |
const highp float AMBIENT_OCCLUSION_SAMPLE_DISTANCE = .05; | |
const highp float SHADOW_SAMPLE_DISTANCE = .25; | |
int MATERIAL_ID = 0; | |
mediump float ITERATION_COUNT = 0.; | |
highp float sample_and_update_material_id(highp vec3 position) | |
{ | |
highp float sphere_1 = length(position - vec3(-3., 0., 0.)) - 3.5; | |
// highp float sphere_2 = length(position + vec3(5., 0., 0.)) - 2.; | |
// highp float sphere_2 = dot(position, vec3(0., 1., 0.)) + 5.; | |
highp float sphere_2 = length(vec2(length(position.xy) - 3., position.z)) - 1.; | |
highp float sphere_3 = length(position - vec3(5., 0., -1.)) - 2. + .2 * sin(time * 10. + position.y * 3.); | |
if (sphere_1 < sphere_2 && sphere_1 < sphere_3) { | |
MATERIAL_ID = 1; | |
return sphere_1; | |
} else if (sphere_2 < sphere_3) { | |
MATERIAL_ID = 2; | |
return sphere_2; | |
} | |
MATERIAL_ID = 3; | |
return sphere_3; | |
} | |
highp float sample(highp vec3 position) | |
{ | |
highp float sphere_1 = length(position - vec3(-3., 0., 0.)) - 3.5; | |
// highp float sphere_2 = length(position + vec3(5., 0., 0.)) - 2.; | |
// highp float sphere_2 = dot(position, vec3(0., 1., 0.)) + 5.; | |
highp float sphere_2 = length(vec2(length(position.xy) - 3., position.z)) - 1.; | |
highp float sphere_3 = length(position - vec3(5., 0., -1.)) - 2. + .2 * sin(time * 10. + position.y * 3.); | |
return min(min(sphere_1, sphere_2), sphere_3); | |
} | |
highp vec3 calculate_local_normal(highp vec3 position) | |
{ | |
return normalize(highp vec3(sample(position + vec3(EPSILON, 0., 0.)) - sample(position - vec3(EPSILON, 0., 0.)), | |
sample(position + vec3(0., EPSILON, 0.)) - sample(position - vec3(0., EPSILON, 0.)), | |
sample(position + vec3(0., 0., EPSILON)) - sample(position - vec3(0., 0., EPSILON)))); | |
} | |
highp float calculate_ambient_occlusion_factor(highp vec3 position, highp vec3 normal) | |
{ | |
highp float result = 0.; | |
for (mediump float i = 0.; i < 5.; ++i) { | |
result += (i * AMBIENT_OCCLUSION_SAMPLE_DISTANCE - | |
sample(position + i * normal * AMBIENT_OCCLUSION_SAMPLE_DISTANCE)); | |
} | |
return 1. - (result * .2); | |
} | |
highp float calculate_shadow_factor(highp vec3 position, highp vec3 direction) | |
{ | |
highp float result = 0.; | |
for (mediump float i = 0.; i < 5.; ++i) { | |
result += (i * SHADOW_SAMPLE_DISTANCE - sample(position + i * direction * SHADOW_SAMPLE_DISTANCE)); | |
} | |
return 1. - (result * .2); | |
} | |
mediump vec4 calculate_diffuse_color() | |
{ | |
if (MATERIAL_ID == 1) { | |
return vec4(.75, .25, 0., 1.); | |
} else if (MATERIAL_ID == 2) { | |
return vec4(0., .835, .45, 1.); | |
} else if (MATERIAL_ID == 3) { | |
return vec4(.67, .88, .14, 1.); | |
} | |
return vec4(1.); | |
} | |
void main() | |
{ | |
lowp float aspect_ratio = screen_dimensions.x / screen_dimensions.y; | |
mediump vec2 normalized_fragment_coordinates = gl_FragCoord.xy / screen_dimensions; | |
mediump vec3 virtual_screen_coordinates = 8. * vec3(2. * normalized_fragment_coordinates - 1., 0.); | |
virtual_screen_coordinates.x *= aspect_ratio; | |
normalized_fragment_coordinates.x *= aspect_ratio; | |
mediump vec4 color = vec4(0., .24, normalized_fragment_coordinates.y, 0.); | |
mediump vec3 camera_position = vec3(0., 0., -10.); | |
mediump vec3 camera_direction = normalize(virtual_screen_coordinates - camera_position); | |
highp float step_size = 0.; | |
mediump vec3 light_position = vec3(15. * cos(time * 10.), 10. * sin(time * 10.), -9.); | |
for (mediump float d = 0.; d < 50.; d += max(step_size, EPSILON)) { | |
highp vec3 position = camera_position + camera_direction * d; | |
step_size = sample_and_update_material_id(position); | |
if (step_size < EPSILON) { | |
highp vec3 normal = calculate_local_normal(position); | |
highp vec3 direction_to_light = normalize(light_position - position); | |
highp float lambert_coefficient = max(dot(direction_to_light, normal), 0.); | |
highp vec3 half_vector = normalize(direction_to_light + normalize(camera_position - position)); | |
highp float blinn_phong_coefficient = pow(max(dot(half_vector, normal), 0.), 50.); | |
highp float ambient_occlusion_factor = calculate_ambient_occlusion_factor(position, normal); | |
highp float shadow_factor = calculate_shadow_factor(position, direction_to_light); | |
color = calculate_diffuse_color() * (lambert_coefficient + blinn_phong_coefficient) * | |
ambient_occlusion_factor * shadow_factor; | |
break; | |
} | |
++ITERATION_COUNT; | |
} | |
gl_FragColor = color; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment