Skip to content

Instantly share code, notes, and snippets.

@gokselgoktas
Last active August 29, 2015 13:55
Show Gist options
  • Save gokselgoktas/8779710 to your computer and use it in GitHub Desktop.
Save gokselgoktas/8779710 to your computer and use it in GitHub Desktop.
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