static void get_lum(double *col, t_scene *s, t_intersect *inter, int m) { t_vec3 l; t_vec3 r; double ln; int i; double is; double id; double dist; double rv; double tmp; t_ray ray; t_intersect shadow; i = -1; if (s->lights[m].light.type == DIRECTIONNAL) { while (++i < 3) { ln = dot_vec3(inter->norm, s->lights[m].light.dir); col[i] = MAX(ln, 0) * s->lights[m].light.color.argb[i] / 255.0 * s->lights[m].light.power; } return ; } l = sub_vec3(s->lights[m].pos, inter->pos); dist = vec3_len(l); l = div_vec3(l, dist); dist -= s->lights[m].light.radius; ln = dot_vec3(l, inter->norm); ln = MAX(ln, 0.0); r = vec3_normalize(sub_vec3(mult_vec3(inter->norm, 2 * ln), l)); is = s->lights[m].light.power / dist; id = s->lights[m].light.radius * is; rv = -dot_vec3(r, inter->dir); rv = MAX(rv, 0.0); ray.pos = add_vec3(inter->pos, mult_vec3(inter->norm, 0.00001)); ray.dir = l; ray.env = NULL; scene_intersect(s, &ray, &shadow); if (shadow.dist < dist - 0.0001) return ; while (++i < 3) { tmp = inter->mat->diffuse * MAX(ln, 0) * id * s->lights[m].light.color.argb[i] / 255.0; col[i] += MAX(tmp, 0); tmp = inter->mat->specular * pow(rv, inter->mat->shininess) * is * s->lights[m].light.color.argb[i] / 255.0; col[i] += MAX(tmp, 0); } }
/* * Fragment shader for surface lighting. One directional light source, phong shading. */ static void fragment_shader_light(int y, int x, struct fragment_input *input, struct uniform_variables *vars){ if(input->frag_coord[VAR_Z] >= read_depth(y, x)){ return; } float *light_dir = &(vars->uniform_float[0]); vec3 eye_normal, object_normal; object_normal[VAR_X] = input->attributes[0] / input->frag_coord[VAR_W]; object_normal[VAR_Y] = input->attributes[1] / input->frag_coord[VAR_W]; object_normal[VAR_Z] = input->attributes[2] / input->frag_coord[VAR_W]; eye_normal[VAR_X] = input->attributes[3] / input->frag_coord[VAR_W]; eye_normal[VAR_Y] = input->attributes[4] / input->frag_coord[VAR_W]; eye_normal[VAR_Z] = input->attributes[5] / input->frag_coord[VAR_W]; normalize_vec3(eye_normal); normalize_vec3(object_normal); if(input->front_facing == ER_FALSE){ eye_normal[VAR_X] = -eye_normal[VAR_X]; eye_normal[VAR_Y] = -eye_normal[VAR_Y]; eye_normal[VAR_Z] = -eye_normal[VAR_Z]; object_normal[VAR_X] = -object_normal[VAR_X]; object_normal[VAR_Y] = -object_normal[VAR_Y]; object_normal[VAR_Z] = -object_normal[VAR_Z]; } float diffuse_term = max(0.0f, dot_vec3(light_dir, eye_normal) ); float specular_term = 0.0f; vec3 view_vector; vec3 half_vector; view_vector[VAR_X] = 0.0f; view_vector[VAR_Y] = 0.0f; view_vector[VAR_Z] = 1.0f; if(diffuse_term > 0.0f){ half_vector[VAR_X] = light_dir[VAR_X] + view_vector[VAR_X]; half_vector[VAR_Y] = light_dir[VAR_Y] + view_vector[VAR_Y]; half_vector[VAR_Z] = light_dir[VAR_Z] + view_vector[VAR_Z]; normalize_vec3(half_vector); specular_term = pow( max(0.0f, dot_vec3(half_vector, eye_normal)), 50.0f ); } float red, green, blue, light_intensity; light_intensity = 0.6f * diffuse_term + 0.4f * specular_term; red = (object_normal[VAR_X] * 0.5f + 0.5f) * light_intensity; red = clamp(red, 0.0f, 1.0f); green = (object_normal[VAR_Y] * 0.5f + 0.5f) * light_intensity; green = clamp(green, 0.0f, 1.0f); blue = (object_normal[VAR_Z] * 0.5f + 0.5f) * light_intensity; blue = clamp(blue, 0.0f, 1.0f); write_color(y, x, red, green, blue, 1.0f); write_depth(y, x, input->frag_coord[VAR_Z]); }
s_mat4 fps_view_rh(s_vec3 eye, float pitch, float yaw) { float cosPitch = cos(pitch); float sinPitch = sin(pitch); float cosYaw = cos(yaw); float sinYaw = sin(yaw); s_vec3 xaxis = vec3(cosYaw, 0, -sinYaw); s_vec3 yaxis = vec3(sinYaw * sinPitch, cosPitch, cosYaw * sinPitch); s_vec3 zaxis = vec3(sinYaw * cosPitch, -sinPitch, cosPitch * cosYaw); // Create a 4x4 view matrix from the right, up, forward and eye position vectors return mat4(xaxis.i, xaxis.j, xaxis.k, -dot_vec3(xaxis, eye), yaxis.i, yaxis.j, yaxis.k, -dot_vec3(yaxis, eye), zaxis.i, zaxis.j, zaxis.k, -dot_vec3(zaxis, eye), 0, 0, 0, 1); }