From 4cd1a9f59c8b784af7714595b55c1d132f7335dd Mon Sep 17 00:00:00 2001 From: Hurlu Date: Wed, 20 Mar 2019 16:17:16 +0900 Subject: [PATCH] Started work on spotlighting --- BaseGLProject/BaseGLProject.vcxproj | 5 +- BaseGLProject/BaseGLProject.vcxproj.filters | 15 +++- BaseGLProject/Light.cpp | 9 +++ BaseGLProject/Light.h | 12 ++++ BaseGLProject/MyGLWindow.cpp | 6 ++ BaseGLProject/Shader.cpp | 16 +++-- BaseGLProject/Shader.h | 1 + BaseGLProject/onelight.frag | 62 ----------------- BaseGLProject/spotlight.frag | 76 +++++++++++++++++++++ BaseGLProject/spotlight.vert | 21 ++++++ BaseGLProject/tex_base_light.frag | 26 ++++--- BaseGLProject/tex_spotlight.frag | 60 ++++++++++++++++ BaseGLProject/tex_spotlight.vert | 24 +++++++ 13 files changed, 252 insertions(+), 81 deletions(-) delete mode 100644 BaseGLProject/onelight.frag create mode 100644 BaseGLProject/spotlight.frag create mode 100644 BaseGLProject/spotlight.vert create mode 100644 BaseGLProject/tex_spotlight.frag create mode 100644 BaseGLProject/tex_spotlight.vert diff --git a/BaseGLProject/BaseGLProject.vcxproj b/BaseGLProject/BaseGLProject.vcxproj index 97f3ed1..83c9bcd 100644 --- a/BaseGLProject/BaseGLProject.vcxproj +++ b/BaseGLProject/BaseGLProject.vcxproj @@ -186,6 +186,8 @@ + + Geometry @@ -198,10 +200,11 @@ 4.0 Document - + + diff --git a/BaseGLProject/BaseGLProject.vcxproj.filters b/BaseGLProject/BaseGLProject.vcxproj.filters index 422e905..bc636a1 100644 --- a/BaseGLProject/BaseGLProject.vcxproj.filters +++ b/BaseGLProject/BaseGLProject.vcxproj.filters @@ -130,9 +130,6 @@ Shaders - - Shaders - Shaders @@ -160,6 +157,18 @@ Shaders + + Shaders + + + Shaders + + + Shaders + + + Shaders + diff --git a/BaseGLProject/Light.cpp b/BaseGLProject/Light.cpp index ed2a510..36fa349 100644 --- a/BaseGLProject/Light.cpp +++ b/BaseGLProject/Light.cpp @@ -2,6 +2,15 @@ Light::Light(glm::vec3 intensity_, glm::vec4 location_) : location(location_), intensity(intensity_) { + type = BASE; +} + +Light::Light(glm::vec3 intensity_, glm::vec4 location_, float spot_cutoff_, float spot_inner_cutoff_, float spot_exponent_, glm::vec3 direction_): + location(location_), intensity(intensity_), spot_cutoff(spot_cutoff_), spot_inner_cutoff(spot_inner_cutoff_) + ,spot_exponent(spot_exponent_), direction(direction_) + +{ + type = SPOT; } diff --git a/BaseGLProject/Light.h b/BaseGLProject/Light.h index a201ac7..c0dbdd8 100644 --- a/BaseGLProject/Light.h +++ b/BaseGLProject/Light.h @@ -6,11 +6,23 @@ class Light { public: + enum LightType + { + BASE, + SPOT + }; + Light(glm::vec3 intensity, glm::vec4 location); + Light(glm::vec3 intensity, glm::vec4 location, float spot_cutoff, float spot_inner_cutoff, float spot_exponent, glm::vec3 direction); ~Light(); bool activated = true; + LightType type; glm::vec3 intensity; glm::vec4 location; + float spot_cutoff; + float spot_inner_cutoff; + float spot_exponent; + glm::vec3 direction; }; diff --git a/BaseGLProject/MyGLWindow.cpp b/BaseGLProject/MyGLWindow.cpp index f12578c..46b89f1 100644 --- a/BaseGLProject/MyGLWindow.cpp +++ b/BaseGLProject/MyGLWindow.cpp @@ -88,6 +88,12 @@ void MyGlWindow::shaderSetup() shaders["TexBaseLight"] = new Shader("tex_base_light.vert", "tex_base_light.frag"); shaders["TexBaseLight"]->addUniform("tex1", 0); + shaders["SpotLight"] = new Shader("spotlight.vert", "spotlight.frag"); + shaders["SpotLight"]->light_type = Light::LightType::SPOT; + shaders["TexSpotLight"] = new Shader("tex_spotlight.vert", "tex_spotlight.frag"); + shaders["TexSpotLight"]->light_type = Light::LightType::SPOT; + + shaders["Silhouette"] = new Shader("silhouette.vert", "silhouette.frag"); shaders["Silhouette"]->uniformFlags = ShaderFlags::MVP_FLAG; shaders["Silhouette"]->addUniform("fColor", glm::vec3(237 / 255, 229 / 255, 194 / 255)); diff --git a/BaseGLProject/Shader.cpp b/BaseGLProject/Shader.cpp index 2c1e688..6f933a9 100644 --- a/BaseGLProject/Shader.cpp +++ b/BaseGLProject/Shader.cpp @@ -48,13 +48,19 @@ void Shader::setLights(SceneContext ctx) return; for (auto light: ctx.lights) { - if (light.second.activated) + if (light.second.activated && light.second.type == light_type) { std::string lightname = "Light[" + std::to_string(i) + "]."; - _program.addUniform(lightname + "Position"); - glUniform4fv(_program.uniform(lightname + "Position"), 1, glm::value_ptr(ctx.viewMatrix * light.second.location)); - _program.addUniform(lightname + "Intensity"); - glUniform3fv(_program.uniform(lightname + "Intensity"), 1, glm::value_ptr(light.second.intensity)); + + glUniform4fv(_program.addUniform(lightname + "Position"), 1, glm::value_ptr(ctx.viewMatrix * light.second.location)); + glUniform3fv(_program.addUniform(lightname + "Intensity"), 1, glm::value_ptr(light.second.intensity)); + if (light.second.type == Light::LightType::SPOT) + { + glUniform1f(_program.addUniform(lightname + "SpotCutoff"), light.second.spot_cutoff); + glUniform1f(_program.addUniform(lightname + "SpotInnerCutoff"), light.second.spot_inner_cutoff); + glUniform1f(_program.addUniform(lightname + "SpotExponent"), light.second.spot_exponent); + glUniform3fv(_program.addUniform(lightname + "SpotDirection"), 1, glm::value_ptr(light.second.direction)); + } i++; } } diff --git a/BaseGLProject/Shader.h b/BaseGLProject/Shader.h index ca072d7..c24791b 100644 --- a/BaseGLProject/Shader.h +++ b/BaseGLProject/Shader.h @@ -33,6 +33,7 @@ public: int uniformFlags = KD_FLAG | KA_FLAG | KS_FLAG | SHINE_FLAG | MVP_FLAG | NORMAL_MAT_FLAG | MODELVIEW_FLAG | LIGHTS_FLAG; Material mat; + Light::LightType light_type = Light::LightType::BASE; void enable(); void disable(); diff --git a/BaseGLProject/onelight.frag b/BaseGLProject/onelight.frag deleted file mode 100644 index ba803a6..0000000 --- a/BaseGLProject/onelight.frag +++ /dev/null @@ -1,62 +0,0 @@ -#version 440 - -in vec3 f_color; -out vec4 FragColors; - -uniform vec3 Kd; -uniform vec3 Ka; -uniform vec3 Ks; -uniform float Shininess; - -uniform vec4 LightLocation; -uniform vec3 LightIntensity; - -uniform vec4 LightDirection; -uniform float Exponent; -uniform float Cutoff; -uniform float InnerCutoff; - -in vec3 fNormal; -in vec3 pos; - -const float a = 1.0f; -const float b = 0.01f; -const float c = 0.001f; - -void main() -{ - - vec3 LightDir = LightDirection.xyz - LightLocation.xyz; - - vec3 L = LightLocation.xyz - pos; - float d = length(L); - L = normalize(L); - - float attenuation = 1.0f / (a + b * d + c * pow(d, 2)); - float angle = acos(dot(-L, normalize(LightDir))); // radian - float spotAttenuation = 1.0f; - if (angle < radians(InnerCutoff)) - spotAttenuation = 1.0f; - else - { - // pos is outside the spot's inner cutoff - float SpotDot = dot(-L, normalize(LightDir)); - float spotValue = smoothstep(cos(radians(Cutoff)), cos(radians(InnerCutoff)), SpotDot); - spotAttenuation = pow(spotValue, Exponent); - } - attenuation *= spotAttenuation; - - vec3 N = normalize(fNormal); - vec3 V = normalize(-pos); - vec3 H = normalize(V + L); - - float dotNL = max(dot(L, N), 0.0); // for diffuse - float dotHN = max(dot(H, N), 0.0); // for spec - float pf = pow(dotHN, Shininess); // for spec - - vec3 ambient = Ka * LightIntensity * attenuation; - vec3 diffuse = Kd * LightIntensity * dotNL * attenuation; - vec3 specular = Ks * LightIntensity * pf * attenuation; - - FragColors = vec4(diffuse + specular + ambient, 1); -} diff --git a/BaseGLProject/spotlight.frag b/BaseGLProject/spotlight.frag new file mode 100644 index 0000000..c12e2a5 --- /dev/null +++ b/BaseGLProject/spotlight.frag @@ -0,0 +1,76 @@ +#version 440 + +in vec3 f_color; +out vec4 FragColors; + +uniform vec3 Kd; +uniform vec3 Ka; +uniform vec3 Ks; +uniform float Shininess; + +struct LightInfo { + vec4 Position; + vec3 Intensity; + float SpotCutoff; + float SpotInnerCutoff; + float SpotExponent; + vec3 SpotDirection; +}; + +uniform LightInfo Light[64]; +uniform int LightCount; + +in vec3 fNormal; +in vec3 pos; + +void main() +{ + + vec3 ambient_sum; + vec3 diffuse_sum; + vec3 specular_sum; + vec3 ambient; + float D; + float attenuation; + + + for (int i=0; i