Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
226 changes: 117 additions & 109 deletions Resources/Shaders/deferred_lighting.frag
Original file line number Diff line number Diff line change
@@ -1,136 +1,144 @@
#version 460
#extension GL_GOOGLE_include_directive : require
#include "bindings.glsl"
#include "light_types.glsl"

layout(location = 0) in vec2 TexCoord;
layout(location = 1) in vec4 ViewPos;

layout(std140, set = 0, binding = 6) readonly buffer DirectionalLightSB
layout(set = 0, binding = 0) uniform UBCamera
{
uint Count;
DirectionalLight Data[];
mat4 View;
mat4 Projection;
vec4 Position;
mat4 InvViewProj;
}
DirectionalLightBuffer;
Camera;

layout(std140, set = 0, binding = 7) readonly buffer PointLightSB
{
uint Count;
PointLight Data[];
}
PointLightBuffer;
layout(set = 2, binding = 0) uniform texture2D GBufferAlbedoAO;
layout(set = 2, binding = 1) uniform texture2D GBufferNormalRoughness;
layout(set = 2, binding = 2) uniform texture2D GBufferMetallicEmissive;
layout(set = 2, binding = 3) uniform texture2D GBufferDepth;
layout(set = 2, binding = 5) uniform sampler GBufferSampler;

layout(std140, set = 0, binding = 8) readonly buffer SpotLightSB
struct GpuDirectionalLight
{
uint Count;
SpotLight Data[];
vec4 Direction;
vec4 Color;
float Intensity;
float _p0;
float _p1;
float _p2;
};
struct GpuPointLight
{
vec4 Position;
vec4 Color;
float Intensity;
float Radius;
float _p0;
float _p1;
};

layout(std430, set = 2, binding = 4) readonly buffer LightSB
{
GpuDirectionalLight DirectionalLights[4];
GpuPointLight PointLights[8];
uint DirectionalCount;
uint PointCount;
uint _pad[2];
}
SpotLightBuffer;

layout(set = 0, binding = 10) uniform sampler2D AlbedoSampler;
layout(set = 0, binding = 11) uniform sampler2D PositionSampler;
layout(set = 0, binding = 12) uniform sampler2D NormalSampler;
layout(set = 0, binding = 13) uniform sampler2D SpecularSampler;
LightBuffer;

layout(location = 0) in vec2 TexCoord;
layout(location = 0) out vec4 OutColor;

vec3 ComputeDirectionalLight(DirectionalLight light, vec3 normal, vec3 viewDir, vec3 albedoMap, vec3 specularMap)
{
vec3 direction = light.Direction.xyz;

vec3 lightDir = normalize(direction);
vec3 ambient = light.Ambient.xyz * albedoMap;

float diff = max(dot(normal, lightDir), 0.0);
vec3 diffuse = diff * light.Diffuse.xyz * albedoMap;
const float PI = 3.14159265359;

vec3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 16);
vec3 specular = spec * light.Specular.xyz * specularMap;

return vec3(ambient + diffuse + specular);
vec3 reconstruct_position(vec2 uv, float depth)
{
vec4 ndc = vec4(uv * 2.0 - 1.0, depth, 1.0);
vec4 world = Camera.InvViewProj * ndc;
return world.xyz / world.w;
}

vec3 ComputePointLight(PointLight light, vec3 normal, vec3 viewDir, vec4 fragPos, vec3 albedoMap, vec3 specularMap)
float distribution_ggx(vec3 N, vec3 H, float roughness)
{
float dist = length(light.Position.xyz - fragPos.xyz);
float attenuation = 1.0 / (light.Constant + (light.Linear * dist) + (light.Quadratic * (dist * dist)));

vec3 lightDir = normalize(light.Position.xyz - fragPos.xyz);
vec3 ambient = light.Ambient.xyz * albedoMap;

float diff = max(dot(normal, lightDir), 0.0);
vec3 diffuse = diff * light.Diffuse.xyz * albedoMap;

vec3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 16); // todo : 16 should be replaced by material.shininess
vec3 specular = spec * light.Specular.xyz * specularMap;

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

return vec3(ambient + diffuse + specular);
float a = roughness * roughness;
float a2 = a * a;
float NdH = max(dot(N, H), 0.0);
float d = NdH * NdH * (a2 - 1.0) + 1.0;
return a2 / (PI * d * d);
}

vec3 ComputeSpotLight(SpotLight light, vec3 normal, vec3 viewDir, vec3 fragPos, vec3 albedoMap, vec3 specularMap)
float geometry_schlick_ggx(float NdV, float roughness)
{
vec3 lightDir = normalize(light.Position.xyz - fragPos);
vec3 direction = normalize(light.Direction.xyz);
float theta = dot(lightDir, direction); // check if lighting is inside the spotlight cone

if (theta > light.CutOff)
{
vec3 ambient = light.Ambient.xyz * albedoMap;

float diff = max(dot(normal, lightDir), 0.0);
vec3 diffuse = diff * light.Diffuse.xyz * albedoMap;
float r = roughness + 1.0;
float k = (r * r) / 8.0;
return NdV / (NdV * (1.0 - k) + k);
}

vec3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 16); // todo : 16 should be replaced by material.shininess
vec3 specular = spec * light.Specular.xyz * specularMap;
float geometry_smith(vec3 N, vec3 V, vec3 L, float roughness)
{
return geometry_schlick_ggx(max(dot(N, V), 0.0), roughness) * geometry_schlick_ggx(max(dot(N, L), 0.0), roughness);
}

float dist = length(light.Position.xyz - fragPos);
float attenuation = 1.0 / (light.Constant + (light.Linear * dist) + (light.Quadratic * (dist * dist)));
vec3 fresnel_schlick(float cosTheta, vec3 F0)
{
return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0);
}

diffuse *= attenuation;
specular *= attenuation;
vec3 pbr_directional(GpuDirectionalLight light, vec3 N, vec3 V, vec3 albedo, float roughness, float metallic)
{
vec3 F0 = mix(vec3(0.04), albedo, metallic);
vec3 L = normalize(-light.Direction.xyz);
vec3 H = normalize(V + L);
vec3 radiance = light.Color.rgb * light.Intensity;
float NDF = distribution_ggx(N, H, roughness);
float G = geometry_smith(N, V, L, roughness);
vec3 F = fresnel_schlick(max(dot(H, V), 0.0), F0);
vec3 spec = (NDF * G * F) / (4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0) + 0.0001);
vec3 kD = (1.0 - F) * (1.0 - metallic);
return (kD * albedo / PI + spec) * radiance * max(dot(N, L), 0.0);
}

return vec3(ambient + diffuse + specular);
}
else
{
return vec3(light.Ambient.xyz * albedoMap);
}
vec3 pbr_point(GpuPointLight light, vec3 WorldPos, vec3 N, vec3 V, vec3 albedo, float roughness, float metallic)
{
vec3 F0 = mix(vec3(0.04), albedo, metallic);
vec3 L = normalize(light.Position.xyz - WorldPos);
vec3 H = normalize(V + L);
float dist = length(light.Position.xyz - WorldPos);
float attenuation = 1.0 / (dist * dist);
vec3 radiance = light.Color.rgb * light.Intensity * attenuation;
float NDF = distribution_ggx(N, H, roughness);
float G = geometry_smith(N, V, L, roughness);
vec3 F = fresnel_schlick(max(dot(H, V), 0.0), F0);
vec3 spec = (NDF * G * F) / (4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0) + 0.0001);
vec3 kD = (1.0 - F) * (1.0 - metallic);
return (kD * albedo / PI + spec) * radiance * max(dot(N, L), 0.0);
}

void main()
{
vec3 norm = texture(NormalSampler, TexCoord).rgb;
vec4 fragPos = texture(PositionSampler, TexCoord);
vec3 albedo = texture(AlbedoSampler, TexCoord).rgb;
vec3 specular = texture(SpecularSampler, TexCoord).rgb;

vec3 viewDir = normalize(ViewPos.xyz - fragPos.xyz);

vec3 lighting = vec3(0.0);
for (uint i = 0; i < DirectionalLightBuffer.Count; ++i)
{
DirectionalLight directionalLight = DirectionalLightBuffer.Data[i];
lighting += ComputeDirectionalLight(directionalLight, norm, viewDir, albedo, specular);
}

for (uint i = 0; i < PointLightBuffer.Count; ++i)
{
PointLight pointLight = PointLightBuffer.Data[i];
lighting += ComputePointLight(pointLight, norm, viewDir, fragPos, albedo, specular);
}

for (uint i = 0; i < SpotLightBuffer.Count; ++i)
{
SpotLight spotLight = SpotLightBuffer.Data[i];
lighting += ComputeSpotLight(spotLight, norm, viewDir, fragPos.xyz, albedo, specular);
}

OutColor = vec4(lighting, 1.0);
vec4 sAlbedoAO = texture(sampler2D(GBufferAlbedoAO, GBufferSampler), TexCoord);
vec4 sNormalRough = texture(sampler2D(GBufferNormalRoughness, GBufferSampler), TexCoord);
vec4 sMetEmit = texture(sampler2D(GBufferMetallicEmissive, GBufferSampler), TexCoord);
float depth = texture(sampler2D(GBufferDepth, GBufferSampler), TexCoord).r;

vec3 albedo = sAlbedoAO.rgb;
float ao = sAlbedoAO.a;
vec3 N = normalize(sNormalRough.rgb * 2.0 - 1.0);
float roughness = max(sNormalRough.a, 0.04);
float metallic = sMetEmit.r;
float emissive = sMetEmit.g;

vec3 WorldPos = reconstruct_position(TexCoord, depth);
vec3 V = normalize(Camera.Position.xyz - WorldPos);

vec3 Lo = vec3(0.0);
for (uint i = 0; i < LightBuffer.DirectionalCount; ++i)
Lo += pbr_directional(LightBuffer.DirectionalLights[i], N, V, albedo, roughness, metallic);
for (uint i = 0; i < LightBuffer.PointCount; ++i)
Lo += pbr_point(LightBuffer.PointLights[i], WorldPos, N, V, albedo, roughness, metallic);

vec3 ambient = vec3(0.03) * albedo * ao;
vec3 color = ambient + Lo + albedo * emissive;

color = color / (color + vec3(1.0));
color = pow(color, vec3(1.0 / 2.2));
OutColor = vec4(color, 1.0);
}
13 changes: 3 additions & 10 deletions Resources/Shaders/deferred_lighting.vert
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
#version 460
#extension GL_GOOGLE_include_directive : require
#include "draw.glsl"

layout(location = 0) out vec2 TexCoord;
layout(location = 1) out vec4 ViewPos;

void main()
{
DrawDataView dataView = GetDrawDataView();

vec4 worldPos = dataView.Transform * dataView.Vertex;
ViewPos = Camera.Position;
gl_Position = Camera.Projection * Camera.View * worldPos;
// Convert gl_Position from NDC [-1, 1] to texture coordinates [0, 1]
TexCoord = (gl_Position.xy / gl_Position.w) * 0.5 + 0.5;
vec2 uv = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
TexCoord = uv;
gl_Position = vec4(uv * 2.0 - 1.0, 0.0, 1.0);
}
42 changes: 25 additions & 17 deletions Resources/Shaders/g_buffer.frag
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,46 @@

layout(location = 0) in vec2 TexCoord;
layout(location = 1) in vec3 WorldNormal;
layout(location = 2) in vec4 FragPos;
layout(location = 3) in flat uint MaterialIdx;
layout(location = 2) in flat uint MaterialIdx;

layout(location = 0) out vec4 OutAlbedo;
layout(location = 1) out vec4 OutSpecular;
layout(location = 2) out vec3 OutNormal;
layout(location = 3) out vec4 OutPosition;
layout(location = 0) out vec4 OutAlbedoAO;
layout(location = 1) out vec4 OutNormalRoughness;
layout(location = 2) out vec4 OutMetallicEmissive;

void main()
{
MaterialData material = FetchMaterial(MaterialIdx);
MaterialData material = FetchMaterial(MaterialIdx);

OutNormal = normalize(WorldNormal);
OutSpecular = material.Specular;
OutAlbedo = material.Albedo;
OutPosition = FragPos;
vec3 albedo = material.Albedo.rgb;
float ao = 1.0;
vec3 normal = normalize(WorldNormal);
float roughness = material.Roughness.y;
float metallic = material.Roughness.x;
float emissive = material.Emissive.r;

if (material.AlbedoMap < INVALID_MAP_HANDLE)
{
uint texId = uint(material.AlbedoMap);
OutAlbedo = texture(sampler2D(TextureArray[nonuniformEXT(texId)], LinearWrapSampler), TexCoord);
albedo = texture(sampler2D(TextureArray[nonuniformEXT(texId)], LinearWrapSampler), TexCoord).rgb;
}

if (material.SpecularMap < INVALID_MAP_HANDLE)
{
uint texId = uint(material.SpecularMap);
OutSpecular = texture(sampler2D(TextureArray[nonuniformEXT(texId)], LinearWrapSampler), TexCoord);
// glTF metallicRoughnessTexture: R=occlusion, G=roughness, B=metallic
uint texId = uint(material.SpecularMap);
vec3 orm = texture(sampler2D(TextureArray[nonuniformEXT(texId)], LinearWrapSampler), TexCoord).rgb;
ao = orm.r;
roughness = orm.g;
metallic = orm.b;
}

if (material.NormalMap < INVALID_MAP_HANDLE)
if (material.EmissiveMap < INVALID_MAP_HANDLE)
{
uint texId = uint(material.NormalMap);
OutNormal = texture(sampler2D(TextureArray[nonuniformEXT(texId)], LinearWrapSampler), TexCoord).rgb;
uint texId = uint(material.EmissiveMap);
emissive = texture(sampler2D(TextureArray[nonuniformEXT(texId)], LinearWrapSampler), TexCoord).r;
}

OutAlbedoAO = vec4(albedo, ao);
OutNormalRoughness = vec4(normal * 0.5 + 0.5, roughness);
OutMetallicEmissive = vec4(metallic, emissive, 0.0, 0.0);
}
5 changes: 1 addition & 4 deletions Resources/Shaders/g_buffer.vert
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,14 @@

layout(location = 0) out vec2 TexCoord;
layout(location = 1) out vec3 WorldNormal;
layout(location = 2) out vec4 FragPos;
layout(location = 3) out flat uint MaterialIdx;
layout(location = 2) out flat uint MaterialIdx;

void main()
{
DrawDataView dataView = GetDrawDataView();

vec4 worldPos = dataView.Transform * dataView.Vertex;
WorldNormal = transpose(inverse(mat3(dataView.Transform))) * dataView.Normal;
TexCoord = dataView.TexCoord;
MaterialIdx = dataView.MaterialId;
FragPos = worldPos;
gl_Position = Camera.Projection * Camera.View * worldPos;
}
1 change: 1 addition & 0 deletions Resources/Shaders/geometry_bindings.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ layout(set = 0, binding = 0) uniform UBCamera
mat4 View;
mat4 Projection;
vec4 Position;
mat4 InvViewProj;
}
Camera;

Expand Down
5 changes: 1 addition & 4 deletions ZEngine/ZEngine/Applications/AppRenderPipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,7 @@ namespace ZEngine::Applications
void AppRenderPipeline::ResizeRenderTarget(uint32_t w, uint32_t h)
{
if (SceneRenderer && SceneRenderer->RenderGraph)
{
auto rendergraph = SceneRenderer->RenderGraph;
rendergraph->Resize(w, h);
}
SceneRenderer->RenderGraph->Resize(w, h);
}

bool AppRenderPipeline::BeginFrame()
Expand Down
2 changes: 1 addition & 1 deletion ZEngine/ZEngine/Core/Memory/MemoryManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ namespace ZEngine::Core::Memory
cfg.Logging = {"Logging", ZMega(8ULL)};
cfg.VirtualFS = {"VirtualFS", ZMega(64ULL)};
cfg.VulkanDevice = {"VulkanDevice", ZGiga(1ULL)};
cfg.ImportPipeline = {"ImportPipeline", ZGiga(1ULL)}; // engine importers (414 MB) + editor importers (414 MB) + coordinator
cfg.ImportPipeline = {"ImportPipeline", ZGiga(1ULL)}; // glTF 64 + Assimp 128 + envmap 32 + editor ~414 MB; each carves directly
cfg.UIContext = {"UIContext", ZMega(64ULL)};
cfg.Swapchain = {"Swapchain", ZMega(8ULL)};
cfg.ShaderCache = {"ShaderCache", ZMega(64ULL)};
Expand Down
Loading
Loading