| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
- // All rights reserved.
- // Code licensed under the BSD License.
- // http://www.anki3d.org/LICENSE
- // Classic deferred lighting shader
- #pragma anki mutator SPECULAR 0 1
- #pragma anki mutator INDIRECT_DIFFUSE 0 1 2
- #pragma anki technique vert pixel
- #include <AnKi/Shaders/QuadVert.hlsl>
- #if ANKI_PIXEL_SHADER
- # include <AnKi/Shaders/PackFunctions.hlsl>
- # include <AnKi/Shaders/LightFunctions.hlsl>
- # include <AnKi/Shaders/IndirectDiffuseClipmaps.hlsl>
- # include <AnKi/Shaders/Include/TraditionalDeferredShadingTypes.h>
- # include <AnKi/Shaders/Include/GpuSceneTypes.h>
- ConstantBuffer<TraditionalDeferredShadingConstants> g_consts : register(b0);
- StructuredBuffer<U32> g_visibleLightIds : register(t0);
- StructuredBuffer<GpuSceneLight> g_lights : register(t1);
- SamplerState g_gbufferSampler : register(s0);
- Texture2D<Vec4> g_gbufferTex0 : register(t2);
- Texture2D<Vec4> g_gbufferTex1 : register(t3);
- Texture2D<Vec4> g_gbufferTex2 : register(t4);
- Texture2D<Vec4> g_depthTex : register(t5);
- // For directional light:
- SamplerComparisonState g_shadowMapSampler : register(s1);
- Texture2D<Vec4> g_shadowMap : register(t6);
- # if INDIRECT_DIFFUSE
- StructuredBuffer<GpuSceneGlobalIlluminationProbe> g_giProbes : register(t7);
- SamplerState g_linearAnyClampSampler : register(s2);
- # endif
- ConstantBuffer<GlobalRendererConstants> g_globalRendererConsts : register(b1);
- # if INDIRECT_DIFFUSE
- Vec3 getDiffuseIndirect(Vec3 worldPos, Vec3 worldNormal)
- {
- # if INDIRECT_DIFFUSE == 1
- const U32 probeCount = getStructuredBufferElementCount(g_giProbes);
- U32 i;
- for(i = 0; i < probeCount; ++i)
- {
- if(all(worldPos < g_giProbes[i].m_aabbMax) && all(worldPos > g_giProbes[i].m_aabbMin))
- {
- break;
- }
- }
- const Bool probeFound = (i != probeCount);
- if(probeFound)
- {
- const GpuSceneGlobalIlluminationProbe probe = g_giProbes[i];
- return sampleGlobalIllumination<F32>(worldPos, worldNormal, probe, getBindlessTexture3DVec4(probe.m_volumeTexture), g_linearAnyClampSampler);
- }
- else
- {
- return 0.0;
- }
- # else
- constexpr SampleClipmapFlag flags =
- kSampleClipmapFlagBackfacingProbeRejection | kSampleClipmapFlagBiasSamplePointSurfaceNormal | kSampleClipmapFlagUsePreviousFrame;
- const IndirectDiffuseClipmapConstants idConsts = g_globalRendererConsts.m_indirectDiffuseClipmaps;
- const Vec3 irradiance =
- sampleClipmapIrradiance(worldPos, worldNormal, g_globalRendererConsts.m_cameraPosition, idConsts, g_linearAnyClampSampler, flags);
- return irradiance;
- # endif
- }
- # endif
- Vec4 main(VertOut input) : SV_TARGET0
- {
- const Vec2 uv = input.m_uv;
- const F32 depth = g_depthTex.SampleLevel(g_gbufferSampler, uv, 0.0).r;
- if(depth == 1.0f)
- {
- discard;
- }
- // Decode and process gbuffer
- GbufferInfo<F32> gbuffer = (GbufferInfo<F32>)0;
- unpackGBufferNoVelocity(g_gbufferTex0.SampleLevel(g_gbufferSampler, uv, 0.0), g_gbufferTex1.SampleLevel(g_gbufferSampler, uv, 0.0),
- g_gbufferTex2.SampleLevel(g_gbufferSampler, uv, 0.0), gbuffer);
- gbuffer.m_subsurface = max(gbuffer.m_subsurface, kSubsurfaceMin * 8.0);
- const Vec4 worldPos4 = mul(g_consts.m_invViewProjMat, Vec4(uvToNdc(uv), depth, 1.0));
- const Vec3 worldPos = worldPos4.xyz / worldPos4.w;
- // Compute diff
- const Vec3 diffC = diffuseLobe(gbuffer.m_diffuse);
- Vec3 outColor = gbuffer.m_emission;
- const Vec3 viewDir = normalize(g_consts.m_cameraPos - worldPos);
- ANKI_MAYBE_UNUSED(viewDir);
- # if INDIRECT_DIFFUSE
- outColor += getDiffuseIndirect(worldPos, gbuffer.m_normal) * gbuffer.m_diffuse;
- # endif
- // Dir light
- if(g_globalRendererConsts.m_directionalLight.m_active)
- {
- const F32 dist = length(g_consts.m_cameraPos - worldPos);
- F32 shadowFactor;
- if(dist < g_consts.m_dirLight.m_effectiveShadowDistance)
- {
- // Acceptable distance
- shadowFactor = computeShadowFactorDirLight<F32>(g_consts.m_dirLight.m_lightMatrix, worldPos, g_shadowMap, g_shadowMapSampler);
- }
- else
- {
- shadowFactor = 1.0;
- }
- const Vec3 l = -g_globalRendererConsts.m_directionalLight.m_direction;
- const F32 lambert = dot(l, gbuffer.m_normal);
- const F32 factor = shadowFactor * max(gbuffer.m_subsurface, lambert);
- # if SPECULAR == 1
- const Vec3 specC = specularIsotropicLobe(gbuffer.m_normal, gbuffer.m_f0, gbuffer.m_roughness, viewDir, l);
- # else
- const Vec3 specC = Vec3(0.0, 0.0, 0.0);
- # endif
- outColor += (specC + diffC) * g_globalRendererConsts.m_directionalLight.m_diffuseColor * factor;
- }
- // For all (other) lights
- const U32 lightCount = g_visibleLightIds[0];
- for(U32 i = 1; i <= lightCount; ++i)
- {
- const GpuSceneLight light = g_lights[g_visibleLightIds[i]];
- const Vec3 frag2Light = light.m_position - worldPos;
- const Vec3 l = normalize(frag2Light);
- const F32 nol = max(0.0, dot(gbuffer.m_normal, l));
- const F32 att = computeAttenuationFactor<F32>(light.m_radius, frag2Light);
- const F32 lambert = nol;
- const F32 spot = light.m_isSpotLight ? computeSpotFactor<F32>(l, light.m_outerCos, light.m_innerCos, light.m_direction) : 1.0f;
- const F32 factor = att * spot * max(lambert, gbuffer.m_subsurface);
- # if SPECULAR == 1
- const Vec3 specC = specularIsotropicLobe(gbuffer.m_normal, gbuffer.m_f0, gbuffer.m_roughness, viewDir, l);
- # else
- const Vec3 specC = Vec3(0.0, 0.0, 0.0);
- # endif
- outColor += (specC + diffC) * light.m_diffuseColor * factor;
- }
- return Vec4(outColor, 0.0);
- }
- #endif // ANKI_PIXEL_SHADER
|