Directional Light PBR.
This commit is contained in:
parent
3e30dfbac9
commit
cd49d5b869
|
|
@ -90,7 +90,7 @@ main(int, char **)
|
||||||
.m_Position = vec4{0.0f, 2.0f, 2.0f, 1.0f},
|
.m_Position = vec4{0.0f, 2.0f, 2.0f, 1.0f},
|
||||||
};
|
};
|
||||||
|
|
||||||
//lightManager.AddDirectional(vec3(0.0f, -1.0f, 0.0f), {0.0f, 1.0f, 0.0f});
|
lightManager.AddDirectional(vec3(0.0f, -1.0f, 0.0f), {0.0f, 0.7f, 0.0f});
|
||||||
lightManager.AddPoint(vec3{2.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, 15.0f);
|
lightManager.AddPoint(vec3{2.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, 15.0f);
|
||||||
lightManager.AddPoint(vec3{-2.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, 15.0f);
|
lightManager.AddPoint(vec3{-2.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, 15.0f);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ struct Block
|
||||||
uint NodeBufferHandle;
|
uint NodeBufferHandle;
|
||||||
uint LightHandle;
|
uint LightHandle;
|
||||||
uint PointLightIndexer;
|
uint PointLightIndexer;
|
||||||
uint DirectionLightIndexer;
|
uint DirectionalLightIndexer;
|
||||||
int MaterialIdx;
|
int MaterialIdx;
|
||||||
uint NodeIdx;
|
uint NodeIdx;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,33 @@ 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.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
float3 Halfway = normalize(ViewDir + LightDir);
|
||||||
|
|
||||||
|
float CosineFactor = max(dot(Halfway, ViewDir), 0.0f);
|
||||||
|
float NdotV = max(dot(Normal, ViewDir), 0.0f);
|
||||||
|
float NdotL = max(dot(Normal, LightDir), 0.0f);
|
||||||
|
|
||||||
|
float3 Radiance = LightColor * Attenuation;
|
||||||
|
|
||||||
|
float NormalDistribution = TrowbridgeReitzGGX(Normal, Halfway, Roughness);
|
||||||
|
float Geometry = GeometrySmith(NdotV, NdotL, Roughness);
|
||||||
|
float3 Fresnel = FresnelSchlick(CosineFactor, F_0);
|
||||||
|
|
||||||
|
float3 Numerator = (NormalDistribution * Geometry) * Fresnel;
|
||||||
|
float Denominator = 4.0f * NdotV * NdotL;
|
||||||
|
float3 Specular = Numerator / max(Denominator, 0.00001);
|
||||||
|
|
||||||
|
float3 K_Specular = Fresnel;
|
||||||
|
float3 K_Diffuse = 1.0f.xxx - K_Specular;
|
||||||
|
|
||||||
|
K_Diffuse *= 1.0f - Metallic;
|
||||||
|
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
if (PushConstant.LightHandle == INVALID_HANDLE)
|
if (PushConstant.LightHandle == INVALID_HANDLE)
|
||||||
|
|
@ -117,7 +144,7 @@ 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);
|
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)
|
||||||
|
|
@ -142,29 +169,49 @@ float3 GetPointLightInfluence(float3 Albedo, float2 MetalRough, float3 Position,
|
||||||
|
|
||||||
float3 LightColor = LightAmp * float3(R, G, B) * 0.00392156862f; // 0.00392156862 = 1/255
|
float3 LightColor = LightAmp * float3(R, G, B) * 0.00392156862f; // 0.00392156862 = 1/255
|
||||||
|
|
||||||
float Attenuation = 1.0f / (LightDistance * LightDistance); // TODO: Controlled Attenuation
|
Contrib += GetPBRContrib(Albedo, LightColor, ViewDir, Normal, Metallic, Roughness, F_0, LightDir, LightDistance);
|
||||||
float3 Halfway = normalize(ViewDir + LightDir);
|
}
|
||||||
|
|
||||||
float CosineFactor = max(dot(Halfway, ViewDir), 0.0f);
|
return Contrib;
|
||||||
float NdotV = max(dot(Normal, ViewDir), 0.0f);
|
}
|
||||||
float NdotL = max(dot(Normal, LightDir), 0.0f);
|
|
||||||
|
|
||||||
float3 Radiance = LightColor * Attenuation;
|
|
||||||
|
|
||||||
float NormalDistribution = TrowbridgeReitzGGX(Normal, Halfway, Roughness);
|
float3 GetDirectionalLightInfluence(float3 Albedo, float2 MetalRough, float3 Position, float3 Normal)
|
||||||
float Geometry = GeometrySmith(NdotV, NdotL, Roughness);
|
{
|
||||||
float3 Fresnel = FresnelSchlick(CosineFactor, F_0);
|
if (PushConstant.LightHandle == INVALID_HANDLE)
|
||||||
|
return 0.0f.xxx;
|
||||||
|
|
||||||
float3 Numerator = (NormalDistribution * Geometry) * Fresnel;
|
uint Count = IndexerCount(PushConstant.DirectionalLightIndexer);
|
||||||
float Denominator = 4.0f * NdotV * NdotL;
|
|
||||||
float3 Specular = Numerator / max(Denominator, 0.00001);
|
|
||||||
|
|
||||||
float3 K_Specular = Fresnel;
|
float3 ViewDir = normalize(Camera.Position.xyz - Position);
|
||||||
float3 K_Diffuse = 1.0f.xxx - K_Specular;
|
|
||||||
|
|
||||||
K_Diffuse *= 1.0f - Metallic;
|
float Metallic = MetalRough.r;
|
||||||
|
float Roughness = MetalRough.g;
|
||||||
|
|
||||||
Contrib += NdotL * Radiance * ((K_Diffuse * Albedo / PI) + Specular);
|
// Dielectric F_0 based on LearnOpenGL.
|
||||||
|
// TODO: Cite
|
||||||
|
float3 F_0 = 0.04f.xxx;
|
||||||
|
F_0 = lerp(F_0, Albedo, Metallic);
|
||||||
|
float3 LightAmp = float3(23.47f, 21.31f, 20.79f); // TODO: Get rid
|
||||||
|
|
||||||
|
float3 Contrib = 0.0f;
|
||||||
|
for (uint i = 0; i < Count; ++i)
|
||||||
|
{
|
||||||
|
DirectionalLight Light = DirectionalLightBuffer[PushConstant.LightHandle][i];
|
||||||
|
|
||||||
|
if (Light.Validity_ < 0.0f)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
float3 LightDir = -normalize(float3(Light.Direction));
|
||||||
|
|
||||||
|
// Color Unpack
|
||||||
|
float R = (Light.Color & 0xFF000000) >> 24;
|
||||||
|
float G = (Light.Color & 0x00FF0000) >> 16;
|
||||||
|
float B = (Light.Color & 0x0000FF00) >> 8;
|
||||||
|
|
||||||
|
float3 LightColor = LightAmp * float3(R, G, B) * 0.00392156862f; // 0.00392156862 = 1/255
|
||||||
|
|
||||||
|
Contrib += GetPBRContrib(Albedo, LightColor, ViewDir, Normal, Metallic, Roughness, F_0, LightDir, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Contrib;
|
return Contrib;
|
||||||
|
|
@ -203,7 +250,7 @@ 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);
|
float3 Color = GetDirectionalLightInfluence(Albedo, MetalRough, Position, Normal) + GetPointLightInfluence(Albedo, MetalRough, Position, Normal);
|
||||||
|
|
||||||
Output.ColorTarget = float4(Uncharted2Tonemap(Color + Emission), Alpha);
|
Output.ColorTarget = float4(Uncharted2Tonemap(Color + Emission), Alpha);
|
||||||
return Output;
|
return Output;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue