60 Commits

Author SHA1 Message Date
1f265bddf4 Fix XAudio2 DequeueProcessedBuffers
Some checks failed
Build Android / Game (Android, Release ARM64) (push) Has been cancelled
Build iOS / Game (iOS, Release ARM64) (push) Has been cancelled
Build Linux / Editor (Linux, Development x64) (push) Has been cancelled
Build Linux / Game (Linux, Release x64) (push) Has been cancelled
Build macOS / Editor (Mac, Development ARM64) (push) Has been cancelled
Build macOS / Game (Mac, Release ARM64) (push) Has been cancelled
Build Windows / Editor (Windows, Development x64) (push) Has been cancelled
Build Windows / Game (Windows, Release x64) (push) Has been cancelled
Tests / Tests (Linux) (push) Has been cancelled
Tests / Tests (Windows) (push) Has been cancelled
FlushSourceBuffers flushes all the pending buffers, not only just the
processed buffers.
2024-05-01 18:48:32 +03:00
3237849132 Fix looping audio sources not looping seamlessly 2024-05-01 18:48:31 +03:00
2be4d2b717 Optimize RichTextBox rendering with long text 2024-05-01 18:45:31 +03:00
dc3a1e142a Refactor native interop internal type lookup 2024-05-01 18:45:20 +03:00
b6d375e9a3 Move generated marshallers into separate namespace
Avoid polluting the `FlaxEngine` namespace with interop related
marshallers, move those to nested namespace called `Interop` where most
of the common marshallers are placed already.
2024-05-01 18:45:20 +03:00
495b6d6abc Include original type of the fields in blittable struct in comments 2024-05-01 18:45:20 +03:00
a49b398c7f Refactor struct custom marshalling generation 2024-05-01 18:45:20 +03:00
c8e893d2ec Fix assigning null values into value types in Custom Editor
Resets back to previous value instead of setting the editor value to
empty.
2024-05-01 18:44:58 +03:00
3a665199e7 Avoid deserializing clipboard content in Custom Editor paste checks 2024-05-01 18:44:58 +03:00
ca1aa89ba1 Update Editor options when window is shown 2024-05-01 18:44:27 +03:00
d92aaeb2b0 Fix Editor options data applying in realtime after first save
Reclone the data in order to not modify the currently applied options
data after save.
2024-05-01 18:44:27 +03:00
5f950cbb7e Store Debug Log view options in Editor options 2024-05-01 18:44:26 +03:00
8f613774cb Expose GPUTexture::DownloadData to Scripting API 2024-05-01 18:43:45 +03:00
c5c440469e Increase Editor profiler depth 2024-05-01 18:43:32 +03:00
1e6ed32c63 Update to enet 2.3.6 2024-05-01 18:43:31 +03:00
3ee6bffef7 Always run fixed update ticks at fixed deltatime
The random variance in fixed updates makes it impossible to do anything deterministic during physics ticks.
2024-05-01 18:43:31 +03:00
6105323ecc Update Transform component separately when applying Gizmo transform 2024-05-01 18:43:31 +03:00
23f8707927 Disable LFS override 2024-05-01 18:42:58 +03:00
761c8415dc Merge branch 'master' into signalgame
# Conflicts:
#	Flax.flaxproj
2024-05-01 18:42:14 +03:00
Wojtek Figat
cdeb9a3b15 Merge remote-tracking branch 'origin/master' into 1.9
# Conflicts:
#	Content/Editor/Camera/M_Camera.flax
#	Content/Editor/CubeTexturePreviewMaterial.flax
#	Content/Editor/DebugMaterials/DDGIDebugProbes.flax
#	Content/Editor/DebugMaterials/SingleColor/Decal.flax
#	Content/Editor/DebugMaterials/SingleColor/Particle.flax
#	Content/Editor/DebugMaterials/SingleColor/Surface.flax
#	Content/Editor/DebugMaterials/SingleColor/SurfaceAdditive.flax
#	Content/Editor/DebugMaterials/SingleColor/Terrain.flax
#	Content/Editor/DefaultFontMaterial.flax
#	Content/Editor/Gizmo/FoliageBrushMaterial.flax
#	Content/Editor/Gizmo/Material.flax
#	Content/Editor/Gizmo/MaterialWire.flax
#	Content/Editor/Gizmo/SelectionOutlineMaterial.flax
#	Content/Editor/Gizmo/VertexColorsPreviewMaterial.flax
#	Content/Editor/Highlight Material.flax
#	Content/Editor/Icons/IconsMaterial.flax
#	Content/Editor/IesProfilePreviewMaterial.flax
#	Content/Editor/Particles/Particle Material Color.flax
#	Content/Editor/Particles/Smoke Material.flax
#	Content/Editor/SpriteMaterial.flax
#	Content/Editor/Terrain/Circle Brush Material.flax
#	Content/Editor/Terrain/Highlight Terrain Material.flax
#	Content/Editor/TexturePreviewMaterial.flax
#	Content/Editor/Wires Debug Material.flax
#	Content/Engine/DefaultDeformableMaterial.flax
#	Content/Engine/DefaultMaterial.flax
#	Content/Engine/DefaultTerrainMaterial.flax
#	Content/Engine/SingleColorMaterial.flax
#	Content/Engine/SkyboxMaterial.flax
#	Source/Engine/Graphics/Materials/MaterialShader.h
2024-04-23 10:30:01 +02:00
Wojtek Figat
60e8d73079 Merge remote-tracking branch 'origin/master' into 1.9
# Conflicts:
#	Source/Engine/Renderer/RenderList.cpp
#	Source/Engine/Renderer/RenderList.h
2024-04-17 09:58:59 +02:00
Wojtek Figat
cf23892bd4 Fix sun shadows invalidate when view rotates 2024-04-14 23:51:20 +02:00
Wojtek Figat
25f3cef8c3 Fix artifacts due to light shape culling and use depth test to improve perf 2024-04-14 23:44:08 +02:00
Wojtek Figat
00f2a0b825 Improve doc 2024-04-12 11:29:21 +02:00
Wojtek Figat
7342629a86 Add dynamic resolution for static shadow map tiles limited by current dynamic res 2024-04-11 18:47:32 +02:00
Wojtek Figat
5f860db6a5 Fix typo 2024-04-11 17:34:21 +02:00
Wojtek Figat
6233718b06 Update engine shaders 2024-04-11 17:33:42 +02:00
Wojtek Figat
62444315de Add METERS_TO_UNITS and impl metric units in shadows rendering 2024-04-11 16:38:43 +02:00
Wojtek Figat
a532ea7b42 Add InvalidateShadow for manual shadow cache refresh 2024-04-11 16:34:42 +02:00
Wojtek Figat
803249f126 Minor tweaks 2024-04-11 16:19:35 +02:00
Wojtek Figat
4e65b76b8c Optimize BoundingSphere.Intersects to be inlined by the compiler 2024-04-11 15:58:34 +02:00
Wojtek Figat
890b2da108 Add **shadows caching for static geometry** 2024-04-11 15:35:18 +02:00
Wojtek Figat
eac1d19a09 Add additional StaticFlagsCompare to Render View for dynamic or static only drawing 2024-04-11 10:21:13 +02:00
Wojtek Figat
c4949de28f Add new Static Flag Shadow for cached shadow maps 2024-04-11 10:20:21 +02:00
Wojtek Figat
340ef194d3 Add grey out to obsolete/deprecated members in properties panel 2024-04-10 13:36:59 +02:00
Wojtek Figat
b4547ec4d2 Minor fixes 2024-04-10 11:03:33 +02:00
Wojtek Figat
89f7e442f7 Fix point light seams due to missing shadow map borders 2024-04-10 11:03:18 +02:00
Wojtek Figat
e7bef5e880 Bring back Optimized PCF sampling for shadow maps
61323f8526
2024-04-09 17:55:29 +02:00
Wojtek Figat
ff7c986fb1 Add better stability to Cascaded Shadow Maps projection 2024-04-09 16:58:22 +02:00
Wojtek Figat
708fba5136 Add variable rate update for shadow maps atlas based on distance to light 2024-04-08 00:04:57 +02:00
Wojtek Figat
7d92779e99 Merge remote-tracking branch 'origin/master' into 1.9 2024-04-05 21:50:42 +02:00
Wojtek Figat
4c8528dcae Remove branch macro as it's just texture sample in lights shader 2024-04-05 12:48:34 +02:00
Wojtek Figat
3efd1e4e84 Optimize local lights sphere mesh rendering to match the area better 2024-04-05 12:48:09 +02:00
Wojtek Figat
0cc6669cbd Reimplement cascaded shadow maps blending via dithering 2024-04-05 10:59:34 +02:00
Wojtek Figat
8bd409e95d DIsable certain shader features in Volumetric Fog shader 2024-04-04 14:35:22 +02:00
Wojtek Figat
3d0d41ebff Add reducing shadows quality for smaller local lights 2024-04-04 13:29:38 +02:00
Wojtek Figat
61323f8526 Refactor shadows rendering to use Shadow Map Atlas 2024-04-04 12:54:07 +02:00
Wojtek Figat
017def29d4 Rename ShadowSamplerPCF to ShadowSamplerLinear 2024-04-03 13:29:45 +02:00
Wojtek Figat
13a04c2941 Add stencilValue for stencil buffer clearing 2024-04-02 14:56:26 +02:00
Wojtek Figat
bc9cdf5cdb Update version 2024-04-02 14:34:43 +02:00
Wojtek Figat
f7470af42d Optimize depth pass rendering to batch simple materials together 2024-03-26 18:04:08 +01:00
Wojtek Figat
5c356ec22a Fix Global Surface Atlas defragmentation flicker when atlas it nearly full 2024-03-26 16:50:58 +01:00
Wojtek Figat
06a35da0a8 Merge remote-tracking branch 'origin/master' into 1.9 2024-03-26 16:45:31 +01:00
Wojtek Figat
55af307c43 Optimize env probes data storage in renderer 2024-03-26 15:01:12 +01:00
Wojtek Figat
4ab572426d Various renamings 2024-03-26 14:27:10 +01:00
Wojtek Figat
01d91bf102 Optimize decals rendering 2024-03-26 14:05:24 +01:00
Wojtek Figat
2dfb1058b2 Optimize world matrix storage for drawable objects to use Matrix3x4 instead of full matrix 2024-03-26 11:29:01 +01:00
Wojtek Figat
cdbb2cc813 Refactor shader structures naming with a prefix 2024-03-25 17:52:48 +01:00
Wojtek Figat
0e00f1e0eb Refactor lights data in renderer storage 2024-03-25 17:13:40 +01:00
Wojtek Figat
d13621e631 Skip CloseFileHandles if file is not in use 2024-03-25 16:50:48 +01:00
162 changed files with 3276 additions and 3274 deletions

View File

@@ -1,4 +1,4 @@
# Redirect to our own Git LFS server # Redirect to our own Git LFS server
[lfs] [lfs]
url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs" #url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs"
locksverify = false locksverify = false

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -16,7 +16,6 @@
#include "./Flax/ExponentialHeightFog.hlsl" #include "./Flax/ExponentialHeightFog.hlsl"
@2// Forward Shading: Constants @2// Forward Shading: Constants
LightData DirectionalLight; LightData DirectionalLight;
LightShadowData DirectionalLightShadow;
LightData SkyLight; LightData SkyLight;
ProbeData EnvironmentProbe; ProbeData EnvironmentProbe;
ExponentialHeightFogData ExponentialHeightFog; ExponentialHeightFogData ExponentialHeightFog;
@@ -26,9 +25,9 @@ LightData LocalLights[MAX_LOCAL_LIGHTS];
@3// Forward Shading: Resources @3// Forward Shading: Resources
TextureCube EnvProbe : register(t__SRV__); TextureCube EnvProbe : register(t__SRV__);
TextureCube SkyLightTexture : register(t__SRV__); TextureCube SkyLightTexture : register(t__SRV__);
Texture2DArray DirectionalLightShadowMap : register(t__SRV__); Buffer<float4> ShadowsBuffer : register(t__SRV__);
Texture2D<float> ShadowMap : register(t__SRV__);
@4// Forward Shading: Utilities @4// Forward Shading: Utilities
DECLARE_LIGHTSHADOWDATA_ACCESS(DirectionalLightShadow);
@5// Forward Shading: Shaders @5// Forward Shading: Shaders
// Pixel Shader function for Forward Pass // Pixel Shader function for Forward Pass
@@ -80,11 +79,8 @@ void PS_Forward(
// Calculate lighting from a single directional light // Calculate lighting from a single directional light
float4 shadowMask = 1.0f; float4 shadowMask = 1.0f;
if (DirectionalLight.CastShadows > 0) ShadowSample shadow = SampleDirectionalLightShadow(DirectionalLight, ShadowsBuffer, ShadowMap, gBuffer);
{ shadowMask = GetShadowMask(shadow);
LightShadowData directionalLightShadowData = GetDirectionalLightShadowData();
shadowMask.r = SampleShadow(DirectionalLight, directionalLightShadowData, DirectionalLightShadowMap, gBuffer, shadowMask.g);
}
float4 light = GetLighting(ViewPos, DirectionalLight, gBuffer, shadowMask, false, false); float4 light = GetLighting(ViewPos, DirectionalLight, gBuffer, shadowMask, false, false);
// Calculate lighting from sky light // Calculate lighting from sky light

View File

@@ -26,7 +26,7 @@ struct RibbonInput
// Primary constant buffer (with additional material parameters) // Primary constant buffer (with additional material parameters)
META_CB_BEGIN(0, Data) META_CB_BEGIN(0, Data)
float4x4 WorldMatrix; float4x3 WorldMatrix;
uint SortedIndicesOffset; uint SortedIndicesOffset;
float PerInstanceRandom; float PerInstanceRandom;
int ParticleStride; int ParticleStride;
@@ -45,7 +45,7 @@ int RibbonWidthOffset;
int RibbonTwistOffset; int RibbonTwistOffset;
int RibbonFacingVectorOffset; int RibbonFacingVectorOffset;
uint RibbonSegmentCount; uint RibbonSegmentCount;
float4x4 WorldMatrixInverseTransposed; float4x3 WorldMatrixInverseTransposed;
@1META_CB_END @1META_CB_END
// Particles attributes buffer // Particles attributes buffer
@@ -138,7 +138,7 @@ MaterialInput GetMaterialInput(PixelInput input)
#if USE_INSTANCING #if USE_INSTANCING
#define GetInstanceTransform(input) float4x4(float4(input.InstanceTransform1.xyz, 0.0f), float4(input.InstanceTransform2.xyz, 0.0f), float4(input.InstanceTransform3.xyz, 0.0f), float4(input.InstanceOrigin.xyz, 1.0f)) #define GetInstanceTransform(input) float4x4(float4(input.InstanceTransform1.xyz, 0.0f), float4(input.InstanceTransform2.xyz, 0.0f), float4(input.InstanceTransform3.xyz, 0.0f), float4(input.InstanceOrigin.xyz, 1.0f))
#else #else
#define GetInstanceTransform(input) WorldMatrix; #define GetInstanceTransform(input) ToMatrix4x4(WorldMatrix);
#endif #endif
// Removes the scale vector from the local to world transformation matrix (supports instancing) // Removes the scale vector from the local to world transformation matrix (supports instancing)
@@ -264,12 +264,12 @@ float4 GetParticleVec4(uint particleIndex, int offset)
float3 TransformParticlePosition(float3 input) float3 TransformParticlePosition(float3 input)
{ {
return mul(float4(input, 1.0f), WorldMatrix).xyz; return mul(float4(input, 1.0f), ToMatrix4x4(WorldMatrix)).xyz;
} }
float3 TransformParticleVector(float3 input) float3 TransformParticleVector(float3 input)
{ {
return mul(float4(input, 0.0f), WorldMatrixInverseTransposed).xyz; return mul(float4(input, 0.0f), ToMatrix4x4(WorldMatrixInverseTransposed)).xyz;
} }
@8 @8
@@ -333,7 +333,7 @@ VertexOutput VS_Sprite(SpriteInput input, uint particleIndex : SV_InstanceID)
float2 spriteSize = GetParticleVec2(particleIndex, SpriteSizeOffset); float2 spriteSize = GetParticleVec2(particleIndex, SpriteSizeOffset);
int spriteFacingMode = SpriteFacingModeOffset != -1 ? GetParticleInt(particleIndex, SpriteFacingModeOffset) : -1; int spriteFacingMode = SpriteFacingModeOffset != -1 ? GetParticleInt(particleIndex, SpriteFacingModeOffset) : -1;
float4x4 world = WorldMatrix; float4x4 world = ToMatrix4x4(WorldMatrix);
float3x3 eulerMatrix = EulerMatrix(radians(particleRotation)); float3x3 eulerMatrix = EulerMatrix(radians(particleRotation));
float3x3 viewRot = transpose((float3x3)ViewMatrix); float3x3 viewRot = transpose((float3x3)ViewMatrix);
float3 position = mul(float4(particlePosition, 1), world).xyz; float3 position = mul(float4(particlePosition, 1), world).xyz;
@@ -463,11 +463,12 @@ VertexOutput VS_Model(ModelInput input, uint particleIndex : SV_InstanceID)
} }
// Read particle data // Read particle data
float4x4 worldMatrix = ToMatrix4x4(WorldMatrix);
float3 particlePosition = GetParticleVec3(particleIndex, PositionOffset); float3 particlePosition = GetParticleVec3(particleIndex, PositionOffset);
float3 particleScale = GetParticleVec3(particleIndex, ScaleOffset); float3 particleScale = GetParticleVec3(particleIndex, ScaleOffset);
float3 particleRotation = GetParticleVec3(particleIndex, RotationOffset); float3 particleRotation = GetParticleVec3(particleIndex, RotationOffset);
int modelFacingMode = ModelFacingModeOffset != -1 ? GetParticleInt(particleIndex, ModelFacingModeOffset) : -1; int modelFacingMode = ModelFacingModeOffset != -1 ? GetParticleInt(particleIndex, ModelFacingModeOffset) : -1;
float3 position = mul(float4(particlePosition, 1), WorldMatrix).xyz; float3 position = mul(float4(particlePosition, 1), worldMatrix).xyz;
// Compute final vertex position in the world // Compute final vertex position in the world
float3x3 eulerMatrix = EulerMatrix(radians(particleRotation)); float3x3 eulerMatrix = EulerMatrix(radians(particleRotation));
@@ -506,7 +507,7 @@ VertexOutput VS_Model(ModelInput input, uint particleIndex : SV_InstanceID)
world = mul(world, scaleMatrix); world = mul(world, scaleMatrix);
} }
world = transpose(world); world = transpose(world);
world = mul(world, WorldMatrix); world = mul(world, worldMatrix);
// Calculate the vertex position in world space // Calculate the vertex position in world space
output.WorldPosition = mul(float4(input.Position, 1), world).xyz; output.WorldPosition = mul(float4(input.Position, 1), world).xyz;
@@ -520,12 +521,12 @@ VertexOutput VS_Model(ModelInput input, uint particleIndex : SV_InstanceID)
#if USE_VERTEX_COLOR #if USE_VERTEX_COLOR
output.VertexColor = input.Color; output.VertexColor = input.Color;
#endif #endif
output.InstanceOrigin = WorldMatrix[3].xyz; output.InstanceOrigin = worldMatrix[3].xyz;
output.InstanceParams = PerInstanceRandom; output.InstanceParams = PerInstanceRandom;
// Calculate tanget space to world space transformation matrix for unit vectors // Calculate tanget space to world space transformation matrix for unit vectors
half3x3 tangentToLocal = CalcTangentToLocal(input); half3x3 tangentToLocal = CalcTangentToLocal(input);
half3x3 tangentToWorld = CalcTangentToWorld(WorldMatrix, tangentToLocal); half3x3 tangentToWorld = CalcTangentToWorld(worldMatrix, tangentToLocal);
output.TBN = tangentToWorld; output.TBN = tangentToWorld;
// Get material input params if need to evaluate any material property // Get material input params if need to evaluate any material property
@@ -625,12 +626,13 @@ VertexOutput VS_Ribbon(RibbonInput input, uint vertexIndex : SV_VertexID)
#if USE_VERTEX_COLOR #if USE_VERTEX_COLOR
output.VertexColor = 1; output.VertexColor = 1;
#endif #endif
output.InstanceOrigin = WorldMatrix[3].xyz; float4x4 world = ToMatrix4x4(WorldMatrix);
output.InstanceOrigin = world[3].xyz;
output.InstanceParams = PerInstanceRandom; output.InstanceParams = PerInstanceRandom;
// Calculate tanget space to world space transformation matrix for unit vectors // Calculate tanget space to world space transformation matrix for unit vectors
half3x3 tangentToLocal = float3x3(tangentRight, tangentUp, cross(tangentRight, tangentUp)); half3x3 tangentToLocal = float3x3(tangentRight, tangentUp, cross(tangentRight, tangentUp));
half3x3 tangentToWorld = CalcTangentToWorld(WorldMatrix, tangentToLocal); half3x3 tangentToWorld = CalcTangentToWorld(world, tangentToLocal);
output.TBN = tangentToWorld; output.TBN = tangentToWorld;
// Get material input params if need to evaluate any material property // Get material input params if need to evaluate any material property

View File

@@ -10,8 +10,8 @@
@7 @7
// Primary constant buffer (with additional material parameters) // Primary constant buffer (with additional material parameters)
META_CB_BEGIN(0, Data) META_CB_BEGIN(0, Data)
float4x4 WorldMatrix; float4x3 WorldMatrix;
float4x4 PrevWorldMatrix; float4x3 PrevWorldMatrix;
float2 Dummy0; float2 Dummy0;
float LODDitherFactor; float LODDitherFactor;
float PerInstanceRandom; float PerInstanceRandom;
@@ -171,7 +171,7 @@ MaterialInput GetMaterialInput(PixelInput input)
#if USE_INSTANCING #if USE_INSTANCING
#define CalculateInstanceTransform(input) float4x4 world = GetInstanceTransform(input); output.Geometry.InstanceTransform1 = input.InstanceTransform1.xyz; output.Geometry.InstanceTransform2 = input.InstanceTransform2.xyz; output.Geometry.InstanceTransform3 = input.InstanceTransform3.xyz; #define CalculateInstanceTransform(input) float4x4 world = GetInstanceTransform(input); output.Geometry.InstanceTransform1 = input.InstanceTransform1.xyz; output.Geometry.InstanceTransform2 = input.InstanceTransform2.xyz; output.Geometry.InstanceTransform3 = input.InstanceTransform3.xyz;
#else #else
#define CalculateInstanceTransform(input) float4x4 world = WorldMatrix; output.Geometry.InstanceTransform1 = world[0].xyz; output.Geometry.InstanceTransform2 = world[1].xyz; output.Geometry.InstanceTransform3 = world[2].xyz; #define CalculateInstanceTransform(input) float4x4 world = ToMatrix4x4(WorldMatrix); output.Geometry.InstanceTransform1 = world[0].xyz; output.Geometry.InstanceTransform2 = world[1].xyz; output.Geometry.InstanceTransform3 = world[2].xyz;
#endif #endif
// Removes the scale vector from the local to world transformation matrix (supports instancing) // Removes the scale vector from the local to world transformation matrix (supports instancing)
@@ -328,7 +328,7 @@ VertexOutput VS(ModelInput input)
// Compute world space vertex position // Compute world space vertex position
CalculateInstanceTransform(input); CalculateInstanceTransform(input);
output.Geometry.WorldPosition = mul(float4(input.Position.xyz, 1), world).xyz; output.Geometry.WorldPosition = mul(float4(input.Position.xyz, 1), world).xyz;
output.Geometry.PrevWorldPosition = mul(float4(input.Position.xyz, 1), PrevWorldMatrix).xyz; output.Geometry.PrevWorldPosition = mul(float4(input.Position.xyz, 1), ToMatrix4x4(PrevWorldMatrix)).xyz;
// Compute clip space position // Compute clip space position
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix); output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
@@ -402,7 +402,7 @@ float4 VS_Depth(ModelInput_PosOnly input) : SV_Position
#if USE_INSTANCING #if USE_INSTANCING
float4x4 world = GetInstanceTransform(input); float4x4 world = GetInstanceTransform(input);
#else #else
float4x4 world = WorldMatrix; float4x4 world = ToMatrix4x4(WorldMatrix);
#endif #endif
float3 worldPosition = mul(float4(input.Position.xyz, 1), world).xyz; float3 worldPosition = mul(float4(input.Position.xyz, 1), world).xyz;
float4 position = mul(float4(worldPosition, 1), ViewProjectionMatrix); float4 position = mul(float4(worldPosition, 1), ViewProjectionMatrix);
@@ -508,9 +508,9 @@ VertexOutput VS_Skinned(ModelInput_Skinned input)
output.Geometry.WorldPosition = mul(float4(position, 1), world).xyz; output.Geometry.WorldPosition = mul(float4(position, 1), world).xyz;
#if PER_BONE_MOTION_BLUR #if PER_BONE_MOTION_BLUR
float3 prevPosition = SkinPrevPosition(input); float3 prevPosition = SkinPrevPosition(input);
output.Geometry.PrevWorldPosition = mul(float4(prevPosition, 1), PrevWorldMatrix).xyz; output.Geometry.PrevWorldPosition = mul(float4(prevPosition, 1), ToMatrix4x4(PrevWorldMatrix)).xyz;
#else #else
output.Geometry.PrevWorldPosition = mul(float4(position, 1), PrevWorldMatrix).xyz; output.Geometry.PrevWorldPosition = mul(float4(position, 1), ToMatrix4x4(PrevWorldMatrix)).xyz;
#endif #endif
// Compute clip space position // Compute clip space position

View File

@@ -17,7 +17,7 @@
@7 @7
// Primary constant buffer (with additional material parameters) // Primary constant buffer (with additional material parameters)
META_CB_BEGIN(0, Data) META_CB_BEGIN(0, Data)
float4x4 WorldMatrix; float4x3 WorldMatrix;
float3 WorldInvScale; float3 WorldInvScale;
float WorldDeterminantSign; float WorldDeterminantSign;
float PerInstanceRandom; float PerInstanceRandom;
@@ -194,7 +194,7 @@ float3 TransformViewVectorToWorld(MaterialInput input, float3 viewVector)
// Transforms a vector from local space to world space // Transforms a vector from local space to world space
float3 TransformLocalVectorToWorld(MaterialInput input, float3 localVector) float3 TransformLocalVectorToWorld(MaterialInput input, float3 localVector)
{ {
float3x3 localToWorld = (float3x3)WorldMatrix; float3x3 localToWorld = (float3x3)ToMatrix4x4(WorldMatrix);
//localToWorld = RemoveScaleFromLocalToWorld(localToWorld); //localToWorld = RemoveScaleFromLocalToWorld(localToWorld);
return mul(localVector, localToWorld); return mul(localVector, localToWorld);
} }
@@ -202,7 +202,7 @@ float3 TransformLocalVectorToWorld(MaterialInput input, float3 localVector)
// Transforms a vector from local space to world space // Transforms a vector from local space to world space
float3 TransformWorldVectorToLocal(MaterialInput input, float3 worldVector) float3 TransformWorldVectorToLocal(MaterialInput input, float3 worldVector)
{ {
float3x3 localToWorld = (float3x3)WorldMatrix; float3x3 localToWorld = (float3x3)ToMatrix4x4(WorldMatrix);
//localToWorld = RemoveScaleFromLocalToWorld(localToWorld); //localToWorld = RemoveScaleFromLocalToWorld(localToWorld);
return mul(localToWorld, worldVector); return mul(localToWorld, worldVector);
} }
@@ -210,7 +210,7 @@ float3 TransformWorldVectorToLocal(MaterialInput input, float3 worldVector)
// Gets the current object position // Gets the current object position
float3 GetObjectPosition(MaterialInput input) float3 GetObjectPosition(MaterialInput input)
{ {
return WorldMatrix[3].xyz; return ToMatrix4x4(WorldMatrix)[3].xyz;
} }
// Gets the current object size // Gets the current object size
@@ -365,7 +365,8 @@ VertexOutput VS(TerrainVertexInput input)
float3 position = float3(positionXZ.x, height, positionXZ.y); float3 position = float3(positionXZ.x, height, positionXZ.y);
// Compute world space vertex position // Compute world space vertex position
output.Geometry.WorldPosition = mul(float4(position, 1), WorldMatrix).xyz; float4x4 worldMatrix = ToMatrix4x4(WorldMatrix);
output.Geometry.WorldPosition = mul(float4(position, 1), worldMatrix).xyz;
// Compute clip space position // Compute clip space position
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix); output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
@@ -389,7 +390,7 @@ VertexOutput VS(TerrainVertexInput input)
// Compute world space normal vector // Compute world space normal vector
float3x3 tangentToLocal = CalcTangentBasisFromWorldNormal(normal); float3x3 tangentToLocal = CalcTangentBasisFromWorldNormal(normal);
float3x3 tangentToWorld = CalcTangentToWorld(WorldMatrix, tangentToLocal); float3x3 tangentToWorld = CalcTangentToWorld(worldMatrix, tangentToLocal);
output.Geometry.WorldNormal = tangentToWorld[2]; output.Geometry.WorldNormal = tangentToWorld[2];
// Get material input params if need to evaluate any material property // Get material input params if need to evaluate any material property

View File

@@ -13,8 +13,8 @@
// Primary constant buffer (with additional material parameters) // Primary constant buffer (with additional material parameters)
META_CB_BEGIN(0, Data) META_CB_BEGIN(0, Data)
float4x4 InverseViewProjectionMatrix; float4x4 InverseViewProjectionMatrix;
float4x4 WorldMatrix; float4x3 WorldMatrix;
float4x4 WorldMatrixInverseTransposed; float4x3 WorldMatrixInverseTransposed;
float3 GridSize; float3 GridSize;
float PerInstanceRandom; float PerInstanceRandom;
float Dummy0; float Dummy0;
@@ -49,7 +49,7 @@ struct MaterialInput
#endif #endif
}; };
#define GetInstanceTransform(input) WorldMatrix; #define GetInstanceTransform(input) ToMatrix4x4(WorldMatrix);
// Removes the scale vector from the local to world transformation matrix (supports instancing) // Removes the scale vector from the local to world transformation matrix (supports instancing)
float3x3 RemoveScaleFromLocalToWorld(float3x3 localToWorld) float3x3 RemoveScaleFromLocalToWorld(float3x3 localToWorld)
@@ -170,12 +170,12 @@ float4 GetParticleVec4(uint particleIndex, int offset)
float3 TransformParticlePosition(float3 input) float3 TransformParticlePosition(float3 input)
{ {
return mul(float4(input, 1.0f), WorldMatrix).xyz; return mul(float4(input, 1.0f), ToMatrix4x4(WorldMatrix)).xyz;
} }
float3 TransformParticleVector(float3 input) float3 TransformParticleVector(float3 input)
{ {
return mul(float4(input, 0.0f), WorldMatrixInverseTransposed).xyz; return mul(float4(input, 0.0f), ToMatrix4x4(WorldMatrixInverseTransposed)).xyz;
} }
@8 @8
@@ -219,7 +219,7 @@ void PS_VolumetricFog(Quad_GS2PS input, out float4 VBufferA : SV_Target0, out fl
materialInput.ParticleIndex = ParticleIndex; materialInput.ParticleIndex = ParticleIndex;
materialInput.TBN = float3x3(float3(1, 0, 0), float3(0, 1, 0), float3(0, 0, 1)); materialInput.TBN = float3x3(float3(1, 0, 0), float3(0, 1, 0), float3(0, 0, 1));
materialInput.TwoSidedSign = 1.0f; materialInput.TwoSidedSign = 1.0f;
materialInput.InstanceOrigin = WorldMatrix[3].xyz; materialInput.InstanceOrigin = ToMatrix4x4(WorldMatrix)[3].xyz;
materialInput.InstanceParams = PerInstanceRandom; materialInput.InstanceParams = PerInstanceRandom;
materialInput.SvPosition = clipPos; materialInput.SvPosition = clipPos;
Material material = GetMaterialPS(materialInput); Material material = GetMaterialPS(materialInput);

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -2,9 +2,9 @@
"Name": "Flax", "Name": "Flax",
"Version": { "Version": {
"Major": 1, "Major": 1,
"Minor": 8, "Minor": 9,
"Revision": 1, "Revision": 0,
"Build": 6511 "Build": 6601
}, },
"Company": "Flax", "Company": "Flax",
"Copyright": "Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.", "Copyright": "Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.",

View File

@@ -377,6 +377,10 @@ namespace FlaxEditor.CustomEditors
else if (Values.HasDefaultValue && CanRevertDefaultValue) else if (Values.HasDefaultValue && CanRevertDefaultValue)
color = Color.Yellow * 0.8f; color = Color.Yellow * 0.8f;
LinkedLabel.HighlightStripColor = color; LinkedLabel.HighlightStripColor = color;
// Grey out deprecated members
if (Values.IsObsolete)
LinkedLabel.TextColor = LinkedLabel.TextColorHighlighted = FlaxEngine.GUI.Style.Current.ForegroundGrey;
} }
} }
@@ -659,7 +663,7 @@ namespace FlaxEditor.CustomEditors
} }
} }
if (obj == null || Values.Type.IsInstanceOfType(obj)) if ((obj == null && !Values.Type.IsValueType) || Values.Type.IsInstanceOfType(obj))
{ {
result = obj; result = obj;
return true; return true;
@@ -671,20 +675,7 @@ namespace FlaxEditor.CustomEditors
/// <summary> /// <summary>
/// Gets a value indicating whether can paste value from the system clipboard to the property value container. /// Gets a value indicating whether can paste value from the system clipboard to the property value container.
/// </summary> /// </summary>
public bool CanPaste public bool CanPaste => !string.IsNullOrEmpty(Clipboard.Text);
{
get
{
try
{
return GetClipboardObject(out _, false);
}
catch
{
return false;
}
}
}
/// <summary> /// <summary>
/// Sets the value from the system clipboard. /// Sets the value from the system clipboard.

View File

@@ -474,32 +474,7 @@ namespace FlaxEditor.CustomEditors.Editors
} }
if (layout.Editors.Count != 0) if (layout.Editors.Count != 0)
{ {
var sb = Clipboard.Text; return !string.IsNullOrEmpty(Clipboard.Text);
if (!string.IsNullOrEmpty(sb))
{
try
{
var data = JsonSerializer.Deserialize<string[]>(sb);
if (data == null || data.Length != layout.Editors.Count)
return false;
for (var i = 0; i < layout.Editors.Count; i++)
{
Clipboard.Text = data[i];
if (!layout.Editors[i].CanPaste)
return false;
}
return true;
}
catch
{
return false;
}
finally
{
Clipboard.Text = sb;
}
}
return false;
} }
if (layout.Children.Any(x => x is LayoutElementsContainer)) if (layout.Children.Any(x => x is LayoutElementsContainer))
{ {

View File

@@ -139,6 +139,11 @@ namespace FlaxEditor.CustomEditors
/// </summary> /// </summary>
public bool IsArray => Type != ScriptType.Null && Type.IsArray; public bool IsArray => Type != ScriptType.Null && Type.IsArray;
/// <summary>
/// True if member or type has <see cref="System.ObsoleteAttribute"/> that marks it as obsolete.
/// </summary>
public bool IsObsolete { get; }
/// <summary> /// <summary>
/// Gets the values types array (without duplicates). /// Gets the values types array (without duplicates).
/// </summary> /// </summary>
@@ -160,6 +165,7 @@ namespace FlaxEditor.CustomEditors
{ {
Info = info; Info = info;
Type = Info.ValueType; Type = Info.ValueType;
IsObsolete = Info.HasAttribute(typeof(ObsoleteAttribute), true);
} }
/// <summary> /// <summary>

View File

@@ -175,13 +175,6 @@ namespace FlaxEditor.Options
[EditorDisplay("Interface", "New Window Location"), EditorOrder(150), Tooltip("Define the opening method for new windows, open in a new tab by default.")] [EditorDisplay("Interface", "New Window Location"), EditorOrder(150), Tooltip("Define the opening method for new windows, open in a new tab by default.")]
public DockStateProxy NewWindowLocation { get; set; } = DockStateProxy.Float; public DockStateProxy NewWindowLocation { get; set; } = DockStateProxy.Float;
/// <summary>
/// Gets or sets the timestamps prefix mode for debug log messages.
/// </summary>
[DefaultValue(TimestampsFormats.None)]
[EditorDisplay("Interface"), EditorOrder(210), Tooltip("The timestamps prefix mode for debug log messages.")]
public TimestampsFormats DebugLogTimestampsFormat { get; set; } = TimestampsFormats.None;
/// <summary> /// <summary>
/// Gets or sets the editor icons scale. Editor restart required. /// Gets or sets the editor icons scale. Editor restart required.
/// </summary> /// </summary>
@@ -211,23 +204,72 @@ namespace FlaxEditor.Options
public bool SeparateValueAndUnit { get; set; } public bool SeparateValueAndUnit { get; set; }
/// <summary> /// <summary>
/// Gets or sets the timestamps prefix mode for output log messages. /// Gets or sets the timestamps prefix mode for debug log messages.
/// </summary> /// </summary>
[DefaultValue(TimestampsFormats.TimeSinceStartup)] [DefaultValue(TimestampsFormats.None)]
[EditorDisplay("Output Log", "Timestamps Format"), EditorOrder(300), Tooltip("The timestamps prefix mode for output log messages.")] [EditorDisplay("Debug Log"), EditorOrder(300), Tooltip("The timestamps prefix mode for debug log messages.")]
public TimestampsFormats OutputLogTimestampsFormat { get; set; } = TimestampsFormats.TimeSinceStartup; public TimestampsFormats DebugLogTimestampsFormat { get; set; } = TimestampsFormats.None;
/// <summary>
/// Gets or sets the clear on play for debug log messages.
/// </summary>
[DefaultValue(true)]
[EditorDisplay("Debug Log", "Clear on Play"), EditorOrder(310), Tooltip("Clears all log entries on enter playmode.")]
public bool DebugLogClearOnPlay { get; set; } = true;
/// <summary>
/// Gets or sets the collapse mode for debug log messages.
/// </summary>
[DefaultValue(true)]
[EditorDisplay("Debug Log"), EditorOrder(312), Tooltip("Collapses similar or repeating log entries.")]
public bool DebugLogCollapse { get; set; } = true;
/// <summary>
/// Gets or sets the automatic pause on error for debug log messages.
/// </summary>
[DefaultValue(false)]
[EditorDisplay("Debug Log", "Pause on Error"), EditorOrder(314), Tooltip("Performs auto pause on error.")]
public bool DebugLogPauseOnError { get; set; } = false;
/// <summary>
/// Gets or sets the automatic pause on error for debug log messages.
/// </summary>
[DefaultValue(true)]
[EditorDisplay("Debug Log", "Show error messages"), EditorOrder(320), Tooltip("Shows/hides error messages.")]
public bool DebugLogShowErrorMessages { get; set; } = true;
/// <summary>
/// Gets or sets the automatic pause on error for debug log messages.
/// </summary>
[DefaultValue(true)]
[EditorDisplay("Debug Log", "Show warning messages"), EditorOrder(322), Tooltip("Shows/hides warning messages.")]
public bool DebugLogShowWarningMessages { get; set; } = true;
/// <summary>
/// Gets or sets the automatic pause on error for debug log messages.
/// </summary>
[DefaultValue(true)]
[EditorDisplay("Debug Log", "Show info messages"), EditorOrder(324), Tooltip("Shows/hides info messages.")]
public bool DebugLogShowInfoMessages { get; set; } = true;
/// <summary> /// <summary>
/// Gets or sets the timestamps prefix mode for output log messages. /// Gets or sets the timestamps prefix mode for output log messages.
/// </summary> /// </summary>
[DefaultValue(TimestampsFormats.TimeSinceStartup)]
[EditorDisplay("Output Log", "Timestamps Format"), EditorOrder(400), Tooltip("The timestamps prefix mode for output log messages.")]
public TimestampsFormats OutputLogTimestampsFormat { get; set; } = TimestampsFormats.TimeSinceStartup;
/// <summary>
/// Gets or sets the log type prefix mode for output log messages.
/// </summary>
[DefaultValue(true)] [DefaultValue(true)]
[EditorDisplay("Output Log", "Show Log Type"), EditorOrder(310), Tooltip("Determines whether show log type prefix in output log messages.")] [EditorDisplay("Output Log", "Show Log Type"), EditorOrder(410), Tooltip("Determines whether show log type prefix in output log messages.")]
public bool OutputLogShowLogType { get; set; } = true; public bool OutputLogShowLogType { get; set; } = true;
/// <summary> /// <summary>
/// Gets or sets the output log text font. /// Gets or sets the output log text font.
/// </summary> /// </summary>
[EditorDisplay("Output Log", "Text Font"), EditorOrder(320), Tooltip("The output log text font.")] [EditorDisplay("Output Log", "Text Font"), EditorOrder(420), Tooltip("The output log text font.")]
public FontReference OutputLogTextFont public FontReference OutputLogTextFont
{ {
get => _outputLogFont; get => _outputLogFont;
@@ -246,63 +288,70 @@ namespace FlaxEditor.Options
/// Gets or sets the output log text color. /// Gets or sets the output log text color.
/// </summary> /// </summary>
[DefaultValue(typeof(Color), "1,1,1,1")] [DefaultValue(typeof(Color), "1,1,1,1")]
[EditorDisplay("Output Log", "Text Color"), EditorOrder(330), Tooltip("The output log text color.")] [EditorDisplay("Output Log", "Text Color"), EditorOrder(430), Tooltip("The output log text color.")]
public Color OutputLogTextColor { get; set; } = Color.White; public Color OutputLogTextColor { get; set; } = Color.White;
/// <summary> /// <summary>
/// Gets or sets the output log text shadow color. /// Gets or sets the output log text shadow color.
/// </summary> /// </summary>
[DefaultValue(typeof(Color), "0,0,0,0.5")] [DefaultValue(typeof(Color), "0,0,0,0.5")]
[EditorDisplay("Output Log", "Text Shadow Color"), EditorOrder(340), Tooltip("The output log text shadow color.")] [EditorDisplay("Output Log", "Text Shadow Color"), EditorOrder(440), Tooltip("The output log text shadow color.")]
public Color OutputLogTextShadowColor { get; set; } = new Color(0, 0, 0, 0.5f); public Color OutputLogTextShadowColor { get; set; } = new Color(0, 0, 0, 0.5f);
/// <summary> /// <summary>
/// Gets or sets the output log text shadow offset. Set to 0 to disable this feature. /// Gets or sets the output log text shadow offset. Set to 0 to disable this feature.
/// </summary> /// </summary>
[DefaultValue(typeof(Float2), "1,1")] [DefaultValue(typeof(Float2), "1,1")]
[EditorDisplay("Output Log", "Text Shadow Offset"), EditorOrder(340), Tooltip("The output log text shadow offset. Set to 0 to disable this feature.")] [EditorDisplay("Output Log", "Text Shadow Offset"), EditorOrder(445), Tooltip("The output log text shadow offset. Set to 0 to disable this feature.")]
public Float2 OutputLogTextShadowOffset { get; set; } = new Float2(1); public Float2 OutputLogTextShadowOffset { get; set; } = new Float2(1);
/// <summary> /// <summary>
/// Gets or sets a value indicating whether auto-focus output log window on code compilation error. /// Gets or sets a value indicating whether auto-focus output log window on code compilation error.
/// </summary> /// </summary>
[DefaultValue(true)] [DefaultValue(true)]
[EditorDisplay("Output Log", "Focus Output Log On Compilation Error"), EditorOrder(350), Tooltip("Determines whether auto-focus output log window on code compilation error.")] [EditorDisplay("Output Log", "Focus Output Log On Compilation Error"), EditorOrder(450), Tooltip("Determines whether auto-focus output log window on code compilation error.")]
public bool FocusOutputLogOnCompilationError { get; set; } = true; public bool FocusOutputLogOnCompilationError { get; set; } = true;
/// <summary> /// <summary>
/// Gets or sets a value indicating whether auto-focus output log window on game build error. /// Gets or sets a value indicating whether auto-focus output log window on game build error.
/// </summary> /// </summary>
[DefaultValue(true)] [DefaultValue(true)]
[EditorDisplay("Output Log", "Focus Output Log On Game Build Error"), EditorOrder(360), Tooltip("Determines whether auto-focus output log window on game build error.")] [EditorDisplay("Output Log", "Focus Output Log On Game Build Error"), EditorOrder(460), Tooltip("Determines whether auto-focus output log window on game build error.")]
public bool FocusOutputLogOnGameBuildError { get; set; } = true; public bool FocusOutputLogOnGameBuildError { get; set; } = true;
/// <summary>
/// Gets or sets the value for automatic scroll to bottom in output log.
/// </summary>
[DefaultValue(true)]
[EditorDisplay("Output Log", "Scroll to bottom"), EditorOrder(470), Tooltip("Scroll the output log view to bottom automatically after new lines are added.")]
public bool OutputLogScrollToBottom { get; set; } = true;
/// <summary> /// <summary>
/// Gets or sets a value indicating whether auto-focus game window on play mode start. /// Gets or sets a value indicating whether auto-focus game window on play mode start.
/// </summary> /// </summary>
[DefaultValue(true)] [DefaultValue(true)]
[EditorDisplay("Play In-Editor", "Focus Game Window On Play"), EditorOrder(400), Tooltip("Determines whether auto-focus game window on play mode start.")] [EditorDisplay("Play In-Editor", "Focus Game Window On Play"), EditorOrder(500), Tooltip("Determines whether auto-focus game window on play mode start.")]
public bool FocusGameWinOnPlay { get; set; } = true; public bool FocusGameWinOnPlay { get; set; } = true;
/// <summary> /// <summary>
/// Gets or sets a value indicating what action should be taken upon pressing the play button. /// Gets or sets a value indicating what action should be taken upon pressing the play button.
/// </summary> /// </summary>
[DefaultValue(PlayAction.PlayScenes)] [DefaultValue(PlayAction.PlayScenes)]
[EditorDisplay("Play In-Editor", "Play Button Action"), EditorOrder(410)] [EditorDisplay("Play In-Editor", "Play Button Action"), EditorOrder(510)]
public PlayAction PlayButtonAction { get; set; } = PlayAction.PlayScenes; public PlayAction PlayButtonAction { get; set; } = PlayAction.PlayScenes;
/// <summary> /// <summary>
/// Gets or sets a value indicating how the game window should be displayed when the game is launched. /// Gets or sets a value indicating how the game window should be displayed when the game is launched.
/// </summary> /// </summary>
[DefaultValue(GameWindowMode.Docked)] [DefaultValue(GameWindowMode.Docked)]
[EditorDisplay("Play In-Editor", "Game Window Mode"), EditorOrder(420), Tooltip("Determines how the game window is displayed when the game is launched.")] [EditorDisplay("Play In-Editor", "Game Window Mode"), EditorOrder(520), Tooltip("Determines how the game window is displayed when the game is launched.")]
public GameWindowMode DefaultGameWindowMode { get; set; } = GameWindowMode.Docked; public GameWindowMode DefaultGameWindowMode { get; set; } = GameWindowMode.Docked;
/// <summary> /// <summary>
/// Gets or sets a value indicating the number of game clients to launch when building and/or running cooked game. /// Gets or sets a value indicating the number of game clients to launch when building and/or running cooked game.
/// </summary> /// </summary>
[DefaultValue(1), Range(1, 4)] [DefaultValue(1), Range(1, 4)]
[EditorDisplay("Cook & Run"), EditorOrder(500)] [EditorDisplay("Cook & Run"), EditorOrder(600)]
public int NumberOfGameClientsToLaunch = 1; public int NumberOfGameClientsToLaunch = 1;
private static FontAsset DefaultFont => FlaxEngine.Content.LoadAsyncInternal<FontAsset>(EditorAssets.PrimaryFont); private static FontAsset DefaultFont => FlaxEngine.Content.LoadAsyncInternal<FontAsset>(EditorAssets.PrimaryFont);
@@ -317,13 +366,13 @@ namespace FlaxEditor.Options
/// <summary> /// <summary>
/// The list of fallback fonts to use when main text font is missing certain characters. Empty to use fonts from GraphicsSettings. /// The list of fallback fonts to use when main text font is missing certain characters. Empty to use fonts from GraphicsSettings.
/// </summary> /// </summary>
[EditorDisplay("Fonts"), EditorOrder(650)] [EditorDisplay("Fonts"), EditorOrder(750)]
public FontAsset[] FallbackFonts = new FontAsset[1] { FlaxEngine.Content.LoadAsyncInternal<FontAsset>(EditorAssets.FallbackFont) }; public FontAsset[] FallbackFonts = new FontAsset[1] { FlaxEngine.Content.LoadAsyncInternal<FontAsset>(EditorAssets.FallbackFont) };
/// <summary> /// <summary>
/// Gets or sets the title font for editor UI. /// Gets or sets the title font for editor UI.
/// </summary> /// </summary>
[EditorDisplay("Fonts"), EditorOrder(600), Tooltip("The title font for editor UI.")] [EditorDisplay("Fonts"), EditorOrder(700), Tooltip("The title font for editor UI.")]
public FontReference TitleFont public FontReference TitleFont
{ {
get => _titleFont; get => _titleFont;
@@ -341,7 +390,7 @@ namespace FlaxEditor.Options
/// <summary> /// <summary>
/// Gets or sets the large font for editor UI. /// Gets or sets the large font for editor UI.
/// </summary> /// </summary>
[EditorDisplay("Fonts"), EditorOrder(610), Tooltip("The large font for editor UI.")] [EditorDisplay("Fonts"), EditorOrder(710), Tooltip("The large font for editor UI.")]
public FontReference LargeFont public FontReference LargeFont
{ {
get => _largeFont; get => _largeFont;
@@ -359,7 +408,7 @@ namespace FlaxEditor.Options
/// <summary> /// <summary>
/// Gets or sets the medium font for editor UI. /// Gets or sets the medium font for editor UI.
/// </summary> /// </summary>
[EditorDisplay("Fonts"), EditorOrder(620), Tooltip("The medium font for editor UI.")] [EditorDisplay("Fonts"), EditorOrder(720), Tooltip("The medium font for editor UI.")]
public FontReference MediumFont public FontReference MediumFont
{ {
get => _mediumFont; get => _mediumFont;
@@ -377,7 +426,7 @@ namespace FlaxEditor.Options
/// <summary> /// <summary>
/// Gets or sets the small font for editor UI. /// Gets or sets the small font for editor UI.
/// </summary> /// </summary>
[EditorDisplay("Fonts"), EditorOrder(630), Tooltip("The small font for editor UI.")] [EditorDisplay("Fonts"), EditorOrder(730), Tooltip("The small font for editor UI.")]
public FontReference SmallFont public FontReference SmallFont
{ {
get => _smallFont; get => _smallFont;

View File

@@ -190,15 +190,7 @@ namespace FlaxEditor.Surface
if (data == null || data.Length < 2) if (data == null || data.Length < 2)
return false; return false;
try return true;
{
var model = JsonConvert.DeserializeObject<DataModel>(data);
return model?.Nodes != null && model.Nodes.Length != 0;
}
catch (Exception)
{
return false;
}
} }
/// <summary> /// <summary>
@@ -215,7 +207,15 @@ namespace FlaxEditor.Surface
try try
{ {
// Load Mr Json // Load Mr Json
var model = FlaxEngine.Json.JsonSerializer.Deserialize<DataModel>(data); DataModel model;
try
{
model = FlaxEngine.Json.JsonSerializer.Deserialize<DataModel>(data);
}
catch
{
return;
}
if (model.Nodes == null) if (model.Nodes == null)
model.Nodes = new DataModelNode[0]; model.Nodes = new DataModelNode[0];

View File

@@ -7,7 +7,7 @@
enum class PixelFormat : unsigned; enum class PixelFormat : unsigned;
enum class DirectorySearchOption; enum class DirectorySearchOption;
class TextureData; struct TextureData;
/// <summary> /// <summary>
/// Helper functions for the editor. /// Helper functions for the editor.

View File

@@ -471,7 +471,13 @@ namespace FlaxEditor.Viewport
trans.SetRotation(ref world); trans.SetRotation(ref world);
trans.Translation += world.TranslationVector; trans.Translation += world.TranslationVector;
} }
obj.Transform = trans; if (obj is ActorNode actorNode)
{
actorNode.Actor.Position = trans.Translation;
actorNode.Actor.Orientation = trans.Orientation;
}
else
obj.Transform = trans;
} }
TransformGizmo.EndTransforming(); TransformGizmo.EndTransforming();
} }
@@ -520,7 +526,9 @@ namespace FlaxEditor.Viewport
/// <param name="scaleDelta">The scale delta.</param> /// <param name="scaleDelta">The scale delta.</param>
public void ApplyTransform(List<SceneGraphNode> selection, ref Vector3 translationDelta, ref Quaternion rotationDelta, ref Vector3 scaleDelta) public void ApplyTransform(List<SceneGraphNode> selection, ref Vector3 translationDelta, ref Quaternion rotationDelta, ref Vector3 scaleDelta)
{ {
bool applyTranslation = !translationDelta.IsZero;
bool applyRotation = !rotationDelta.IsIdentity; bool applyRotation = !rotationDelta.IsIdentity;
bool applyScale = !scaleDelta.IsZero;
bool useObjCenter = TransformGizmo.ActivePivot == TransformGizmoBase.PivotType.ObjectCenter; bool useObjCenter = TransformGizmo.ActivePivot == TransformGizmoBase.PivotType.ObjectCenter;
Vector3 gizmoPosition = TransformGizmo.Position; Vector3 gizmoPosition = TransformGizmo.Position;
@@ -555,13 +563,29 @@ namespace FlaxEditor.Viewport
} }
// Apply scale // Apply scale
const float scaleLimit = 99_999_999.0f; if (applyScale)
trans.Scale = Float3.Clamp(trans.Scale + scaleDelta, new Float3(-scaleLimit), new Float3(scaleLimit)); {
const float scaleLimit = 99_999_999.0f;
trans.Scale = Float3.Clamp(trans.Scale + scaleDelta, new Float3(-scaleLimit), new Float3(scaleLimit)); ;
}
// Apply translation // Apply translation
trans.Translation += translationDelta; if (applyTranslation)
{
trans.Translation += translationDelta;
}
obj.Transform = trans; if (obj is ActorNode actorNode)
{
if (applyTranslation)
actorNode.Actor.Position = trans.Translation;
if (applyRotation)
actorNode.Actor.Orientation = trans.Orientation;
if (applyScale)
actorNode.Actor.Scale = trans.Scale;
}
else
obj.Transform = trans;
} }
} }

View File

@@ -357,7 +357,9 @@ namespace FlaxEditor.Viewport
/// <param name="scaleDelta">The scale delta.</param> /// <param name="scaleDelta">The scale delta.</param>
public void ApplyTransform(List<SceneGraphNode> selection, ref Vector3 translationDelta, ref Quaternion rotationDelta, ref Vector3 scaleDelta) public void ApplyTransform(List<SceneGraphNode> selection, ref Vector3 translationDelta, ref Quaternion rotationDelta, ref Vector3 scaleDelta)
{ {
bool applyTranslation = !translationDelta.IsZero;
bool applyRotation = !rotationDelta.IsIdentity; bool applyRotation = !rotationDelta.IsIdentity;
bool applyScale = !scaleDelta.IsZero;
bool useObjCenter = TransformGizmo.ActivePivot == TransformGizmoBase.PivotType.ObjectCenter; bool useObjCenter = TransformGizmo.ActivePivot == TransformGizmoBase.PivotType.ObjectCenter;
Vector3 gizmoPosition = TransformGizmo.Position; Vector3 gizmoPosition = TransformGizmo.Position;
@@ -387,13 +389,29 @@ namespace FlaxEditor.Viewport
} }
// Apply scale // Apply scale
const float scaleLimit = 99_999_999.0f; if (applyScale)
trans.Scale = Float3.Clamp(trans.Scale + scaleDelta, new Float3(-scaleLimit), new Float3(scaleLimit)); {
const float scaleLimit = 99_999_999.0f;
trans.Scale = Float3.Clamp(trans.Scale + scaleDelta, new Float3(-scaleLimit), new Float3(scaleLimit));
}
// Apply translation // Apply translation
trans.Translation += translationDelta; if (applyTranslation)
{
trans.Translation += translationDelta;
}
obj.Transform = trans; if (obj is ActorNode actorNode)
{
if (applyTranslation)
actorNode.Actor.Position = trans.Translation;
if (applyRotation)
actorNode.Actor.Orientation = trans.Orientation;
if (applyScale)
actorNode.Actor.Scale = trans.Scale;
}
else
obj.Transform = trans;
} }
} }

View File

@@ -318,7 +318,6 @@ namespace FlaxEditor.Windows
{ {
Title = "Debug Log"; Title = "Debug Log";
Icon = IconInfo; Icon = IconInfo;
OnEditorOptionsChanged(Editor.Options.Options);
FlaxEditor.Utilities.Utils.SetupCommonInputActions(this); FlaxEditor.Utilities.Utils.SetupCommonInputActions(this);
// Toolstrip // Toolstrip
@@ -327,14 +326,42 @@ namespace FlaxEditor.Windows
Parent = this, Parent = this,
}; };
toolstrip.AddButton("Clear", Clear).LinkTooltip("Clears all log entries"); toolstrip.AddButton("Clear", Clear).LinkTooltip("Clears all log entries");
_clearOnPlayButton = (ToolStripButton)toolstrip.AddButton("Clear on Play").SetAutoCheck(true).SetChecked(true).LinkTooltip("Clears all log entries on enter playmode"); _clearOnPlayButton = (ToolStripButton)toolstrip.AddButton("Clear on Play", () =>
_collapseLogsButton = (ToolStripButton)toolstrip.AddButton("Collapse").SetAutoCheck(true).SetChecked(true).LinkTooltip("Collapses similar logs."); {
_pauseOnErrorButton = (ToolStripButton)toolstrip.AddButton("Pause on Error").SetAutoCheck(true).LinkTooltip("Performs auto pause on error"); editor.Options.Options.Interface.DebugLogClearOnPlay = _clearOnPlayButton.Checked;
editor.Options.Apply(editor.Options.Options);
}).SetAutoCheck(true).LinkTooltip("Clears all log entries on enter playmode");
_collapseLogsButton = (ToolStripButton)toolstrip.AddButton("Collapse", () =>
{
editor.Options.Options.Interface.DebugLogCollapse = _collapseLogsButton.Checked;
editor.Options.Apply(editor.Options.Options);
}).SetAutoCheck(true).LinkTooltip("Collapses similar logs.");
_pauseOnErrorButton = (ToolStripButton)toolstrip.AddButton("Pause on Error", () =>
{
editor.Options.Options.Interface.DebugLogPauseOnError = _pauseOnErrorButton.Checked;
editor.Options.Apply(editor.Options.Options);
}).SetAutoCheck(true).LinkTooltip("Performs auto pause on error");
toolstrip.AddSeparator(); toolstrip.AddSeparator();
_groupButtons[0] = (ToolStripButton)toolstrip.AddButton(editor.Icons.Error32, () => UpdateLogTypeVisibility(LogGroup.Error, _groupButtons[0].Checked)).SetAutoCheck(true).SetChecked(true).LinkTooltip("Shows/hides error messages"); _groupButtons[0] = (ToolStripButton)toolstrip.AddButton(editor.Icons.Error32, () =>
_groupButtons[1] = (ToolStripButton)toolstrip.AddButton(editor.Icons.Warning32, () => UpdateLogTypeVisibility(LogGroup.Warning, _groupButtons[1].Checked)).SetAutoCheck(true).SetChecked(true).LinkTooltip("Shows/hides warning messages"); {
_groupButtons[2] = (ToolStripButton)toolstrip.AddButton(editor.Icons.Info32, () => UpdateLogTypeVisibility(LogGroup.Info, _groupButtons[2].Checked)).SetAutoCheck(true).SetChecked(true).LinkTooltip("Shows/hides info messages"); UpdateLogTypeVisibility(LogGroup.Error, _groupButtons[0].Checked);
editor.Options.Options.Interface.DebugLogShowErrorMessages = _groupButtons[0].Checked;
editor.Options.Apply(editor.Options.Options);
}).SetAutoCheck(true).LinkTooltip("Shows/hides error messages");
_groupButtons[1] = (ToolStripButton)toolstrip.AddButton(editor.Icons.Warning32, () =>
{
UpdateLogTypeVisibility(LogGroup.Warning, _groupButtons[1].Checked);
editor.Options.Options.Interface.DebugLogShowWarningMessages = _groupButtons[1].Checked;
editor.Options.Apply(editor.Options.Options);
}).SetAutoCheck(true).LinkTooltip("Shows/hides warning messages");
_groupButtons[2] = (ToolStripButton)toolstrip.AddButton(editor.Icons.Info32, () =>
{
UpdateLogTypeVisibility(LogGroup.Info, _groupButtons[2].Checked);
editor.Options.Options.Interface.DebugLogShowInfoMessages = _groupButtons[2].Checked;
editor.Options.Apply(editor.Options.Options);
}).SetAutoCheck(true).LinkTooltip("Shows/hides info messages");
UpdateCount(); UpdateCount();
OnEditorOptionsChanged(Editor.Options.Options);
// Split panel // Split panel
_split = new SplitPanel(Orientation.Vertical, ScrollBars.Vertical, ScrollBars.Both) _split = new SplitPanel(Orientation.Vertical, ScrollBars.Vertical, ScrollBars.Both)
@@ -380,6 +407,12 @@ namespace FlaxEditor.Windows
private void OnEditorOptionsChanged(EditorOptions options) private void OnEditorOptionsChanged(EditorOptions options)
{ {
_timestampsFormats = options.Interface.DebugLogTimestampsFormat; _timestampsFormats = options.Interface.DebugLogTimestampsFormat;
_clearOnPlayButton.Checked = options.Interface.DebugLogClearOnPlay;
_collapseLogsButton.Checked = options.Interface.DebugLogCollapse;
_pauseOnErrorButton.Checked = options.Interface.DebugLogPauseOnError;
_groupButtons[0].Checked = options.Interface.DebugLogShowErrorMessages;
_groupButtons[1].Checked = options.Interface.DebugLogShowWarningMessages;
_groupButtons[2].Checked = options.Interface.DebugLogShowInfoMessages;
} }
/// <summary> /// <summary>

View File

@@ -162,7 +162,7 @@ namespace FlaxEditor.Windows
Editor.Options.Apply(_options); Editor.Options.Apply(_options);
ClearDirtyFlag(); GatherData();
} }
private void SetupCustomTabs() private void SetupCustomTabs()
@@ -234,6 +234,18 @@ namespace FlaxEditor.Windows
base.OnDestroy(); base.OnDestroy();
} }
/// <inheritdoc />
protected override void OnShow()
{
if (!_isDataDirty)
{
// Refresh the data, skip when data is modified during window docking
GatherData();
}
base.OnShow();
}
/// <inheritdoc /> /// <inheritdoc />
protected override bool OnClosing(ClosingReason reason) protected override bool OnClosing(ClosingReason reason)
{ {

View File

@@ -1,6 +1,5 @@
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. // Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using FlaxEditor.CustomEditors; using FlaxEditor.CustomEditors;
using FlaxEngine; using FlaxEngine;
@@ -96,14 +95,6 @@ namespace FlaxEditor.Windows
set => Graphics.ShadowMapsQuality = value; set => Graphics.ShadowMapsQuality = value;
} }
[DefaultValue(false)]
[EditorOrder(1320), EditorDisplay("Quality", "Allow CSM Blending"), Tooltip("Enables cascades splits blending for directional light shadows.")]
public bool AllowCSMBlending
{
get => Graphics.AllowCSMBlending;
set => Graphics.AllowCSMBlending = value;
}
[NoSerialize, DefaultValue(1.0f), Limit(0.05f, 5, 0)] [NoSerialize, DefaultValue(1.0f), Limit(0.05f, 5, 0)]
[EditorOrder(1400), EditorDisplay("Quality")] [EditorOrder(1400), EditorDisplay("Quality")]
[Tooltip("The scale of the rendering resolution relative to the output dimensions. If lower than 1 the scene and postprocessing will be rendered at a lower resolution and upscaled to the output backbuffer.")] [Tooltip("The scale of the rendering resolution relative to the output dimensions. If lower than 1 the scene and postprocessing will be rendered at a lower resolution and upscaled to the output backbuffer.")]

View File

@@ -526,7 +526,7 @@ namespace FlaxEditor.Windows.Profiler
} }
row.Depth = e.Depth; row.Depth = e.Depth;
row.Width = _table.Width; row.Width = _table.Width;
row.Visible = e.Depth < 2; row.Visible = e.Depth < 10;
row.BackgroundColor = i % 2 == 0 ? rowColor2 : Color.Transparent; row.BackgroundColor = i % 2 == 0 ? rowColor2 : Color.Transparent;
row.Parent = _table; row.Parent = _table;
} }

View File

@@ -370,7 +370,7 @@ namespace FlaxEditor.Windows.Profiler
} }
row.Depth = e.Depth; row.Depth = e.Depth;
row.Width = _table.Width; row.Width = _table.Width;
row.Visible = e.Depth < 3; row.Visible = e.Depth < 13;
row.BackgroundColor = i % 2 == 0 ? rowColor2 : Color.Transparent; row.BackgroundColor = i % 2 == 0 ? rowColor2 : Color.Transparent;
row.Parent = _table; row.Parent = _table;
} }

View File

@@ -3,6 +3,7 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling; using System.Runtime.InteropServices.Marshalling;
using FlaxEngine.Interop;
namespace FlaxEngine namespace FlaxEngine
{ {

View File

@@ -428,23 +428,23 @@ void AudioSource::Update()
// Handle streaming buffers queue submit (ensure that clip has loaded the first chunk with audio data) // Handle streaming buffers queue submit (ensure that clip has loaded the first chunk with audio data)
if (_needToUpdateStreamingBuffers && clip->Buffers[_streamingFirstChunk] != AUDIO_BUFFER_ID_INVALID) if (_needToUpdateStreamingBuffers && clip->Buffers[_streamingFirstChunk] != AUDIO_BUFFER_ID_INVALID)
{ {
// Clear flag
_needToUpdateStreamingBuffers = false;
// Get buffers in a queue count // Get buffers in a queue count
int32 numQueuedBuffers; int32 numQueuedBuffers;
AudioBackend::Source::GetQueuedBuffersCount(this, numQueuedBuffers); AudioBackend::Source::GetQueuedBuffersCount(this, numQueuedBuffers);
// Queue missing buffers // Queue missing buffers, make sure there is at least two buffers in queue to avoid gaps in playback
uint32 bufferId; uint32 bufferId;
if (numQueuedBuffers < 1 && (bufferId = clip->Buffers[_streamingFirstChunk]) != AUDIO_BUFFER_ID_INVALID) for (int i = numQueuedBuffers; i < 2; i++)
{ {
AudioBackend::Source::QueueBuffer(this, bufferId); int bufferIndex = (_streamingFirstChunk + i) % clip->Buffers.Count();
if ((bufferId = clip->Buffers[bufferIndex]) != AUDIO_BUFFER_ID_INVALID)
AudioBackend::Source::QueueBuffer(this, bufferId);
else
_needToUpdateStreamingBuffers = true; // The buffer has not been streamed yet, try again later
} }
if (numQueuedBuffers < 2 && _streamingFirstChunk + 1 < clip->Buffers.Count() && (bufferId = clip->Buffers[_streamingFirstChunk + 1]) != AUDIO_BUFFER_ID_INVALID)
{
AudioBackend::Source::QueueBuffer(this, bufferId);
}
// Clear flag
_needToUpdateStreamingBuffers = false;
// Play it if need to // Play it if need to
if (!_isActuallyPlayingSth) if (!_isActuallyPlayingSth)
@@ -469,18 +469,25 @@ void AudioSource::Update()
// Move the chunk pointer (AudioStreamingHandler will request new chunks streaming) // Move the chunk pointer (AudioStreamingHandler will request new chunks streaming)
_streamingFirstChunk += numProcessedBuffers; _streamingFirstChunk += numProcessedBuffers;
if (GetIsLooping())
{
int32 numQueuedBuffers;
AudioBackend::Source::GetQueuedBuffersCount(this, numQueuedBuffers);
if (numQueuedBuffers < 1)
{
// Audio engine unexpectedly stopped playing the clip after queue emptied, restart the clip
_isActuallyPlayingSth = false;
}
}
// Check if reached the end // Check if reached the end
if (_streamingFirstChunk >= clip->Buffers.Count()) if (_streamingFirstChunk >= clip->Buffers.Count())
{ {
// Loop over the clip or end play // Loop over the clip or end play
if (GetIsLooping()) if (GetIsLooping())
{ {
// Move to the begin // Move to the beginning
_streamingFirstChunk = 0; _streamingFirstChunk = 0;
// Stop audio and request buffers re-sync and then play continue
Stop();
Play();
} }
else else
{ {

View File

@@ -686,8 +686,6 @@ void AudioBackendXAudio2::Source_DequeueProcessedBuffers(AudioSource* source)
auto aSource = XAudio2::GetSource(source); auto aSource = XAudio2::GetSource(source);
if (aSource && aSource->Voice) if (aSource && aSource->Voice)
{ {
const HRESULT hr = aSource->Voice->FlushSourceBuffers();
XAUDIO2_CHECK_ERROR(FlushSourceBuffers);
aSource->BuffersProcessed = 0; aSource->BuffersProcessed = 0;
} }
} }

View File

@@ -1336,6 +1336,11 @@ FileReadStream* FlaxStorage::OpenFile()
bool FlaxStorage::CloseFileHandles() bool FlaxStorage::CloseFileHandles()
{ {
// Early out if no handles are opened
Array<FileReadStream*> streams;
_file.GetValues(streams);
if (streams.IsEmpty() && Platform::AtomicRead(&_chunksLock) == 0)
return false;
PROFILE_CPU(); PROFILE_CPU();
// Note: this is usually called by the content manager when this file is not used or on exit // Note: this is usually called by the content manager when this file is not used or on exit
@@ -1367,7 +1372,7 @@ bool FlaxStorage::CloseFileHandles()
return true; // Failed, someone is still accessing the file return true; // Failed, someone is still accessing the file
// Close file handles (from all threads) // Close file handles (from all threads)
Array<FileReadStream*> streams; streams.Clear();
_file.GetValues(streams); _file.GetValues(streams);
for (FileReadStream* stream : streams) for (FileReadStream* stream : streams)
{ {

View File

@@ -61,9 +61,10 @@ public:
/// <summary> /// <summary>
/// Enables cascades splits blending for directional light shadows. /// Enables cascades splits blending for directional light shadows.
/// [Deprecated in v1.9]
/// </summary> /// </summary>
API_FIELD(Attributes="EditorOrder(1320), DefaultValue(false), EditorDisplay(\"Quality\", \"Allow CSM Blending\")") API_FIELD(Attributes="EditorOrder(1320), DefaultValue(false), EditorDisplay(\"Quality\", \"Allow CSM Blending\")")
bool AllowCSMBlending = false; DEPRECATED bool AllowCSMBlending = false;
/// <summary> /// <summary>
/// Default probes cubemap resolution (use for Environment Probes, can be overriden per-actor). /// Default probes cubemap resolution (use for Environment Probes, can be overriden per-actor).

View File

@@ -23,3 +23,8 @@
#define OUT_OF_MEMORY Platform::OutOfMemory(__LINE__, __FILE__) #define OUT_OF_MEMORY Platform::OutOfMemory(__LINE__, __FILE__)
#define MISSING_CODE(info) Platform::MissingCode(__LINE__, __FILE__, info) #define MISSING_CODE(info) Platform::MissingCode(__LINE__, __FILE__, info)
#define NON_COPYABLE(type) type(type&&) = delete; type(const type&) = delete; type& operator=(const type&) = delete; type& operator=(type&&) = delete; #define NON_COPYABLE(type) type(type&&) = delete; type(const type&) = delete; type& operator=(const type&) = delete; type& operator=(type&&) = delete;
#define POD_COPYABLE(type) \
type(const type& other) { Platform::MemoryCopy(this, &other, sizeof(type)); } \
type(type&& other) noexcept { Platform::MemoryCopy(this, &other, sizeof(type)); } \
type& operator=(const type& other) { Platform::MemoryCopy(this, &other, sizeof(type)); return *this; } \
type& operator=(type&& other) noexcept { Platform::MemoryCopy(this, &other, sizeof(type)); return *this; }

View File

@@ -51,7 +51,11 @@ bool BoundingSphere::Intersects(const BoundingBox& box) const
bool BoundingSphere::Intersects(const BoundingSphere& sphere) const bool BoundingSphere::Intersects(const BoundingSphere& sphere) const
{ {
return CollisionsHelper::SphereIntersectsSphere(*this, sphere); const Real radiisum = Radius + sphere.Radius;
const Real x = Center.X - sphere.Center.X;
const Real y = Center.Y - sphere.Center.Y;
const Real z = Center.Z - sphere.Center.Z;
return x * x + y * y + z * z <= radiisum * radiisum;
} }
ContainmentType BoundingSphere::Contains(const Vector3& point) const ContainmentType BoundingSphere::Contains(const Vector3& point) const

View File

@@ -2,6 +2,7 @@
#include "Matrix.h" #include "Matrix.h"
#include "Matrix3x3.h" #include "Matrix3x3.h"
#include "Matrix3x4.h"
#include "Vector2.h" #include "Vector2.h"
#include "Quaternion.h" #include "Quaternion.h"
#include "Transform.h" #include "Transform.h"
@@ -887,3 +888,39 @@ Float4 Matrix::TransformPosition(const Matrix& m, const Float4& v)
m.Values[0][3] * v.Raw[0] + m.Values[1][3] * v.Raw[1] + m.Values[2][3] * v.Raw[2] + m.Values[3][3] * v.Raw[3] m.Values[0][3] * v.Raw[0] + m.Values[1][3] * v.Raw[1] + m.Values[2][3] * v.Raw[2] + m.Values[3][3] * v.Raw[3]
); );
} }
void Matrix3x4::SetMatrix(const Matrix& m)
{
const float* src = m.Raw;
float* dst = Raw;
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
dst[3] = src[3];
dst[4] = src[4];
dst[5] = src[5];
dst[6] = src[6];
dst[7] = src[7];
dst[8] = src[8];
dst[9] = src[9];
dst[10] = src[10];
dst[11] = src[11];
}
void Matrix3x4::SetMatrixTranspose(const Matrix& m)
{
const float* src = m.Raw;
float* dst = Raw;
dst[0] = src[0];
dst[1] = src[4];
dst[2] = src[8];
dst[3] = src[12];
dst[4] = src[1];
dst[5] = src[5];
dst[6] = src[9];
dst[7] = src[13];
dst[8] = src[2];
dst[9] = src[6];
dst[10] = src[10];
dst[11] = src[14];
}

View File

@@ -890,7 +890,7 @@ public:
/// <param name="translation">The translation.</param> /// <param name="translation">The translation.</param>
/// <param name="rotation">Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.</param> /// <param name="rotation">Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.</param>
/// <param name="scaling">The scaling.</param> /// <param name="scaling">The scaling.</param>
/// <param name="result">When the method completes, contains the created rotation matrix.</param> /// <param name="result">When the method completes, contains the created transformation matrix.</param>
static void Transformation(const Float3& scaling, const Quaternion& rotation, const Float3& translation, Matrix& result); static void Transformation(const Float3& scaling, const Quaternion& rotation, const Float3& translation, Matrix& result);
// Creates a 3D affine transformation matrix. // Creates a 3D affine transformation matrix.

View File

@@ -9,43 +9,14 @@
/// </summary> /// </summary>
struct FLAXENGINE_API Matrix3x4 struct FLAXENGINE_API Matrix3x4
{ {
float M[3][4]; union
void SetMatrix(const Matrix& m)
{ {
const float* src = m.Raw; float Values[3][4];
float* dst = &M[0][0]; float Raw[12];
dst[0] = src[0]; };
dst[1] = src[1];
dst[2] = src[2];
dst[3] = src[3];
dst[4] = src[4];
dst[5] = src[5];
dst[6] = src[6];
dst[7] = src[7];
dst[8] = src[8];
dst[9] = src[9];
dst[10] = src[10];
dst[11] = src[11];
}
void SetMatrixTranspose(const Matrix& m) void SetMatrix(const Matrix& m);
{ void SetMatrixTranspose(const Matrix& m);
const float* src = m.Raw;
float* dst = &M[0][0];
dst[0] = src[0];
dst[1] = src[4];
dst[2] = src[8];
dst[3] = src[12];
dst[4] = src[1];
dst[5] = src[5];
dst[6] = src[9];
dst[7] = src[13];
dst[8] = src[2];
dst[9] = src[6];
dst[10] = src[10];
dst[11] = src[14];
}
}; };
template<> template<>

View File

@@ -1010,9 +1010,6 @@ namespace FlaxEngine.Interop
{ {
#if FLAX_EDITOR #if FLAX_EDITOR
// Clear all caches which might hold references to assemblies in collectible ALC // Clear all caches which might hold references to assemblies in collectible ALC
typeCache.Clear();
// Release all references in collectible ALC
cachedDelegatesCollectible.Clear(); cachedDelegatesCollectible.Clear();
foreach (var pair in managedTypesCollectible) foreach (var pair in managedTypesCollectible)
pair.Value.handle.Free(); pair.Value.handle.Free();

View File

@@ -31,8 +31,6 @@ namespace FlaxEngine.Interop
private static bool firstAssemblyLoaded = false; private static bool firstAssemblyLoaded = false;
private static Dictionary<string, Type> typeCache = new();
private static IntPtr boolTruePtr = ManagedHandle.ToIntPtr(ManagedHandle.Alloc((int)1, GCHandleType.Pinned)); private static IntPtr boolTruePtr = ManagedHandle.ToIntPtr(ManagedHandle.Alloc((int)1, GCHandleType.Pinned));
private static IntPtr boolFalsePtr = ManagedHandle.ToIntPtr(ManagedHandle.Alloc((int)0, GCHandleType.Pinned)); private static IntPtr boolFalsePtr = ManagedHandle.ToIntPtr(ManagedHandle.Alloc((int)0, GCHandleType.Pinned));
@@ -279,44 +277,6 @@ namespace FlaxEngine.Interop
return dst; return dst;
} }
private static Type FindType(string typeName)
{
if (typeCache.TryGetValue(typeName, out Type type))
return type;
type = Type.GetType(typeName, ResolveAssembly, null);
if (type == null)
type = ResolveSlow(typeName);
if (type == null)
{
string fullTypeName = typeName;
typeName = typeName.Substring(0, typeName.IndexOf(','));
type = Type.GetType(typeName, ResolveAssembly, null);
if (type == null)
type = ResolveSlow(typeName);
typeName = fullTypeName;
}
typeCache.Add(typeName, type);
return type;
static Type ResolveSlow(string typeName)
{
foreach (var assembly in scriptingAssemblyLoadContext.Assemblies)
{
var type = assembly.GetType(typeName);
if (type != null)
return type;
}
return null;
}
static Assembly ResolveAssembly(AssemblyName name) => ResolveScriptingAssemblyByName(name, allowPartial: false);
}
/// <summary>Find <paramref name="assemblyName"/> among the scripting assemblies.</summary> /// <summary>Find <paramref name="assemblyName"/> among the scripting assemblies.</summary>
/// <param name="assemblyName">The name to find</param> /// <param name="assemblyName">The name to find</param>
/// <param name="allowPartial">If true, partial names should be allowed to be resolved.</param> /// <param name="allowPartial">If true, partial names should be allowed to be resolved.</param>
@@ -378,18 +338,15 @@ namespace FlaxEngine.Interop
/// </summary> /// </summary>
internal static Type GetInternalType(Type type) internal static Type GetInternalType(Type type)
{ {
string[] splits = type.AssemblyQualifiedName.Split(','); Type marshallerType = type.GetCustomAttribute<System.Runtime.InteropServices.Marshalling.NativeMarshallingAttribute>()?.NativeType;
string @namespace = string.Join('.', splits[0].Split('.').SkipLast(1)); if (marshallerType == null)
string className = @namespace.Length > 0 ? splits[0].Substring(@namespace.Length + 1) : splits[0]; return null;
string parentClassName = "";
if (className.Contains('+')) Type internalType = marshallerType.GetNestedType($"{type.Name}Internal");
{ if (internalType == null)
parentClassName = className.Substring(0, className.LastIndexOf('+') + 1); return null;
className = className.Substring(parentClassName.Length);
} return internalType;
string marshallerName = className + "Marshaller";
string internalAssemblyQualifiedName = $"{@namespace}.{parentClassName}{marshallerName}+{className}Internal,{String.Join(',', splits.Skip(1))}";
return FindType(internalAssemblyQualifiedName);
} }
internal class ReferenceTypePlaceholder { } internal class ReferenceTypePlaceholder { }
@@ -1338,7 +1295,7 @@ namespace FlaxEngine.Interop
if (invokeDelegate == null && !method.DeclaringType.IsValueType) if (invokeDelegate == null && !method.DeclaringType.IsValueType)
{ {
// Thread-safe creation // Thread-safe creation
lock (typeCache) lock (method)
{ {
if (invokeDelegate == null) if (invokeDelegate == null)
{ {

View File

@@ -94,7 +94,7 @@ bool Time::TickData::OnTickBegin(double time, float targetFps, float maxDeltaTim
if (targetFps > ZeroTolerance) if (targetFps > ZeroTolerance)
{ {
int skip = (int)(1 + (time - NextBegin) * targetFps); const int skip = (int)(1 + (time - NextBegin) * targetFps);
NextBegin += (1.0 / targetFps) * skip; NextBegin += (1.0 / targetFps) * skip;
} }
} }
@@ -132,14 +132,12 @@ bool Time::FixedStepTickData::OnTickBegin(double time, float targetFps, float ma
if (FixedDeltaTimeEnable) if (FixedDeltaTimeEnable)
{ {
deltaTime = (double)FixedDeltaTimeValue; deltaTime = (double)FixedDeltaTimeValue;
minDeltaTime = deltaTime;
} }
else else
{ {
if (time < NextBegin) if (time < NextBegin)
return false; return false;
minDeltaTime = targetFps > ZeroTolerance ? 1.0 / targetFps : 0.0;
deltaTime = Math::Max((time - LastBegin), 0.0); deltaTime = Math::Max((time - LastBegin), 0.0);
if (deltaTime > maxDeltaTime) if (deltaTime > maxDeltaTime)
{ {
@@ -149,21 +147,10 @@ bool Time::FixedStepTickData::OnTickBegin(double time, float targetFps, float ma
if (targetFps > ZeroTolerance) if (targetFps > ZeroTolerance)
{ {
int skip = (int)(1 + (time - NextBegin) * targetFps); deltaTime = 1.0 / targetFps;
NextBegin += (1.0 / targetFps) * skip; NextBegin += 1.0 / targetFps;
} }
} }
Samples.Add(deltaTime);
// Check if last few ticks were not taking too long so it's running slowly
const bool isRunningSlowly = Samples.Average() > 1.5 * minDeltaTime;
if (!isRunningSlowly)
{
// Make steps fixed size
const double diff = deltaTime - minDeltaTime;
time -= diff;
deltaTime = minDeltaTime;
}
// Update data // Update data
Advance(time, deltaTime); Advance(time, deltaTime);

View File

@@ -5,7 +5,6 @@
#include "Engine/Core/Types/TimeSpan.h" #include "Engine/Core/Types/TimeSpan.h"
#include "Engine/Core/Types/DateTime.h" #include "Engine/Core/Types/DateTime.h"
#include "Engine/Scripting/ScriptingType.h" #include "Engine/Scripting/ScriptingType.h"
#include "Engine/Core/Collections/SamplesBuffer.h"
/// <summary> /// <summary>
/// Game ticking and timing system. /// Game ticking and timing system.
@@ -89,12 +88,7 @@ public:
class FixedStepTickData : public TickData class FixedStepTickData : public TickData
{ {
public: public:
/// <summary>
/// The last few ticks delta times. Used to check if can use fixed steps or whenever is running slowly so should use normal stepping.
/// </summary>
SamplesBuffer<double, 4> Samples;
public:
// [TickData] // [TickData]
bool OnTickBegin(double time, float targetFps, float maxDeltaTime) override; bool OnTickBegin(double time, float targetFps, float maxDeltaTime) override;
}; };

View File

@@ -0,0 +1,5 @@
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
#pragma once
#define METERS_TO_UNITS(meters) (meters * 100.0f)

View File

@@ -252,7 +252,7 @@ API_ENUM() enum class PartitionMode
Logarithmic = 1, Logarithmic = 1,
/// <summary> /// <summary>
/// PSSM cascade splits. /// Parallel-Split Shadow Maps cascade splits.
/// </summary> /// </summary>
PSSM = 2, PSSM = 2,
}; };

View File

@@ -186,7 +186,8 @@ public:
/// </summary> /// </summary>
/// <param name="depthBuffer">The depth buffer to clear.</param> /// <param name="depthBuffer">The depth buffer to clear.</param>
/// <param name="depthValue">The clear depth value.</param> /// <param name="depthValue">The clear depth value.</param>
API_FUNCTION() virtual void ClearDepth(GPUTextureView* depthBuffer, float depthValue = 1.0f) = 0; /// <param name="stencilValue">The clear stencil value.</param>
API_FUNCTION() virtual void ClearDepth(GPUTextureView* depthBuffer, float depthValue = 1.0f, uint8 stencilValue = 0) = 0;
/// <summary> /// <summary>
/// Clears an unordered access buffer with a float value. /// Clears an unordered access buffer with a float value.

View File

@@ -65,7 +65,6 @@ void GraphicsSettings::Apply()
Graphics::VolumetricFogQuality = VolumetricFogQuality; Graphics::VolumetricFogQuality = VolumetricFogQuality;
Graphics::ShadowsQuality = ShadowsQuality; Graphics::ShadowsQuality = ShadowsQuality;
Graphics::ShadowMapsQuality = ShadowMapsQuality; Graphics::ShadowMapsQuality = ShadowMapsQuality;
Graphics::AllowCSMBlending = AllowCSMBlending;
Graphics::GlobalSDFQuality = GlobalSDFQuality; Graphics::GlobalSDFQuality = GlobalSDFQuality;
Graphics::GIQuality = GIQuality; Graphics::GIQuality = GIQuality;
Graphics::PostProcessSettings = ::PostProcessSettings(); Graphics::PostProcessSettings = ::PostProcessSettings();

View File

@@ -50,8 +50,9 @@ public:
/// <summary> /// <summary>
/// Enables cascades splits blending for directional light shadows. /// Enables cascades splits blending for directional light shadows.
/// [Deprecated in v1.9]
/// </summary> /// </summary>
API_FIELD() static bool AllowCSMBlending; API_FIELD() DEPRECATED static bool AllowCSMBlending;
/// <summary> /// <summary>
/// The Global SDF quality. Controls the volume texture resolution and amount of cascades to use. /// The Global SDF quality. Controls the volume texture resolution and amount of cascades to use.

View File

@@ -34,8 +34,7 @@ void DecalMaterialShader::Bind(BindParameters& params)
ASSERT_LOW_LAYER(cb.Length() >= sizeof(DecalMaterialShaderData)); ASSERT_LOW_LAYER(cb.Length() >= sizeof(DecalMaterialShaderData));
auto materialData = reinterpret_cast<DecalMaterialShaderData*>(cb.Get()); auto materialData = reinterpret_cast<DecalMaterialShaderData*>(cb.Get());
cb = Span<byte>(cb.Get() + sizeof(DecalMaterialShaderData), cb.Length() - sizeof(DecalMaterialShaderData)); cb = Span<byte>(cb.Get() + sizeof(DecalMaterialShaderData), cb.Length() - sizeof(DecalMaterialShaderData));
int32 srv = 0; const bool isCameraInside = OrientedBoundingBox(Vector3::Half, drawCall.World).Contains(view.Position) == ContainmentType::Contains;
const bool isCameraInside = OrientedBoundingBox(Vector3::Half, params.FirstDrawCall->World).Contains(view.Position) == ContainmentType::Contains;
// Setup parameters // Setup parameters
MaterialParameter::BindMeta bindMeta; MaterialParameter::BindMeta bindMeta;

View File

@@ -3,6 +3,7 @@
#include "DeferredMaterialShader.h" #include "DeferredMaterialShader.h"
#include "MaterialShaderFeatures.h" #include "MaterialShaderFeatures.h"
#include "MaterialParams.h" #include "MaterialParams.h"
#include "Engine/Core/Math/Matrix3x4.h"
#include "Engine/Graphics/RenderBuffers.h" #include "Engine/Graphics/RenderBuffers.h"
#include "Engine/Graphics/RenderView.h" #include "Engine/Graphics/RenderView.h"
#include "Engine/Renderer/DrawCall.h" #include "Engine/Renderer/DrawCall.h"
@@ -17,8 +18,8 @@
#include "Engine/Graphics/RenderTask.h" #include "Engine/Graphics/RenderTask.h"
PACK_STRUCT(struct DeferredMaterialShaderData { PACK_STRUCT(struct DeferredMaterialShaderData {
Matrix WorldMatrix; Matrix3x4 WorldMatrix;
Matrix PrevWorldMatrix; Matrix3x4 PrevWorldMatrix;
Float2 Dummy0; Float2 Dummy0;
float LODDitherFactor; float LODDitherFactor;
float PerInstanceRandom; float PerInstanceRandom;
@@ -70,8 +71,8 @@ void DeferredMaterialShader::Bind(BindParameters& params)
// Setup material constants // Setup material constants
{ {
Matrix::Transpose(drawCall.World, materialData->WorldMatrix); materialData->WorldMatrix.SetMatrixTranspose(drawCall.World);
Matrix::Transpose(drawCall.Surface.PrevWorld, materialData->PrevWorldMatrix); materialData->PrevWorldMatrix.SetMatrixTranspose(drawCall.Surface.PrevWorld);
materialData->WorldDeterminantSign = drawCall.WorldDeterminantSign; materialData->WorldDeterminantSign = drawCall.WorldDeterminantSign;
materialData->LODDitherFactor = drawCall.Surface.LODDitherFactor; materialData->LODDitherFactor = drawCall.Surface.LODDitherFactor;
materialData->PerInstanceRandom = drawCall.PerInstanceRandom; materialData->PerInstanceRandom = drawCall.PerInstanceRandom;

View File

@@ -3,6 +3,7 @@
#include "ForwardMaterialShader.h" #include "ForwardMaterialShader.h"
#include "MaterialShaderFeatures.h" #include "MaterialShaderFeatures.h"
#include "MaterialParams.h" #include "MaterialParams.h"
#include "Engine/Core/Math/Matrix3x4.h"
#include "Engine/Graphics/GPUContext.h" #include "Engine/Graphics/GPUContext.h"
#include "Engine/Graphics/GPUDevice.h" #include "Engine/Graphics/GPUDevice.h"
#include "Engine/Graphics/GPULimits.h" #include "Engine/Graphics/GPULimits.h"
@@ -18,8 +19,8 @@
#endif #endif
PACK_STRUCT(struct ForwardMaterialShaderData { PACK_STRUCT(struct ForwardMaterialShaderData {
Matrix WorldMatrix; Matrix3x4 WorldMatrix;
Matrix PrevWorldMatrix; Matrix3x4 PrevWorldMatrix;
Float2 Dummy0; Float2 Dummy0;
float LODDitherFactor; float LODDitherFactor;
float PerInstanceRandom; float PerInstanceRandom;
@@ -76,8 +77,8 @@ void ForwardMaterialShader::Bind(BindParameters& params)
// Setup material constants // Setup material constants
{ {
Matrix::Transpose(drawCall.World, materialData->WorldMatrix); materialData->WorldMatrix.SetMatrixTranspose(drawCall.World);
Matrix::Transpose(drawCall.Surface.PrevWorld, materialData->PrevWorldMatrix); materialData->PrevWorldMatrix.SetMatrixTranspose(drawCall.Surface.PrevWorld);
materialData->WorldDeterminantSign = drawCall.WorldDeterminantSign; materialData->WorldDeterminantSign = drawCall.WorldDeterminantSign;
materialData->LODDitherFactor = drawCall.Surface.LODDitherFactor; materialData->LODDitherFactor = drawCall.Surface.LODDitherFactor;
materialData->PerInstanceRandom = drawCall.PerInstanceRandom; materialData->PerInstanceRandom = drawCall.PerInstanceRandom;

View File

@@ -119,7 +119,7 @@ public:
struct InstancingHandler struct InstancingHandler
{ {
void (*GetHash)(const DrawCall& drawCall, uint32& batchKey); void (*GetHash)(const DrawCall& drawCall, uint32& batchKey);
bool (*CanBatch)(const DrawCall& a, const DrawCall& b); bool (*CanBatch)(const DrawCall& a, const DrawCall& b, DrawPass pass);
void (*WriteDrawCall)(struct InstanceData* instanceData, const DrawCall& drawCall); void (*WriteDrawCall)(struct InstanceData* instanceData, const DrawCall& drawCall);
}; };

View File

@@ -10,7 +10,7 @@
/// <summary> /// <summary>
/// Current materials shader version. /// Current materials shader version.
/// </summary> /// </summary>
#define MATERIAL_GRAPH_VERSION 162 #define MATERIAL_GRAPH_VERSION 165
class Material; class Material;
class GPUShader; class GPUShader;

View File

@@ -21,7 +21,8 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<by
ASSERT_LOW_LAYER(cb.Length() >= sizeof(Data)); ASSERT_LOW_LAYER(cb.Length() >= sizeof(Data));
const int32 envProbeShaderRegisterIndex = srv + 0; const int32 envProbeShaderRegisterIndex = srv + 0;
const int32 skyLightShaderRegisterIndex = srv + 1; const int32 skyLightShaderRegisterIndex = srv + 1;
const int32 dirLightShaderRegisterIndex = srv + 2; const int32 shadowsBufferRegisterIndex = srv + 2;
const int32 shadowMapShaderRegisterIndex = srv + 3;
const bool canUseShadow = view.Pass != DrawPass::Depth; const bool canUseShadow = view.Pass != DrawPass::Depth;
// Set fog input // Set fog input
@@ -39,31 +40,26 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<by
if (cache->DirectionalLights.HasItems()) if (cache->DirectionalLights.HasItems())
{ {
const auto& dirLight = cache->DirectionalLights.First(); const auto& dirLight = cache->DirectionalLights.First();
const auto shadowPass = ShadowsPass::Instance(); GPUTexture* shadowMapAtlas;
const bool useShadow = shadowPass->LastDirLightIndex == 0 && canUseShadow; GPUBufferView* shadowsBuffer;
if (useShadow) ShadowsPass::GetShadowAtlas(params.RenderContext.Buffers, shadowMapAtlas, shadowsBuffer);
{ const bool useShadow = shadowMapAtlas && canUseShadow && dirLight.HasShadow;
data.DirectionalLightShadow = shadowPass->LastDirLight; dirLight.SetShaderData(data.DirectionalLight, useShadow);
params.GPUContext->BindSR(dirLightShaderRegisterIndex, shadowPass->LastDirLightShadowMap); params.GPUContext->BindSR(shadowsBufferRegisterIndex, shadowsBuffer);
} params.GPUContext->BindSR(shadowMapShaderRegisterIndex, shadowMapAtlas);
else
{
params.GPUContext->UnBindSR(dirLightShaderRegisterIndex);
}
dirLight.SetupLightData(&data.DirectionalLight, useShadow);
} }
else else
{ {
data.DirectionalLight.Color = Float3::Zero; Platform::MemoryClear(&data.DirectionalLight, sizeof(data.DirectionalLight));
data.DirectionalLight.CastShadows = 0.0f; params.GPUContext->UnBindSR(shadowsBufferRegisterIndex);
params.GPUContext->UnBindSR(dirLightShaderRegisterIndex); params.GPUContext->UnBindSR(shadowMapShaderRegisterIndex);
} }
// Set sky light // Set sky light
if (cache->SkyLights.HasItems()) if (cache->SkyLights.HasItems())
{ {
auto& skyLight = cache->SkyLights.First(); auto& skyLight = cache->SkyLights.First();
skyLight.SetupLightData(&data.SkyLight, false); skyLight.SetShaderData(data.SkyLight, false);
const auto texture = skyLight.Image ? skyLight.Image->GetTexture() : nullptr; const auto texture = skyLight.Image ? skyLight.Image->GetTexture() : nullptr;
params.GPUContext->BindSR(skyLightShaderRegisterIndex, GET_TEXTURE_VIEW_SAFE(texture)); params.GPUContext->BindSR(skyLightShaderRegisterIndex, GET_TEXTURE_VIEW_SAFE(texture));
} }
@@ -74,24 +70,21 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<by
} }
// Set reflection probe data // Set reflection probe data
EnvironmentProbe* probe = nullptr; bool noEnvProbe = true;
// TODO: optimize env probe searching for a transparent material - use spatial cache for renderer to find it // TODO: optimize env probe searching for a transparent material - use spatial cache for renderer to find it
const BoundingSphere objectBoundsWorld(drawCall.ObjectPosition + view.Origin, drawCall.ObjectRadius); const BoundingSphere objectBounds(drawCall.ObjectPosition, drawCall.ObjectRadius);
for (int32 i = 0; i < cache->EnvironmentProbes.Count(); i++) for (int32 i = 0; i < cache->EnvironmentProbes.Count(); i++)
{ {
const auto p = cache->EnvironmentProbes[i]; const RenderEnvironmentProbeData& probe = cache->EnvironmentProbes.Get()[i];
if (CollisionsHelper::SphereIntersectsSphere(objectBoundsWorld, p->GetSphere())) if (objectBounds.Intersects(BoundingSphere(probe.Position, probe.Radius)))
{ {
probe = p; noEnvProbe = false;
probe.SetShaderData(data.EnvironmentProbe);
params.GPUContext->BindSR(envProbeShaderRegisterIndex, probe.Texture);
break; break;
} }
} }
if (probe && probe->GetProbe()) if (noEnvProbe)
{
probe->SetupProbeData(params.RenderContext, &data.EnvironmentProbe);
params.GPUContext->BindSR(envProbeShaderRegisterIndex, probe->GetProbe());
}
else
{ {
data.EnvironmentProbe.Data1 = Float4::Zero; data.EnvironmentProbe.Data1 = Float4::Zero;
params.GPUContext->UnBindSR(envProbeShaderRegisterIndex); params.GPUContext->UnBindSR(envProbeShaderRegisterIndex);
@@ -99,23 +92,22 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<by
// Set local lights // Set local lights
data.LocalLightsCount = 0; data.LocalLightsCount = 0;
const BoundingSphere objectBounds(drawCall.ObjectPosition, drawCall.ObjectRadius);
// TODO: optimize lights searching for a transparent material - use spatial cache for renderer to find it // TODO: optimize lights searching for a transparent material - use spatial cache for renderer to find it
for (int32 i = 0; i < cache->PointLights.Count() && data.LocalLightsCount < MaxLocalLights; i++) for (int32 i = 0; i < cache->PointLights.Count() && data.LocalLightsCount < MaxLocalLights; i++)
{ {
const auto& light = cache->PointLights[i]; const auto& light = cache->PointLights[i];
if (CollisionsHelper::SphereIntersectsSphere(objectBounds, BoundingSphere(light.Position, light.Radius))) if (objectBounds.Intersects(BoundingSphere(light.Position, light.Radius)))
{ {
light.SetupLightData(&data.LocalLights[data.LocalLightsCount], false); light.SetShaderData(data.LocalLights[data.LocalLightsCount], false);
data.LocalLightsCount++; data.LocalLightsCount++;
} }
} }
for (int32 i = 0; i < cache->SpotLights.Count() && data.LocalLightsCount < MaxLocalLights; i++) for (int32 i = 0; i < cache->SpotLights.Count() && data.LocalLightsCount < MaxLocalLights; i++)
{ {
const auto& light = cache->SpotLights[i]; const auto& light = cache->SpotLights[i];
if (CollisionsHelper::SphereIntersectsSphere(objectBounds, BoundingSphere(light.Position, light.Radius))) if (objectBounds.Intersects(BoundingSphere(light.Position, light.Radius)))
{ {
light.SetupLightData(&data.LocalLights[data.LocalLightsCount], false); light.SetShaderData(data.LocalLights[data.LocalLightsCount], false);
data.LocalLightsCount++; data.LocalLightsCount++;
} }
} }

View File

@@ -23,18 +23,17 @@ struct ForwardShadingFeature : MaterialShaderFeature
{ {
enum { MaxLocalLights = 4 }; enum { MaxLocalLights = 4 };
enum { SRVs = 3 }; enum { SRVs = 4 };
PACK_STRUCT(struct Data PACK_STRUCT(struct Data
{ {
LightData DirectionalLight; ShaderLightData DirectionalLight;
LightShadowData DirectionalLightShadow; ShaderLightData SkyLight;
LightData SkyLight; ShaderEnvProbeData EnvironmentProbe;
ProbeData EnvironmentProbe; ShaderExponentialHeightFogData ExponentialHeightFog;
ExponentialHeightFogData ExponentialHeightFog;
Float3 Dummy2; Float3 Dummy2;
uint32 LocalLightsCount; uint32 LocalLightsCount;
LightData LocalLights[MaxLocalLights]; ShaderLightData LocalLights[MaxLocalLights];
}); });
static void Bind(MaterialShader::BindParameters& params, Span<byte>& cb, int32& srv); static void Bind(MaterialShader::BindParameters& params, Span<byte>& cb, int32& srv);

View File

@@ -3,6 +3,7 @@
#include "ParticleMaterialShader.h" #include "ParticleMaterialShader.h"
#include "MaterialShaderFeatures.h" #include "MaterialShaderFeatures.h"
#include "MaterialParams.h" #include "MaterialParams.h"
#include "Engine/Core/Math/Matrix3x4.h"
#include "Engine/Renderer/DrawCall.h" #include "Engine/Renderer/DrawCall.h"
#include "Engine/Renderer/RenderList.h" #include "Engine/Renderer/RenderList.h"
#include "Engine/Graphics/RenderView.h" #include "Engine/Graphics/RenderView.h"
@@ -15,7 +16,7 @@
#include "Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.h" #include "Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.h"
PACK_STRUCT(struct ParticleMaterialShaderData { PACK_STRUCT(struct ParticleMaterialShaderData {
Matrix WorldMatrix; Matrix3x4 WorldMatrix;
uint32 SortedIndicesOffset; uint32 SortedIndicesOffset;
float PerInstanceRandom; float PerInstanceRandom;
int32 ParticleStride; int32 ParticleStride;
@@ -34,7 +35,7 @@ PACK_STRUCT(struct ParticleMaterialShaderData {
int32 RibbonTwistOffset; int32 RibbonTwistOffset;
int32 RibbonFacingVectorOffset; int32 RibbonFacingVectorOffset;
uint32 RibbonSegmentCount; uint32 RibbonSegmentCount;
Matrix WorldMatrixInverseTransposed; Matrix3x4 WorldMatrixInverseTransposed;
}); });
DrawPass ParticleMaterialShader::GetDrawModes() const DrawPass ParticleMaterialShader::GetDrawModes() const
@@ -101,7 +102,7 @@ void ParticleMaterialShader::Bind(BindParameters& params)
static StringView ParticleScaleOffset(TEXT("Scale")); static StringView ParticleScaleOffset(TEXT("Scale"));
static StringView ParticleModelFacingModeOffset(TEXT("ModelFacingMode")); static StringView ParticleModelFacingModeOffset(TEXT("ModelFacingMode"));
Matrix::Transpose(drawCall.World, materialData->WorldMatrix); materialData->WorldMatrix.SetMatrixTranspose(drawCall.World);
materialData->SortedIndicesOffset = drawCall.Particle.Particles->GPU.SortedIndices && params.RenderContext.View.Pass != DrawPass::Depth ? sortedIndicesOffset : 0xFFFFFFFF; materialData->SortedIndicesOffset = drawCall.Particle.Particles->GPU.SortedIndices && params.RenderContext.View.Pass != DrawPass::Depth ? sortedIndicesOffset : 0xFFFFFFFF;
materialData->PerInstanceRandom = drawCall.PerInstanceRandom; materialData->PerInstanceRandom = drawCall.PerInstanceRandom;
materialData->ParticleStride = drawCall.Particle.Particles->Stride; materialData->ParticleStride = drawCall.Particle.Particles->Stride;
@@ -113,7 +114,9 @@ void ParticleMaterialShader::Bind(BindParameters& params)
materialData->RotationOffset = drawCall.Particle.Particles->Layout->FindAttributeOffset(ParticleRotationOffset, ParticleAttribute::ValueTypes::Float3, -1); materialData->RotationOffset = drawCall.Particle.Particles->Layout->FindAttributeOffset(ParticleRotationOffset, ParticleAttribute::ValueTypes::Float3, -1);
materialData->ScaleOffset = drawCall.Particle.Particles->Layout->FindAttributeOffset(ParticleScaleOffset, ParticleAttribute::ValueTypes::Float3, -1); materialData->ScaleOffset = drawCall.Particle.Particles->Layout->FindAttributeOffset(ParticleScaleOffset, ParticleAttribute::ValueTypes::Float3, -1);
materialData->ModelFacingModeOffset = drawCall.Particle.Particles->Layout->FindAttributeOffset(ParticleModelFacingModeOffset, ParticleAttribute::ValueTypes::Int, -1); materialData->ModelFacingModeOffset = drawCall.Particle.Particles->Layout->FindAttributeOffset(ParticleModelFacingModeOffset, ParticleAttribute::ValueTypes::Int, -1);
Matrix::Invert(drawCall.World, materialData->WorldMatrixInverseTransposed); Matrix worldMatrixInverseTransposed;
Matrix::Invert(drawCall.World, worldMatrixInverseTransposed);
materialData->WorldMatrixInverseTransposed.SetMatrix(worldMatrixInverseTransposed);
} }
// Select pipeline state based on current pass and render mode // Select pipeline state based on current pass and render mode

View File

@@ -3,6 +3,7 @@
#include "TerrainMaterialShader.h" #include "TerrainMaterialShader.h"
#include "MaterialShaderFeatures.h" #include "MaterialShaderFeatures.h"
#include "MaterialParams.h" #include "MaterialParams.h"
#include "Engine/Core/Math/Matrix3x4.h"
#include "Engine/Graphics/GPUContext.h" #include "Engine/Graphics/GPUContext.h"
#include "Engine/Graphics/GPULimits.h" #include "Engine/Graphics/GPULimits.h"
#include "Engine/Graphics/GPUDevice.h" #include "Engine/Graphics/GPUDevice.h"
@@ -16,7 +17,7 @@
#include "Engine/Terrain/TerrainPatch.h" #include "Engine/Terrain/TerrainPatch.h"
PACK_STRUCT(struct TerrainMaterialShaderData { PACK_STRUCT(struct TerrainMaterialShaderData {
Matrix WorldMatrix; Matrix3x4 WorldMatrix;
Float3 WorldInvScale; Float3 WorldInvScale;
float WorldDeterminantSign; float WorldDeterminantSign;
float PerInstanceRandom; float PerInstanceRandom;
@@ -66,7 +67,7 @@ void TerrainMaterialShader::Bind(BindParameters& params)
// Setup material constants // Setup material constants
{ {
Matrix::Transpose(drawCall.World, materialData->WorldMatrix); materialData->WorldMatrix.SetMatrixTranspose(drawCall.World);
const float scaleX = Float3(drawCall.World.M11, drawCall.World.M12, drawCall.World.M13).Length(); const float scaleX = Float3(drawCall.World.M11, drawCall.World.M12, drawCall.World.M13).Length();
const float scaleY = Float3(drawCall.World.M21, drawCall.World.M22, drawCall.World.M23).Length(); const float scaleY = Float3(drawCall.World.M21, drawCall.World.M22, drawCall.World.M23).Length();
const float scaleZ = Float3(drawCall.World.M31, drawCall.World.M32, drawCall.World.M33).Length(); const float scaleZ = Float3(drawCall.World.M31, drawCall.World.M32, drawCall.World.M33).Length();

View File

@@ -3,6 +3,7 @@
#include "VolumeParticleMaterialShader.h" #include "VolumeParticleMaterialShader.h"
#include "MaterialShaderFeatures.h" #include "MaterialShaderFeatures.h"
#include "MaterialParams.h" #include "MaterialParams.h"
#include "Engine/Core/Math/Matrix3x4.h"
#include "Engine/Renderer/DrawCall.h" #include "Engine/Renderer/DrawCall.h"
#include "Engine/Renderer/VolumetricFogPass.h" #include "Engine/Renderer/VolumetricFogPass.h"
#include "Engine/Renderer/RenderList.h" #include "Engine/Renderer/RenderList.h"
@@ -16,8 +17,8 @@
PACK_STRUCT(struct VolumeParticleMaterialShaderData { PACK_STRUCT(struct VolumeParticleMaterialShaderData {
Matrix InverseViewProjectionMatrix; Matrix InverseViewProjectionMatrix;
Matrix WorldMatrix; Matrix3x4 WorldMatrix;
Matrix WorldMatrixInverseTransposed; Matrix3x4 WorldMatrixInverseTransposed;
Float3 GridSize; Float3 GridSize;
float PerInstanceRandom; float PerInstanceRandom;
float Dummy0; float Dummy0;
@@ -76,8 +77,10 @@ void VolumeParticleMaterialShader::Bind(BindParameters& params)
// Setup material constants // Setup material constants
{ {
Matrix::Transpose(view.IVP, materialData->InverseViewProjectionMatrix); Matrix::Transpose(view.IVP, materialData->InverseViewProjectionMatrix);
Matrix::Transpose(drawCall.World, materialData->WorldMatrix); materialData->WorldMatrix.SetMatrixTranspose(drawCall.World);
Matrix::Invert(drawCall.World, materialData->WorldMatrixInverseTransposed); Matrix worldMatrixInverseTransposed;
Matrix::Invert(drawCall.World, worldMatrixInverseTransposed);
materialData->WorldMatrixInverseTransposed.SetMatrix(worldMatrixInverseTransposed);
materialData->GridSize = customData->GridSize; materialData->GridSize = customData->GridSize;
materialData->PerInstanceRandom = drawCall.PerInstanceRandom; materialData->PerInstanceRandom = drawCall.PerInstanceRandom;
materialData->VolumetricFogMaxDistance = customData->VolumetricFogMaxDistance; materialData->VolumetricFogMaxDistance = customData->VolumetricFogMaxDistance;

View File

@@ -337,14 +337,14 @@ void RenderTools::ComputePitch(PixelFormat format, int32 width, int32 height, ui
case PixelFormat::ASTC_8x8_UNorm_sRGB: case PixelFormat::ASTC_8x8_UNorm_sRGB:
case PixelFormat::ASTC_10x10_UNorm: case PixelFormat::ASTC_10x10_UNorm:
case PixelFormat::ASTC_10x10_UNorm_sRGB: case PixelFormat::ASTC_10x10_UNorm_sRGB:
{ {
const int32 blockSize = PixelFormatExtensions::ComputeBlockSize(format); const int32 blockSize = PixelFormatExtensions::ComputeBlockSize(format);
uint32 nbw = Math::Max<uint32>(1, Math::DivideAndRoundUp(width, blockSize)); uint32 nbw = Math::Max<uint32>(1, Math::DivideAndRoundUp(width, blockSize));
uint32 nbh = Math::Max<uint32>(1, Math::DivideAndRoundUp(height, blockSize)); uint32 nbh = Math::Max<uint32>(1, Math::DivideAndRoundUp(height, blockSize));
rowPitch = nbw * 16; // All ASTC blocks use 128 bits rowPitch = nbw * 16; // All ASTC blocks use 128 bits
slicePitch = rowPitch * nbh; slicePitch = rowPitch * nbh;
} }
break; break;
case PixelFormat::R8G8_B8G8_UNorm: case PixelFormat::R8G8_B8G8_UNorm:
case PixelFormat::G8R8_G8B8_UNorm: case PixelFormat::G8R8_G8B8_UNorm:
ASSERT(PixelFormatExtensions::IsPacked(format)); ASSERT(PixelFormatExtensions::IsPacked(format));
@@ -552,6 +552,14 @@ void RenderTools::ComputeCascadeUpdateFrequency(int32 cascadeIndex, int32 cascad
} }
} }
float RenderTools::ComputeTemporalTime()
{
const float time = Time::Draw.UnscaledTime.GetTotalSeconds();
const float scale = 10;
const float integral = roundf(time / scale) * scale;
return time - integral;
}
void RenderTools::CalculateTangentFrame(FloatR10G10B10A2& resultNormal, FloatR10G10B10A2& resultTangent, const Float3& normal) void RenderTools::CalculateTangentFrame(FloatR10G10B10A2& resultNormal, FloatR10G10B10A2& resultTangent, const Float3& normal)
{ {
// Calculate tangent // Calculate tangent
@@ -579,6 +587,23 @@ void RenderTools::CalculateTangentFrame(FloatR10G10B10A2& resultNormal, FloatR10
resultTangent = Float1010102(tangent * 0.5f + 0.5f, sign); resultTangent = Float1010102(tangent * 0.5f + 0.5f, sign);
} }
void RenderTools::ComputeSphereModelDrawMatrix(const RenderView& view, const Float3& position, float radius, Matrix& resultWorld, bool& resultIsViewInside)
{
// Construct world matrix
constexpr float sphereModelScale = 0.0205f; // Manually tweaked for 'Engine/Models/Sphere' with some slack
const float scaling = radius * sphereModelScale;
resultWorld = Matrix::Identity;
resultWorld.M11 = scaling;
resultWorld.M22 = scaling;
resultWorld.M33 = scaling;
resultWorld.M41 = position.X;
resultWorld.M42 = position.Y;
resultWorld.M43 = position.Z;
// Check if view is inside the sphere
resultIsViewInside = Float3::DistanceSquared(view.Position, position) < Math::Square(radius * 1.1f); // Manually tweaked bias
}
int32 MipLevelsCount(int32 width, bool useMipLevels) int32 MipLevelsCount(int32 width, bool useMipLevels)
{ {
if (!useMipLevels) if (!useMipLevels)
@@ -636,22 +661,6 @@ int32 MipLevelsCount(int32 width, int32 height, int32 depth, bool useMipLevels)
return result; return result;
} }
float ViewToCenterLessRadius(const RenderView& view, const Float3& center, float radius)
{
// Calculate distance from view to sphere center
float viewToCenter = Float3::Distance(view.Position, center);
// Check if need to fix the radius
//if (radius + viewToCenter > view.Far)
{
// Clamp radius
//radius = view.Far - viewToCenter;
}
// Calculate result
return viewToCenter - radius;
}
void MeshBase::SetMaterialSlotIndex(int32 value) void MeshBase::SetMaterialSlotIndex(int32 value)
{ {
if (value < 0 || value >= _model->MaterialSlots.Count()) if (value < 0 || value >= _model->MaterialSlots.Count())

View File

@@ -121,8 +121,14 @@ public:
return (frameIndex % updateFrequency == updatePhrase) || updateForce; return (frameIndex % updateFrequency == updatePhrase) || updateForce;
} }
// Calculates temporal offset in the dithering factor that gets cleaned out by TAA.
// Returns 0-1 value based on unscaled draw time for temporal effects to reduce artifacts from screen-space dithering when using Temporal Anti-Aliasing.
static float ComputeTemporalTime();
static void CalculateTangentFrame(FloatR10G10B10A2& resultNormal, FloatR10G10B10A2& resultTangent, const Float3& normal); static void CalculateTangentFrame(FloatR10G10B10A2& resultNormal, FloatR10G10B10A2& resultTangent, const Float3& normal);
static void CalculateTangentFrame(FloatR10G10B10A2& resultNormal, FloatR10G10B10A2& resultTangent, const Float3& normal, const Float3& tangent); static void CalculateTangentFrame(FloatR10G10B10A2& resultNormal, FloatR10G10B10A2& resultTangent, const Float3& normal, const Float3& tangent);
static void ComputeSphereModelDrawMatrix(const RenderView& view, const Float3& position, float radius, Matrix& resultWorld, bool& resultIsViewInside);
}; };
// Calculate mip levels count for a texture 1D // Calculate mip levels count for a texture 1D
@@ -145,12 +151,3 @@ extern int32 MipLevelsCount(int32 width, int32 height, bool useMipLevels = true)
// @param useMipLevels True if use mip levels, otherwise false (use only 1 mip) // @param useMipLevels True if use mip levels, otherwise false (use only 1 mip)
// @returns Mip levels count // @returns Mip levels count
extern int32 MipLevelsCount(int32 width, int32 height, int32 depth, bool useMipLevels = true); extern int32 MipLevelsCount(int32 width, int32 height, int32 depth, bool useMipLevels = true);
/// <summary>
/// Calculate distance from view center to the sphere center less sphere radius, clamped to fit view far plane
/// </summary>
/// <param name="view">Render View</param>
/// <param name="center">Sphere center</param>
/// <param name="radius">Sphere radius</param>
/// <returns>Distance from view center to the sphere center less sphere radius</returns>
extern float ViewToCenterLessRadius(const RenderView& view, const Float3& center, float radius);

View File

@@ -127,6 +127,11 @@ public:
/// </summary> /// </summary>
API_FIELD() StaticFlags StaticFlagsMask = StaticFlags::None; API_FIELD() StaticFlags StaticFlagsMask = StaticFlags::None;
/// <summary>
/// The static flags mask comparision rhs. Allows to draw objects that don't pass the static flags mask. Objects are checked with the following formula: (ObjectStaticFlags and StaticFlagsMask) == StaticFlagsMaskCompare.
/// </summary>
API_FIELD() StaticFlags StaticFlagsCompare = StaticFlags::None;
/// <summary> /// <summary>
/// The view flags. /// The view flags.
/// </summary> /// </summary>

View File

@@ -7,8 +7,8 @@
class GPUContext; class GPUContext;
class GPUTask; class GPUTask;
class TextureMipData; struct TextureMipData;
class TextureData; struct TextureData;
template<typename T> template<typename T>
class DataContainer; class DataContainer;
typedef DataContainer<byte> BytesContainer; typedef DataContainer<byte> BytesContainer;
@@ -533,7 +533,7 @@ public:
/// </summary> /// </summary>
/// <param name="result">The result data.</param> /// <param name="result">The result data.</param>
/// <returns>True if cannot download data, otherwise false.</returns> /// <returns>True if cannot download data, otherwise false.</returns>
bool DownloadData(TextureData& result); API_FUNCTION() bool DownloadData(API_PARAM(Out) TextureData& result);
/// <summary> /// <summary>
/// Creates GPU async task that will gather texture data from the GPU. /// Creates GPU async task that will gather texture data from the GPU.

View File

@@ -5,8 +5,8 @@
#include "Engine/Content/BinaryAsset.h" #include "Engine/Content/BinaryAsset.h"
#include "StreamingTexture.h" #include "StreamingTexture.h"
class TextureData; struct TextureData;
class TextureMipData; struct TextureMipData;
/// <summary> /// <summary>
/// Base class for <see cref="Texture"/>, <see cref="SpriteAtlas"/>, <see cref="IESProfile"/> and other assets that can contain texture data. /// Base class for <see cref="Texture"/>, <see cref="SpriteAtlas"/>, <see cref="IESProfile"/> and other assets that can contain texture data.

View File

@@ -10,13 +10,21 @@
/// <summary> /// <summary>
/// Single texture mip map entry data. /// Single texture mip map entry data.
/// </summary> /// </summary>
class FLAXENGINE_API TextureMipData API_STRUCT() struct FLAXENGINE_API TextureMipData
{ {
DECLARE_SCRIPTING_TYPE_MINIMAL(TextureMipData);
public: public:
uint32 RowPitch; // The row pitch.
uint32 DepthPitch; API_FIELD() uint32 RowPitch;
uint32 Lines;
BytesContainer Data; // The depth pitch.
API_FIELD() uint32 DepthPitch;
// The number of lines.
API_FIELD() uint32 Lines;
// The data.
API_FIELD(ReadOnly) BytesContainer Data;
TextureMipData(); TextureMipData();
TextureMipData(const TextureMipData& other); TextureMipData(const TextureMipData& other);
@@ -40,22 +48,39 @@ public:
} }
}; };
template<>
struct TIsPODType<TextureMipData>
{
enum { Value = true };
};
/// <summary>
/// Single entry of the texture array. Contains collection of mip maps.
/// </summary>
API_STRUCT(NoDefault) struct FLAXENGINE_API TextureDataArrayEntry
{
DECLARE_SCRIPTING_TYPE_MINIMAL(TextureDataArrayEntry);
/// <summary>
/// The mip maps collection.
/// </summary>
API_FIELD(ReadOnly) Array<TextureMipData, FixedAllocation<GPU_MAX_TEXTURE_MIP_LEVELS>> Mips;
};
template<>
struct TIsPODType<TextureDataArrayEntry>
{
enum { Value = false };
};
/// <summary> /// <summary>
/// Texture data container (used to keep data downloaded from the GPU). /// Texture data container (used to keep data downloaded from the GPU).
/// </summary> /// </summary>
class FLAXENGINE_API TextureData API_STRUCT() struct FLAXENGINE_API TextureData
{ {
DECLARE_SCRIPTING_TYPE_MINIMAL(TextureData);
public: public:
/// <summary>
/// Single entry of the texture array. Contains collection of mip maps.
/// </summary>
struct FLAXENGINE_API ArrayEntry
{
/// <summary>
/// The mip maps collection.
/// </summary>
Array<TextureMipData, FixedAllocation<GPU_MAX_TEXTURE_MIP_LEVELS>> Mips;
};
public: public:
/// <summary> /// <summary>
@@ -76,27 +101,27 @@ public:
/// <summary> /// <summary>
/// Top level texture width (in pixels). /// Top level texture width (in pixels).
/// </summary> /// </summary>
int32 Width = 0; API_FIELD() int32 Width = 0;
/// <summary> /// <summary>
/// Top level texture height (in pixels). /// Top level texture height (in pixels).
/// </summary> /// </summary>
int32 Height = 0; API_FIELD() int32 Height = 0;
/// <summary> /// <summary>
/// Top level texture depth (in pixels). /// Top level texture depth (in pixels).
/// </summary> /// </summary>
int32 Depth = 0; API_FIELD() int32 Depth = 0;
/// <summary> /// <summary>
/// The texture data format. /// The texture data format.
/// </summary> /// </summary>
PixelFormat Format = PixelFormat::Unknown; API_FIELD() PixelFormat Format = PixelFormat::Unknown;
/// <summary> /// <summary>
/// The items collection (depth slices or array slices). /// The items collection (depth slices or array slices).
/// </summary> /// </summary>
Array<ArrayEntry, InlinedAllocation<6>> Items; API_FIELD() Array<TextureDataArrayEntry, InlinedAllocation<6>> Items;
public: public:
/// <summary> /// <summary>
@@ -145,3 +170,9 @@ public:
Items.Resize(0, false); Items.Resize(0, false);
} }
}; };
template<>
struct TIsPODType<TextureData>
{
enum { Value = false };
};

View File

@@ -120,7 +120,7 @@ void GPUContextDX11::FrameBegin()
_device->_samplerLinearWrap, _device->_samplerLinearWrap,
_device->_samplerPointWrap, _device->_samplerPointWrap,
_device->_samplerShadow, _device->_samplerShadow,
_device->_samplerShadowPCF _device->_samplerShadowLinear
}; };
_context->VSSetSamplers(0, ARRAY_COUNT(samplers), samplers); _context->VSSetSamplers(0, ARRAY_COUNT(samplers), samplers);
#if GPU_ALLOW_TESSELLATION_SHADERS #if GPU_ALLOW_TESSELLATION_SHADERS
@@ -159,21 +159,19 @@ bool GPUContextDX11::IsDepthBufferBinded()
void GPUContextDX11::Clear(GPUTextureView* rt, const Color& color) void GPUContextDX11::Clear(GPUTextureView* rt, const Color& color)
{ {
auto rtDX11 = static_cast<GPUTextureViewDX11*>(rt); auto rtDX11 = static_cast<GPUTextureViewDX11*>(rt);
if (rtDX11) if (rtDX11)
{ {
_context->ClearRenderTargetView(rtDX11->RTV(), color.Raw); _context->ClearRenderTargetView(rtDX11->RTV(), color.Raw);
} }
} }
void GPUContextDX11::ClearDepth(GPUTextureView* depthBuffer, float depthValue) void GPUContextDX11::ClearDepth(GPUTextureView* depthBuffer, float depthValue, uint8 stencilValue)
{ {
auto depthBufferDX11 = static_cast<GPUTextureViewDX11*>(depthBuffer); auto depthBufferDX11 = static_cast<GPUTextureViewDX11*>(depthBuffer);
if (depthBufferDX11) if (depthBufferDX11)
{ {
ASSERT(depthBufferDX11->DSV()); ASSERT(depthBufferDX11->DSV());
_context->ClearDepthStencilView(depthBufferDX11->DSV(), D3D11_CLEAR_DEPTH, depthValue, 0xff); _context->ClearDepthStencilView(depthBufferDX11->DSV(), D3D11_CLEAR_DEPTH, depthValue, stencilValue);
} }
} }

View File

@@ -113,7 +113,7 @@ public:
void* GetNativePtr() const override; void* GetNativePtr() const override;
bool IsDepthBufferBinded() override; bool IsDepthBufferBinded() override;
void Clear(GPUTextureView* rt, const Color& color) override; void Clear(GPUTextureView* rt, const Color& color) override;
void ClearDepth(GPUTextureView* depthBuffer, float depthValue) override; void ClearDepth(GPUTextureView* depthBuffer, float depthValue, uint8 stencilValue) override;
void ClearUA(GPUBuffer* buf, const Float4& value) override; void ClearUA(GPUBuffer* buf, const Float4& value) override;
void ClearUA(GPUBuffer* buf, const uint32 value[4]) override; void ClearUA(GPUBuffer* buf, const uint32 value[4]) override;
void ClearUA(GPUTexture* texture, const uint32 value[4]) override; void ClearUA(GPUTexture* texture, const uint32 value[4]) override;

View File

@@ -227,16 +227,7 @@ GPUDevice* GPUDeviceDX11::Create()
GPUDeviceDX11::GPUDeviceDX11(IDXGIFactory* dxgiFactory, GPUAdapterDX* adapter) GPUDeviceDX11::GPUDeviceDX11(IDXGIFactory* dxgiFactory, GPUAdapterDX* adapter)
: GPUDeviceDX(getRendererType(adapter), getShaderProfile(adapter), adapter) : GPUDeviceDX(getRendererType(adapter), getShaderProfile(adapter), adapter)
, _device(nullptr)
, _imContext(nullptr)
, _factoryDXGI(dxgiFactory) , _factoryDXGI(dxgiFactory)
, _mainContext(nullptr)
, _samplerLinearClamp(nullptr)
, _samplerPointClamp(nullptr)
, _samplerLinearWrap(nullptr)
, _samplerPointWrap(nullptr)
, _samplerShadow(nullptr)
, _samplerShadowPCF(nullptr)
{ {
Platform::MemoryClear(RasterizerStates, sizeof(RasterizerStates)); Platform::MemoryClear(RasterizerStates, sizeof(RasterizerStates));
Platform::MemoryClear(DepthStencilStates, sizeof(DepthStencilStates)); Platform::MemoryClear(DepthStencilStates, sizeof(DepthStencilStates));
@@ -450,14 +441,17 @@ bool GPUDeviceDX11::Init()
{ {
D3D11_SAMPLER_DESC samplerDesc; D3D11_SAMPLER_DESC samplerDesc;
Platform::MemoryClear(&samplerDesc, sizeof(samplerDesc)); Platform::MemoryClear(&samplerDesc, sizeof(samplerDesc));
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
samplerDesc.MipLODBias = 0.0f;
samplerDesc.MaxAnisotropy = 1;
samplerDesc.ComparisonFunc = D3D11_COMPARISON_LESS_EQUAL;
// Linear Clamp // Linear Clamp
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
result = _device->CreateSamplerState(&samplerDesc, &_samplerLinearClamp); result = _device->CreateSamplerState(&samplerDesc, &_samplerLinearClamp);
LOG_DIRECTX_RESULT_WITH_RETURN(result, true); LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
@@ -466,8 +460,6 @@ bool GPUDeviceDX11::Init()
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
result = _device->CreateSamplerState(&samplerDesc, &_samplerPointClamp); result = _device->CreateSamplerState(&samplerDesc, &_samplerPointClamp);
LOG_DIRECTX_RESULT_WITH_RETURN(result, true); LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
@@ -476,8 +468,6 @@ bool GPUDeviceDX11::Init()
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
result = _device->CreateSamplerState(&samplerDesc, &_samplerLinearWrap); result = _device->CreateSamplerState(&samplerDesc, &_samplerLinearWrap);
LOG_DIRECTX_RESULT_WITH_RETURN(result, true); LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
@@ -486,8 +476,6 @@ bool GPUDeviceDX11::Init()
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
result = _device->CreateSamplerState(&samplerDesc, &_samplerPointWrap); result = _device->CreateSamplerState(&samplerDesc, &_samplerPointWrap);
LOG_DIRECTX_RESULT_WITH_RETURN(result, true); LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
@@ -496,26 +484,15 @@ bool GPUDeviceDX11::Init()
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.MipLODBias = 0.0f;
samplerDesc.MaxAnisotropy = 1;
samplerDesc.ComparisonFunc = D3D11_COMPARISON_LESS_EQUAL;
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
result = _device->CreateSamplerState(&samplerDesc, &_samplerShadow); result = _device->CreateSamplerState(&samplerDesc, &_samplerShadow);
LOG_DIRECTX_RESULT_WITH_RETURN(result, true); LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
// Shadow PCF // Shadow Linear
samplerDesc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR; samplerDesc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR;
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.MipLODBias = 0.0f; result = _device->CreateSamplerState(&samplerDesc, &_samplerShadowLinear);
samplerDesc.MaxAnisotropy = 1;
samplerDesc.ComparisonFunc = D3D11_COMPARISON_LESS_EQUAL;
samplerDesc.BorderColor[0] = samplerDesc.BorderColor[1] = samplerDesc.BorderColor[2] = samplerDesc.BorderColor[3] = 0;
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
result = _device->CreateSamplerState(&samplerDesc, &_samplerShadowPCF);
LOG_DIRECTX_RESULT_WITH_RETURN(result, true); LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
} }
@@ -616,7 +593,7 @@ void GPUDeviceDX11::Dispose()
SAFE_RELEASE(_samplerLinearWrap); SAFE_RELEASE(_samplerLinearWrap);
SAFE_RELEASE(_samplerPointWrap); SAFE_RELEASE(_samplerPointWrap);
SAFE_RELEASE(_samplerShadow); SAFE_RELEASE(_samplerShadow);
SAFE_RELEASE(_samplerShadowPCF); SAFE_RELEASE(_samplerShadowLinear);
// //
for (auto i = BlendStates.Begin(); i.IsNotEnd(); ++i) for (auto i = BlendStates.Begin(); i.IsNotEnd(); ++i)
{ {

View File

@@ -24,20 +24,20 @@ class GPUDeviceDX11 : public GPUDeviceDX
private: private:
// Private Stuff // Private Stuff
ID3D11Device* _device; ID3D11Device* _device = nullptr;
ID3D11DeviceContext* _imContext; ID3D11DeviceContext* _imContext = nullptr;
IDXGIFactory* _factoryDXGI; IDXGIFactory* _factoryDXGI;
GPUContextDX11* _mainContext; GPUContextDX11* _mainContext = nullptr;
bool _allowTearing = false; bool _allowTearing = false;
// Static Samplers // Static Samplers
ID3D11SamplerState* _samplerLinearClamp; ID3D11SamplerState* _samplerLinearClamp = nullptr;
ID3D11SamplerState* _samplerPointClamp; ID3D11SamplerState* _samplerPointClamp = nullptr;
ID3D11SamplerState* _samplerLinearWrap; ID3D11SamplerState* _samplerLinearWrap = nullptr;
ID3D11SamplerState* _samplerPointWrap; ID3D11SamplerState* _samplerPointWrap = nullptr;
ID3D11SamplerState* _samplerShadow; ID3D11SamplerState* _samplerShadow = nullptr;
ID3D11SamplerState* _samplerShadowPCF; ID3D11SamplerState* _samplerShadowLinear = nullptr;
// Shared data for pipeline states // Shared data for pipeline states
CriticalSection BlendStatesWriteLocker; CriticalSection BlendStatesWriteLocker;

View File

@@ -703,7 +703,6 @@ bool GPUContextDX12::IsDepthBufferBinded()
void GPUContextDX12::Clear(GPUTextureView* rt, const Color& color) void GPUContextDX12::Clear(GPUTextureView* rt, const Color& color)
{ {
auto rtDX12 = static_cast<GPUTextureViewDX12*>(rt); auto rtDX12 = static_cast<GPUTextureViewDX12*>(rt);
if (rtDX12) if (rtDX12)
{ {
SetResourceState(rtDX12->GetResourceOwner(), D3D12_RESOURCE_STATE_RENDER_TARGET, rtDX12->SubresourceIndex); SetResourceState(rtDX12->GetResourceOwner(), D3D12_RESOURCE_STATE_RENDER_TARGET, rtDX12->SubresourceIndex);
@@ -713,16 +712,15 @@ void GPUContextDX12::Clear(GPUTextureView* rt, const Color& color)
} }
} }
void GPUContextDX12::ClearDepth(GPUTextureView* depthBuffer, float depthValue) void GPUContextDX12::ClearDepth(GPUTextureView* depthBuffer, float depthValue, uint8 stencilValue)
{ {
auto depthBufferDX12 = static_cast<GPUTextureViewDX12*>(depthBuffer); auto depthBufferDX12 = static_cast<GPUTextureViewDX12*>(depthBuffer);
if (depthBufferDX12) if (depthBufferDX12)
{ {
SetResourceState(depthBufferDX12->GetResourceOwner(), D3D12_RESOURCE_STATE_DEPTH_WRITE, depthBufferDX12->SubresourceIndex); SetResourceState(depthBufferDX12->GetResourceOwner(), D3D12_RESOURCE_STATE_DEPTH_WRITE, depthBufferDX12->SubresourceIndex);
flushRBs(); flushRBs();
_commandList->ClearDepthStencilView(depthBufferDX12->DSV(), D3D12_CLEAR_FLAG_DEPTH, depthValue, 0xff, 0, nullptr); _commandList->ClearDepthStencilView(depthBufferDX12->DSV(), D3D12_CLEAR_FLAG_DEPTH, depthValue, stencilValue, 0, nullptr);
} }
} }

View File

@@ -159,7 +159,7 @@ public:
void* GetNativePtr() const override; void* GetNativePtr() const override;
bool IsDepthBufferBinded() override; bool IsDepthBufferBinded() override;
void Clear(GPUTextureView* rt, const Color& color) override; void Clear(GPUTextureView* rt, const Color& color) override;
void ClearDepth(GPUTextureView* depthBuffer, float depthValue) override; void ClearDepth(GPUTextureView* depthBuffer, float depthValue, uint8 stencilValue) override;
void ClearUA(GPUBuffer* buf, const Float4& value) override; void ClearUA(GPUBuffer* buf, const Float4& value) override;
void ClearUA(GPUBuffer* buf, const uint32 value[4]) override; void ClearUA(GPUBuffer* buf, const uint32 value[4]) override;
void ClearUA(GPUTexture* texture, const uint32 value[4]) override; void ClearUA(GPUTexture* texture, const uint32 value[4]) override;

View File

@@ -568,7 +568,6 @@ bool GPUDeviceDX12::Init()
// Static samplers // Static samplers
D3D12_STATIC_SAMPLER_DESC staticSamplers[6]; D3D12_STATIC_SAMPLER_DESC staticSamplers[6];
static_assert(GPU_STATIC_SAMPLERS_COUNT == ARRAY_COUNT(staticSamplers), "Update static samplers setup."); static_assert(GPU_STATIC_SAMPLERS_COUNT == ARRAY_COUNT(staticSamplers), "Update static samplers setup.");
// TODO: describe visibilities for the static samples, maybe use all pixel? or again pixel + all combo?
// Linear Clamp // Linear Clamp
staticSamplers[0].Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR; staticSamplers[0].Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
staticSamplers[0].AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; staticSamplers[0].AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
@@ -650,8 +649,6 @@ bool GPUDeviceDX12::Init()
staticSamplers[5].RegisterSpace = 0; staticSamplers[5].RegisterSpace = 0;
staticSamplers[5].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; staticSamplers[5].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
// TODO: static samplers for the shadow pass change into bindable samplers or sth?
// Init // Init
D3D12_ROOT_SIGNATURE_DESC rootSignatureDesc; D3D12_ROOT_SIGNATURE_DESC rootSignatureDesc;
rootSignatureDesc.NumParameters = ARRAY_COUNT(rootParameters); rootSignatureDesc.NumParameters = ARRAY_COUNT(rootParameters);

View File

@@ -48,7 +48,7 @@ public:
{ {
} }
void ClearDepth(GPUTextureView* depthBuffer, float depthValue) override void ClearDepth(GPUTextureView* depthBuffer, float depthValue, uint8 stencilValue) override
{ {
} }

View File

@@ -797,10 +797,9 @@ void GPUContextVulkan::Clear(GPUTextureView* rt, const Color& color)
} }
} }
void GPUContextVulkan::ClearDepth(GPUTextureView* depthBuffer, float depthValue) void GPUContextVulkan::ClearDepth(GPUTextureView* depthBuffer, float depthValue, uint8 stencilValue)
{ {
const auto rtVulkan = static_cast<GPUTextureViewVulkan*>(depthBuffer); const auto rtVulkan = static_cast<GPUTextureViewVulkan*>(depthBuffer);
if (rtVulkan) if (rtVulkan)
{ {
// TODO: detect if inside render pass and use ClearAttachments // TODO: detect if inside render pass and use ClearAttachments
@@ -815,7 +814,7 @@ void GPUContextVulkan::ClearDepth(GPUTextureView* depthBuffer, float depthValue)
VkClearDepthStencilValue clear; VkClearDepthStencilValue clear;
clear.depth = depthValue; clear.depth = depthValue;
clear.stencil = 0; clear.stencil = stencilValue;
vkCmdClearDepthStencilImage(cmdBuffer->GetHandle(), rtVulkan->Image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear, 1, &rtVulkan->Info.subresourceRange); vkCmdClearDepthStencilImage(cmdBuffer->GetHandle(), rtVulkan->Image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear, 1, &rtVulkan->Info.subresourceRange);
} }
} }

View File

@@ -151,7 +151,7 @@ public:
void* GetNativePtr() const override; void* GetNativePtr() const override;
bool IsDepthBufferBinded() override; bool IsDepthBufferBinded() override;
void Clear(GPUTextureView* rt, const Color& color) override; void Clear(GPUTextureView* rt, const Color& color) override;
void ClearDepth(GPUTextureView* depthBuffer, float depthValue) override; void ClearDepth(GPUTextureView* depthBuffer, float depthValue, uint8 stencilValue) override;
void ClearUA(GPUBuffer* buf, const Float4& value) override; void ClearUA(GPUBuffer* buf, const Float4& value) override;
void ClearUA(GPUBuffer* buf, const uint32 value[4]) override; void ClearUA(GPUBuffer* buf, const uint32 value[4]) override;
void ClearUA(GPUTexture* texture, const uint32 value[4]) override; void ClearUA(GPUTexture* texture, const uint32 value[4]) override;

Some files were not shown because too many files have changed in this diff Show More