Started work on spotlighting

This commit is contained in:
Hurlu 2019-03-20 16:17:16 +09:00
parent 2fbd67f9c6
commit 4cd1a9f59c
13 changed files with 252 additions and 81 deletions

View File

@ -186,6 +186,8 @@
<None Include="fog.frag" />
<None Include="fog.vert" />
<None Include="base_light.vert" />
<None Include="spotlight.frag" />
<None Include="spotlight.vert" />
<None Include="tex_base_light.frag" />
<None Include="tex_base_light.vert">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Geometry</ShaderType>
@ -198,10 +200,11 @@
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">4.0</ShaderModel>
<FileType>Document</FileType>
</None>
<None Include="onelight.frag" />
<None Include="silhouette.frag" />
<None Include="silhouette.vert" />
<None Include="simple.vert" />
<None Include="tex_spotlight.frag" />
<None Include="tex_spotlight.vert" />
<None Include="toon.frag" />
</ItemGroup>
<ItemGroup>

View File

@ -130,9 +130,6 @@
<None Include="simple.vert">
<Filter>Shaders</Filter>
</None>
<None Include="onelight.frag">
<Filter>Shaders</Filter>
</None>
<None Include="toon.frag">
<Filter>Shaders</Filter>
</None>
@ -160,6 +157,18 @@
<None Include="base_light.vert">
<Filter>Shaders</Filter>
</None>
<None Include="spotlight.vert">
<Filter>Shaders</Filter>
</None>
<None Include="spotlight.frag">
<Filter>Shaders</Filter>
</None>
<None Include="tex_spotlight.vert">
<Filter>Shaders</Filter>
</None>
<None Include="tex_spotlight.frag">
<Filter>Shaders</Filter>
</None>
</ItemGroup>
<ItemGroup>
<Image Include="brick1.jpg">

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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));

View File

@ -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++;
}
}

View File

@ -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();

View File

@ -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);
}

View File

@ -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<LightCount; i++)
{
D = distance(Light[i].Position.xyz, pos);
attenuation = 1 / (1 + 0.01 * D + 0.001 * D * D);
vec3 L = normalize(Light[i].Position.xyz - pos);
vec3 N = fNormal;
vec3 V = normalize(-pos);
//vec3 R = normalize(reflect(-L, N));
vec3 H = normalize(V + L);
float SpotAttenuation = 1.0;
vec spotDot = dot(Light[i].SpotCutoff, Light[i].SpotInnerCutoff);
float theta = dot(L, normalize(Light[i].SpotDirection)); //Angle between the light direction and the fragment-light vector.
float phi = ; // Angle between the light direction and the inner cutoff.
if (theta < Light[i].SpotInnerCutoff)
{
SpotAttenuation = 1.0; //No change in the attenuation
}
else
{
//Fragment is outside the Cone
//Interpolate between cos(Innercutoff )and cos(cutoff) with cos(theta)
float Spot = smoothstep(cos(Light[i].SpotCutoff),cos(Light[i].SpotInnerCutoff),cos(theta));
SpotAttenuation = pow(Spot, Light[i].SpotExponent);
}
attenuation *= SpotAttenuation;
vec3 diffuse = Kd * Light[i].Intensity * max(dot(L, N), 0.0) * attenuation;
vec3 specular = Ks * Light[i].Intensity * pow(max(dot(H, N), 0.0), Shininess) * attenuation;
ambient_sum += ambient;
diffuse_sum += diffuse;
specular_sum += specular;
}
FragColors = vec4(diffuse_sum + specular_sum + ambient_sum / LightCount, 1);
}

View File

@ -0,0 +1,21 @@
#version 440
layout(location=0) in vec3 coord3d;
layout(location=1) in vec3 v_normal;
layout(location=2) in vec3 v_color;
layout(location=3) in vec2 v_texmap;
uniform mat4 mvp;
uniform mat3 NormalMatrix;
uniform mat4 ModelViewMatrix;
out vec3 fNormal;
out vec3 pos;
void main(void)
{
fNormal = normalize(NormalMatrix * v_normal);
pos = (ModelViewMatrix * vec4(coord3d, 1.0)).xyz;
gl_Position = mvp * vec4(coord3d, 1.0f);
}

View File

@ -30,20 +30,26 @@ void main()
vec3 diffuse_sum;
vec3 specular_sum;
vec3 ambient;
float D;
float attenuation;
ambient = Ka * Light[0].Intensity;
D = distance(Light[0].Position.xyz, pos);
attenuation = 1 / (1 + 0.01 * D + 0.001 * D * D);
ambient = Ka * Light[0].Intensity * attenuation;
for (int i=0; i<LightCount; i++)
{
vec3 L = normalize(Light[i].Position.xyz - pos);
vec3 N = fNormal;
vec3 V = normalize(-pos);
//vec3 R = normalize(reflect(-L, N));
vec3 H = normalize(V + L);
D = distance(Light[i].Position.xyz, pos);
attenuation = 1 / (1 + 0.01 * D + 0.001 * D * D);
vec3 L = normalize(Light[i].Position.xyz - pos);
vec3 N = fNormal;
vec3 V = normalize(-pos);
//vec3 R = normalize(reflect(-L, N));
vec3 H = normalize(V + L);
vec3 diffuse = Kd * Light[i].Intensity * max(dot(L, N), 0.0);
vec3 specular = Ks * Light[i].Intensity * pow(max(dot(H, N), 0.0), Shininess);
diffuse_sum += diffuse;
specular_sum += specular;
vec3 diffuse = Kd * Light[i].Intensity * max(dot(L, N), 0.0) * attenuation;
vec3 specular = Ks * Light[i].Intensity * pow(max(dot(H, N), 0.0), Shininess) * attenuation;
diffuse_sum += diffuse;
specular_sum += specular;
}
vec4 texColor = texture(tex1, texCoord);

View File

@ -0,0 +1,60 @@
#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;
in vec2 texCoord;
uniform sampler2D tex1;
void main()
{
vec3 finalColor;
vec3 diffuse_sum;
vec3 specular_sum;
vec3 ambient;
float D;
float attenuation;
D = distance(Light[0].Position.xyz, pos);
attenuation = 1 / (1 + 0.01 * D + 0.001 * D * D);
ambient = Ka * Light[0].Intensity * attenuation;
for (int i=0; i<LightCount; i++)
{
D = distance(Light[i].Position.xyz, pos);
attenuation = 1 / (1 + 0.01 * D + 0.001 * D * D);
vec3 L = normalize(Light[i].Position.xyz - pos);
vec3 N = fNormal;
vec3 V = normalize(-pos);
//vec3 R = normalize(reflect(-L, N));
vec3 H = normalize(V + L);
vec3 diffuse = Kd * Light[i].Intensity * max(dot(L, N), 0.0) * attenuation;
vec3 specular = Ks * Light[i].Intensity * pow(max(dot(H, N), 0.0), Shininess) * attenuation;
diffuse_sum += diffuse;
specular_sum += specular;
}
FragColors = vec4(diffuse_sum + specular_sum + ambient, 1);
}

View File

@ -0,0 +1,24 @@
#version 440
layout(location=0) in vec3 coord3d;
layout(location=1) in vec3 v_normal;
layout(location=2) in vec3 v_color;
layout(location=3) in vec2 v_texmap;
uniform mat4 mvp;
uniform mat3 NormalMatrix;
uniform mat4 ModelViewMatrix;
out vec3 fNormal;
out vec3 pos;
out vec2 texCoord;
void main(void)
{
fNormal = normalize(NormalMatrix * v_normal);
pos = (ModelViewMatrix * vec4(coord3d, 1.0)).xyz;
texCoord = v_texmap;
gl_Position = mvp * vec4(coord3d, 1.0f);
}