1617a3babSopenharmony_ci/* 2617a3babSopenharmony_ciThe MIT License (MIT) 3617a3babSopenharmony_ci 4617a3babSopenharmony_ciCopyright (c) 2022 Google LLC 5617a3babSopenharmony_ciCopyright (c) 2022 Sascha Willems 6617a3babSopenharmony_ci 7617a3babSopenharmony_ciPermission is hereby granted, free of charge, to any person obtaining a copy 8617a3babSopenharmony_ciof this software and associated documentation files (the "Software"), to deal 9617a3babSopenharmony_ciin the Software without restriction, including without limitation the rights 10617a3babSopenharmony_cito use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11617a3babSopenharmony_cicopies of the Software, and to permit persons to whom the Software is 12617a3babSopenharmony_cifurnished to do so, subject to the following conditions: 13617a3babSopenharmony_ci 14617a3babSopenharmony_ciThe above copyright notice and this permission notice shall be included in all 15617a3babSopenharmony_cicopies or substantial portions of the Software. 16617a3babSopenharmony_ci 17617a3babSopenharmony_ciTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18617a3babSopenharmony_ciIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19617a3babSopenharmony_ciFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20617a3babSopenharmony_ciAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21617a3babSopenharmony_ciLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22617a3babSopenharmony_ciOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23617a3babSopenharmony_ciSOFTWARE. 24617a3babSopenharmony_ci*/ 25617a3babSopenharmony_ci 26617a3babSopenharmony_ciTexture2D textureposition : register(t1); 27617a3babSopenharmony_ciSamplerState samplerposition : register(s1); 28617a3babSopenharmony_ciTexture2D textureNormal : register(t2); 29617a3babSopenharmony_ciSamplerState samplerNormal : register(s2); 30617a3babSopenharmony_ciTexture2D textureAlbedo : register(t3); 31617a3babSopenharmony_ciSamplerState samplerAlbedo : register(s3); 32617a3babSopenharmony_ci// Depth from the light's point of view 33617a3babSopenharmony_ci//layout (binding = 5) uniform sampler2DShadow samplerShadowMap; 34617a3babSopenharmony_ciTexture2DArray textureShadowMap : register(t5); 35617a3babSopenharmony_ciSamplerState samplerShadowMap : register(s5); 36617a3babSopenharmony_ci 37617a3babSopenharmony_ci#define LIGHT_COUNT 3 38617a3babSopenharmony_ci#define SHADOW_FACTOR 0.25 39617a3babSopenharmony_ci#define AMBIENT_LIGHT 0.1 40617a3babSopenharmony_ci#define USE_PCF 41617a3babSopenharmony_ci 42617a3babSopenharmony_cistruct Light 43617a3babSopenharmony_ci{ 44617a3babSopenharmony_ci float4 position; 45617a3babSopenharmony_ci float4 target; 46617a3babSopenharmony_ci float4 color; 47617a3babSopenharmony_ci float4x4 viewMatrix; 48617a3babSopenharmony_ci}; 49617a3babSopenharmony_ci 50617a3babSopenharmony_cistruct UBO 51617a3babSopenharmony_ci{ 52617a3babSopenharmony_ci float4 viewPos; 53617a3babSopenharmony_ci Light lights[LIGHT_COUNT]; 54617a3babSopenharmony_ci int useShadows; 55617a3babSopenharmony_ci int displayDebugTarget; 56617a3babSopenharmony_ci}; 57617a3babSopenharmony_ci 58617a3babSopenharmony_cicbuffer ubo : register(b4) { UBO ubo; } 59617a3babSopenharmony_ci 60617a3babSopenharmony_cifloat textureProj(float4 P, float layer, float2 offset) 61617a3babSopenharmony_ci{ 62617a3babSopenharmony_ci float shadow = 1.0; 63617a3babSopenharmony_ci float4 shadowCoord = P / P.w; 64617a3babSopenharmony_ci shadowCoord.xy = shadowCoord.xy * 0.5 + 0.5; 65617a3babSopenharmony_ci 66617a3babSopenharmony_ci if (shadowCoord.z > -1.0 && shadowCoord.z < 1.0) 67617a3babSopenharmony_ci { 68617a3babSopenharmony_ci float dist = textureShadowMap.Sample(samplerShadowMap, float3(shadowCoord.xy + offset, layer)).r; 69617a3babSopenharmony_ci if (shadowCoord.w > 0.0 && dist < shadowCoord.z) 70617a3babSopenharmony_ci { 71617a3babSopenharmony_ci shadow = SHADOW_FACTOR; 72617a3babSopenharmony_ci } 73617a3babSopenharmony_ci } 74617a3babSopenharmony_ci return shadow; 75617a3babSopenharmony_ci} 76617a3babSopenharmony_ci 77617a3babSopenharmony_cifloat filterPCF(float4 sc, float layer) 78617a3babSopenharmony_ci{ 79617a3babSopenharmony_ci int2 texDim; int elements; int levels; 80617a3babSopenharmony_ci textureShadowMap.GetDimensions(0, texDim.x, texDim.y, elements, levels); 81617a3babSopenharmony_ci float scale = 1.5; 82617a3babSopenharmony_ci float dx = scale * 1.0 / float(texDim.x); 83617a3babSopenharmony_ci float dy = scale * 1.0 / float(texDim.y); 84617a3babSopenharmony_ci 85617a3babSopenharmony_ci float shadowFactor = 0.0; 86617a3babSopenharmony_ci int count = 0; 87617a3babSopenharmony_ci int range = 1; 88617a3babSopenharmony_ci 89617a3babSopenharmony_ci for (int x = -range; x <= range; x++) 90617a3babSopenharmony_ci { 91617a3babSopenharmony_ci for (int y = -range; y <= range; y++) 92617a3babSopenharmony_ci { 93617a3babSopenharmony_ci shadowFactor += textureProj(sc, layer, float2(dx*x, dy*y)); 94617a3babSopenharmony_ci count++; 95617a3babSopenharmony_ci } 96617a3babSopenharmony_ci 97617a3babSopenharmony_ci } 98617a3babSopenharmony_ci return shadowFactor / count; 99617a3babSopenharmony_ci} 100617a3babSopenharmony_ci 101617a3babSopenharmony_cifloat3 shadow(float3 fragcolor, float3 fragPos) { 102617a3babSopenharmony_ci for (int i = 0; i < LIGHT_COUNT; ++i) 103617a3babSopenharmony_ci { 104617a3babSopenharmony_ci float4 shadowClip = mul(ubo.lights[i].viewMatrix, float4(fragPos.xyz, 1.0)); 105617a3babSopenharmony_ci 106617a3babSopenharmony_ci float shadowFactor; 107617a3babSopenharmony_ci #ifdef USE_PCF 108617a3babSopenharmony_ci shadowFactor= filterPCF(shadowClip, i); 109617a3babSopenharmony_ci #else 110617a3babSopenharmony_ci shadowFactor = textureProj(shadowClip, i, float2(0.0, 0.0)); 111617a3babSopenharmony_ci #endif 112617a3babSopenharmony_ci 113617a3babSopenharmony_ci fragcolor *= shadowFactor; 114617a3babSopenharmony_ci } 115617a3babSopenharmony_ci return fragcolor; 116617a3babSopenharmony_ci} 117617a3babSopenharmony_ci 118617a3babSopenharmony_cifloat4 main([[vk::location(0)]] float2 inUV : TEXCOORD0) : SV_TARGET 119617a3babSopenharmony_ci{ 120617a3babSopenharmony_ci // Get G-Buffer values 121617a3babSopenharmony_ci float3 fragPos = textureposition.Sample(samplerposition, inUV).rgb; 122617a3babSopenharmony_ci float3 normal = textureNormal.Sample(samplerNormal, inUV).rgb; 123617a3babSopenharmony_ci float4 albedo = textureAlbedo.Sample(samplerAlbedo, inUV); 124617a3babSopenharmony_ci 125617a3babSopenharmony_ci float3 fragcolor; 126617a3babSopenharmony_ci 127617a3babSopenharmony_ci // Debug display 128617a3babSopenharmony_ci if (ubo.displayDebugTarget > 0) { 129617a3babSopenharmony_ci switch (ubo.displayDebugTarget) { 130617a3babSopenharmony_ci case 1: 131617a3babSopenharmony_ci fragcolor.rgb = shadow(float3(1.0, 1.0, 1.0), fragPos); 132617a3babSopenharmony_ci break; 133617a3babSopenharmony_ci case 2: 134617a3babSopenharmony_ci fragcolor.rgb = fragPos; 135617a3babSopenharmony_ci break; 136617a3babSopenharmony_ci case 3: 137617a3babSopenharmony_ci fragcolor.rgb = normal; 138617a3babSopenharmony_ci break; 139617a3babSopenharmony_ci case 4: 140617a3babSopenharmony_ci fragcolor.rgb = albedo.rgb; 141617a3babSopenharmony_ci break; 142617a3babSopenharmony_ci case 5: 143617a3babSopenharmony_ci fragcolor.rgb = albedo.aaa; 144617a3babSopenharmony_ci break; 145617a3babSopenharmony_ci } 146617a3babSopenharmony_ci return float4(fragcolor, 1.0); 147617a3babSopenharmony_ci } 148617a3babSopenharmony_ci 149617a3babSopenharmony_ci // Ambient part 150617a3babSopenharmony_ci fragcolor = albedo.rgb * AMBIENT_LIGHT; 151617a3babSopenharmony_ci 152617a3babSopenharmony_ci float3 N = normalize(normal); 153617a3babSopenharmony_ci 154617a3babSopenharmony_ci for(int i = 0; i < LIGHT_COUNT; ++i) 155617a3babSopenharmony_ci { 156617a3babSopenharmony_ci // Vector to light 157617a3babSopenharmony_ci float3 L = ubo.lights[i].position.xyz - fragPos; 158617a3babSopenharmony_ci // Distance from light to fragment position 159617a3babSopenharmony_ci float dist = length(L); 160617a3babSopenharmony_ci L = normalize(L); 161617a3babSopenharmony_ci 162617a3babSopenharmony_ci // Viewer to fragment 163617a3babSopenharmony_ci float3 V = ubo.viewPos.xyz - fragPos; 164617a3babSopenharmony_ci V = normalize(V); 165617a3babSopenharmony_ci 166617a3babSopenharmony_ci float lightCosInnerAngle = cos(radians(15.0)); 167617a3babSopenharmony_ci float lightCosOuterAngle = cos(radians(25.0)); 168617a3babSopenharmony_ci float lightRange = 100.0; 169617a3babSopenharmony_ci 170617a3babSopenharmony_ci // Direction vector from source to target 171617a3babSopenharmony_ci float3 dir = normalize(ubo.lights[i].position.xyz - ubo.lights[i].target.xyz); 172617a3babSopenharmony_ci 173617a3babSopenharmony_ci // Dual cone spot light with smooth transition between inner and outer angle 174617a3babSopenharmony_ci float cosDir = dot(L, dir); 175617a3babSopenharmony_ci float spotEffect = smoothstep(lightCosOuterAngle, lightCosInnerAngle, cosDir); 176617a3babSopenharmony_ci float heightAttenuation = smoothstep(lightRange, 0.0f, dist); 177617a3babSopenharmony_ci 178617a3babSopenharmony_ci // Diffuse lighting 179617a3babSopenharmony_ci float NdotL = max(0.0, dot(N, L)); 180617a3babSopenharmony_ci float3 diff = NdotL.xxx; 181617a3babSopenharmony_ci 182617a3babSopenharmony_ci // Specular lighting 183617a3babSopenharmony_ci float3 R = reflect(-L, N); 184617a3babSopenharmony_ci float NdotR = max(0.0, dot(R, V)); 185617a3babSopenharmony_ci float3 spec = (pow(NdotR, 16.0) * albedo.a * 2.5).xxx; 186617a3babSopenharmony_ci 187617a3babSopenharmony_ci fragcolor += float3((diff + spec) * spotEffect * heightAttenuation) * ubo.lights[i].color.rgb * albedo.rgb; 188617a3babSopenharmony_ci } 189617a3babSopenharmony_ci 190617a3babSopenharmony_ci // Shadow calculations in a separate pass 191617a3babSopenharmony_ci if (ubo.useShadows > 0) 192617a3babSopenharmony_ci { 193617a3babSopenharmony_ci fragcolor = shadow(fragcolor, fragPos); 194617a3babSopenharmony_ci } 195617a3babSopenharmony_ci 196617a3babSopenharmony_ci return float4(fragcolor, 1); 197617a3babSopenharmony_ci} 198