| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- // Copyright (C) 2009-2020, 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 LIGHT_TYPE 0 1 2
- #pragma anki mutator SPECULAR 0 1
- #define POINT_LIGHT_TYPE 0
- #define SPOT_LIGHT_TYPE 1
- #define DIR_LIGHT_TYPE 2
- // VERT
- #pragma anki start vert
- #include <shaders/Common.glsl>
- out gl_PerVertex
- {
- Vec4 gl_Position;
- };
- #if LIGHT_TYPE == DIR_LIGHT_TYPE
- void main()
- {
- Vec2 uv = Vec2(gl_VertexID & 1, gl_VertexID >> 1) * 2.0;
- Vec2 pos = uv * 2.0 - 1.0;
- gl_Position = Vec4(pos, 0.0, 1.0);
- }
- #else
- layout(location = 0) in Vec3 in_position;
- layout(set = 0, binding = 0, row_major) uniform u0_
- {
- Mat4 u_mvp;
- };
- void main()
- {
- gl_Position = u_mvp * Vec4(in_position, 1.0);
- }
- #endif
- #pragma anki end
- // FRAG
- #pragma anki start frag
- #include <shaders/Pack.glsl>
- #include <shaders/LightFunctions.glsl>
- #include <shaders/glsl_cpp_common/TraditionalDeferredShading.h>
- layout(location = 0) out Vec3 out_color;
- layout(set = 0, binding = 1, row_major) uniform u1_
- {
- #if LIGHT_TYPE == POINT_LIGHT_TYPE
- DeferredPointLightUniforms u_unis;
- #elif LIGHT_TYPE == SPOT_LIGHT_TYPE
- DeferredSpotLightUniforms u_unis;
- #elif LIGHT_TYPE == DIR_LIGHT_TYPE
- DeferredDirectionalLightUniforms u_unis;
- #else
- # error See file
- #endif
- };
- layout(set = 0, binding = 2) uniform sampler u_msSampler;
- layout(set = 0, binding = 3) uniform texture2D u_msRt0;
- layout(set = 0, binding = 4) uniform texture2D u_msRt1;
- layout(set = 0, binding = 5) uniform texture2D u_msRt2;
- layout(set = 0, binding = 6) uniform texture2D u_msDepthRt;
- #if LIGHT_TYPE == DIR_LIGHT_TYPE
- layout(set = 0, binding = 7) uniform samplerShadow u_shadowMapSampler;
- layout(set = 0, binding = 8) uniform texture2D u_shadowMap;
- #endif
- void main()
- {
- // Compute UV coordinates
- const Vec2 uvToRead = fma(Vec2(gl_FragCoord.xy), u_unis.m_inputTexUvScale, u_unis.m_inputTexUvBias);
- const Vec2 uvToWrite = fma(Vec2(gl_FragCoord.xy), u_unis.m_fbUvScale, u_unis.m_fbUvBias);
- const F32 depth = textureLod(u_msDepthRt, u_msSampler, uvToRead, 0.0).r;
- #if LIGHT_TYPE != DIR_LIGHT_TYPE
- // Do manual depth test
- if(gl_FragCoord.z < depth)
- {
- discard;
- }
- #endif
- // Decode and process gbuffer
- GbufferInfo gbuffer;
- readGBuffer(u_msRt0, u_msRt1, u_msRt2, u_msSampler, uvToRead, 0.0, gbuffer);
- gbuffer.m_subsurface = max(gbuffer.m_subsurface, SUBSURFACE_MIN * 8.0);
- const Vec4 worldPos4 = u_unis.m_invViewProjMat * Vec4(UV_TO_NDC(uvToWrite), depth, 1.0);
- const Vec3 worldPos = worldPos4.xyz / worldPos4.w;
- // Compute diff
- const Vec3 diffC = diffuseLambert(gbuffer.m_diffuse);
- // Compute spec
- const Vec3 viewDir = normalize(u_unis.m_camPos - worldPos);
- #if LIGHT_TYPE == DIR_LIGHT_TYPE
- const Vec3 l = -u_unis.m_lightDir;
- #else
- const Vec3 frag2Light = u_unis.m_position - worldPos;
- const Vec3 l = normalize(frag2Light);
- const F32 nol = max(0.0, dot(gbuffer.m_normal, l));
- #endif
- #if SPECULAR == 1
- const Vec3 specC = computeSpecularColorBrdf(gbuffer, viewDir, l);
- #else
- const Vec3 specC = Vec3(0.0);
- #endif
- // Compute factors
- #if LIGHT_TYPE == POINT_LIGHT_TYPE
- const F32 att = computeAttenuationFactor(u_unis.m_oneOverSquareRadius, frag2Light);
- const F32 lambert = nol;
- const F32 factor = att * max(lambert, gbuffer.m_subsurface);
- #elif LIGHT_TYPE == SPOT_LIGHT_TYPE
- const F32 att = computeAttenuationFactor(u_unis.m_oneOverSquareRadius, frag2Light);
- const F32 lambert = nol;
- const F32 spot = computeSpotFactor(l, u_unis.m_outerCos, u_unis.m_innerCos, u_unis.m_lightDir);
- const F32 factor = att * spot * max(lambert, gbuffer.m_subsurface);
- #else
- const F32 linearDepth = linearizeDepth(depth, u_unis.m_near, u_unis.m_far);
- F32 shadowFactor;
- if(linearDepth * (u_unis.m_far - u_unis.m_near) < u_unis.m_effectiveShadowDistance)
- {
- // Acceptable distance
- shadowFactor = computeShadowFactorDirLight(u_unis.m_lightMatrix, worldPos, u_shadowMap, u_shadowMapSampler);
- }
- else
- {
- shadowFactor = 1.0;
- }
- const F32 lambert = dot(l, gbuffer.m_normal);
- const F32 factor = shadowFactor * max(gbuffer.m_subsurface, lambert);
- #endif
- out_color = gbuffer.m_diffuse * gbuffer.m_emission;
- out_color += (specC + diffC) * u_unis.m_diffuseColor * factor;
- }
- #pragma anki end
|