particles will take emitter velocity, and set visible in planar reflection

This commit is contained in:
Turánszki János
2023-09-30 09:09:51 +02:00
parent e2ad204b07
commit 996a6d018b
15 changed files with 68 additions and 50 deletions
@@ -41,6 +41,7 @@ static const uint EMITTER_OPTION_BIT_COLLIDERS_DISABLED = 1 << 3;
CBUFFER(EmittedParticleCB, CBSLOT_OTHER_EMITTEDPARTICLE)
{
ShaderTransform xEmitterTransform;
ShaderTransform xEmitterTransformPrev;
uint xEmitCount;
uint xEmitterMeshIndexCount;
@@ -31,18 +31,25 @@ float4 main(VertextoPixel input) : SV_TARGET
}
uint2 pixel = input.pos.xy;
float2 ScreenCoord = pixel * GetCamera().internal_resolution_rcp;
float4 depthScene = texture_lineardepth.GatherRed(sampler_linear_clamp, ScreenCoord) * GetCamera().z_far;
float depthFragment = input.pos.w;
float fade = saturate(1.0 / input.size*(max(max(depthScene.x, depthScene.y), max(depthScene.z, depthScene.w)) - depthFragment));
float4 inputColor;
inputColor.r = ((input.color >> 0) & 0xFF) / 255.0f;
inputColor.g = ((input.color >> 8) & 0xFF) / 255.0f;
inputColor.b = ((input.color >> 16) & 0xFF) / 255.0f;
inputColor.a = ((input.color >> 24) & 0xFF) / 255.0f;
float opacity = saturate(color.a * inputColor.a * fade);
float opacity = color.a * inputColor.a;
[branch]
if (GetCamera().texture_lineardepth_index >= 0)
{
float2 ScreenCoord = pixel * GetCamera().internal_resolution_rcp;
float4 depthScene = texture_lineardepth.GatherRed(sampler_linear_clamp, ScreenCoord) * GetCamera().z_far;
float depthFragment = input.pos.w;
opacity *= saturate(1.0 / input.size * (max(max(depthScene.x, depthScene.y), max(depthScene.z, depthScene.w)) - depthFragment));
}
opacity = saturate(opacity);
color.rgb *= inputColor.rgb * (1 + material.GetEmissive());
color.a = opacity;
@@ -25,6 +25,8 @@ void main(uint3 DTid : SV_DispatchThreadID)
rng.init(uint2(xEmitterRandomness, DTid.x), GetFrame().frame_count);
const float4x4 worldMatrix = xEmitterTransform.GetMatrix();
const float4x4 worldMatrixPrev = xEmitterTransformPrev.GetMatrix();
float3 emitPos = 0;
#ifdef EMIT_FROM_MESH
// random triangle on emitter surface:
@@ -57,25 +59,28 @@ void main(uint3 DTid : SV_DispatchThreadID)
float2 bary = float2(f, g);
// compute final surface position on triangle from barycentric coords:
float3 pos = attribute_at_bary(pos_nor0.xyz, pos_nor1.xyz, pos_nor2.xyz, bary);
emitPos = attribute_at_bary(pos_nor0.xyz, pos_nor1.xyz, pos_nor2.xyz, bary);
float3 nor = normalize(attribute_at_bary(nor0, nor1, nor2, bary));
pos = mul(worldMatrix, float4(pos, 1)).xyz;
nor = normalize(mul((float3x3)worldMatrix, nor));
#else
#ifdef EMITTER_VOLUME
// Emit inside volume:
float3 pos = mul(worldMatrix, float4(rng.next_float() * 2 - 1, rng.next_float() * 2 - 1, rng.next_float() * 2 - 1, 1)).xyz;
emitPos = float3(rng.next_float() * 2 - 1, rng.next_float() * 2 - 1, rng.next_float() * 2 - 1);
#else
// Just emit from center point:
float3 pos = mul(worldMatrix, float4(0, 0, 0, 1)).xyz;
emitPos = 0;
#endif // EMITTER_VOLUME
float3 nor = 0;
#endif // EMIT_FROM_MESH
float3 pos = mul(worldMatrix, float4(emitPos, 1)).xyz;
float3 posPrev = mul(worldMatrixPrev, float4(emitPos, 1)).xyz;
float3 emitVelocity = pos - posPrev;
float particleStartingSize = xParticleSize + xParticleSize * (rng.next_float() - 0.5f) * xParticleRandomFactor;
// create new particle:
@@ -83,7 +88,7 @@ void main(uint3 DTid : SV_DispatchThreadID)
particle.position = pos;
particle.force = 0;
particle.mass = xParticleMass;
particle.velocity = xParticleVelocity + (nor + (float3(rng.next_float(), rng.next_float(), rng.next_float()) - 0.5f) * xParticleRandomFactor) * xParticleNormalFactor;
particle.velocity = emitVelocity + xParticleVelocity + (nor + (float3(rng.next_float(), rng.next_float(), rng.next_float()) - 0.5f) * xParticleRandomFactor) * xParticleNormalFactor;
particle.rotationalVelocity = xParticleRotation + (rng.next_float() - 0.5f) * xParticleRandomFactor;
particle.maxLife = xParticleLifeSpan + xParticleLifeSpan * (rng.next_float() - 0.5f) * xParticleLifeSpanRandomness;
particle.life = particle.maxLife;
+13 -16
View File
@@ -5,13 +5,12 @@
struct GSInput
{
float4 pos : SV_POSITION;
uint instanceID : INSTANCEINDEX;
uint emissiveColor : EMISSIVECOLOR;
float4 color : COLOR;
float4 uvsets : UVSETS;
float2 atl : ATLAS;
float3 nor : NORMAL;
float4 tan : TANGENT;
uint instanceIndex_dither : INSTANCEINDEX_DITHER;
min16float4 color : COLOR;
min16float4 uvsets : UVSETS;
min16float4 tan : TANGENT;
min16float3 nor : NORMAL;
min16float2 atl : ATLAS;
float3 pos3D : WORLDPOSITION;
uint RTIndex : RTINDEX;
};
@@ -19,13 +18,12 @@ struct GSInput
struct GSOutput
{
float4 pos : SV_POSITION;
uint instanceID : INSTANCEINDEX;
uint emissiveColor : EMISSIVECOLOR;
float4 color : COLOR;
float4 uvsets : UVSETS;
float2 atl : ATLAS;
float3 nor : NORMAL;
float4 tan : TANGENT;
uint instanceIndex_dither : INSTANCEINDEX_DITHER;
min16float4 color : COLOR;
min16float4 uvsets : UVSETS;
min16float4 tan : TANGENT;
min16float3 nor : NORMAL;
min16float2 atl : ATLAS;
float3 pos3D : WORLDPOSITION;
uint RTIndex : SV_RenderTargetArrayIndex;
};
@@ -40,8 +38,7 @@ void main(
{
GSOutput element;
element.pos = input[i].pos;
element.instanceID = input[i].instanceID;
element.emissiveColor = input[i].emissiveColor;
element.instanceIndex_dither = input[i].instanceIndex_dither;
element.color = input[i].color;
element.uvsets = input[i].uvsets;
element.atl = input[i].atl;
@@ -5,14 +5,14 @@
struct GSInput
{
float4 pos : SV_POSITION;
float3 nor : NORMAL;
min16float3 nor : NORMAL;
uint RTIndex : RTINDEX;
};
struct GSOutput
{
float4 pos : SV_POSITION;
float3 nor : NORMAL;
min16float3 nor : NORMAL;
uint RTIndex : SV_RenderTargetArrayIndex;
};
@@ -5,10 +5,9 @@ struct GSInput
{
float4 pos : SV_POSITION;
float clip : SV_ClipDistance0;
uint instanceIndex : INSTANCEINDEX;
uint instanceIndex_dither : INSTANCEINDEX_DITHER;
#ifdef ALPHATEST
nointerpolation float dither : DITHER;
float4 uvsets : UVSETS;
min16float4 uvsets : UVSETS;
#endif // ALPHATEST
};
@@ -16,10 +15,9 @@ struct GSOutput
{
float4 pos : SV_POSITION;
float clip : SV_ClipDistance0;
uint instanceIndex : INSTANCEINDEX;
uint instanceIndex_dither : INSTANCEINDEX_DITHER;
#ifdef ALPHATEST
nointerpolation float dither : DITHER;
float4 uvsets : UVSETS;
min16float4 uvsets : UVSETS;
#endif // ALPHATEST
uint primitiveID : PRIMITIVEID;
};
@@ -36,9 +34,8 @@ void main(
GSOutput element;
element.pos = input[i].pos;
element.clip = input[i].clip;
element.instanceIndex = input[i].instanceIndex;
element.instanceIndex_dither = input[i].instanceIndex_dither;
#ifdef ALPHATEST
element.dither = input[i].dither;
element.uvsets = input[i].uvsets;
#endif // ALPHATEST
element.primitiveID = primitiveID;
@@ -5,14 +5,14 @@
struct GSInput
{
float4 pos : SV_POSITION;
float4 uvsets : UVSETS;
min16float4 uvsets : UVSETS;
uint VPIndex : VPINDEX;
};
struct GSOutput
{
float4 pos : SV_POSITION;
float4 uvsets : UVSETS;
min16float4 uvsets : UVSETS;
uint VPIndex : SV_ViewportArrayIndex;
};
@@ -5,16 +5,16 @@
struct GSInput
{
float4 pos : SV_POSITION;
float4 color : COLOR;
float4 uvsets : UVSETS;
min16float4 color : COLOR;
min16float4 uvsets : UVSETS;
uint VPIndex : VPINDEX;
};
struct GSOutput
{
float4 pos : SV_POSITION;
float4 color : COLOR;
float4 uvsets : UVSETS;
min16float4 color : COLOR;
min16float4 uvsets : UVSETS;
uint VPIndex : SV_ViewportArrayIndex;
};
+8
View File
@@ -315,6 +315,12 @@ namespace wi
void EmittedParticleSystem::UpdateCPU(const TransformComponent& transform, float dt)
{
if (!particleBuffer.IsValid())
{
// set initial prev matrix to current:
transformPrev = transform.world;
}
CreateSelfBuffers();
if (IsPaused())
@@ -363,6 +369,8 @@ namespace wi
{
EmittedParticleCB cb;
cb.xEmitterTransform.Create(transform.world);
cb.xEmitterTransformPrev.Create(transformPrev);
transformPrev = transform.world;
cb.xEmitCount = (uint32_t)emit;
cb.xEmitterMeshIndexCount = mesh == nullptr ? 0 : (uint32_t)mesh->indices.size();
cb.xEmitterRandomness = wi::random::GetRandom(0.0f, 1.0f);
+1
View File
@@ -132,6 +132,7 @@ namespace wi
// Non-serialized attributes:
XMFLOAT3 center;
uint32_t layerMask = ~0u;
mutable XMFLOAT4X4 transformPrev = wi::math::IDENTITY_MATRIX;
inline bool IsDebug() const { return _flags & FLAG_DEBUG; }
inline bool IsPaused() const { return _flags & FLAG_PAUSED; }
-1
View File
@@ -93,7 +93,6 @@ namespace wi
// Non-serialized attributes:
XMFLOAT4X4 world;
XMFLOAT4X4 worldPrev;
wi::primitive::AABB aabb;
wi::vector<uint32_t> indices; // it is dependent on vertex_lengths and contains triangles with non-zero lengths
uint32_t layerMask = ~0u;
+8 -3
View File
@@ -369,7 +369,10 @@ namespace wi
visibility_reflection.layerMask = getLayerMask();
visibility_reflection.scene = scene;
visibility_reflection.camera = &camera_reflection;
visibility_reflection.flags = wi::renderer::Visibility::ALLOW_OBJECTS;
visibility_reflection.flags =
wi::renderer::Visibility::ALLOW_OBJECTS |
wi::renderer::Visibility::ALLOW_EMITTERS
;
wi::renderer::UpdateVisibility(visibility_reflection);
}
@@ -1207,6 +1210,8 @@ namespace wi
device->EventEnd(cmd);
}
wi::renderer::DrawSoftParticles(visibility_reflection, false, cmd);
device->RenderPassEnd(cmd);
wi::profiler::EndRange(range); // Planar Reflections
@@ -1872,7 +1877,7 @@ namespace wi
wi::renderer::DrawLightVisualizers(visibility_main, cmd);
wi::renderer::DrawSoftParticles(visibility_main, rtLinearDepth, false, cmd);
wi::renderer::DrawSoftParticles(visibility_main, false, cmd);
if (getVolumeLightsEnabled() && visibility_main.IsRequestedVolumetricLights())
{
@@ -1951,7 +1956,7 @@ namespace wi
vp.height = (float)rtParticleDistortion.GetDesc().height;
device->BindViewports(1, &vp, cmd);
wi::renderer::DrawSoftParticles(visibility_main, rtLinearDepth, true, cmd);
wi::renderer::DrawSoftParticles(visibility_main, true, cmd);
device->RenderPassEnd(cmd);
}
-1
View File
@@ -4835,7 +4835,6 @@ void DrawWaterRipples(const Visibility& vis, CommandList cmd)
void DrawSoftParticles(
const Visibility& vis,
const Texture& lineardepth,
bool distortion,
CommandList cmd
)
-1
View File
@@ -255,7 +255,6 @@ namespace wi::renderer
// Draw Soft offscreen particles.
void DrawSoftParticles(
const Visibility& vis,
const wi::graphics::Texture& lineardepth,
bool distortion,
wi::graphics::CommandList 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 = 303;
const int revision = 304;
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);