diff --git a/Editor/EmitterWindow.cpp b/Editor/EmitterWindow.cpp index cb884004a..6ae9f2ad6 100644 --- a/Editor/EmitterWindow.cpp +++ b/Editor/EmitterWindow.cpp @@ -83,7 +83,7 @@ EmitterWindow::EmitterWindow(wiGUI* gui) : GUI(gui) emitCountSlider->SetTooltip("Set the number of particles to emit per second."); emitterWindow->AddWidget(emitCountSlider); - emitSizeSlider = new wiSlider(0.01f, 1000.0f, 1.0f, 100000, "Size: "); + emitSizeSlider = new wiSlider(0.01f, 10.0f, 1.0f, 100000, "Size: "); emitSizeSlider->SetSize(XMFLOAT2(200, 30)); emitSizeSlider->SetPos(XMFLOAT2(x, y += step)); emitSizeSlider->OnSlide([&](wiEventArgs args) { diff --git a/Editor/ForceFieldWindow.cpp b/Editor/ForceFieldWindow.cpp index 4d23a3a3c..acbb64987 100644 --- a/Editor/ForceFieldWindow.cpp +++ b/Editor/ForceFieldWindow.cpp @@ -48,7 +48,7 @@ ForceFieldWindow::ForceFieldWindow(wiGUI* gui) : GUI(gui) forceFieldWindow->AddWidget(typeComboBox); - gravitySlider = new wiSlider(-0.01f, 0.01f, 0, 100000, "Gravity: "); + gravitySlider = new wiSlider(-10, 10, 0, 100000, "Gravity: "); gravitySlider->SetSize(XMFLOAT2(200, 30)); gravitySlider->SetPos(XMFLOAT2(x, y += step)); gravitySlider->OnSlide([&](wiEventArgs args) { @@ -62,7 +62,7 @@ ForceFieldWindow::ForceFieldWindow(wiGUI* gui) : GUI(gui) forceFieldWindow->AddWidget(gravitySlider); - rangeSlider = new wiSlider(0.0f, 1000.0f, 10, 100000, "Range: "); + rangeSlider = new wiSlider(0.0f, 100.0f, 10, 100000, "Range: "); rangeSlider->SetSize(XMFLOAT2(200, 30)); rangeSlider->SetPos(XMFLOAT2(x, y += step)); rangeSlider->OnSlide([&](wiEventArgs args) { diff --git a/Editor/config.ini b/Editor/config.ini index db7591a73..fcbe7ab01 100644 --- a/Editor/config.ini +++ b/Editor/config.ini @@ -1,7 +1,7 @@ enabled 1 x 0 y 0 -w 1920 -h 1080 +w 3840 +h 2160 fullscreen 0 borderless 1 \ No newline at end of file diff --git a/WickedEngine/WickedEngine_SHADERS.vcxproj.filters b/WickedEngine/WickedEngine_SHADERS.vcxproj.filters index 09b98f95b..05df703ca 100644 --- a/WickedEngine/WickedEngine_SHADERS.vcxproj.filters +++ b/WickedEngine/WickedEngine_SHADERS.vcxproj.filters @@ -612,16 +612,16 @@ CS - + CS - + CS CS - + CS diff --git a/WickedEngine/emittedparticle_simulateCS.hlsl b/WickedEngine/emittedparticle_simulateCS.hlsl index dd57749d0..988ac924c 100644 --- a/WickedEngine/emittedparticle_simulateCS.hlsl +++ b/WickedEngine/emittedparticle_simulateCS.hlsl @@ -13,15 +13,23 @@ struct LDS_ForceField uint type; float3 position; float gravity; - float range; + float range_inverse; + float3 normal; }; groupshared LDS_ForceField forceFields[NUM_LDS_FORCEFIELDS]; +groupshared uint aliveParticleCount = 0; [numthreads(THREADCOUNT_SIMULATION, 1, 1)] void main(uint3 DTid : SV_DispatchThreadID, uint Gid : SV_GroupIndex) { - // First, load the forcefields to LDS: + // Read alive particle count and store in LDS: + if (Gid == 0) + { + aliveParticleCount = counterBuffer[0][0]; + } + + // Load the forcefields into LDS: uint numForceFields = min(g_xFrame_ForceFieldCount, NUM_LDS_FORCEFIELDS); if (Gid < numForceFields) { @@ -31,17 +39,15 @@ void main(uint3 DTid : SV_DispatchThreadID, uint Gid : SV_GroupIndex) forceFields[Gid].type = (uint)forceField.type; forceFields[Gid].position = forceField.positionWS; forceFields[Gid].gravity = forceField.energy; - forceFields[Gid].range = max(0.001f, forceField.range); + forceFields[Gid].range_inverse = forceField.range; + forceFields[Gid].normal = forceField.directionWS; } GroupMemoryBarrierWithGroupSync(); - - uint aliveCount = counterBuffer[0][0]; - - if (DTid.x < aliveCount) + if (DTid.x < aliveParticleCount) { - uint dt = g_xFrame_DeltaTime * 60.0f; + const float dt = g_xFrame_DeltaTime; uint particleIndex = aliveBuffer_OLD[DTid.x]; Particle particle = particleBuffer[particleIndex]; @@ -54,9 +60,19 @@ void main(uint3 DTid : SV_DispatchThreadID, uint Gid : SV_GroupIndex) { LDS_ForceField forceField = forceFields[i]; - float3 diff = forceField.position - particle.position; - float dist = length(diff); - float3 force = diff * forceField.gravity * (1 - saturate(dist / forceField.range)); + float3 dir = forceField.position - particle.position; + float dist; + if (forceField.type == ENTITY_TYPE_FORCEFIELD_POINT) // point-based force field + { + dist = length(dir); + } + else // planar force field + { + dist = dot(forceField.normal, dir); + dir = forceField.normal; + } + + float3 force = dir * forceField.gravity * (1 - saturate(dist * forceField.range_inverse)); particle.velocity += force * dt; } diff --git a/WickedEngine/wiEmittedParticle.cpp b/WickedEngine/wiEmittedParticle.cpp index e0278127a..1f76b4f6a 100644 --- a/WickedEngine/wiEmittedParticle.cpp +++ b/WickedEngine/wiEmittedParticle.cpp @@ -221,9 +221,9 @@ void wiEmittedParticle::UpdateRenderData(GRAPHICSTHREAD threadID) cb.xEmitterMeshVertexNormalStride = sizeof(Mesh::Vertex_NOR); cb.xEmitterRandomness = wiRandom::getRandom(0, 1000) * 0.001f; cb.xEmitCount = (UINT)emit; - cb.xParticleLifeSpan = life; + cb.xParticleLifeSpan = life / 60.0f; cb.xParticleLifeSpanRandomness = random_life; - cb.xParticleNormalFactor = normal_factor / 60.0f; + cb.xParticleNormalFactor = normal_factor; cb.xParticleRandomFactor = random_factor; cb.xParticleScaling = scaleX; cb.xParticleSize = size; diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index fae0b3c56..38a7114ad 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -2104,9 +2104,10 @@ void wiRenderer::UpdateRenderData(GRAPHICSTHREAD threadID) entityArray[entityCounter].type = force->type; entityArray[entityCounter].positionWS = force->translation; - XMStoreFloat3(&entityArray[entityCounter].directionWS, XMVector3TransformNormal(XMVectorSet(0, 1, 0, 0), XMLoadFloat4x4(&force->world))); entityArray[entityCounter].energy = force->gravity; - entityArray[entityCounter].range = force->range; + entityArray[entityCounter].range = 1.0f / max(0.0001f, force->range); // avoid division in shader + // The default planar force field is facing upwards, and thus the pull direction is downwards: + XMStoreFloat3(&entityArray[entityCounter].directionWS, XMVector3Normalize(XMVector3TransformNormal(XMVectorSet(0, -1, 0, 0), XMLoadFloat4x4(&force->world)))); entityCounter++; } diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index dcf18045d..363074fab 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wiVersion // minor features, major updates const int minor = 13; // minor bug fixes, alterations, refactors, updates - const int revision = 67; + const int revision = 68; long GetVersion() diff --git a/features.txt b/features.txt index d8c69bca4..e1f9e147f 100644 --- a/features.txt +++ b/features.txt @@ -69,3 +69,4 @@ Real time Voxel Cone traced reflections Temporal Antialiasing Tiled deferred rendering Huge draw distance support with reversed Z-buffer +Force Fields GPU simulation diff --git a/models/Emitter/profiling_10_30_9_49_12.csv b/models/Emitter/profiling_10_30_9_49_12.csv new file mode 100644 index 000000000..f8a9400da --- /dev/null +++ b/models/Emitter/profiling_10_30_9_49_12.csv @@ -0,0 +1,136 @@ +HUD frame time nsec:,16670000 + +Range Index,Elapsed Time, First Event,Last Event +0,11552,302,302 +1,26464,304,304 +2,6752,306,306 +3,13312,308,308 +4,6752,310,310 +5,8544,327,327 +6,26720,329,329 +7,13568,331,331 +8,14080,333,333 +9,10880,335,335 +10,8032,352,352 +11,23808,354,354 +12,6976,356,356 +13,15264,358,358 +14,6624,360,360 +15,21760,384,384 +16,21312,389,389 +17,21312,394,394 +18,36928,433,433 +19,47008,466,466 +20,63712,499,499 +21,394240,559,559 +22,925120,584,584 +23,10289696,609,609 +24,1822656,651,651 +25,469856,682,682 +26,565760,703,703 +27,26624,717,717 +28,26592,731,731 +29,1583776,751,751 +30,2679520,838,838 +31,5802240,853,853 +32,6654112,873,873 +33,416768,890,890 +34,641024,906,906 +35,1735904,920,920 +36,3130688,937,937 +37,3904352,953,953 +38,3941088,983,983 +39,3938144,997,997 +40,3938080,1014,1014 +41,3933120,1017,1017 +42,3933280,1034,1034 +43,3933120,1037,1037 +44,3933056,1054,1054 +45,3933152,1057,1057 +46,3936288,1071,1071 +47,3936128,1089,1089 +48,3936032,1092,1092 +49,3936064,1106,1106 +50,3935520,1124,1124 +51,3935488,1127,1127 +52,3935360,1141,1141 +53,3935264,1159,1159 +54,3935360,1162,1162 +55,3936064,1176,1176 +56,3936064,1194,1194 +57,3935136,1197,1197 +58,3934688,1211,1211 +59,3934848,1229,1229 +60,3934784,1232,1232 +61,3935456,1246,1246 +62,3935584,1264,1264 +63,3932416,1267,1267 +64,3933152,1281,1281 +65,3932384,1299,1299 +66,3932224,1302,1302 +67,3933984,1316,1316 +68,3934176,1334,1334 +69,3933056,1337,1337 +70,3932480,1351,1351 +71,3932480,1369,1369 +72,3932544,1372,1372 +73,3933664,1386,1386 +74,3933760,1404,1404 +75,3933536,1407,1407 +76,3934432,1421,1421 +77,3934496,1439,1439 +78,3932864,1442,1442 +79,3937216,1456,1456 +80,3937248,1474,1474 +81,3936160,1477,1477 +82,3936160,1491,1491 +83,3936096,1509,1509 +84,3935936,1512,1512 +85,3935872,1526,1526 +86,3935264,1543,1543 +87,3935168,1546,1546 +88,3935072,1560,1560 +89,3935072,1577,1577 +90,3935008,1580,1580 +91,3935008,1594,1594 +92,3934976,1611,1611 +93,3934464,1614,1614 +94,3934432,1628,1628 +95,3934432,1642,1642 +96,3934208,1659,1659 +97,3934176,1662,1662 +98,3934144,1676,1676 +99,3934112,1694,1694 +100,3932416,1697,1697 +101,3934080,1711,1711 +102,3934240,1729,1729 +103,3934272,1732,1732 +104,3935328,1746,1746 +105,3935392,1764,1764 +106,3935072,1767,1767 +107,3933696,1781,1781 +108,3933792,1799,1799 +109,3933792,1802,1802 +110,3934816,1816,1816 +111,3951552,1834,1834 +112,3951008,1837,1837 +113,3951840,1851,1851 +114,3951968,1869,1869 +115,3952000,1872,1872 +116,3952480,1886,1886 +117,3951104,1904,1904 +118,3950304,1907,1907 +119,3950464,1921,1921 +120,3950336,1939,1939 +121,3950304,1942,1942 +122,3950624,1956,1956 +123,3950592,1974,1974 +124,3950560,1977,1977 +125,5083744,1996,1996 +126,6175968,2009,2009 +127,6180064,2023,2023 +128,6183200,2037,2037 +129,6182624,2054,2054 +130,6182848,2057,2057 +131,6188480,2074,2074 +132,6199360,2077,2077 diff --git a/models/Emitter/temp/history0 b/models/Emitter/temp/history0 new file mode 100644 index 000000000..38166fc9e Binary files /dev/null and b/models/Emitter/temp/history0 differ diff --git a/models/Emitter/temp/history1 b/models/Emitter/temp/history1 new file mode 100644 index 000000000..f487f8fbe Binary files /dev/null and b/models/Emitter/temp/history1 differ diff --git a/models/Emitter/temp/history2 b/models/Emitter/temp/history2 new file mode 100644 index 000000000..06052b687 Binary files /dev/null and b/models/Emitter/temp/history2 differ