render: march sun shafts at quarter res with reach-proportional steps
This commit is contained in:
parent
4d616e4d45
commit
ceb98c34ec
4 changed files with 621 additions and 589 deletions
|
|
@ -52,7 +52,8 @@ cbuffer C : register(b0) {
|
|||
// strength / phase g, p1.xy = proj m22 / m32, vp/vs0/vs1/vs2 = the
|
||||
// row-vector inverse view-projection (world = clip * M).
|
||||
float4 vp; // tonemap/linearize: x = |m00|, y = |m11|, z = m22, w = m32
|
||||
float4 vs0; // tonemap: w = shaft intensity (xyz unused)
|
||||
float4 vs0; // tonemap: x = shaft plane resolution divisor (>= 2),
|
||||
// w = shaft intensity (yz unused)
|
||||
float4 vs1; // tonemap: xyz = haze tint (xe space), w = haze intensity
|
||||
float4 vs2; // tonemap: xyz = sun direction in AO view space (toward the
|
||||
// sun), w = haze density (1 / view unit)
|
||||
|
|
@ -248,7 +249,14 @@ float4 ps_vol_shafts(VSOut i) : SV_Target {
|
|||
float dist = length(ray);
|
||||
float3 rdir = ray / max(dist, 1e-4);
|
||||
float reach = min(dist, src.w);
|
||||
float steps = clamp(p0.x, 8.0, 64.0);
|
||||
// Constant per-meter sample density: a short ray to near geometry needs
|
||||
// proportionally fewer steps for the same marched quality (the fixed
|
||||
// count oversampled a 5 m ray 8x versus the full-reach case), and the
|
||||
// path-fraction scale keeps near-surface terms small enough that the
|
||||
// extra variance stays under the tent blur.
|
||||
float steps_max = clamp(p0.x, 8.0, 64.0);
|
||||
float steps = clamp(ceil(steps_max * reach / max(src.w, 1.0)), 8.0,
|
||||
steps_max);
|
||||
float jitter = Ign(i.pos.xy);
|
||||
float lit = 0.0;
|
||||
float tot = 0.0;
|
||||
|
|
@ -400,7 +408,8 @@ float4 ps_tonemap(VSOut i) : SV_Target {
|
|||
bool sc_vol = sc_mask < 0 || (sc_mask & 64) != 0;
|
||||
if (vs0.w > 0.0 && sc_vol) {
|
||||
float dpix = lin_depth.SampleLevel(smp_point, i.uv, 0);
|
||||
float2 vt = size.zw * 2.0; // one shaft-plane texel in uv
|
||||
// One shaft-plane texel in uv (vs0.x = the march resolution divisor).
|
||||
float2 vt = size.zw * max(vs0.x, 2.0);
|
||||
float2 base = (floor(i.uv / vt - 0.5) + 0.5) * vt;
|
||||
float2 f = saturate((i.uv - base) / vt);
|
||||
float acc = 0.0;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -249,10 +249,20 @@ REXCVAR_DEFINE_DOUBLE(skate3_native_render_scene_shafts_reach, 40.0, "Skate 3",
|
|||
.range(5.0, 300.0)
|
||||
.lifecycle(rex::cvar::Lifecycle::kHotReload);
|
||||
REXCVAR_DEFINE_INT32(skate3_native_render_scene_shafts_steps, 64, "Skate 3",
|
||||
"Sun-shaft march steps per pixel (half-res pass). More steps "
|
||||
"resolve thinner shadow volumes at proportional GPU cost.")
|
||||
"Sun-shaft march step ceiling per pixel; rays shorter than "
|
||||
"the full reach take proportionally fewer steps at the same "
|
||||
"per-meter density. More steps resolve thinner shadow "
|
||||
"volumes at proportional GPU cost.")
|
||||
.range(8, 64)
|
||||
.lifecycle(rex::cvar::Lifecycle::kHotReload);
|
||||
REXCVAR_DEFINE_INT32(skate3_native_render_scene_shafts_res, 4, "Skate 3",
|
||||
"Sun-shaft march resolution divisor (2 = half res, 4 = "
|
||||
"quarter res). The march output is low frequency (jittered "
|
||||
"average under a tent blur) and upsamples depth-aware, so "
|
||||
"higher divisors trade little quality for a proportional "
|
||||
"GPU saving.")
|
||||
.range(2, 8)
|
||||
.lifecycle(rex::cvar::Lifecycle::kHotReload);
|
||||
REXCVAR_DEFINE_BOOL(skate3_native_render_scene_sun_override, false, "Skate 3",
|
||||
"Lighting lab: replace the captured sun direction with the "
|
||||
"azimuth/elevation cvars. Every per-frame light transform is "
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ REXCVAR_DECLARE(bool, skate3_native_render_scene_shafts);
|
|||
REXCVAR_DECLARE(double, skate3_native_render_scene_shafts_intensity);
|
||||
REXCVAR_DECLARE(double, skate3_native_render_scene_shafts_reach);
|
||||
REXCVAR_DECLARE(int32_t, skate3_native_render_scene_shafts_steps);
|
||||
REXCVAR_DECLARE(int32_t, skate3_native_render_scene_shafts_res);
|
||||
REXCVAR_DECLARE(bool, skate3_native_render_scene_ssao_debug);
|
||||
REXCVAR_DECLARE(bool, skate3_native_render_scene_ssao_full_res);
|
||||
REXCVAR_DECLARE(double, skate3_native_render_scene_ssao_intensity);
|
||||
|
|
@ -1087,9 +1088,13 @@ bool ApplyVolumetricPass(const NativeGuestOutputRenderContext& context,
|
|||
}
|
||||
}
|
||||
|
||||
// ---- Shaft planes (half res, march + blurred), rebuilt on resize.
|
||||
const uint32_t vw = std::max(1u, (width + 1) / 2);
|
||||
const uint32_t vh = std::max(1u, (height + 1) / 2);
|
||||
// ---- Shaft planes (march + blurred), rebuilt on resize or divisor
|
||||
// change; the tonemap upsample reads the divisor from vs0.x.
|
||||
const uint32_t vol_div = uint32_t(
|
||||
std::clamp<int32_t>(REXCVAR_GET(skate3_native_render_scene_shafts_res),
|
||||
2, 8));
|
||||
const uint32_t vw = std::max(1u, (width + vol_div - 1) / vol_div);
|
||||
const uint32_t vh = std::max(1u, (height + vol_div - 1) / vol_div);
|
||||
if (shafts &&
|
||||
(g_r.vol_width != vw || g_r.vol_height != vh || g_r.vol_tex == nullptr ||
|
||||
g_r.vol_tex_b == nullptr)) {
|
||||
|
|
@ -1272,7 +1277,7 @@ bool ApplyVolumetricPass(const NativeGuestOutputRenderContext& context,
|
|||
g_r.vol_rows[1] = std::fabs(pr[5]);
|
||||
g_r.vol_rows[2] = pr[10];
|
||||
g_r.vol_rows[3] = pr[14];
|
||||
g_r.vol_rows[4] = 0.0f;
|
||||
g_r.vol_rows[4] = float(vol_div);
|
||||
g_r.vol_rows[5] = 0.0f;
|
||||
g_r.vol_rows[6] = 0.0f;
|
||||
g_r.vol_rows[7] = shaft_plane ? shaft_int : 0.0f;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue