From e5448ede7f1e3b13dc2041819bdc75effb08708c Mon Sep 17 00:00:00 2001 From: iurii Date: Sat, 7 Sep 2024 22:56:06 +0300 Subject: fake spotlight --- res/shaders/colors.fs | 55 +++++++++++++++++++++++++++++++-------------------- src/main.odin | 7 ++++++- 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/res/shaders/colors.fs b/res/shaders/colors.fs index f2e6bd9..228f555 100644 --- a/res/shaders/colors.fs +++ b/res/shaders/colors.fs @@ -11,6 +11,9 @@ struct Material { struct Light { vec3 position; + vec3 direction; + + float cutOff; vec3 ambient; vec3 diffuse; @@ -30,26 +33,36 @@ uniform Material material; uniform Light light; void main() { - // ambient - vec3 ambient = light.ambient * texture(material.diffuse, TexCoords).rgb; - // diffuse - vec3 norm = normalize(Normal); vec3 light_dir = normalize(light.position - FragPos); - float diff = max(dot(norm, light_dir), 0.0); - vec3 diffuse = light.diffuse * diff * texture(material.diffuse, TexCoords).rgb; - // specular - vec3 view_dir = normalize(view_position - FragPos); - vec3 reflect_dir = reflect(-light_dir, norm); - float spec = pow(max(dot(view_dir, reflect_dir), 0.0), material.shininess); - vec3 specular = light.specular * spec * texture(material.specular, TexCoords).rgb; - - float distance = length(light.position - FragPos); - float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); - - ambient *= attenuation; - diffuse *= attenuation; - specular *= attenuation; - - vec3 result = ambient + diffuse + specular; - FragColor = vec4(result, 1.0); + + float theta = dot(light_dir, normalize(-light.direction)); + + if (theta > light.cutOff) { + // ambient + vec3 ambient = light.ambient * texture(material.diffuse, TexCoords).rgb; + + // diffuse + vec3 norm = normalize(Normal); + float diff = max(dot(norm, light_dir), 0.0); + vec3 diffuse = light.diffuse * diff * texture(material.diffuse, TexCoords).rgb; + + // specular + vec3 view_dir = normalize(view_position - FragPos); + vec3 reflect_dir = reflect(-light_dir, norm); + float spec = pow(max(dot(view_dir, reflect_dir), 0.0), material.shininess); + vec3 specular = light.specular * spec * texture(material.specular, TexCoords).rgb; + + float distance = length(light.position - FragPos); + float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); + + diffuse *= attenuation; + specular *= attenuation; + + vec3 result = ambient + diffuse + specular; + FragColor = vec4(result, 1.0); + } else { + FragColor = vec4(light.ambient * texture(material.diffuse, TexCoords).rgb, 1.0); + } + + } diff --git a/src/main.odin b/src/main.odin index a55ce7e..997aeb2 100644 --- a/src/main.odin +++ b/src/main.odin @@ -196,7 +196,12 @@ main :: proc() { shader_set_vec3(lighting_shader, cstring("light.diffuse"), &light_diffuse) shader_set_vec3(lighting_shader, cstring("light.specular"), &light_specular) - shader_set_vec3(lighting_shader, cstring("light.position"), &light_pos) + shader_set_vec3(lighting_shader, cstring("light.position"), &camera.position) + shader_set_vec3(lighting_shader, cstring("light.direction"), &camera.front) + + cutoff_angle : f32 = math.cos(linalg.to_radians(f32(12.5))) + shader_set_f32(lighting_shader, "light.cutOff", cutoff_angle) + shader_set_vec3(lighting_shader, cstring("view_position"), &camera.position) shader_set_f32(lighting_shader, "light.constant", 1.0) -- cgit 1.4.1-2-gfad0