Skip to content

Commit

Permalink
Improved light casters and added separate sandbox
Browse files Browse the repository at this point in the history
  • Loading branch information
denyskryvytskyi committed Mar 3, 2024
1 parent 966a813 commit 9f96261
Show file tree
Hide file tree
Showing 16 changed files with 963 additions and 410 deletions.
2 changes: 2 additions & 0 deletions Engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ set(ENGINE_HEADERS
"src/Renderer/VertexArray.h"
"src/Renderer/Texture2D.h"
"src/Renderer/TextRenderer.h"
"src/Renderer/Material.h"
"src/Renderer/Light.h"
"src/Platform/Windows/WindowsWindow.h"
"src/Platform/OpenGL/OpenGLBuffer.h"
"src/Platform/OpenGL/OpenGLContext.h"
Expand Down
3 changes: 3 additions & 0 deletions Engine/src/Elven.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
#include "Renderer/Shader.h"
#include "Renderer/VertexArray.h"

#include "Renderer/Light.h"
#include "Renderer/Material.h"

#include "Resources/TextureManager.h"

/// Scene ////////////////////////////////////
Expand Down
5 changes: 5 additions & 0 deletions Engine/src/ImGui/EditorHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,9 @@ void DrawRGBColorControl(const std::string& label, lia::vec3& colorProperty)
ImGui::ColorEdit3(label.c_str(), colorProperty.elementsPtr());
}

void DrawRGBAColorControl(const std::string& label, lia::vec4& colorProperty)
{
ImGui::ColorEdit4(label.c_str(), colorProperty.elementsPtr());
}

} // namespace elv::editor
1 change: 1 addition & 0 deletions Engine/src/ImGui/EditorHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ void DrawVec3Control(const std::string& id, const std::string& label, lia::vec3&
void DrawSliderFloat(const std::string& label, const float min, const float max, float& property);

void DrawRGBColorControl(const std::string& label, lia::vec3& colorProperty);
void DrawRGBAColorControl(const std::string& label, lia::vec4& colorProperty);
} // namespace elv::editor
40 changes: 40 additions & 0 deletions Engine/src/Renderer/Light.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#pragma once
namespace elv {
struct PointLight {
lia::vec3 position { 0.0f, 0.8f, 1.2f };

lia::vec3 ambient { 0.2f, 0.2f, 0.2f };
lia::vec3 diffuse { 0.4f, 0.4f, 0.4f };
lia::vec3 specular { 1.0f, 1.0f, 1.0f };

// distance 50
float constant { 1.0f };
float linear { 0.09f };
float quadratic { 0.032f };
};

struct DirectionalLight {
lia::vec3 direction { -0.2f, -1.0f, -0.3f };

lia::vec3 ambient { 0.2f, 0.2f, 0.2f };
lia::vec3 diffuse { 0.4f, 0.4f, 0.4f };
lia::vec3 specular { 1.0f, 1.0f, 1.0f };
};

struct SpotLight {
lia::vec3 position;
lia::vec3 direction;

lia::vec3 ambient { 0.2f, 0.2f, 0.2f };
lia::vec3 diffuse { 0.4f, 0.4f, 0.4f };
lia::vec3 specular { 1.0f, 1.0f, 1.0f };

float cutOff { 12.5f };
float outerCutOff { 17.5f };
// distance 50
float constant { 1.0f };
float linear { 0.09f };
float quadratic { 0.032f };
};

} // namespace elv
10 changes: 10 additions & 0 deletions Engine/src/Renderer/Material.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

namespace elv {
struct Material {
lia::vec3 ambient { 1.0f, 0.5f, 0.31f };
lia::vec3 diffuse { 1.0f, 0.5f, 0.31f };
lia::vec3 specular { 0.5f, 0.5f, 0.5f };
float shininess { 32.0f };
};
} // namespace elv
6 changes: 4 additions & 2 deletions Sandbox3D/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ set(SANDBOX_SOURCES
"src/SandboxApp.cpp"
"src/CubesSandbox.h"
"src/CubesSandbox.cpp"
"src/LightingSandbox.h"
"src/LightingSandbox.cpp"
"src/SimpleLightSandbox.h"
"src/SimpleLightSandbox.cpp"
"src/LightCastersSandbox.h"
"src/LightCastersSandbox.cpp"
"assets/shaders/default.frag"
"assets/shaders/default.vert"
"assets/shaders/colors.frag"
Expand Down
10 changes: 9 additions & 1 deletion Sandbox3D/assets/shaders/light_cube.frag
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
// Fragment shader for the light objects (LightingSandbox)
#version 450 core

struct LightColor {
vec3 ambient;
vec3 diffuse;
};
uniform LightColor u_Color;

out vec4 FragColor;

void main()
{
FragColor = vec4(1.0); // set all 4 vector values to 1.0
vec3 result = u_Color.ambient + u_Color.diffuse;
FragColor = vec4(result, 1.0);
}
204 changes: 204 additions & 0 deletions Sandbox3D/assets/shaders/textured_cube_with_light_casters.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
// Fragment shader for the cube with texture (LightingSandbox)
// with support of directional, point, and spotlight
#version 450 core

struct Material {
sampler2D diffuse;
sampler2D specular;
sampler2D emission;
float shininess;
bool enableEmission;
};

struct DirLight {
vec3 direction;

vec3 ambient;
vec3 diffuse;
vec3 specular;
};

struct PointLight {
vec3 position;

vec3 ambient;
vec3 diffuse;
vec3 specular;

float constant;
float linear;
float quadratic;
};

struct SpotLight {
vec3 position;
vec3 direction;

vec3 ambient;
vec3 diffuse;
vec3 specular;

float constant;
float linear;
float quadratic;
float cutOff; // cos of the angle
float outerCutOff;
};

#define NR_POINT_LIGHTS 4

uniform vec3 u_ViewPos;
uniform Material u_Material;
uniform bool u_DirLightEnabled;
uniform bool u_PointLightEnabled;
uniform bool u_SpotLightEnabled;
uniform DirLight u_DirLight;
uniform PointLight u_PointLights[NR_POINT_LIGHTS];
uniform SpotLight u_SpotLight;

in vec3 v_FragPos;
in vec3 v_Normal;
in vec2 v_UV;

out vec4 FragColor;

vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir);
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 viewDir);
vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 viewDir);

void main()
{
// output color
vec3 result = vec3(0.0);

vec3 normal = normalize(v_Normal);
vec3 viewDir = normalize(u_ViewPos - v_FragPos);

// lights calculation
if (u_DirLightEnabled)
{
result += CalcDirLight(u_DirLight, normal, viewDir);
}

if (u_PointLightEnabled)
{
for (int i = 0; i < NR_POINT_LIGHTS; ++i)
result += CalcPointLight(u_PointLights[i], normal, viewDir);
}

if (u_SpotLightEnabled)
{
result += CalcSpotLight(u_SpotLight, normal, viewDir);
}

FragColor = vec4(result, 1.0);
}

vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir)
{
vec3 lightDir = normalize(-light.direction);
vec3 reflectDir = reflect(-lightDir, normal);

// ambient
vec3 diffuseMap = texture(u_Material.diffuse, v_UV).rgb;
vec3 ambient = light.ambient * diffuseMap;

// diffuse
float diff = max(dot(normal, lightDir), 0.0f);
vec3 diffuse = light.diffuse * diff * texture(u_Material.diffuse, v_UV).rgb;

// specular
float spec = pow(max(dot(viewDir, reflectDir), 0.0), u_Material.shininess);
vec3 specularMap = texture(u_Material.specular, v_UV).rgb;
vec3 specular = light.specular * spec * specularMap;

// emission
vec3 emission = vec3(0.0f);

if (u_Material.enableEmission && specularMap == vec3(0.0f))
{
emission = texture(u_Material.emission, v_UV).rgb;
}

return (ambient + diffuse + specular + emission);
}

vec3 CalcPointLight(PointLight light, vec3 normal, vec3 viewDir)
{
vec3 lightDir = normalize(light.position - v_FragPos);
vec3 reflectDir = reflect(-lightDir, normal);

// ambient
vec3 diffuseMap = texture(u_Material.diffuse, v_UV).rgb;
vec3 ambient = light.ambient * diffuseMap;

// diffuse
float diff = max(dot(normal, lightDir), 0.0f);
vec3 diffuse = light.diffuse * diff * texture(u_Material.diffuse, v_UV).rgb;

// specular
float spec = pow(max(dot(viewDir, reflectDir), 0.0), u_Material.shininess);
vec3 specularMap = texture(u_Material.specular, v_UV).rgb;
vec3 specular = light.specular * spec * specularMap;

// emission
vec3 emission = vec3(0.0f);

if (u_Material.enableEmission && specularMap == vec3(0.0f))
{
emission = texture(u_Material.emission, v_UV).rgb;
}

// attenuation
float distance = length(light.position - v_FragPos);
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));

ambient *= attenuation;
diffuse *= attenuation;
specular *= attenuation;

return (ambient + diffuse + specular + emission);
}

vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 viewDir)
{
vec3 lightDir = normalize(light.position - v_FragPos);
vec3 reflectDir = reflect(-lightDir, normal);

// ambient
vec3 diffuseMap = texture(u_Material.diffuse, v_UV).rgb;
vec3 ambient = light.ambient * diffuseMap;

// diffuse
float diff = max(dot(normal, lightDir), 0.0f);
vec3 diffuse = light.diffuse * diff * texture(u_Material.diffuse, v_UV).rgb;

// specular
float spec = pow(max(dot(viewDir, reflectDir), 0.0), u_Material.shininess);
vec3 specularMap = texture(u_Material.specular, v_UV).rgb;
vec3 specular = light.specular * spec * specularMap;

// emission
vec3 emission = vec3(0.0f);

if (u_Material.enableEmission && specularMap == vec3(0.0f))
{
emission = texture(u_Material.emission, v_UV).rgb;
}

// spotlight with soft edges
float theta = dot(lightDir, normalize(-light.direction));
float epsilon = light.cutOff - light.outerCutOff;
float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0);
diffuse *= intensity;
specular *= intensity;

// attenuation
float distance = length(light.position - v_FragPos);
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
ambient *= attenuation;
diffuse *= attenuation;
specular *= attenuation;

return (ambient + diffuse + specular + emission);
}
Loading

0 comments on commit 9f96261

Please sign in to comment.