PBR Factored
This commit is contained in:
@@ -4,12 +4,20 @@ bool HydraGame::Initialise()
|
||||
{
|
||||
// m_angle = 0.01f;
|
||||
|
||||
// m_sun_light_id = GetEngine()->ActorManager()->CreateActor<HydraPointLightActor>();
|
||||
// GetEngine()->ActorManager()->InitialiseActor(m_sun_light_id);
|
||||
// GetEngine()->ActorManager()->SetOrientation(m_sun_light_id, -0.5f, 0.0f, 0.0f);
|
||||
// GetEngine()->ActorManager()->SetPosition(m_sun_light_id, glm::dvec3(0.0f, 4.0f, 10.0f));
|
||||
|
||||
m_sun_light_id = GetEngine()->ActorManager()->CreateActor<HydraPointLightActor>();
|
||||
GetEngine()->ActorManager()->InitialiseActor(m_sun_light_id);
|
||||
GetEngine()->ActorManager()->SetOrientation(m_sun_light_id, -0.5f, 0.0f, 0.0f);
|
||||
GetEngine()->ActorManager()->SetPosition(m_sun_light_id, glm::dvec3(0.0f, 4.0f, 10.0f));
|
||||
|
||||
|
||||
m_other_light_id = GetEngine()->ActorManager()->CreateActor<HydraPointLightActor>();
|
||||
GetEngine()->ActorManager()->InitialiseActor(m_other_light_id);
|
||||
GetEngine()->ActorManager()->SetOrientation(m_other_light_id, -0.5f, 0.0f, 0.0f);
|
||||
GetEngine()->ActorManager()->SetPosition(m_other_light_id, glm::dvec3(5.0f, 4.0f, 5.0f));
|
||||
// m_other_light_id = GetEngine()->ActorManager()->CreateActor<HydraDirectionalLightActor>();
|
||||
// GetEngine()->ActorManager()->InitialiseActor(m_other_light_id);
|
||||
// GetEngine()->ActorManager()->SetOrientation(m_other_light_id, 0.4f, 0.5f, 0.0f);
|
||||
|
||||
@@ -18,11 +18,17 @@ uint HYDRA_LIGHT_SPOT = 3;
|
||||
|
||||
struct light_structure
|
||||
{
|
||||
vec4 light_colour;
|
||||
float light_intensity;
|
||||
uint chunk_id;
|
||||
vec4 ambient;
|
||||
vec4 diffuse;
|
||||
vec4 specular;
|
||||
float intensity;
|
||||
float constant;
|
||||
float linear;
|
||||
float quadratic;
|
||||
float falloff;
|
||||
float falloff_smooth;
|
||||
uint entity_id;
|
||||
uint light_type;
|
||||
float padding[1];
|
||||
};
|
||||
|
||||
layout(binding = 0) uniform uniform_per_frame
|
||||
@@ -105,32 +111,20 @@ vec3 fresnelSchlick(float cosTheta, vec3 F0)
|
||||
return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0);
|
||||
}
|
||||
|
||||
vec3 DirectionalShading(vec3 normal, vec3 diffuse, float roughness, float metallic, float light_intensity, vec3 lightColour, vec3 lightDir, vec3 lightPos, vec3 worldPos, vec3 viewPos)
|
||||
vec3 CalculatePBR(vec3 normal, vec3 view_pos, vec3 world_pos,vec3 light_dir, vec3 diffuse, vec3 radiance, float roughness, float metallic )
|
||||
{
|
||||
|
||||
vec3 N = normalize(normal);
|
||||
vec3 V = normalize(viewPos - worldPos);
|
||||
vec3 V = normalize(view_pos - world_pos);
|
||||
|
||||
// calculate reflectance at normal incidence; if dia-electric (like plastic) use F0
|
||||
// of 0.04 and if it's a metal, use the albedo color as F0 (metallic workflow)
|
||||
vec3 F0 = vec3(0.04);
|
||||
F0 = mix(F0, diffuse, metallic);
|
||||
|
||||
// reflectance equation
|
||||
vec3 Lo = vec3(0.0);
|
||||
|
||||
// calculate per-light radiance
|
||||
vec3 L = normalize(lightDir);
|
||||
vec3 L = normalize(light_dir);
|
||||
vec3 H = normalize(V + L);
|
||||
float distance = length(lightPos - worldPos);
|
||||
float attenuation = 1.0;
|
||||
|
||||
// if(light_intensity > 0)
|
||||
// {
|
||||
// attenuation = light_intensity / (distance * distance);
|
||||
// }
|
||||
|
||||
vec3 radiance = lightColour * attenuation;
|
||||
|
||||
// Cook-Torrance BRDF
|
||||
float NDF = DistributionGGX(N, H, roughness);
|
||||
@@ -156,61 +150,133 @@ vec3 DirectionalShading(vec3 normal, vec3 diffuse, float roughness, float metall
|
||||
float NdotL = max(dot(N, L), 0.0);
|
||||
|
||||
// add to outgoing radiance Lo
|
||||
Lo += (kD * diffuse / PI + specular) * radiance * NdotL; // note that we already multiplied the BRDF by the Fresnel (kS) so we won't multiply by kS again
|
||||
vec3 Lo = (kD * diffuse / PI + specular) * radiance * NdotL; // note that we already multiplied the BRDF by the Fresnel (kS) so we won't multiply by kS again
|
||||
|
||||
return Lo;
|
||||
}
|
||||
|
||||
vec3 DirectionalShading(vec3 normal,
|
||||
vec3 diffuse,
|
||||
float roughness,
|
||||
float metallic,
|
||||
float light_intensity,
|
||||
vec3 light_dir,
|
||||
vec3 light_pos,
|
||||
vec3 world_pos,
|
||||
vec3 view_pos)
|
||||
{
|
||||
|
||||
// vec3 N = normalize(normal);
|
||||
// vec3 V = normalize(vieview_pos - world_pos);
|
||||
|
||||
// // calculate reflectance at normal incidence; if dia-electric (like plastic) use F0
|
||||
// // of 0.04 and if it's a metal, use the albedo color as F0 (metallic workflow)
|
||||
// vec3 F0 = vec3(0.04);
|
||||
// F0 = mix(F0, diffuse, metallic);
|
||||
|
||||
// // reflectance equation
|
||||
// vec3 Lo = vec3(0.0);
|
||||
|
||||
// // calculate per-light radiance
|
||||
// vec3 L = normalize(lightDir);
|
||||
// vec3 H = normalize(V + L);
|
||||
float distance = length(light_pos - world_pos);
|
||||
float attenuation = 1.0;
|
||||
|
||||
vec3 radiance = diffuse * attenuation;
|
||||
|
||||
vec3 Lo = CalculatePBR(normal, view_pos, world_pos, light_dir, diffuse, radiance, roughness, metallic);
|
||||
// // Cook-Torrance BRDF
|
||||
// float NDF = DistributionGGX(N, H, roughness);
|
||||
// float G = GeometrySmith(N, V, L, roughness);
|
||||
// vec3 F = fresnelSchlick(clamp(dot(H, V), 0.0, 1.0), F0);
|
||||
|
||||
// vec3 numerator = NDF * G * F;
|
||||
// float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0) + 0.0001; // + 0.0001 to prevent divide by zero
|
||||
// vec3 specular = numerator / denominator;
|
||||
|
||||
// // kS is equal to Fresnel
|
||||
// vec3 kS = F;
|
||||
// // for energy conservation, the diffuse and specular light can't
|
||||
// // be above 1.0 (unless the surface emits light); to preserve this
|
||||
// // relationship the diffuse component (kD) should equal 1.0 - kS.
|
||||
// vec3 kD = vec3(1.0) - kS;
|
||||
// // multiply kD by the inverse metalness such that only non-metals
|
||||
// // have diffuse lighting, or a linear blend if partly metal (pure metals
|
||||
// // have no diffuse light).
|
||||
// kD *= 1.0 - metallic;
|
||||
|
||||
// // scale light by NdotL
|
||||
// float NdotL = max(dot(N, L), 0.0);
|
||||
|
||||
// // add to outgoing radiance Lo
|
||||
// Lo += (kD * diffuse / PI + specular) * radiance * NdotL; // note that we already multiplied the BRDF by the Fresnel (kS) so we won't multiply by kS again
|
||||
|
||||
return Lo;
|
||||
}
|
||||
|
||||
|
||||
vec3 PointShading(vec3 normal, vec3 diffuse, float roughness, float metallic, float light_intensity, vec3 lightColour, vec3 lightDir, vec3 lightPos, vec3 worldPos, vec3 viewPos)
|
||||
vec3 PointShading(vec3 normal,
|
||||
vec3 diffuse,
|
||||
float roughness,
|
||||
float metallic,
|
||||
float light_intensity,
|
||||
vec3 light_pos,
|
||||
float light_constant,
|
||||
float light_linear,
|
||||
float light_quadratic,
|
||||
vec3 world_pos,
|
||||
vec3 view_pos)
|
||||
{
|
||||
|
||||
vec3 N = normalize(normal);
|
||||
vec3 V = normalize(viewPos - worldPos);
|
||||
// vec3 N = normalize(normal);
|
||||
// vec3 V = normalize(viewPos - worldPos);
|
||||
|
||||
// calculate reflectance at normal incidence; if dia-electric (like plastic) use F0
|
||||
// of 0.04 and if it's a metal, use the albedo color as F0 (metallic workflow)
|
||||
vec3 F0 = vec3(0.04);
|
||||
F0 = mix(F0, diffuse, metallic);
|
||||
// // calculate reflectance at normal incidence; if dia-electric (like plastic) use F0
|
||||
// // of 0.04 and if it's a metal, use the albedo color as F0 (metallic workflow)
|
||||
// vec3 F0 = vec3(0.04);
|
||||
// F0 = mix(F0, diffuse, metallic);
|
||||
|
||||
// reflectance equation
|
||||
vec3 Lo = vec3(0.0);
|
||||
// // reflectance equation
|
||||
// vec3 Lo = vec3(0.0);
|
||||
|
||||
// calculate per-light radiance
|
||||
vec3 L = normalize(lightPos - worldPos);
|
||||
vec3 H = normalize(V + L);
|
||||
float distance = length(lightPos - worldPos);
|
||||
// // calculate per-light radiance
|
||||
// vec3 L = normalize(lightPos - worldPos);
|
||||
// vec3 H = normalize(V + L);
|
||||
float distance = length(light_pos - world_pos);
|
||||
float attenuation = 1.0;
|
||||
|
||||
attenuation = light_intensity / (distance * distance);
|
||||
//attenuation = light_intensity / (distance * distance);
|
||||
attenuation = light_intensity / (light_constant + (light_linear * distance) + (light_quadratic * distance * distance));
|
||||
vec3 radiance = diffuse * attenuation;
|
||||
vec3 light_dir = normalize(light_pos - world_pos);
|
||||
vec3 Lo = CalculatePBR(normal, view_pos, world_pos, light_dir, diffuse, radiance, roughness, metallic);
|
||||
|
||||
vec3 radiance = lightColour * attenuation;
|
||||
// // Cook-Torrance BRDF
|
||||
// float NDF = DistributionGGX(N, H, roughness);
|
||||
// float G = GeometrySmith(N, V, L, roughness);
|
||||
// vec3 F = fresnelSchlick(clamp(dot(H, V), 0.0, 1.0), F0);
|
||||
|
||||
// Cook-Torrance BRDF
|
||||
float NDF = DistributionGGX(N, H, roughness);
|
||||
float G = GeometrySmith(N, V, L, roughness);
|
||||
vec3 F = fresnelSchlick(clamp(dot(H, V), 0.0, 1.0), F0);
|
||||
// vec3 numerator = NDF * G * F;
|
||||
// float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0) + 0.0001; // + 0.0001 to prevent divide by zero
|
||||
// vec3 specular = (numerator / denominator) * attenuation;
|
||||
|
||||
vec3 numerator = NDF * G * F;
|
||||
float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0) + 0.0001; // + 0.0001 to prevent divide by zero
|
||||
vec3 specular = numerator / denominator;
|
||||
// // kS is equal to Fresnel
|
||||
// vec3 kS = F;
|
||||
// // for energy conservation, the diffuse and specular light can't
|
||||
// // be above 1.0 (unless the surface emits light); to preserve this
|
||||
// // relationship the diffuse component (kD) should equal 1.0 - kS.
|
||||
// vec3 kD = vec3(1.0) - kS;
|
||||
// // multiply kD by the inverse metalness such that only non-metals
|
||||
// // have diffuse lighting, or a linear blend if partly metal (pure metals
|
||||
// // have no diffuse light).
|
||||
// kD *= 1.0 - metallic;
|
||||
|
||||
// kS is equal to Fresnel
|
||||
vec3 kS = F;
|
||||
// for energy conservation, the diffuse and specular light can't
|
||||
// be above 1.0 (unless the surface emits light); to preserve this
|
||||
// relationship the diffuse component (kD) should equal 1.0 - kS.
|
||||
vec3 kD = vec3(1.0) - kS;
|
||||
// multiply kD by the inverse metalness such that only non-metals
|
||||
// have diffuse lighting, or a linear blend if partly metal (pure metals
|
||||
// have no diffuse light).
|
||||
kD *= 1.0 - metallic;
|
||||
// // scale light by NdotL
|
||||
// float NdotL = max(dot(N, L), 0.0);
|
||||
|
||||
// scale light by NdotL
|
||||
float NdotL = max(dot(N, L), 0.0);
|
||||
|
||||
// add to outgoing radiance Lo
|
||||
Lo += (kD * diffuse / PI + specular) * radiance * NdotL; // note that we already multiplied the BRDF by the Fresnel (kS) so we won't multiply by kS again
|
||||
// // add to outgoing radiance Lo
|
||||
// Lo += (kD * diffuse / PI + specular) * radiance * NdotL; // note that we already multiplied the BRDF by the Fresnel (kS) so we won't multiply by kS again
|
||||
|
||||
return Lo;
|
||||
}
|
||||
@@ -245,21 +311,31 @@ void main()
|
||||
vec3 Lo = vec3(0,0,0);
|
||||
for(int i = 0; i < ubo_per_frame.light_count; i ++)
|
||||
{
|
||||
mat4 model = model_matrix[lights[i].chunk_id];
|
||||
mat4 model = model_matrix[lights[i].entity_id];
|
||||
mat3 rot_mat = GetRotationOnlyMatrix(model);
|
||||
vec3 light_direction = rot_mat * vec3(0,0,1);
|
||||
|
||||
vec3 light_pos = model[3].xyz;
|
||||
if(lights[i].light_type == HYDRA_LIGHT_DIRECTIONAL)
|
||||
{
|
||||
Lo+= DirectionalShading(normal, diffuse.xyz, rough, metal, lights[i].light_intensity, lights[i].light_colour.xyz, light_direction, light_pos, world_pos, ubo_per_frame.viewer_pos);
|
||||
Lo+= DirectionalShading(normal, diffuse.xyz, rough, metal, lights[i].intensity, light_direction, light_pos, world_pos, ubo_per_frame.viewer_pos);
|
||||
}
|
||||
else if(lights[i].light_type == HYDRA_LIGHT_POINT)
|
||||
{
|
||||
Lo+= PointShading(normal, diffuse.xyz, rough, metal, lights[i].light_intensity, lights[i].light_colour.xyz, light_direction, light_pos, world_pos, ubo_per_frame.viewer_pos);
|
||||
|
||||
Lo+= PointShading(normal,
|
||||
diffuse.xyz,
|
||||
rough,
|
||||
metal,
|
||||
lights[i].intensity,
|
||||
light_pos,
|
||||
lights[i].constant,
|
||||
lights[i].linear,
|
||||
lights[i].quadratic,
|
||||
world_pos,
|
||||
ubo_per_frame.viewer_pos);
|
||||
}
|
||||
|
||||
//uFragColor = vec4(light_direction, 1);
|
||||
}
|
||||
|
||||
float lighting = 0;
|
||||
@@ -271,7 +347,7 @@ void main()
|
||||
float ao = 1;
|
||||
vec3 ambient = vec3(0.05) * diffuse.xyz * ao;
|
||||
|
||||
vec3 output_color = ambient + Lo;
|
||||
vec3 output_color = Lo;
|
||||
|
||||
// HDR tonemapping
|
||||
output_color = output_color / (output_color + vec3(1.0));
|
||||
|
||||
@@ -28,8 +28,8 @@ void HydraDirectionalLightActor::InitialiseComponents()
|
||||
|
||||
//light_comp.light_id = GetEngine()->LightBufferManager()->CreateLight(light);
|
||||
|
||||
light_comp.light_colour = glm::vec4(1,1,1,1);
|
||||
light_comp.light_intensity = 100.0f;
|
||||
light_comp.diffuse = glm::vec4(1,1,1,1);
|
||||
light_comp.intensity = 1.0f;
|
||||
light_comp.light_type = static_cast<uint32_t>(HYDRA_LIGHT_TYPE::HYDRA_LIGHT_DIRECTIONAL);
|
||||
light_comp.entity_id = GetID();
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ void HydraPointLightActor::InitialiseComponents()
|
||||
HydraLightComponent light_comp = {};
|
||||
HydraECS *ecs = GetEngine()->ECS();
|
||||
|
||||
light_comp.light_colour = glm::vec4(1,1,1,1);
|
||||
light_comp.light_intensity = 10.0f;
|
||||
light_comp.diffuse = glm::vec4(1,1,1,1);
|
||||
light_comp.intensity = 100.0f;
|
||||
light_comp.light_type = static_cast<uint32_t>(HYDRA_LIGHT_TYPE::HYDRA_LIGHT_POINT);
|
||||
light_comp.entity_id = GetID();
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
#include "HydraSpotLightActor.h"
|
||||
#include "../engine/HydraEngine.h"
|
||||
#include "../actor/HydraActorManager.h"
|
||||
#include "../task/HydraTask.h"
|
||||
#include "../ecs/HydraECS.h"
|
||||
#include "../ecs/components/HydraPositionComponent.h"
|
||||
#include "../ecs/components/HydraMeshComponent.h"
|
||||
#include "../ecs/components/HydraRenderableComponent.h"
|
||||
#include "../ecs/components/HydraMaterialComponent.h"
|
||||
#include "../ecs/components/HydraLightComponent.h"
|
||||
|
||||
#include "../buffer/HydraLightBufferManager.h"
|
||||
#include "../buffer/HydraLightBuffer.h"
|
||||
|
||||
|
||||
|
||||
|
||||
void HydraSpotLightActor::InitialiseComponents()
|
||||
{
|
||||
HydraLightComponent light_comp = {};
|
||||
HydraECS *ecs = GetEngine()->ECS();
|
||||
|
||||
light_comp.diffuse = glm::vec4(1,1,1,1);
|
||||
light_comp.intensity = 100.0f;
|
||||
light_comp.light_type = static_cast<uint32_t>(HYDRA_LIGHT_TYPE::HYDRA_LIGHT_SPOT);
|
||||
|
||||
light_comp.entity_id = GetID();
|
||||
|
||||
ecs->AddComponent<HydraLightComponent>(GetID(), light_comp);
|
||||
|
||||
HydraPositionComponent position_component;
|
||||
ecs->AddComponent<HydraPositionComponent>(GetID(), position_component);
|
||||
}
|
||||
|
||||
void HydraSpotLightActor::Destroy()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef HYDRASPOTLIGHTACTOR
|
||||
#define HYDRASPOTLIGHTACTOR
|
||||
|
||||
#include "HydraActor.h"
|
||||
|
||||
class CLASS_DEFINE HydraSpotLightActor : public HydraActor
|
||||
{
|
||||
private:
|
||||
|
||||
protected:
|
||||
|
||||
public:
|
||||
virtual void InitialiseComponents() override;
|
||||
virtual void Destroy() override;
|
||||
|
||||
};
|
||||
|
||||
#endif /* HYDRASPOTLIGHTACTOR */
|
||||
@@ -4,11 +4,17 @@
|
||||
|
||||
struct HydraLightComponent
|
||||
{
|
||||
glm::vec4 light_colour;
|
||||
float light_intensity;
|
||||
glm::vec4 ambient = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
glm::vec4 diffuse = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
glm::vec4 specular = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
float intensity = 1.0f;
|
||||
float constant = 1.0f;
|
||||
float linear = 0.7;
|
||||
float quadratic = 1.8;
|
||||
float falloff = 1.5;
|
||||
float falloff_smooth = 0.0f;
|
||||
HydraID entity_id;
|
||||
uint32_t light_type;
|
||||
float padding[1];
|
||||
};
|
||||
|
||||
#endif /* HYDRAECSLIGHTCOMPONENT */
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user