diff --git a/Res/Shader/volume.hlsl b/Res/Shader/volume.hlsl index 3f370cb0..82b618a2 100644 --- a/Res/Shader/volume.hlsl +++ b/Res/Shader/volume.hlsl @@ -59,6 +59,31 @@ float get_value_coord(inout pnanovdb_readaccessor_t acc, float3 pos) return pnanovdb_read_float(buf, address); } +uint get_dim_coord(inout pnanovdb_readaccessor_t acc, float3 pos) +{ + pnanovdb_vec3_t p = pos; + pnanovdb_coord_t ijk = pnanovdb_hdda_pos_to_ijk(p); + return pnanovdb_readaccessor_get_dim(PNANOVDB_GRID_TYPE_FLOAT, buf, acc, ijk); +} + +bool get_hdda_hit(inout pnanovdb_readaccessor_t acc, inout float tmin, float3 origin, float3 direction, float tmax, out float valueAtHit) +{ + pnanovdb_vec3_t p_origin = origin; + pnanovdb_vec3_t p_direction = direction; + float thit; + bool hit = pnanovdb_hdda_tree_marcher( + PNANOVDB_GRID_TYPE_FLOAT, + buf, + acc, + p_origin, tmin, + p_direction, tmax, + thit, + valueAtHit + ); + tmin = thit; + return hit; +} + PSInput MainVS(VSInput input) { PSInput output; @@ -100,19 +125,45 @@ float4 MainPS(PSInput input) : SV_TARGET float3 color = float3(0, 0, 0); float transmittance = 1.0; + float not_used; + bool hit = get_hdda_hit(volume.acc, tmin, _CameraPos, rayDir, tmax, not_used); + if (!hit) { return float4(0, 0, 0, 0); } + + float skip = 0; + for (uint i = 0; i < _MaxSteps; i++) { - float t = tmin + i * _StepSize; - if (t > tmax || transmittance < 0.01) break; + if (tmin >= tmax || transmittance < 0.01) break; - float3 worldPos = _CameraPos + rayDir * t; + float3 worldPos = _CameraPos + rayDir * tmin; + + uint dim = get_dim_coord(volume.acc, worldPos); + if (dim > 1) { + float skip_step = 15.0; + tmin += skip_step; + skip = skip_step; + continue; + } float density = get_value_coord(volume.acc, worldPos) * _DensityScale; - if (density > 0.001) { - float3 S = density * float3(1, 1, 1); - color += transmittance * S * _StepSize; - transmittance *= exp(-density * _StepSize); + if (density < 0.001) { + float skip_step = 5.0; + tmin += skip_step; + skip = skip_step; + continue; } + + if (skip > 0) { + tmin -= skip * 0.8; + worldPos = _CameraPos + rayDir * tmin; + skip = 0; + } + + float3 S = density * float3(1, 1, 1); + color += transmittance * S * _StepSize; + transmittance *= exp(-density * _StepSize); + + tmin += _StepSize; } float alpha = 1.0 - transmittance;