diff --git a/WickedEngine/shaders/ShaderInterop_EmittedParticle.h b/WickedEngine/shaders/ShaderInterop_EmittedParticle.h index 07db5cfb6..ab0c50df4 100644 --- a/WickedEngine/shaders/ShaderInterop_EmittedParticle.h +++ b/WickedEngine/shaders/ShaderInterop_EmittedParticle.h @@ -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; diff --git a/WickedEngine/shaders/emittedparticlePS_soft.hlsl b/WickedEngine/shaders/emittedparticlePS_soft.hlsl index 903774ac2..695eb0ec8 100644 --- a/WickedEngine/shaders/emittedparticlePS_soft.hlsl +++ b/WickedEngine/shaders/emittedparticlePS_soft.hlsl @@ -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; diff --git a/WickedEngine/shaders/emittedparticle_emitCS.hlsl b/WickedEngine/shaders/emittedparticle_emitCS.hlsl index 05680feeb..6b095ad32 100644 --- a/WickedEngine/shaders/emittedparticle_emitCS.hlsl +++ b/WickedEngine/shaders/emittedparticle_emitCS.hlsl @@ -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; diff --git a/WickedEngine/shaders/envMapGS_emulation.hlsl b/WickedEngine/shaders/envMapGS_emulation.hlsl index 865b5e2f9..060f07a8c 100644 --- a/WickedEngine/shaders/envMapGS_emulation.hlsl +++ b/WickedEngine/shaders/envMapGS_emulation.hlsl @@ -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; diff --git a/WickedEngine/shaders/envMap_skyGS_emulation.hlsl b/WickedEngine/shaders/envMap_skyGS_emulation.hlsl index eb2881749..83c836fdb 100644 --- a/WickedEngine/shaders/envMap_skyGS_emulation.hlsl +++ b/WickedEngine/shaders/envMap_skyGS_emulation.hlsl @@ -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; }; diff --git a/WickedEngine/shaders/objectGS_primitiveID_emulation.hlsl b/WickedEngine/shaders/objectGS_primitiveID_emulation.hlsl index 9d33add8f..83895648e 100644 --- a/WickedEngine/shaders/objectGS_primitiveID_emulation.hlsl +++ b/WickedEngine/shaders/objectGS_primitiveID_emulation.hlsl @@ -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; diff --git a/WickedEngine/shaders/shadowGS_alphatest_emulation.hlsl b/WickedEngine/shaders/shadowGS_alphatest_emulation.hlsl index 887da440c..7806aa076 100644 --- a/WickedEngine/shaders/shadowGS_alphatest_emulation.hlsl +++ b/WickedEngine/shaders/shadowGS_alphatest_emulation.hlsl @@ -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; }; diff --git a/WickedEngine/shaders/shadowGS_transparent_emulation.hlsl b/WickedEngine/shaders/shadowGS_transparent_emulation.hlsl index 0a35105b0..8c20d588a 100644 --- a/WickedEngine/shaders/shadowGS_transparent_emulation.hlsl +++ b/WickedEngine/shaders/shadowGS_transparent_emulation.hlsl @@ -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; }; diff --git a/WickedEngine/wiEmittedParticle.cpp b/WickedEngine/wiEmittedParticle.cpp index b42de13bc..cfff07c0d 100644 --- a/WickedEngine/wiEmittedParticle.cpp +++ b/WickedEngine/wiEmittedParticle.cpp @@ -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); diff --git a/WickedEngine/wiEmittedParticle.h b/WickedEngine/wiEmittedParticle.h index 20a156380..a0344b30d 100644 --- a/WickedEngine/wiEmittedParticle.h +++ b/WickedEngine/wiEmittedParticle.h @@ -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; } diff --git a/WickedEngine/wiHairParticle.h b/WickedEngine/wiHairParticle.h index 92d30c184..d56fddf65 100644 --- a/WickedEngine/wiHairParticle.h +++ b/WickedEngine/wiHairParticle.h @@ -93,7 +93,6 @@ namespace wi // Non-serialized attributes: XMFLOAT4X4 world; - XMFLOAT4X4 worldPrev; wi::primitive::AABB aabb; wi::vector indices; // it is dependent on vertex_lengths and contains triangles with non-zero lengths uint32_t layerMask = ~0u; diff --git a/WickedEngine/wiRenderPath3D.cpp b/WickedEngine/wiRenderPath3D.cpp index 36df375a3..7563fe3b3 100644 --- a/WickedEngine/wiRenderPath3D.cpp +++ b/WickedEngine/wiRenderPath3D.cpp @@ -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); } diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 9e4645d16..61cef4fe1 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -4835,7 +4835,6 @@ void DrawWaterRipples(const Visibility& vis, CommandList cmd) void DrawSoftParticles( const Visibility& vis, - const Texture& lineardepth, bool distortion, CommandList cmd ) diff --git a/WickedEngine/wiRenderer.h b/WickedEngine/wiRenderer.h index 8e5dcf4f3..b5307a671 100644 --- a/WickedEngine/wiRenderer.h +++ b/WickedEngine/wiRenderer.h @@ -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 ); diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 53aeea927..e4464b4d9 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -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);