@vs vs in vec3 a_pos; in vec2 a_tex_coords; in vec3 a_norm; out vec2 tex_coords; out vec3 normal; out vec3 frag_pos; out vec4 frag_pos_light; uniform vs_p { uniform mat4 vp; uniform mat4 model; uniform mat4 proj; uniform mat4 lsm; }; void main() { frag_pos = vec3(model * vec4(a_pos, 1.0)); gl_Position = proj * vp * vec4(frag_pos, 1.0); tex_coords = a_tex_coords; normal = mat3(transpose(inverse(model))) * a_norm; frag_pos_light = lsm * vec4(frag_pos, 1.0); } @end @fs fs in vec2 tex_coords; in vec3 normal; in vec3 frag_pos; in vec4 frag_pos_light; out vec4 frag_color; uniform texture2D diffuse; uniform texture2D normmap; uniform texture2D shadow_map; uniform sampler smp; uniform fs_p { uniform vec3 point_pos; uniform vec3 dir_dir; uniform vec3 view_pos; uniform vec3 spot_pos; uniform vec3 spot_dir; uniform vec2 shadow_dim; }; /* Ambient light */ float amb_str = 0.3; vec3 amb_color = vec3(1,1,1); float spec_str = 0.5; /* point */ float constant = 1; float linear = 0.09; float quad = 0.032; /* spotlight */ float cutoff = 12.5; /* cutoff in radians */ float outer_cutoff = 17.5; vec3 norm = vec3(0,0,0); vec3 view = vec3(0,0,0); float light_str(vec3 dir) { float d = max(dot(norm, dir), 0.0); vec3 refl = reflect(-dir, norm); float s = pow(max(dot(view,refl), 0.0), 32); return s+d; } float shadow_calc(vec4 fg) { vec3 pc = fg.xyz / fg.w; pc = pc * 0.5 + 0.5; if (pc.z > 1.0) return 0.0; float closest_depth = texture(sampler2D(shadow_map,smp), pc.xy).r; float cur_depth = pc.z; vec3 light_dir = normalize(vec3(4,100,20) - frag_pos); /* light pos */ float bias = max(0.05 * (1 - dot(norm, light_dir)), 0.005); return cur_depth - bias > closest_depth ? 1.0 : 0.0; float s; vec2 texel_size = 1 / shadow_dim; for (int x = -1; x <= 1; ++x) { for (int y = -1; y <= 1; ++y) { float pcf_depth = texture(sampler2D(shadow_map,smp), pc.xy + vec2(x,y) * texel_size).r; s += cur_depth - bias > pcf_depth ? 1.0 : 0.0; } } s /= 9.0; return s; } void main() { norm = normalize(normal); view = normalize(view_pos - frag_pos); float point_amt = light_str(normalize(point_pos-frag_pos)); float dist = length(point_pos - frag_pos); float atten = 1.0 / (constant + linear * dist + quad * (dist*dist)); point_amt *= atten; float dir_amt = light_str(normalize(-dir_dir)); vec3 spot_dir = normalize(spot_pos - frag_pos); float theta = dot(spot_dir, normalize(-spot_dir)); float spot_amt = 0; float epsilon = cutoff - outer_cutoff; if (theta > cutoff) { float intensity = clamp((theta - outer_cutoff)/epsilon,0.0,1.0); spot_amt = light_str(spot_dir) * intensity; } vec4 mm = texture(sampler2D(diffuse,smp),tex_coords); float shadow = shadow_calc(frag_pos_light); vec3 res = mm.rgb * (amb_str + (point_amt + dir_amt) * (1 - shadow)); frag_color = vec4(res, mm.a); } @end @program diffuse vs fs