172 lines
5.3 KiB
HLSL
172 lines
5.3 KiB
HLSL
#ifndef metalic_roughness_ambient_h_ixray_included
|
|
#define metalic_roughness_ambient_h_ixray_included
|
|
|
|
#include "common.hlsli"
|
|
|
|
//fitted for height-correlated smith
|
|
float2 EpicGamesEnvBRDFApprox(float NdotV, float roughness)
|
|
{
|
|
//clamped cuz of extreme spike
|
|
NdotV = min(NdotV, 0.998);
|
|
|
|
float nsqr = NdotV * NdotV;
|
|
float rsqr = roughness * roughness;
|
|
|
|
float4 fac = float4(0.0187, 1.0133, 1.0000, 1.0000) +
|
|
float4(1.9496, -2.4717, -0.0333, 2.0508) * NdotV +
|
|
float4(1.2265, -1.2172, -1.3097, 0.2342) * roughness +
|
|
float4(-7.6907, 3.4300, 0.5972, -26.9406) * NdotV * roughness +
|
|
float4(18.3314, 1.4794, 19.3537, 11.1429) * nsqr +
|
|
float4(-0.2894, 0.5564, 1.5052, 7.0828) * rsqr +
|
|
float4(-19.3056, -2.2456, -28.2302, 18.5470) * nsqr * roughness +
|
|
float4(7.0144, -1.8934, 1.3307, 50.6469) * NdotV * rsqr +
|
|
float4(1.5728, 1.3618, 15.2939, -63.3557) * nsqr * rsqr;
|
|
|
|
return saturate(fac.xy / fac.zw);
|
|
}
|
|
|
|
float3 CompureDiffuseIrradance(float3 N, float3 Hemi)
|
|
{
|
|
float3 LightDirection = mul((float3x3)m_invV, N).xyz;
|
|
|
|
#ifdef IBL_REMAP_IRRADANCE
|
|
RemapVector(LightDirection);
|
|
#endif
|
|
|
|
#ifdef USE_NORMAL_HEMI_DISTRIBUTION
|
|
Hemi = min(Hemi, LightDirection.yyy * 0.375f + 0.375f);
|
|
#endif
|
|
|
|
float3 SampleLast = env_s0.SampleLevel(smp_linear, LightDirection, 0.0f).xyz;
|
|
float3 SampleNext = env_s1.SampleLevel(smp_linear, LightDirection, 0.0f).xyz;
|
|
|
|
#ifdef USE_CGIM_SKY_TWEAK
|
|
float topToDownVec = saturate(LightDirection.y);
|
|
topToDownVec *= topToDownVec;
|
|
|
|
float Factor = SMALLSKY_TOP_VECTOR_POWER;
|
|
Factor = saturate(Factor + (1.0 - Factor) * topToDownVec) + (1.0 - Factor) * 0.5f;
|
|
|
|
Hemi *= Factor * Factor; float3 Irradance = 1.0f;
|
|
Hemi *= lerp(SampleLast, SampleNext, L_hemi_color.w);
|
|
#else
|
|
float3 Irradance = lerp(SampleLast, SampleNext, L_hemi_color.w);
|
|
#endif
|
|
|
|
#ifdef USE_DIFFUSE_SKY_COLOR
|
|
#ifdef USE_BGRA_SKYCOLOR
|
|
Irradance *= L_sky_color.zyx;
|
|
#else
|
|
Irradance *= L_sky_color.xyz;
|
|
#endif
|
|
#else
|
|
Irradance *= L_hemi_color.xyz;
|
|
#endif
|
|
|
|
#ifdef USE_LEGACY_LIGHT
|
|
Irradance *= Irradance;
|
|
#endif
|
|
|
|
return Irradance * Hemi;
|
|
}
|
|
|
|
float3 CompureSpecularIrradance(float3 R, float3 Hemi, float Roughness)
|
|
{
|
|
float3 LightDirection = mul((float3x3)m_invV, R);
|
|
|
|
#ifdef USE_OLD_VIEW_REFLECTIONS
|
|
R = mul(m_V_old, LightDirection);
|
|
#endif
|
|
|
|
#ifndef IBL_MAX_LOD
|
|
float4 MipLevels = 0.0f;
|
|
sky_s0.GetDimensions(MipLevels.x, MipLevels.y, MipLevels.z, MipLevels.w);
|
|
float2 Lod = MipLevels.w * Roughness;
|
|
#ifdef USE_HQ_SKY2_LOD
|
|
sky_s1.GetDimensions(MipLevels.x, MipLevels.y, MipLevels.z, MipLevels.w);
|
|
Lod.y = MipLevels.w * Roughness;
|
|
#endif
|
|
#else
|
|
float2 Lod = IBL_MAX_LOD * Roughness;
|
|
#endif
|
|
|
|
#ifdef IBL_FAKE_IRRADANCE
|
|
float3 SampleLastD = env_s0.SampleLevel(smp_rtlinear, LightDirection, 0.0f).xyz;
|
|
float3 SampleNextD = env_s1.SampleLevel(smp_rtlinear, LightDirection, 0.0f).xyz;
|
|
#endif
|
|
|
|
#ifdef IBL_REMAP_POSITIVE_Y
|
|
LightDirection.y = abs(LightDirection.y);
|
|
#endif
|
|
|
|
#ifdef IBL_REMAP_REFLECTIONS
|
|
RemapVector(LightDirection);
|
|
#endif
|
|
|
|
float3 SampleLast = sky_s0.SampleLevel(smp_linear, LightDirection, Lod.x).xyz;
|
|
float3 SampleNext = sky_s1.SampleLevel(smp_linear, LightDirection, Lod.y).xyz;
|
|
|
|
#ifdef IBL_FAKE_IRRADANCE
|
|
SampleLast = lerp(SampleLast, SampleLastD, Roughness);
|
|
SampleNext = lerp(SampleNext, SampleNextD, Roughness);
|
|
#endif
|
|
|
|
float3 Irradance = lerp(SampleLast, SampleNext, L_hemi_color.w);
|
|
|
|
#ifdef USE_SPECULAR_HEMI_COLOR
|
|
Irradance *= L_hemi_color.xyz;
|
|
#else
|
|
#ifdef USE_BGRA_SKYCOLOR
|
|
Irradance *= L_sky_color.zyx;
|
|
#else
|
|
Irradance *= L_sky_color.xyz;
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef USE_VIEW_REFLECTIONS
|
|
float4 SampleRef = s_env.SampleLevel(smp_linear, R, 8.0f * Roughness);
|
|
SampleRef.xyz *= rcp(1.00001f - SampleRef.xyz);
|
|
|
|
float fog = saturate(SampleRef.w * fog_params.w + fog_params.x);
|
|
Irradance = lerp(PopGamma(SampleRef.xyz), Irradance, fog);
|
|
#endif
|
|
|
|
return Irradance * Hemi;
|
|
}
|
|
|
|
float3 AmbientLighting(float3 DiffuseIrradance, float3 SpecularIrradance, float NdotV, float3 Color, float Metalness, float Roughness, float3 F0 = 0.04f)
|
|
{
|
|
DiffuseIrradance = PushGamma(DiffuseIrradance);
|
|
SpecularIrradance = PushGamma(SpecularIrradance);
|
|
|
|
DiffuseIrradance *= (1.0f - Metalness) * Color;
|
|
|
|
float2 BRDF = EpicGamesEnvBRDFApprox(NdotV, Roughness);
|
|
float3 F = lerp(F0, Color, Metalness) * BRDF.x + BRDF.y;
|
|
|
|
return lerp(DiffuseIrradance, SpecularIrradance, F);
|
|
}
|
|
|
|
float3 AmbientLighting(float3 View, float3 Normal, float3 Color, float Metalness, float Roughness, float Hemi, float3 F0 = 0.04f)
|
|
{
|
|
float3 Reflect = reflect(View, Normal);
|
|
|
|
#ifndef USE_LEGACY_LIGHT
|
|
float3 DiffuseIrradance = CompureDiffuseIrradance(Normal, Hemi) + L_ambient.xyz;
|
|
float3 SpecularIrradance = CompureSpecularIrradance(Reflect, Hemi, Roughness);
|
|
float NdotV = max(0.0, dot(Normal, -View));
|
|
|
|
return AmbientLighting(DiffuseIrradance, SpecularIrradance, NdotV, Color, Metalness, Roughness, F0);
|
|
#else
|
|
float Specular = 0.5f - 0.5f * dot(View, Reflect);
|
|
float2 Material = s_material.SampleLevel(smp_material, float3(Hemi, Specular, Metalness), 0).xy;
|
|
|
|
float3 DiffuseIrradance = CompureDiffuseIrradance(Normal, Material.x) + L_ambient.xyz;
|
|
float3 SpecularIrradance = CompureDiffuseIrradance(Reflect, Material.y);
|
|
|
|
return DiffuseIrradance * Color + SpecularIrradance * Roughness;
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
|