Diffuse Irradiance contribution to IBL.
This commit is contained in:
parent
ba2e21f52e
commit
7ba132ec0c
Binary file not shown.
Binary file not shown.
|
|
@ -372,6 +372,7 @@ main(int, char **)
|
||||||
bool rotating = false;
|
bool rotating = false;
|
||||||
bool lockToScreen = true;
|
bool lockToScreen = true;
|
||||||
bool showDiffuse = false;
|
bool showDiffuse = false;
|
||||||
|
bool useDiffuse = true;
|
||||||
i32 height = Cast<i32>(internalResolution.height);
|
i32 height = Cast<i32>(internalResolution.height);
|
||||||
f32 camPitch = glm::degrees(cameraController.m_Pitch);
|
f32 camPitch = glm::degrees(cameraController.m_Pitch);
|
||||||
f32 camYaw = glm::degrees(cameraController.m_Yaw);
|
f32 camYaw = glm::degrees(cameraController.m_Yaw);
|
||||||
|
|
@ -446,7 +447,11 @@ main(int, char **)
|
||||||
{
|
{
|
||||||
cameraController.SetPosition(camPosition);
|
cameraController.SetPosition(camPosition);
|
||||||
}
|
}
|
||||||
|
gui::Separator();
|
||||||
|
gui::Text("IBL");
|
||||||
gui::Checkbox("Show DiffIrr", &showDiffuse);
|
gui::Checkbox("Show DiffIrr", &showDiffuse);
|
||||||
|
gui::Checkbox("Use DiffIrr", &useDiffuse);
|
||||||
|
gui::Separator();
|
||||||
gui::Checkbox("Rotate", &rotating);
|
gui::Checkbox("Rotate", &rotating);
|
||||||
gui::PopItemWidth();
|
gui::PopItemWidth();
|
||||||
if (gui::Button("Exit"))
|
if (gui::Button("Exit"))
|
||||||
|
|
@ -559,6 +564,18 @@ main(int, char **)
|
||||||
cmd.pushConstants(pipeline.m_Layout, vk::ShaderStageFlagBits::eAll, pcbOffset, sizeof texCube, &texCube);
|
cmd.pushConstants(pipeline.m_Layout, vk::ShaderStageFlagBits::eAll, pcbOffset, sizeof texCube, &texCube);
|
||||||
pcbOffset += sizeof texCube;
|
pcbOffset += sizeof texCube;
|
||||||
}
|
}
|
||||||
|
if (useDiffuse)
|
||||||
|
{
|
||||||
|
cmd.pushConstants(pipeline.m_Layout, vk::ShaderStageFlagBits::eAll, pcbOffset, sizeof diffuseIrr,
|
||||||
|
&diffuseIrr);
|
||||||
|
pcbOffset += sizeof diffuseIrr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TextureHandle invalid;
|
||||||
|
cmd.pushConstants(pipeline.m_Layout, vk::ShaderStageFlagBits::eAll, pcbOffset, sizeof invalid, &invalid);
|
||||||
|
pcbOffset += sizeof invalid;
|
||||||
|
}
|
||||||
static_assert(sizeof texCube == sizeof diffuseIrr);
|
static_assert(sizeof texCube == sizeof diffuseIrr);
|
||||||
cmd.pushConstants(pipeline.m_Layout, vk::ShaderStageFlagBits::eAll, pcbOffset, sizeof lightManager.m_MetaInfo,
|
cmd.pushConstants(pipeline.m_Layout, vk::ShaderStageFlagBits::eAll, pcbOffset, sizeof lightManager.m_MetaInfo,
|
||||||
&lightManager.m_MetaInfo);
|
&lightManager.m_MetaInfo);
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ CreatePipeline(const Device *device, vk::Format attachmentFormat, const GpuResou
|
||||||
vk::PushConstantRange pushConstantRange = {
|
vk::PushConstantRange pushConstantRange = {
|
||||||
.stageFlags = vk::ShaderStageFlagBits::eAll,
|
.stageFlags = vk::ShaderStageFlagBits::eAll,
|
||||||
.offset = 0,
|
.offset = 0,
|
||||||
.size = 40,
|
.size = 44,
|
||||||
};
|
};
|
||||||
|
|
||||||
vk::PipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
|
vk::PipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
|
||||||
|
|
@ -206,7 +206,7 @@ CreateBackgroundPipeline(const Device *device, vk::Format attachmentFormat, cons
|
||||||
vk::PushConstantRange pushConstantRange = {
|
vk::PushConstantRange pushConstantRange = {
|
||||||
.stageFlags = vk::ShaderStageFlagBits::eAll,
|
.stageFlags = vk::ShaderStageFlagBits::eAll,
|
||||||
.offset = 0,
|
.offset = 0,
|
||||||
.size = 40,
|
.size = 44,
|
||||||
};
|
};
|
||||||
|
|
||||||
vk::PipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
|
vk::PipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ struct Block
|
||||||
uint MaterialBufferHandle;
|
uint MaterialBufferHandle;
|
||||||
uint NodeBufferHandle;
|
uint NodeBufferHandle;
|
||||||
uint EnvCubeHandle;
|
uint EnvCubeHandle;
|
||||||
|
uint DiffuseIrradianceHandle;
|
||||||
uint LightHandle;
|
uint LightHandle;
|
||||||
uint PointLightIndexer;
|
uint PointLightIndexer;
|
||||||
uint DirectionalLightIndexer;
|
uint DirectionalLightIndexer;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ struct FS_Input
|
||||||
|
|
||||||
struct FS_Output
|
struct FS_Output
|
||||||
{
|
{
|
||||||
float4 ColorTarget : SV_Target0;
|
float4 ColorTarget : SV_Target0;
|
||||||
};
|
};
|
||||||
|
|
||||||
float4 GetAlbedo(float2 UV, float4 InColor)
|
float4 GetAlbedo(float2 UV, float4 InColor)
|
||||||
|
|
@ -21,6 +21,13 @@ float4 GetAlbedo(float2 UV, float4 InColor)
|
||||||
return AlbedoFactor * InColor * (AlbedoTexId != INVALID_HANDLE ? Textures[AlbedoTexId].Sample(ImmutableSamplers[AlbedoTexId], UV) : 1.0f.xxxx);
|
return AlbedoFactor * InColor * (AlbedoTexId != INVALID_HANDLE ? Textures[AlbedoTexId].Sample(ImmutableSamplers[AlbedoTexId], UV) : 1.0f.xxxx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float GetOcclusion(float2 UV)
|
||||||
|
{
|
||||||
|
uint OcclusionTexId = MaterialsBuffer[PushConstant.MaterialBufferHandle][PushConstant.MaterialIdx].OcclusionTex;
|
||||||
|
|
||||||
|
return OcclusionTexId != INVALID_HANDLE ? Textures[OcclusionTexId].Sample(ImmutableSamplers[OcclusionTexId], UV).r : 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
float3 GetEmissive(float2 UV)
|
float3 GetEmissive(float2 UV)
|
||||||
{
|
{
|
||||||
float3 EmissionFactor = (float3) MaterialsBuffer[PushConstant.MaterialBufferHandle][PushConstant.MaterialIdx].EmissionFactor;
|
float3 EmissionFactor = (float3) MaterialsBuffer[PushConstant.MaterialBufferHandle][PushConstant.MaterialIdx].EmissionFactor;
|
||||||
|
|
@ -61,6 +68,15 @@ float2 GetMetalRough(float2 UV)
|
||||||
return MetalRoughFactors * (MetalRoughTexId != INVALID_HANDLE ? Textures[MetalRoughTexId].Sample(ImmutableSamplers[MetalRoughTexId], UV).bg : 1.0f.xx); // Metal is B, Rough is G.
|
return MetalRoughFactors * (MetalRoughTexId != INVALID_HANDLE ? Textures[MetalRoughTexId].Sample(ImmutableSamplers[MetalRoughTexId], UV).bg : 1.0f.xx); // Metal is B, Rough is G.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float3 SampleIrradiance(float3 Direction)
|
||||||
|
{
|
||||||
|
if (PushConstant.DiffuseIrradianceHandle != INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
return TextureCubes[PushConstant.DiffuseIrradianceHandle].Sample(ImmutableSamplers[PushConstant.DiffuseIrradianceHandle], Direction).rgb;
|
||||||
|
}
|
||||||
|
return 0.04f.xxx;
|
||||||
|
}
|
||||||
|
|
||||||
float TrowbridgeReitzGGX(float3 Normal, float3 Halfway, float Roughness)
|
float TrowbridgeReitzGGX(float3 Normal, float3 Halfway, float Roughness)
|
||||||
{
|
{
|
||||||
float Coeff = Roughness * Roughness;
|
float Coeff = Roughness * Roughness;
|
||||||
|
|
@ -100,6 +116,12 @@ float3 FresnelSchlick(float cosine, float3 F_0)
|
||||||
return F_0 + (1.0f - F_0) * pow(clamp(1.0f - cosine, 0.0f, 1.0f), 5.0f); // Clamp to avoid artifacts.
|
return F_0 + (1.0f - F_0) * pow(clamp(1.0f - cosine, 0.0f, 1.0f), 5.0f); // Clamp to avoid artifacts.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sebastian Lagarde
|
||||||
|
float3 FresnelSchlickRoughness(float cosine, float3 F_0, float Roughness)
|
||||||
|
{
|
||||||
|
return F_0 + (max((1.0f - Roughness).xxx, F_0) - F_0) * pow(clamp(1.0f - cosine, 0.0f, 1.0f), 5.0f); // Clamp to avoid artifacts.
|
||||||
|
}
|
||||||
|
|
||||||
float3 GetPBRContrib(float3 Albedo, float3 LightColor, float3 ViewDir, float3 Normal, float Metallic, float Roughness, float3 F_0, float3 LightDir, float LightDistance)
|
float3 GetPBRContrib(float3 Albedo, float3 LightColor, float3 ViewDir, float3 Normal, float Metallic, float Roughness, float3 F_0, float3 LightDir, float LightDistance)
|
||||||
{
|
{
|
||||||
float Attenuation = 1.0f / (LightDistance * LightDistance); // TODO: Controlled Attenuation
|
float Attenuation = 1.0f / (LightDistance * LightDistance); // TODO: Controlled Attenuation
|
||||||
|
|
@ -113,18 +135,18 @@ float3 GetPBRContrib(float3 Albedo, float3 LightColor, float3 ViewDir, float3 No
|
||||||
|
|
||||||
float NormalDistribution = TrowbridgeReitzGGX(Normal, Halfway, Roughness);
|
float NormalDistribution = TrowbridgeReitzGGX(Normal, Halfway, Roughness);
|
||||||
float Geometry = GeometrySmith(NdotV, NdotL, Roughness);
|
float Geometry = GeometrySmith(NdotV, NdotL, Roughness);
|
||||||
float3 Fresnel = FresnelSchlick(CosineFactor, F_0);
|
float3 Fresnel = FresnelSchlickRoughness(CosineFactor, F_0, Roughness);
|
||||||
|
|
||||||
float3 Numerator = (NormalDistribution * Geometry) * Fresnel;
|
float3 Numerator = (NormalDistribution * Geometry) * Fresnel;
|
||||||
float Denominator = 4.0f * NdotV * NdotL;
|
float Denominator = 4.0f * NdotV * NdotL;
|
||||||
float3 Specular = Numerator / max(Denominator, 0.00001);
|
float3 Specular = Numerator / (Denominator + 0.00001f);
|
||||||
|
|
||||||
float3 K_Specular = Fresnel;
|
float3 K_Specular = Fresnel;
|
||||||
float3 K_Diffuse = 1.0f.xxx - K_Specular;
|
float3 K_Diffuse = 1.0f.xxx - K_Specular;
|
||||||
|
|
||||||
K_Diffuse *= 1.0f - Metallic;
|
K_Diffuse *= 1.0f - Metallic;
|
||||||
|
|
||||||
return NdotL * Radiance * ((K_Diffuse * Albedo / PI) + Specular);
|
return NdotL * Radiance * (K_Diffuse * Albedo / PI + Specular);
|
||||||
}
|
}
|
||||||
|
|
||||||
float3 GetPointLightInfluence(float3 Albedo, float2 MetalRough, float3 Position, float3 Normal)
|
float3 GetPointLightInfluence(float3 Albedo, float2 MetalRough, float3 Position, float3 Normal)
|
||||||
|
|
@ -144,7 +166,6 @@ float3 GetPointLightInfluence(float3 Albedo, float2 MetalRough, float3 Position,
|
||||||
// TODO: Cite
|
// TODO: Cite
|
||||||
float3 F_0 = 0.04f.xxx;
|
float3 F_0 = 0.04f.xxx;
|
||||||
F_0 = lerp(F_0, Albedo, Metallic);
|
F_0 = lerp(F_0, Albedo, Metallic);
|
||||||
float3 LightAmp = float3(23.47f, 21.31f, 20.79f); // TODO: Get rid
|
|
||||||
|
|
||||||
float3 Contrib = 0.0f;
|
float3 Contrib = 0.0f;
|
||||||
for (uint i = 0; i < Count; ++i)
|
for (uint i = 0; i < Count; ++i)
|
||||||
|
|
@ -167,7 +188,7 @@ float3 GetPointLightInfluence(float3 Albedo, float2 MetalRough, float3 Position,
|
||||||
float G = (Light.Color & 0x00FF0000) >> 16;
|
float G = (Light.Color & 0x00FF0000) >> 16;
|
||||||
float B = (Light.Color & 0x0000FF00) >> 8;
|
float B = (Light.Color & 0x0000FF00) >> 8;
|
||||||
|
|
||||||
float3 LightColor = LightAmp * Light.Intensity * float3(R, G, B) * 0.00392156862f; // 0.00392156862 = 1/255
|
float3 LightColor = Light.Intensity * float3(R, G, B) * 0.00392156862f; // 0.00392156862 = 1/255
|
||||||
|
|
||||||
Contrib += GetPBRContrib(Albedo, LightColor, ViewDir, Normal, Metallic, Roughness, F_0, LightDir, LightDistance);
|
Contrib += GetPBRContrib(Albedo, LightColor, ViewDir, Normal, Metallic, Roughness, F_0, LightDir, LightDistance);
|
||||||
}
|
}
|
||||||
|
|
@ -192,7 +213,6 @@ float3 GetDirectionalLightInfluence(float3 Albedo, float2 MetalRough, float3 Pos
|
||||||
// TODO: Cite
|
// TODO: Cite
|
||||||
float3 F_0 = 0.04f.xxx;
|
float3 F_0 = 0.04f.xxx;
|
||||||
F_0 = lerp(F_0, Albedo, Metallic);
|
F_0 = lerp(F_0, Albedo, Metallic);
|
||||||
float3 LightAmp = float3(23.47f, 21.31f, 20.79f); // TODO: Get rid
|
|
||||||
|
|
||||||
float3 Contrib = 0.0f;
|
float3 Contrib = 0.0f;
|
||||||
for (uint i = 0; i < Count; ++i)
|
for (uint i = 0; i < Count; ++i)
|
||||||
|
|
@ -209,7 +229,7 @@ float3 GetDirectionalLightInfluence(float3 Albedo, float2 MetalRough, float3 Pos
|
||||||
float G = (Light.Color & 0x00FF0000) >> 16;
|
float G = (Light.Color & 0x00FF0000) >> 16;
|
||||||
float B = (Light.Color & 0x0000FF00) >> 8;
|
float B = (Light.Color & 0x0000FF00) >> 8;
|
||||||
|
|
||||||
float3 LightColor = LightAmp * Light.Intensity * float3(R, G, B) * 0.00392156862f; // 0.00392156862 = 1/255
|
float3 LightColor = Light.Intensity * float3(R, G, B) * 0.00392156862f; // 0.00392156862 = 1/255
|
||||||
|
|
||||||
Contrib += GetPBRContrib(Albedo, LightColor, ViewDir, Normal, Metallic, Roughness, F_0, LightDir, 1.0f);
|
Contrib += GetPBRContrib(Albedo, LightColor, ViewDir, Normal, Metallic, Roughness, F_0, LightDir, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
@ -217,12 +237,27 @@ float3 GetDirectionalLightInfluence(float3 Albedo, float2 MetalRough, float3 Pos
|
||||||
return Contrib;
|
return Contrib;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float3 GetAmbientInfluence(float3 Albedo, float2 MetalRough, float3 Position, float3 Normal, float Occlusion)
|
||||||
|
{
|
||||||
|
float3 ViewDir = normalize(Camera.Position.xyz - Position);
|
||||||
|
float CosineFactor = max(dot(Normal, ViewDir), 0.0f); // TODO: Is Normal or is it Halfway?
|
||||||
|
|
||||||
|
float3 F_0 = 0.04f.xxx;
|
||||||
|
F_0 = lerp(F_0, Albedo, MetalRough.r);
|
||||||
|
float3 K_Specular = FresnelSchlickRoughness(CosineFactor, F_0, MetalRough.g);
|
||||||
|
float3 K_Diffuse = 1.0f.xxx - K_Specular;
|
||||||
|
|
||||||
|
K_Diffuse *= 1.0f - MetalRough.r; // Metals don't have diffuse/refractions.
|
||||||
|
|
||||||
|
float3 DiffuseIrradiance = K_Diffuse * Albedo * SampleIrradiance(Normal) * Occlusion;
|
||||||
|
|
||||||
|
return DiffuseIrradiance;
|
||||||
|
}
|
||||||
|
|
||||||
FS_Output main(FS_Input StageInput)
|
FS_Output main(FS_Input StageInput)
|
||||||
{
|
{
|
||||||
FS_Output Output;
|
FS_Output Output;
|
||||||
|
|
||||||
float3 Ambient = float3(0.02f, 0.02f, 0.02f);
|
|
||||||
|
|
||||||
// TODO: This should be invalid on the CPU side.
|
// TODO: This should be invalid on the CPU side.
|
||||||
if (PushConstant.MaterialIdx < 0)
|
if (PushConstant.MaterialIdx < 0)
|
||||||
{
|
{
|
||||||
|
|
@ -238,7 +273,12 @@ FS_Output main(FS_Input StageInput)
|
||||||
float Alpha = AlbedoAlpha.a;
|
float Alpha = AlbedoAlpha.a;
|
||||||
float2 MetalRough = GetMetalRough(StageInput.InUV0);
|
float2 MetalRough = GetMetalRough(StageInput.InUV0);
|
||||||
float3 Emission = GetEmissive(StageInput.InUV0);
|
float3 Emission = GetEmissive(StageInput.InUV0);
|
||||||
float3 Color = GetDirectionalLightInfluence(Albedo, MetalRough, Position, Normal) + GetPointLightInfluence(Albedo, MetalRough, Position, Normal);
|
float Occlusion = GetOcclusion(StageInput.InUV0);
|
||||||
|
|
||||||
|
float3 DirectionalLightLum = GetDirectionalLightInfluence(Albedo, MetalRough, Position, Normal);
|
||||||
|
float3 PointLighLum = GetPointLightInfluence(Albedo, MetalRough, Position, Normal);
|
||||||
|
float3 AmbientLum = GetAmbientInfluence(Albedo, MetalRough, Position, Normal, Occlusion);
|
||||||
|
float3 Color = DirectionalLightLum + PointLighLum + AmbientLum;
|
||||||
|
|
||||||
Output.ColorTarget = float4(Uncharted2Tonemap(Color + Emission), Alpha);
|
Output.ColorTarget = float4(Uncharted2Tonemap(Color + Emission), Alpha);
|
||||||
return Output;
|
return Output;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue