Skip to content

Commit bcfbc73

Browse files
committed
Merge branch 'dev/adunn/particle_features' into 'main'
RTX-Particles (part 2) - Visual Features See merge request lightspeedrtx/dxvk-remix-nv!1564
2 parents fec440c + e830103 commit bcfbc73

30 files changed

+656
-163
lines changed

RtxOptions.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,18 +498,29 @@ Tables below enumerate all the options and their defaults set by RTX Remix. Note
498498
|rtx.orthographicIsUI|bool|True|When enabled, draw calls that are orthographic will be considered as UI\.|
499499
|rtx.particleSoftnessFactor|float|0.05|Multiplier for the view distance that is used to calculate the particle blending range\.|
500500
|rtx.particles.enable|bool|True|Enables dust particle simulation and rendering\.|
501+
|rtx.particles.globalPreset.alignParticlesToVelocity|bool|False|Rotates the particles such that they are always aligned with their direction of travel, in this mode we ignore rotation speed\.|
502+
|rtx.particles.globalPreset.collisionRestitution|float|0.5|The fraction of velocity retained after a collision with scene geometry\. 1\.0 = perfectly elastic \(no speed loss\), 0\.0 = completely inelastic \(velocity zeroed\)\. Values outside \[0,1\] will be clamped to this range\.|
503+
|rtx.particles.globalPreset.collisionThickness|float|5|The maximum penetration depth \(in world units\) at which a particle will still collide with geometry\. Particles that penetrate deeper than this value are considered to have passed through thin objects and will not collide\.|
504+
|rtx.particles.globalPreset.enableCollisionDetection|bool|False|Enables particle collisions with the world\.|
505+
|rtx.particles.globalPreset.enableMotionTrail|bool|False|Elongates the particle with respect to velocity, texture edges are preserved, with only the center being stretched which provides a motion blur like effect on the particles themselves\. This will automatically align particles rotation with their individual velocitys \(similar to rtx\.particles\.globalPreset\.alignParticlesToVelocity\) and so rotation parameters are no longer taken into account when this setting is enabled\.|
501506
|rtx.particles.globalPreset.gravityForce|float|-0.5|Net influence of gravity acting on each particle \(meters per second squared\)\.|
507+
|rtx.particles.globalPreset.initialVelocityConeAngleDegrees|float|0|Specifies the half angle, in degrees, of the random emission cone around the triangles surface normal when spawning a new particle\. A value in the range of 0 to 180 degrees is expected\.|
502508
|rtx.particles.globalPreset.initialVelocityFromNormal|float|10|Initial speed to apply on spawn \(units/sec\) along the normal vector of the spawning triangle\.|
503509
|rtx.particles.globalPreset.maxParticleLife|float|6|Maximum lifetime \(in seconds\) to give to a particle when spawned\.|
504510
|rtx.particles.globalPreset.maxParticleSize|float|3|Maximum size \(in world units\) to give to a particle when spawned\.|
511+
|rtx.particles.globalPreset.maxRotationSpeed|float|1|Maximum rotation speed \(in revolutions per second\) to give to a particle when spawned\.|
512+
|rtx.particles.globalPreset.maxSpawnColor|float4|1, 1, 1, 1|Minimum range of the color to tint a particle with when spawned\.|
505513
|rtx.particles.globalPreset.maxSpeed|float|3|Maximum speed of a particle in world space\.|
506514
|rtx.particles.globalPreset.minParticleLife|float|3|Minimum lifetime \(in seconds\) to give to a particle when spawned\.|
507515
|rtx.particles.globalPreset.minParticleSize|float|1|Minimum size \(in world units\) to give to a particle when spawned\.|
516+
|rtx.particles.globalPreset.minRotationSpeed|float|0.1|Minimum rotation speed \(in revolutions per second\) to give to a particle when spawned\.|
517+
|rtx.particles.globalPreset.minSpawnColor|float4|1, 1, 1, 1|Minimum range of the color to tint a particle with when spawned\.|
518+
|rtx.particles.globalPreset.motionTrailMultiplier|float|1|When enableMotionTrail is set to enabled, this value can be used to increase \(or decrease\) the length of the tail artificially, which is determined by the velocity\. A value of 1 \(the default\) will ensure each particle is the exact size of the motion over the previous frame\. Values geater than 1 will increase that size linearly\. Likewise for smaller than 1\. 0 and below is an invalid value\.|
508519
|rtx.particles.globalPreset.numberOfParticlesPerMaterial|int|98304|Maximum number of particles to simulate per material simultaneously\. There is a performance consideration, lower numbers are more performant\. Ideal is to tune this number for your specific needs\.|
509-
|rtx.particles.globalPreset.opacityMultiplier|float|1|Multiplier for the opacity of a particle in relation to the opacity of the triangle spawning the particle\.|
510520
|rtx.particles.globalPreset.spawnRatePerSecond|int|100|Number of particles \(per system\) to spawn per second on average\.|
511521
|rtx.particles.globalPreset.turbulenceAmplitude|float|5|How much turbulence influences the force of a particle\.|
512522
|rtx.particles.globalPreset.turbulenceFrequency|float|0.05|The rate of change of turbulence forces\.|
523+
|rtx.particles.globalPreset.useSpawnTexcoords|bool|False|Use the texcoords of the emitter mesh when spawning particles\.|
513524
|rtx.particles.globalPreset.useTurbulence|bool|True|Enable turbulence simulation\.|
514525
|rtx.particles.timeScale|float|1|Time modifier, can be used to slow/speed up time\.|
515526
|rtx.pathMaxBounces|int|4|The maximum number of indirect bounces the path will be allowed to complete\. Must be \< 16\.<br>Higher values result in better indirect lighting quality due to biasing the signal less, lower values result in better performance\.<br>Very high values are not recommended however as while long paths may be technically needed for unbiased rendering, in practice the contributions from higher bounces have diminishing returns\.|

meson.build

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -707,7 +707,7 @@ if dxvk_is_ninja
707707
command : [recursive_copy_path,
708708
join_paths(usd_lib_path, 'lib/usd/'),
709709
join_paths(output_path, 'usd/')] )
710-
copy_usd_dll = []
710+
copy_usd_dll = []
711711
foreach ulib : nvusd_deplibs
712712
copy_usd_dll += custom_target('copy_usd_dll_' + ulib + '_' + target_suffix,
713713
output : ['copy_usd_dll_' + ulib + '_' + target_suffix],
@@ -719,37 +719,37 @@ if dxvk_is_ninja
719719

720720
copy_usd_plugins_dlls = []
721721

722-
copy_usd_plugins_dlls += custom_target('copy_usd_plugins_json_' + target_suffix,
722+
copy_usd_plugins_dlls += custom_target('copy_usd_plugins_json_' + target_suffix,
723723
output : ['copy_usd_plugins_json_' + target_suffix],
724724
command : [copy_script_path,
725725
join_paths(global_src_root_norm, 'src', 'usd-plugins'),
726726
join_paths(output_path, 'usd/plugins/'),
727727
'plugInfo.json'] )
728728
foreach usd_plugin : usd_plugins
729-
copy_usd_plugins_dlls += custom_target('copy_usd_plugins_' + usd_plugin.name() + '_dll_' + target_suffix,
730-
depends : [ usd_plugin ],
729+
copy_usd_plugins_dlls += custom_target('copy_usd_plugins_' + usd_plugin.name() + '_dll_' + target_suffix,
730+
depends : [ usd_plugin ],
731731
output : ['copy_usd_plugins_' + usd_plugin.name() + '_dll_' + target_suffix],
732732
command : [copy_script_path,
733733
fs.parent(usd_plugin.full_path()) ,
734734
join_paths(output_path, 'usd/plugins', usd_plugin.name() + '/'),
735735
usd_plugin.name() + '.dll'] )
736736

737-
copy_usd_plugins_dlls += custom_target('copy_usd_plugins_' + usd_plugin.name() + '_json_' + target_suffix,
738-
depends : [ usd_plugin ],
737+
copy_usd_plugins_dlls += custom_target('copy_usd_plugins_' + usd_plugin.name() + '_json_' + target_suffix,
738+
depends : [ usd_plugin ],
739739
output : ['copy_usd_plugins_' + usd_plugin.name() + '_json_' + target_suffix],
740740
command : [copy_script_path,
741741
fs.parent(usd_plugin.full_path()),
742742
join_paths(output_path, 'usd/plugins', usd_plugin.name(), 'resources/'),
743743
'plugInfo.json'] )
744744

745-
copy_usd_plugins_dlls += custom_target('copy_usd_plugins_' + usd_plugin.name() + '_schema_' + target_suffix,
746-
depends : [ usd_plugin ],
745+
copy_usd_plugins_dlls += custom_target('copy_usd_plugins_' + usd_plugin.name() + '_schema_' + target_suffix,
746+
depends : [ usd_plugin ],
747747
output : ['copy_usd_plugins_' + usd_plugin.name() + '_schema_' + target_suffix],
748748
command : [copy_script_path,
749749
fs.parent(usd_plugin.full_path()),
750750
join_paths(output_path, 'usd/plugins', usd_plugin.name() + '/'),
751751
'generatedSchema.usda'] )
752-
endforeach
752+
endforeach
753753

754754
copy_nrc_dll = custom_target('copy_nrc_dll_' + target_suffix,
755755
output : ['copy_nrc_dll_' + target_suffix],

src/dxvk/rtx_render/rtx_debug_view.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,13 @@ namespace dxvk {
320320
{DEBUG_VIEW_NRD_INSTANCE_0_VALIDATION_LAYER, "NRD Instance 0 Validation Layer", "Requires NRD and \"NRD/Common Settings/Validation Layer\" enabled" },
321321
{DEBUG_VIEW_NRD_INSTANCE_1_VALIDATION_LAYER, "NRD Instance 1 Validation Layer", "Requires NRD and \"NRD/Common Settings/Validation Layer\" enabled" },
322322
{DEBUG_VIEW_NRD_INSTANCE_2_VALIDATION_LAYER, "NRD Instance 2 Validation Layer", "Requires NRD and \"NRD/Common Settings/Validation Layer\" enabled" },
323+
324+
{DEBUG_VIEW_PREV_WORLD_POSITION_AND_TBN, "Encoded previous world position and TBN texture",
325+
"Parameterize via ROUND(Debug Knob [0]):\n"
326+
" 0: World Position\n"
327+
" 1: World Normal\n"
328+
" 2: World Tangent\n"
329+
" 3: World Bitangent" },
323330
} };
324331

325332
// Note: this does a linear search through the debug view vector so do not use it in performance critical code
@@ -542,6 +549,7 @@ namespace dxvk {
542549
TEXTURE2D(DEBUG_VIEW_BINDING_NRD_VALIDATION_LAYER_INPUT)
543550
TEXTURE2D(DEBUG_VIEW_BINDING_COMPOSITE_INPUT)
544551
TEXTURE2D(DEBUG_VIEW_BINDING_ALTERNATE_DISOCCLUSION_THRESHOLD_INPUT)
552+
TEXTURE2D(DEBUG_VIEW_BINDING_PREV_WORLD_POSITION_INPUT)
545553

546554
RW_TEXTURE2D(DEBUG_VIEW_BINDING_ACCUMULATED_DEBUG_VIEW_INPUT_OUTPUT)
547555

@@ -1303,17 +1311,22 @@ namespace dxvk {
13031311
break;
13041312
}
13051313
}
1306-
1314+
1315+
const uint32_t frameIdx = ctx->getDevice()->getCurrentFrameId();
1316+
13071317
ctx->bindResourceView(DEBUG_VIEW_BINDING_COMPOSITE_INPUT, rtOutput.m_compositeOutput.view(Resources::AccessType::Read), nullptr);
13081318
ctx->bindResourceView(DEBUG_VIEW_BINDING_ALTERNATE_DISOCCLUSION_THRESHOLD_INPUT, rtOutput.m_primaryDisocclusionThresholdMix.view, nullptr);
13091319

1320+
ctx->bindResourceView(DEBUG_VIEW_BINDING_PREV_WORLD_POSITION_INPUT,
1321+
rtOutput.getPreviousPrimaryWorldPositionWorldTriangleNormal().view(Resources::AccessType::Read,
1322+
rtOutput.getPreviousPrimaryWorldPositionWorldTriangleNormal().matchesWriteFrameIdx(frameIdx - 1)), nullptr);
1323+
13101324
// Inputs / Outputs
13111325

13121326
ctx->bindResourceView(DEBUG_VIEW_BINDING_ACCUMULATED_DEBUG_VIEW_INPUT_OUTPUT, m_accumulatedFrameDebugView.view, nullptr);
13131327

13141328
// Outputs
13151329

1316-
const uint32_t frameIdx = ctx->getDevice()->getCurrentFrameId();
13171330
VkDeviceSize statisticsBufferOffset = (frameIdx % kMaxFramesInFlight) * sizeof(m_outputStatistics);
13181331
ctx->bindResourceBuffer(DEBUG_VIEW_BINDING_STATISTICS_BUFFER_OUTPUT, DxvkBufferSlice(m_statisticsBuffer, statisticsBufferOffset, m_statisticsBuffer->info().size));
13191332

src/dxvk/rtx_render/rtx_imgui.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,17 @@ namespace ImGui {
372372
return changed;
373373
}
374374

375+
// Variant handling RtxOption as input
376+
template <typename ... Args>
377+
IMGUI_API bool ColorPicker4(const char* label, dxvk::RtxOption<dxvk::Vector4>* rtxOption, Args&& ... args) {
378+
dxvk::Vector4 value = rtxOption->get();
379+
bool changed = IMGUI_ADD_TOOLTIP(ColorPicker4(label, value.data, std::forward<Args>(args)...), rtxOption->getDescription());
380+
if (changed) {
381+
rtxOption->setDeferred(value);
382+
}
383+
return changed;
384+
}
385+
375386
// Variant handling RtxOption as input
376387
template <typename ... Args>
377388
IMGUI_API bool InputText(const char* label, dxvk::RtxOption<std::string>* rtxOption, Args&& ... args) {

src/dxvk/rtx_render/rtx_mod_usd.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -492,8 +492,8 @@ void UsdMod::Impl::processLight(Args& args, const pxr::UsdPrim& lightPrim, const
492492
}
493493
}
494494

495-
inline float4 toFloat4(const pxr::GfVec4f& v) {
496-
float4 f;
495+
inline Vector4 toFloat4(const pxr::GfVec4f& v) {
496+
Vector4 f;
497497
f.x = v[0];
498498
f.y = v[1];
499499
f.z = v[2];
@@ -572,18 +572,28 @@ bool UsdMod::Impl::processParticleSystem(Args& args, const pxr::UsdPrim& prim) {
572572
}
573573

574574
// Read all simulation parameters
575-
READ_ATTR(float, MinTtl, minTtl);
576-
READ_ATTR(float, MaxTtl, maxTtl);
577-
READ_ATTR(float, OpacityMultiplier, opacityMultiplier);
575+
READ_ATTR(float, MinTimeToLive, minTtl);
576+
READ_ATTR(float, MaxTimeToLive, maxTtl);
578577
READ_ATTR(float, InitialVelocityFromNormal, initialVelocityFromNormal);
578+
READ_ATTR(float, InitialVelocityConeAngleDegrees, initialVelocityConeAngleDegrees);
579579
READ_ATTR(float, MinParticleSize, minParticleSize);
580580
READ_ATTR(float, MaxParticleSize, maxParticleSize);
581+
READ_ATTR(float, MinRotationSpeed, minRotationSpeed);
582+
READ_ATTR(float, MaxRotationSpeed, maxRotationSpeed);
581583
READ_ATTR(float, GravityForce, gravityForce);
582584
READ_ATTR(float, MaxSpeed, maxSpeed);
583585
READ_ATTR(float, TurbulenceFrequency, turbulenceFrequency);
584586
READ_ATTR(float, TurbulenceAmplitude, turbulenceAmplitude);
587+
READ_ATTR(float, CollisionThickness, collisionThickness);
588+
READ_ATTR(float, CollisionRestitution, collisionRestitution);
589+
READ_ATTR(float, MotionTrailMultiplier, motionTrailMultiplier);
585590
READ_ATTR(int, MaxNumParticles, maxNumParticles);
586591
READ_ATTR(bool, UseTurbulence, useTurbulence);
592+
READ_ATTR(bool, UseSpawnTexcoords, useSpawnTexcoords);
593+
READ_ATTR(bool, EnableCollisionDetection, enableCollisionDetection);
594+
READ_ATTR(bool, AlignParticlesToVelocity, alignParticlesToVelocity);
595+
READ_ATTR(bool, EnableMotionTrail, enableMotionTrail);
596+
READ_ATTR(float, SpawnRatePerSecond, spawnRate);
587597
READ_ATTR_CONV(GfVec4f, MaxSpawnColor, maxSpawnColor, toFloat4);
588598
READ_ATTR_CONV(GfVec4f, MinSpawnColor, minSpawnColor, toFloat4);
589599

src/dxvk/rtx_render/rtx_option.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ namespace dxvk {
107107
case OptionType::Vector3:
108108
delete value.v3;
109109
break;
110+
case OptionType::Vector4:
111+
delete value.v4;
112+
break;
110113
case OptionType::Vector2i:
111114
delete value.v2i;
112115
break;
@@ -131,6 +134,7 @@ namespace dxvk {
131134
case OptionType::Vector2: return "float2";
132135
case OptionType::Vector3: return "float3";
133136
case OptionType::Vector2i: return "int2";
137+
case OptionType::Vector4: return "float4";
134138
case OptionType::String: return "string";
135139
default:
136140
return "unknown type";
@@ -151,6 +155,7 @@ namespace dxvk {
151155
case OptionType::Vector2: return Config::generateOptionString(*value.v2);
152156
case OptionType::Vector3: return Config::generateOptionString(*value.v3);
153157
case OptionType::Vector2i: return Config::generateOptionString(*value.v2i);
158+
case OptionType::Vector4: return Config::generateOptionString(*value.v4);
154159
case OptionType::String: return *value.string;
155160
default:
156161
return "unknown type";
@@ -226,6 +231,9 @@ namespace dxvk {
226231
case OptionType::String:
227232
*value.string = options.getOption<std::string>(fullName.c_str(), *value.string, env);
228233
break;
234+
case OptionType::Vector4:
235+
*value.v4 = options.getOption<Vector4>(fullName.c_str(), *value.v4, env);
236+
break;
229237
default:
230238
break;
231239
}
@@ -289,6 +297,9 @@ namespace dxvk {
289297
case OptionType::String:
290298
options.setOption(fullName.c_str(), *value.string);
291299
break;
300+
case OptionType::Vector4:
301+
options.setOption(fullName.c_str(), *value.v4);
302+
break;
292303
default:
293304
break;
294305
}
@@ -336,6 +347,9 @@ namespace dxvk {
336347
case OptionType::String:
337348
return *aValue.string == *bValue.string;
338349
break;
350+
case OptionType::Vector4:
351+
return *aValue.v4 == *bValue.v4;
352+
break;
339353
}
340354
return false;
341355
}
@@ -395,6 +409,9 @@ namespace dxvk {
395409
case OptionType::String:
396410
*value.string = *source.string;
397411
break;
412+
case OptionType::Vector4:
413+
*value.v4 = *source.v4;
414+
break;
398415
default:
399416
break;
400417
}

src/dxvk/rtx_render/rtx_option.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ namespace dxvk {
6060
Vector3,
6161
Vector2i,
6262
String,
63-
VirtualKeys
63+
VirtualKeys,
64+
Vector4
6465
};
6566

6667
union GenericValue {
@@ -69,6 +70,7 @@ namespace dxvk {
6970
float f;
7071
Vector2* v2;
7172
Vector3* v3;
73+
Vector4* v4;
7274
Vector2i* v2i;
7375
fast_unordered_set* hashSet;
7476
std::vector<XXH64_hash_t>* hashVector;
@@ -249,6 +251,7 @@ namespace dxvk {
249251
if constexpr (std::is_same_v<T, fast_unordered_set>) return OptionType::HashSet;
250252
if constexpr (std::is_same_v<T, std::vector<XXH64_hash_t>>) return OptionType::HashVector;
251253
if constexpr (std::is_same_v<T, std::vector<int32_t>>) return OptionType::IntVector;
254+
if constexpr (std::is_same_v<T, Vector4>) return OptionType::Vector4;
252255
if constexpr (std::is_same_v<T, Vector2>) return OptionType::Vector2;
253256
if constexpr (std::is_same_v<T, Vector3>) return OptionType::Vector3;
254257
if constexpr (std::is_same_v<T, Vector2i>) return OptionType::Vector2i;

0 commit comments

Comments
 (0)