added capsule reflection blockers

This commit is contained in:
Turánszki János
2025-05-26 07:54:29 +02:00
parent 96f267e14f
commit 8b1535ca06
6 changed files with 41 additions and 46 deletions
@@ -1047,7 +1047,7 @@ struct alignas(16) ShaderFrustumCorners
#endif // __cplusplus
};
static const float CAPSULE_SHADOW_AFFECTION_RANGE = 2; // how far away the capsule shadow can reach outside of their own radius
static const float CAPSULE_SHADOW_AFFECTION_RANGE = 4; // how far away the capsule shadow can reach outside of their own radius
static const float CAPSULE_SHADOW_BOLDEN = 1.1f; // multiplier for capsule shadow capsule radiuses globally
static const uint SHADER_ENTITY_COUNT = 256;
+7 -6
View File
@@ -750,6 +750,7 @@ struct PrimitiveID
#define HEMISPHERE_SAMPLING_PDF rcp(2 * PI)
#define sqr(a) ((a)*(a))
#define pow3(a) ((a)*(a)*(a))
#define pow4(a) ((a)*(a)*(a)*(a))
#define pow5(a) ((a)*(a)*(a)*(a)*(a))
#define pow8(a) ((a)*(a)*(a)*(a)*(a)*(a)*(a)*(a))
@@ -881,31 +882,31 @@ inline uint4 align(uint4 value, uint4 alignment)
inline float2 uv_to_clipspace(in float2 uv)
{
float2 clipspace = uv * 2 - 1;
float2 clipspace = mad(uv, 2, -1);
clipspace.y *= -1;
return clipspace;
}
inline half2 uv_to_clipspace(in half2 uv)
{
half2 clipspace = uv * 2 - 1;
half2 clipspace = mad(uv, 2, -1);
clipspace.y *= -1;
return clipspace;
}
inline float2 clipspace_to_uv(in float2 clipspace)
{
return clipspace * float2(0.5, -0.5) + 0.5;
return mad(clipspace, float2(0.5, -0.5), 0.5);
}
inline float3 clipspace_to_uv(in float3 clipspace)
{
return clipspace * float3(0.5, -0.5, 1) + float3(0.5, 0.5, 0);
return mad(clipspace, float3(0.5, -0.5, 1), float3(0.5, 0.5, 0));
}
inline half2 clipspace_to_uv(in half2 clipspace)
{
return clipspace * half2(0.5, -0.5) + 0.5;
return mad(clipspace, half2(0.5, -0.5), 0.5);
}
inline half3 clipspace_to_uv(in half3 clipspace)
{
return clipspace * half3(0.5, -0.5, 1) + half3(0.5, 0.5, 0);
return mad(clipspace, half3(0.5, -0.5, 1), half3(0.5, 0.5, 0));
}
inline half3 GetSunColor() { return unpack_half3(GetWeather().sun_color); } // sun color with intensity applied
-2
View File
@@ -2,8 +2,6 @@
#include "cullingShaderHF.hlsli"
#include "lightingHF.hlsli"
#define entityCount (GetFrame().entity_culling_count)
RWStructuredBuffer<uint> entityTiles : register(u0);
// Group shared variables.
+15 -7
View File
@@ -557,16 +557,18 @@ inline void TiledLighting(inout Surface surface, inout Lighting lighting, uint f
}
}
// Capsule shadows:
// Capsule shadows and capsule reflection blockers:
[branch]
if ((GetFrame().options & OPTION_BIT_CAPSULE_SHADOW_ENABLED) && !surface.IsCapsuleShadowDisabled() && !forces().empty()) // capsule shadows are contained in forces array for now...
{
half4 cone = half4(surface.dominant_lightdir, GetCapsuleShadowAngle());
half4 occlusion_cone = half4(surface.dominant_lightdir, GetCapsuleShadowAngle());
half4 reflection_cone = half4(surface.R, max(0.001, sqr(surface.roughness) * 0.5));
half capsuleshadow = 1;
half capsulereflection = 1;
// Loop through light buckets in the tile:
ShaderEntityIterator iterator = forces();
for (uint bucket = iterator.first_bucket(); (bucket <= iterator.last_bucket()) && (capsuleshadow > 0); ++bucket)
for (uint bucket = iterator.first_bucket(); (bucket <= iterator.last_bucket()) && (capsuleshadow > 0 || capsulereflection > 0); ++bucket)
{
uint bucket_bits = load_entitytile(flatTileIndex + bucket);
bucket_bits = iterator.mask_entity(bucket, bucket_bits);
@@ -577,7 +579,7 @@ inline void TiledLighting(inout Surface surface, inout Lighting lighting, uint f
#endif // ENTITY_TILE_UNIFORM
[loop]
while ((bucket_bits != 0) && (capsuleshadow > 0))
while ((bucket_bits != 0) && (capsuleshadow > 0 || capsulereflection > 0))
{
// Retrieve global entity index from local bucket, then remove bit from local bucket:
const uint bucket_bit_index = firstbitlow(bucket_bits);
@@ -591,21 +593,27 @@ inline void TiledLighting(inout Surface surface, inout Lighting lighting, uint f
float3 A = entity.position;
float3 B = entity.GetColliderTip();
half radius = entity.GetRange() * CAPSULE_SHADOW_BOLDEN;
half occ = directionalOcclusionCapsule(surface.P, A, B, radius, cone);
half occ = directionalOcclusionCapsule(surface.P, A, B, radius, occlusion_cone);
half ref = directionalOcclusionCapsule(surface.P, A, B, radius, reflection_cone);
// attenuation based on capsule-sphere:
float3 center = lerp(A, B, 0.5);
half range = distance(center, A) + radius + CAPSULE_SHADOW_AFFECTION_RANGE;
half range2 = range * range;
half dist2 = distance_squared(surface.P, center);
occ = 1 - saturate((1 - occ) * saturate(attenuation_pointlight(dist2, range, range2)));
occ = 1 - saturate((1 - occ) * saturate(attenuation_pointlight(distance_squared(surface.P, center), range, range2)));
ref = 1 - saturate((1 - ref) * saturate(attenuation_pointlight(distance_squared(closest_point_on_line(surface.P, surface.P + surface.R, center), center), range, range2)));
capsuleshadow *= occ;
capsulereflection *= ref;
}
}
capsuleshadow = lerp(capsuleshadow, 1, GetCapsuleShadowFade());
capsuleshadow = saturate(capsuleshadow);
surface.occlusion *= capsuleshadow;
capsulereflection = pow4(capsulereflection);
lighting.direct.specular *= capsulereflection;
lighting.indirect.specular *= capsulereflection;
}
}
+17 -29
View File
@@ -9922,42 +9922,30 @@ void ComputeTiledLightCulling(
BindCommonResources(cmd);
// Perform the culling
device->EventBegin("Entity Culling", cmd);
if (GetDebugLightCulling() && debugUAV.IsValid())
{
device->EventBegin("Entity Culling", cmd);
if (GetDebugLightCulling() && debugUAV.IsValid())
{
device->BindComputeShader(&shaders[GetAdvancedLightCulling() ? CSTYPE_LIGHTCULLING_ADVANCED_DEBUG : CSTYPE_LIGHTCULLING_DEBUG], cmd);
device->BindUAV(&debugUAV, 3, cmd);
}
else
{
device->BindComputeShader(&shaders[GetAdvancedLightCulling() ? CSTYPE_LIGHTCULLING_ADVANCED : CSTYPE_LIGHTCULLING], cmd);
}
const GPUResource* uavs[] = {
&res.entityTiles,
};
device->BindUAVs(uavs, 0, arraysize(uavs), cmd);
device->Dispatch(res.tileCount.x, res.tileCount.y, 1, cmd);
{
GPUBarrier barriers[] = {
GPUBarrier::Buffer(&res.entityTiles, ResourceState::UNORDERED_ACCESS, ResourceState::SHADER_RESOURCE),
};
device->Barrier(barriers, arraysize(barriers), cmd);
}
device->EventEnd(cmd);
device->BindComputeShader(&shaders[GetAdvancedLightCulling() ? CSTYPE_LIGHTCULLING_ADVANCED_DEBUG : CSTYPE_LIGHTCULLING_DEBUG], cmd);
device->BindUAV(&debugUAV, 3, cmd);
}
else
{
device->BindComputeShader(&shaders[GetAdvancedLightCulling() ? CSTYPE_LIGHTCULLING_ADVANCED : CSTYPE_LIGHTCULLING], cmd);
}
device->BindUAV(&res.entityTiles, 0, cmd);
device->Dispatch(res.tileCount.x, res.tileCount.y, 1, cmd);
device->Barrier(GPUBarrier::Buffer(&res.entityTiles, ResourceState::UNORDERED_ACCESS, ResourceState::SHADER_RESOURCE), cmd);
device->EventEnd(cmd);
// Unbind from UAV slots:
GPUResource empty;
const GPUResource* uavs[] = {
&empty,
&empty
};
device->BindUAVs(uavs, 0, arraysize(uavs), cmd);
+1 -1
View File
@@ -9,7 +9,7 @@ namespace wi::version
// minor features, major updates, breaking compatibility changes
const int minor = 71;
// minor bug fixes, alterations, refactors, updates
const int revision = 776;
const int revision = 777;
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);