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
[lfs]
url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs"
locksverify = false
#url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs"
locksverify = false

BIN
Content/Editor/Camera/M_Camera.flax (Stored with Git LFS)

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.

BIN
Content/Editor/DefaultFontMaterial.flax (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

BIN
Content/Editor/Gizmo/Material.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Editor/Gizmo/MaterialWire.flax (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Content/Editor/Highlight Material.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Editor/Icons/IconsMaterial.flax (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

View File

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

View File

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

View File

@@ -10,8 +10,8 @@
@7
// Primary constant buffer (with additional material parameters)
META_CB_BEGIN(0, Data)
float4x4 WorldMatrix;
float4x4 PrevWorldMatrix;
float4x3 WorldMatrix;
float4x3 PrevWorldMatrix;
float2 Dummy0;
float LODDitherFactor;
float PerInstanceRandom;
@@ -171,7 +171,7 @@ MaterialInput GetMaterialInput(PixelInput input)
#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;
#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
// 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
CalculateInstanceTransform(input);
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
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
@@ -402,7 +402,7 @@ float4 VS_Depth(ModelInput_PosOnly input) : SV_Position
#if USE_INSTANCING
float4x4 world = GetInstanceTransform(input);
#else
float4x4 world = WorldMatrix;
float4x4 world = ToMatrix4x4(WorldMatrix);
#endif
float3 worldPosition = mul(float4(input.Position.xyz, 1), world).xyz;
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;
#if PER_BONE_MOTION_BLUR
float3 prevPosition = SkinPrevPosition(input);
output.Geometry.PrevWorldPosition = mul(float4(prevPosition, 1), PrevWorldMatrix).xyz;
output.Geometry.PrevWorldPosition = mul(float4(prevPosition, 1), ToMatrix4x4(PrevWorldMatrix)).xyz;
#else
output.Geometry.PrevWorldPosition = mul(float4(position, 1), PrevWorldMatrix).xyz;
output.Geometry.PrevWorldPosition = mul(float4(position, 1), ToMatrix4x4(PrevWorldMatrix)).xyz;
#endif
// Compute clip space position

View File

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

View File

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

Binary file not shown.

Binary file not shown.

BIN
Content/Editor/SpriteMaterial.flax (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Content/Editor/TexturePreviewMaterial.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Editor/Wires Debug Material.flax (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

BIN
Content/Engine/DefaultMaterial.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Engine/DefaultTerrainMaterial.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Engine/SingleColorMaterial.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Engine/SkyboxMaterial.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Shaders/GI/GlobalSurfaceAtlas.flax (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

BIN
Content/Shaders/Lights.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Shaders/Quad.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Shaders/Shadows.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Shaders/VolumetricFog.flax (Stored with Git LFS)

Binary file not shown.

View File

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

View File

@@ -377,6 +377,10 @@ namespace FlaxEditor.CustomEditors
else if (Values.HasDefaultValue && CanRevertDefaultValue)
color = Color.Yellow * 0.8f;
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;
return true;
@@ -671,20 +675,7 @@ namespace FlaxEditor.CustomEditors
/// <summary>
/// Gets a value indicating whether can paste value from the system clipboard to the property value container.
/// </summary>
public bool CanPaste
{
get
{
try
{
return GetClipboardObject(out _, false);
}
catch
{
return false;
}
}
}
public bool CanPaste => !string.IsNullOrEmpty(Clipboard.Text);
/// <summary>
/// Sets the value from the system clipboard.

View File

@@ -474,32 +474,7 @@ namespace FlaxEditor.CustomEditors.Editors
}
if (layout.Editors.Count != 0)
{
var sb = 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;
return !string.IsNullOrEmpty(Clipboard.Text);
}
if (layout.Children.Any(x => x is LayoutElementsContainer))
{

View File

@@ -139,6 +139,11 @@ namespace FlaxEditor.CustomEditors
/// </summary>
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>
/// Gets the values types array (without duplicates).
/// </summary>
@@ -160,6 +165,7 @@ namespace FlaxEditor.CustomEditors
{
Info = info;
Type = Info.ValueType;
IsObsolete = Info.HasAttribute(typeof(ObsoleteAttribute), true);
}
/// <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.")]
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>
/// Gets or sets the editor icons scale. Editor restart required.
/// </summary>
@@ -211,23 +204,72 @@ namespace FlaxEditor.Options
public bool SeparateValueAndUnit { get; set; }
/// <summary>
/// Gets or sets the timestamps prefix mode for output log messages.
/// Gets or sets the timestamps prefix mode for debug log messages.
/// </summary>
[DefaultValue(TimestampsFormats.TimeSinceStartup)]
[EditorDisplay("Output Log", "Timestamps Format"), EditorOrder(300), Tooltip("The timestamps prefix mode for output log messages.")]
public TimestampsFormats OutputLogTimestampsFormat { get; set; } = TimestampsFormats.TimeSinceStartup;
[DefaultValue(TimestampsFormats.None)]
[EditorDisplay("Debug Log"), EditorOrder(300), Tooltip("The timestamps prefix mode for debug log messages.")]
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>
/// Gets or sets the timestamps prefix mode for output log messages.
/// </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)]
[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;
/// <summary>
/// Gets or sets the output log text font.
/// </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
{
get => _outputLogFont;
@@ -246,63 +288,70 @@ namespace FlaxEditor.Options
/// Gets or sets the output log text color.
/// </summary>
[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;
/// <summary>
/// Gets or sets the output log text shadow color.
/// </summary>
[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);
/// <summary>
/// Gets or sets the output log text shadow offset. Set to 0 to disable this feature.
/// </summary>
[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);
/// <summary>
/// Gets or sets a value indicating whether auto-focus output log window on code compilation error.
/// </summary>
[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;
/// <summary>
/// Gets or sets a value indicating whether auto-focus output log window on game build error.
/// </summary>
[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;
/// <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>
/// Gets or sets a value indicating whether auto-focus game window on play mode start.
/// </summary>
[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;
/// <summary>
/// Gets or sets a value indicating what action should be taken upon pressing the play button.
/// </summary>
[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;
/// <summary>
/// Gets or sets a value indicating how the game window should be displayed when the game is launched.
/// </summary>
[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;
/// <summary>
/// Gets or sets a value indicating the number of game clients to launch when building and/or running cooked game.
/// </summary>
[DefaultValue(1), Range(1, 4)]
[EditorDisplay("Cook & Run"), EditorOrder(500)]
[EditorDisplay("Cook & Run"), EditorOrder(600)]
public int NumberOfGameClientsToLaunch = 1;
private static FontAsset DefaultFont => FlaxEngine.Content.LoadAsyncInternal<FontAsset>(EditorAssets.PrimaryFont);
@@ -317,13 +366,13 @@ namespace FlaxEditor.Options
/// <summary>
/// The list of fallback fonts to use when main text font is missing certain characters. Empty to use fonts from GraphicsSettings.
/// </summary>
[EditorDisplay("Fonts"), EditorOrder(650)]
[EditorDisplay("Fonts"), EditorOrder(750)]
public FontAsset[] FallbackFonts = new FontAsset[1] { FlaxEngine.Content.LoadAsyncInternal<FontAsset>(EditorAssets.FallbackFont) };
/// <summary>
/// Gets or sets the title font for editor UI.
/// </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
{
get => _titleFont;
@@ -341,7 +390,7 @@ namespace FlaxEditor.Options
/// <summary>
/// Gets or sets the large font for editor UI.
/// </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
{
get => _largeFont;
@@ -359,7 +408,7 @@ namespace FlaxEditor.Options
/// <summary>
/// Gets or sets the medium font for editor UI.
/// </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
{
get => _mediumFont;
@@ -377,7 +426,7 @@ namespace FlaxEditor.Options
/// <summary>
/// Gets or sets the small font for editor UI.
/// </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
{
get => _smallFont;

View File

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

View File

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

View File

@@ -471,7 +471,13 @@ namespace FlaxEditor.Viewport
trans.SetRotation(ref world);
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();
}
@@ -520,7 +526,9 @@ namespace FlaxEditor.Viewport
/// <param name="scaleDelta">The scale delta.</param>
public void ApplyTransform(List<SceneGraphNode> selection, ref Vector3 translationDelta, ref Quaternion rotationDelta, ref Vector3 scaleDelta)
{
bool applyTranslation = !translationDelta.IsZero;
bool applyRotation = !rotationDelta.IsIdentity;
bool applyScale = !scaleDelta.IsZero;
bool useObjCenter = TransformGizmo.ActivePivot == TransformGizmoBase.PivotType.ObjectCenter;
Vector3 gizmoPosition = TransformGizmo.Position;
@@ -555,13 +563,29 @@ namespace FlaxEditor.Viewport
}
// Apply scale
const float scaleLimit = 99_999_999.0f;
trans.Scale = Float3.Clamp(trans.Scale + scaleDelta, new Float3(-scaleLimit), new Float3(scaleLimit));
if (applyScale)
{
const float scaleLimit = 99_999_999.0f;
trans.Scale = Float3.Clamp(trans.Scale + scaleDelta, new Float3(-scaleLimit), new Float3(scaleLimit)); ;
}
// 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>
public void ApplyTransform(List<SceneGraphNode> selection, ref Vector3 translationDelta, ref Quaternion rotationDelta, ref Vector3 scaleDelta)
{
bool applyTranslation = !translationDelta.IsZero;
bool applyRotation = !rotationDelta.IsIdentity;
bool applyScale = !scaleDelta.IsZero;
bool useObjCenter = TransformGizmo.ActivePivot == TransformGizmoBase.PivotType.ObjectCenter;
Vector3 gizmoPosition = TransformGizmo.Position;
@@ -387,13 +389,29 @@ namespace FlaxEditor.Viewport
}
// Apply scale
const float scaleLimit = 99_999_999.0f;
trans.Scale = Float3.Clamp(trans.Scale + scaleDelta, new Float3(-scaleLimit), new Float3(scaleLimit));
if (applyScale)
{
const float scaleLimit = 99_999_999.0f;
trans.Scale = Float3.Clamp(trans.Scale + scaleDelta, new Float3(-scaleLimit), new Float3(scaleLimit));
}
// 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";
Icon = IconInfo;
OnEditorOptionsChanged(Editor.Options.Options);
FlaxEditor.Utilities.Utils.SetupCommonInputActions(this);
// Toolstrip
@@ -327,14 +326,42 @@ namespace FlaxEditor.Windows
Parent = this,
};
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");
_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");
_clearOnPlayButton = (ToolStripButton)toolstrip.AddButton("Clear on Play", () =>
{
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();
_groupButtons[0] = (ToolStripButton)toolstrip.AddButton(editor.Icons.Error32, () => UpdateLogTypeVisibility(LogGroup.Error, _groupButtons[0].Checked)).SetAutoCheck(true).SetChecked(true).LinkTooltip("Shows/hides error messages");
_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");
_groupButtons[0] = (ToolStripButton)toolstrip.AddButton(editor.Icons.Error32, () =>
{
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();
OnEditorOptionsChanged(Editor.Options.Options);
// Split panel
_split = new SplitPanel(Orientation.Vertical, ScrollBars.Vertical, ScrollBars.Both)
@@ -380,6 +407,12 @@ namespace FlaxEditor.Windows
private void OnEditorOptionsChanged(EditorOptions options)
{
_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>

View File

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

View File

@@ -1,6 +1,5 @@
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
using System.Collections.Generic;
using System.ComponentModel;
using FlaxEditor.CustomEditors;
using FlaxEngine;
@@ -96,14 +95,6 @@ namespace FlaxEditor.Windows
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)]
[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.")]

View File

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

View File

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

View File

@@ -3,6 +3,7 @@
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
using FlaxEngine.Interop;
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)
if (_needToUpdateStreamingBuffers && clip->Buffers[_streamingFirstChunk] != AUDIO_BUFFER_ID_INVALID)
{
// Clear flag
_needToUpdateStreamingBuffers = false;
// Get buffers in a queue count
int32 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;
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
if (!_isActuallyPlayingSth)
@@ -469,18 +469,25 @@ void AudioSource::Update()
// Move the chunk pointer (AudioStreamingHandler will request new chunks streaming)
_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
if (_streamingFirstChunk >= clip->Buffers.Count())
{
// Loop over the clip or end play
if (GetIsLooping())
{
// Move to the begin
// Move to the beginning
_streamingFirstChunk = 0;
// Stop audio and request buffers re-sync and then play continue
Stop();
Play();
}
else
{

View File

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

View File

@@ -1336,6 +1336,11 @@ FileReadStream* FlaxStorage::OpenFile()
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();
// 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
// Close file handles (from all threads)
Array<FileReadStream*> streams;
streams.Clear();
_file.GetValues(streams);
for (FileReadStream* stream : streams)
{

View File

@@ -61,9 +61,10 @@ public:
/// <summary>
/// Enables cascades splits blending for directional light shadows.
/// [Deprecated in v1.9]
/// </summary>
API_FIELD(Attributes="EditorOrder(1320), DefaultValue(false), EditorDisplay(\"Quality\", \"Allow CSM Blending\")")
bool AllowCSMBlending = false;
DEPRECATED bool AllowCSMBlending = false;
/// <summary>
/// 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 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 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
{
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

View File

@@ -2,6 +2,7 @@
#include "Matrix.h"
#include "Matrix3x3.h"
#include "Matrix3x4.h"
#include "Vector2.h"
#include "Quaternion.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]
);
}
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="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="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);
// Creates a 3D affine transformation matrix.

View File

@@ -9,43 +9,14 @@
/// </summary>
struct FLAXENGINE_API Matrix3x4
{
float M[3][4];
void SetMatrix(const Matrix& m)
union
{
const float* src = m.Raw;
float* dst = &M[0][0];
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];
}
float Values[3][4];
float Raw[12];
};
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];
}
void SetMatrix(const Matrix& m);
void SetMatrixTranspose(const Matrix& m);
};
template<>

View File

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

View File

@@ -31,8 +31,6 @@ namespace FlaxEngine.Interop
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 boolFalsePtr = ManagedHandle.ToIntPtr(ManagedHandle.Alloc((int)0, GCHandleType.Pinned));
@@ -279,44 +277,6 @@ namespace FlaxEngine.Interop
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>
/// <param name="assemblyName">The name to find</param>
/// <param name="allowPartial">If true, partial names should be allowed to be resolved.</param>
@@ -378,18 +338,15 @@ namespace FlaxEngine.Interop
/// </summary>
internal static Type GetInternalType(Type type)
{
string[] splits = type.AssemblyQualifiedName.Split(',');
string @namespace = string.Join('.', splits[0].Split('.').SkipLast(1));
string className = @namespace.Length > 0 ? splits[0].Substring(@namespace.Length + 1) : splits[0];
string parentClassName = "";
if (className.Contains('+'))
{
parentClassName = className.Substring(0, className.LastIndexOf('+') + 1);
className = className.Substring(parentClassName.Length);
}
string marshallerName = className + "Marshaller";
string internalAssemblyQualifiedName = $"{@namespace}.{parentClassName}{marshallerName}+{className}Internal,{String.Join(',', splits.Skip(1))}";
return FindType(internalAssemblyQualifiedName);
Type marshallerType = type.GetCustomAttribute<System.Runtime.InteropServices.Marshalling.NativeMarshallingAttribute>()?.NativeType;
if (marshallerType == null)
return null;
Type internalType = marshallerType.GetNestedType($"{type.Name}Internal");
if (internalType == null)
return null;
return internalType;
}
internal class ReferenceTypePlaceholder { }
@@ -1338,7 +1295,7 @@ namespace FlaxEngine.Interop
if (invokeDelegate == null && !method.DeclaringType.IsValueType)
{
// Thread-safe creation
lock (typeCache)
lock (method)
{
if (invokeDelegate == null)
{

View File

@@ -94,7 +94,7 @@ bool Time::TickData::OnTickBegin(double time, float targetFps, float maxDeltaTim
if (targetFps > ZeroTolerance)
{
int skip = (int)(1 + (time - NextBegin) * targetFps);
const int skip = (int)(1 + (time - NextBegin) * targetFps);
NextBegin += (1.0 / targetFps) * skip;
}
}
@@ -132,14 +132,12 @@ bool Time::FixedStepTickData::OnTickBegin(double time, float targetFps, float ma
if (FixedDeltaTimeEnable)
{
deltaTime = (double)FixedDeltaTimeValue;
minDeltaTime = deltaTime;
}
else
{
if (time < NextBegin)
return false;
minDeltaTime = targetFps > ZeroTolerance ? 1.0 / targetFps : 0.0;
deltaTime = Math::Max((time - LastBegin), 0.0);
if (deltaTime > maxDeltaTime)
{
@@ -149,21 +147,10 @@ bool Time::FixedStepTickData::OnTickBegin(double time, float targetFps, float ma
if (targetFps > ZeroTolerance)
{
int skip = (int)(1 + (time - NextBegin) * targetFps);
NextBegin += (1.0 / targetFps) * skip;
deltaTime = 1.0 / targetFps;
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
Advance(time, deltaTime);

View File

@@ -5,7 +5,6 @@
#include "Engine/Core/Types/TimeSpan.h"
#include "Engine/Core/Types/DateTime.h"
#include "Engine/Scripting/ScriptingType.h"
#include "Engine/Core/Collections/SamplesBuffer.h"
/// <summary>
/// Game ticking and timing system.
@@ -89,12 +88,7 @@ public:
class FixedStepTickData : public TickData
{
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]
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,
/// <summary>
/// PSSM cascade splits.
/// Parallel-Split Shadow Maps cascade splits.
/// </summary>
PSSM = 2,
};

View File

@@ -186,7 +186,8 @@ public:
/// </summary>
/// <param name="depthBuffer">The depth buffer to clear.</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>
/// Clears an unordered access buffer with a float value.

View File

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

View File

@@ -50,8 +50,9 @@ public:
/// <summary>
/// Enables cascades splits blending for directional light shadows.
/// [Deprecated in v1.9]
/// </summary>
API_FIELD() static bool AllowCSMBlending;
API_FIELD() DEPRECATED static bool AllowCSMBlending;
/// <summary>
/// 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));
auto materialData = reinterpret_cast<DecalMaterialShaderData*>(cb.Get());
cb = Span<byte>(cb.Get() + sizeof(DecalMaterialShaderData), cb.Length() - sizeof(DecalMaterialShaderData));
int32 srv = 0;
const bool isCameraInside = OrientedBoundingBox(Vector3::Half, params.FirstDrawCall->World).Contains(view.Position) == ContainmentType::Contains;
const bool isCameraInside = OrientedBoundingBox(Vector3::Half, drawCall.World).Contains(view.Position) == ContainmentType::Contains;
// Setup parameters
MaterialParameter::BindMeta bindMeta;

View File

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

View File

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

View File

@@ -119,7 +119,7 @@ public:
struct InstancingHandler
{
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);
};

View File

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

View File

@@ -21,7 +21,8 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<by
ASSERT_LOW_LAYER(cb.Length() >= sizeof(Data));
const int32 envProbeShaderRegisterIndex = srv + 0;
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;
// Set fog input
@@ -39,31 +40,26 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<by
if (cache->DirectionalLights.HasItems())
{
const auto& dirLight = cache->DirectionalLights.First();
const auto shadowPass = ShadowsPass::Instance();
const bool useShadow = shadowPass->LastDirLightIndex == 0 && canUseShadow;
if (useShadow)
{
data.DirectionalLightShadow = shadowPass->LastDirLight;
params.GPUContext->BindSR(dirLightShaderRegisterIndex, shadowPass->LastDirLightShadowMap);
}
else
{
params.GPUContext->UnBindSR(dirLightShaderRegisterIndex);
}
dirLight.SetupLightData(&data.DirectionalLight, useShadow);
GPUTexture* shadowMapAtlas;
GPUBufferView* shadowsBuffer;
ShadowsPass::GetShadowAtlas(params.RenderContext.Buffers, shadowMapAtlas, shadowsBuffer);
const bool useShadow = shadowMapAtlas && canUseShadow && dirLight.HasShadow;
dirLight.SetShaderData(data.DirectionalLight, useShadow);
params.GPUContext->BindSR(shadowsBufferRegisterIndex, shadowsBuffer);
params.GPUContext->BindSR(shadowMapShaderRegisterIndex, shadowMapAtlas);
}
else
{
data.DirectionalLight.Color = Float3::Zero;
data.DirectionalLight.CastShadows = 0.0f;
params.GPUContext->UnBindSR(dirLightShaderRegisterIndex);
Platform::MemoryClear(&data.DirectionalLight, sizeof(data.DirectionalLight));
params.GPUContext->UnBindSR(shadowsBufferRegisterIndex);
params.GPUContext->UnBindSR(shadowMapShaderRegisterIndex);
}
// Set sky light
if (cache->SkyLights.HasItems())
{
auto& skyLight = cache->SkyLights.First();
skyLight.SetupLightData(&data.SkyLight, false);
skyLight.SetShaderData(data.SkyLight, false);
const auto texture = skyLight.Image ? skyLight.Image->GetTexture() : nullptr;
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
EnvironmentProbe* probe = nullptr;
bool noEnvProbe = true;
// 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++)
{
const auto p = cache->EnvironmentProbes[i];
if (CollisionsHelper::SphereIntersectsSphere(objectBoundsWorld, p->GetSphere()))
const RenderEnvironmentProbeData& probe = cache->EnvironmentProbes.Get()[i];
if (objectBounds.Intersects(BoundingSphere(probe.Position, probe.Radius)))
{
probe = p;
noEnvProbe = false;
probe.SetShaderData(data.EnvironmentProbe);
params.GPUContext->BindSR(envProbeShaderRegisterIndex, probe.Texture);
break;
}
}
if (probe && probe->GetProbe())
{
probe->SetupProbeData(params.RenderContext, &data.EnvironmentProbe);
params.GPUContext->BindSR(envProbeShaderRegisterIndex, probe->GetProbe());
}
else
if (noEnvProbe)
{
data.EnvironmentProbe.Data1 = Float4::Zero;
params.GPUContext->UnBindSR(envProbeShaderRegisterIndex);
@@ -99,23 +92,22 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<by
// Set local lights
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
for (int32 i = 0; i < cache->PointLights.Count() && data.LocalLightsCount < MaxLocalLights; 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++;
}
}
for (int32 i = 0; i < cache->SpotLights.Count() && data.LocalLightsCount < MaxLocalLights; 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++;
}
}

View File

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

View File

@@ -3,6 +3,7 @@
#include "ParticleMaterialShader.h"
#include "MaterialShaderFeatures.h"
#include "MaterialParams.h"
#include "Engine/Core/Math/Matrix3x4.h"
#include "Engine/Renderer/DrawCall.h"
#include "Engine/Renderer/RenderList.h"
#include "Engine/Graphics/RenderView.h"
@@ -15,7 +16,7 @@
#include "Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.h"
PACK_STRUCT(struct ParticleMaterialShaderData {
Matrix WorldMatrix;
Matrix3x4 WorldMatrix;
uint32 SortedIndicesOffset;
float PerInstanceRandom;
int32 ParticleStride;
@@ -34,7 +35,7 @@ PACK_STRUCT(struct ParticleMaterialShaderData {
int32 RibbonTwistOffset;
int32 RibbonFacingVectorOffset;
uint32 RibbonSegmentCount;
Matrix WorldMatrixInverseTransposed;
Matrix3x4 WorldMatrixInverseTransposed;
});
DrawPass ParticleMaterialShader::GetDrawModes() const
@@ -101,7 +102,7 @@ void ParticleMaterialShader::Bind(BindParameters& params)
static StringView ParticleScaleOffset(TEXT("Scale"));
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->PerInstanceRandom = drawCall.PerInstanceRandom;
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->ScaleOffset = drawCall.Particle.Particles->Layout->FindAttributeOffset(ParticleScaleOffset, ParticleAttribute::ValueTypes::Float3, -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

View File

@@ -3,6 +3,7 @@
#include "TerrainMaterialShader.h"
#include "MaterialShaderFeatures.h"
#include "MaterialParams.h"
#include "Engine/Core/Math/Matrix3x4.h"
#include "Engine/Graphics/GPUContext.h"
#include "Engine/Graphics/GPULimits.h"
#include "Engine/Graphics/GPUDevice.h"
@@ -16,7 +17,7 @@
#include "Engine/Terrain/TerrainPatch.h"
PACK_STRUCT(struct TerrainMaterialShaderData {
Matrix WorldMatrix;
Matrix3x4 WorldMatrix;
Float3 WorldInvScale;
float WorldDeterminantSign;
float PerInstanceRandom;
@@ -66,7 +67,7 @@ void TerrainMaterialShader::Bind(BindParameters& params)
// 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 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();

View File

@@ -3,6 +3,7 @@
#include "VolumeParticleMaterialShader.h"
#include "MaterialShaderFeatures.h"
#include "MaterialParams.h"
#include "Engine/Core/Math/Matrix3x4.h"
#include "Engine/Renderer/DrawCall.h"
#include "Engine/Renderer/VolumetricFogPass.h"
#include "Engine/Renderer/RenderList.h"
@@ -16,8 +17,8 @@
PACK_STRUCT(struct VolumeParticleMaterialShaderData {
Matrix InverseViewProjectionMatrix;
Matrix WorldMatrix;
Matrix WorldMatrixInverseTransposed;
Matrix3x4 WorldMatrix;
Matrix3x4 WorldMatrixInverseTransposed;
Float3 GridSize;
float PerInstanceRandom;
float Dummy0;
@@ -76,8 +77,10 @@ void VolumeParticleMaterialShader::Bind(BindParameters& params)
// Setup material constants
{
Matrix::Transpose(view.IVP, materialData->InverseViewProjectionMatrix);
Matrix::Transpose(drawCall.World, materialData->WorldMatrix);
Matrix::Invert(drawCall.World, materialData->WorldMatrixInverseTransposed);
materialData->WorldMatrix.SetMatrixTranspose(drawCall.World);
Matrix worldMatrixInverseTransposed;
Matrix::Invert(drawCall.World, worldMatrixInverseTransposed);
materialData->WorldMatrixInverseTransposed.SetMatrix(worldMatrixInverseTransposed);
materialData->GridSize = customData->GridSize;
materialData->PerInstanceRandom = drawCall.PerInstanceRandom;
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_10x10_UNorm:
case PixelFormat::ASTC_10x10_UNorm_sRGB:
{
const int32 blockSize = PixelFormatExtensions::ComputeBlockSize(format);
uint32 nbw = Math::Max<uint32>(1, Math::DivideAndRoundUp(width, blockSize));
uint32 nbh = Math::Max<uint32>(1, Math::DivideAndRoundUp(height, blockSize));
rowPitch = nbw * 16; // All ASTC blocks use 128 bits
slicePitch = rowPitch * nbh;
}
break;
{
const int32 blockSize = PixelFormatExtensions::ComputeBlockSize(format);
uint32 nbw = Math::Max<uint32>(1, Math::DivideAndRoundUp(width, blockSize));
uint32 nbh = Math::Max<uint32>(1, Math::DivideAndRoundUp(height, blockSize));
rowPitch = nbw * 16; // All ASTC blocks use 128 bits
slicePitch = rowPitch * nbh;
}
break;
case PixelFormat::R8G8_B8G8_UNorm:
case PixelFormat::G8R8_G8B8_UNorm:
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)
{
// Calculate tangent
@@ -579,6 +587,23 @@ void RenderTools::CalculateTangentFrame(FloatR10G10B10A2& resultNormal, FloatR10
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)
{
if (!useMipLevels)
@@ -636,22 +661,6 @@ int32 MipLevelsCount(int32 width, int32 height, int32 depth, bool useMipLevels)
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)
{
if (value < 0 || value >= _model->MaterialSlots.Count())

View File

@@ -121,8 +121,14 @@ public:
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, 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
@@ -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)
// @returns Mip levels count
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>
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>
/// The view flags.
/// </summary>

View File

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

View File

@@ -5,8 +5,8 @@
#include "Engine/Content/BinaryAsset.h"
#include "StreamingTexture.h"
class TextureData;
class TextureMipData;
struct TextureData;
struct TextureMipData;
/// <summary>
/// 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>
/// Single texture mip map entry data.
/// </summary>
class FLAXENGINE_API TextureMipData
API_STRUCT() struct FLAXENGINE_API TextureMipData
{
DECLARE_SCRIPTING_TYPE_MINIMAL(TextureMipData);
public:
uint32 RowPitch;
uint32 DepthPitch;
uint32 Lines;
BytesContainer Data;
// The row pitch.
API_FIELD() uint32 RowPitch;
// The depth pitch.
API_FIELD() uint32 DepthPitch;
// The number of lines.
API_FIELD() uint32 Lines;
// The data.
API_FIELD(ReadOnly) BytesContainer Data;
TextureMipData();
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>
/// Texture data container (used to keep data downloaded from the GPU).
/// </summary>
class FLAXENGINE_API TextureData
API_STRUCT() struct FLAXENGINE_API TextureData
{
DECLARE_SCRIPTING_TYPE_MINIMAL(TextureData);
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:
/// <summary>
@@ -76,27 +101,27 @@ public:
/// <summary>
/// Top level texture width (in pixels).
/// </summary>
int32 Width = 0;
API_FIELD() int32 Width = 0;
/// <summary>
/// Top level texture height (in pixels).
/// </summary>
int32 Height = 0;
API_FIELD() int32 Height = 0;
/// <summary>
/// Top level texture depth (in pixels).
/// </summary>
int32 Depth = 0;
API_FIELD() int32 Depth = 0;
/// <summary>
/// The texture data format.
/// </summary>
PixelFormat Format = PixelFormat::Unknown;
API_FIELD() PixelFormat Format = PixelFormat::Unknown;
/// <summary>
/// The items collection (depth slices or array slices).
/// </summary>
Array<ArrayEntry, InlinedAllocation<6>> Items;
API_FIELD() Array<TextureDataArrayEntry, InlinedAllocation<6>> Items;
public:
/// <summary>
@@ -145,3 +170,9 @@ public:
Items.Resize(0, false);
}
};
template<>
struct TIsPODType<TextureData>
{
enum { Value = false };
};

View File

@@ -120,7 +120,7 @@ void GPUContextDX11::FrameBegin()
_device->_samplerLinearWrap,
_device->_samplerPointWrap,
_device->_samplerShadow,
_device->_samplerShadowPCF
_device->_samplerShadowLinear
};
_context->VSSetSamplers(0, ARRAY_COUNT(samplers), samplers);
#if GPU_ALLOW_TESSELLATION_SHADERS
@@ -159,21 +159,19 @@ bool GPUContextDX11::IsDepthBufferBinded()
void GPUContextDX11::Clear(GPUTextureView* rt, const Color& color)
{
auto rtDX11 = static_cast<GPUTextureViewDX11*>(rt);
if (rtDX11)
{
_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);
if (depthBufferDX11)
{
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;
bool IsDepthBufferBinded() 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 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)
: GPUDeviceDX(getRendererType(adapter), getShaderProfile(adapter), adapter)
, _device(nullptr)
, _imContext(nullptr)
, _factoryDXGI(dxgiFactory)
, _mainContext(nullptr)
, _samplerLinearClamp(nullptr)
, _samplerPointClamp(nullptr)
, _samplerLinearWrap(nullptr)
, _samplerPointWrap(nullptr)
, _samplerShadow(nullptr)
, _samplerShadowPCF(nullptr)
{
Platform::MemoryClear(RasterizerStates, sizeof(RasterizerStates));
Platform::MemoryClear(DepthStencilStates, sizeof(DepthStencilStates));
@@ -450,14 +441,17 @@ bool GPUDeviceDX11::Init()
{
D3D11_SAMPLER_DESC 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
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
result = _device->CreateSamplerState(&samplerDesc, &_samplerLinearClamp);
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
@@ -466,8 +460,6 @@ bool GPUDeviceDX11::Init()
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
result = _device->CreateSamplerState(&samplerDesc, &_samplerPointClamp);
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
@@ -476,8 +468,6 @@ bool GPUDeviceDX11::Init()
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
result = _device->CreateSamplerState(&samplerDesc, &_samplerLinearWrap);
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
@@ -486,8 +476,6 @@ bool GPUDeviceDX11::Init()
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
result = _device->CreateSamplerState(&samplerDesc, &_samplerPointWrap);
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
@@ -496,26 +484,15 @@ bool GPUDeviceDX11::Init()
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressV = 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);
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
// Shadow PCF
// Shadow Linear
samplerDesc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR;
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.MipLODBias = 0.0f;
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);
result = _device->CreateSamplerState(&samplerDesc, &_samplerShadowLinear);
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
}
@@ -616,7 +593,7 @@ void GPUDeviceDX11::Dispose()
SAFE_RELEASE(_samplerLinearWrap);
SAFE_RELEASE(_samplerPointWrap);
SAFE_RELEASE(_samplerShadow);
SAFE_RELEASE(_samplerShadowPCF);
SAFE_RELEASE(_samplerShadowLinear);
//
for (auto i = BlendStates.Begin(); i.IsNotEnd(); ++i)
{

View File

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

View File

@@ -703,7 +703,6 @@ bool GPUContextDX12::IsDepthBufferBinded()
void GPUContextDX12::Clear(GPUTextureView* rt, const Color& color)
{
auto rtDX12 = static_cast<GPUTextureViewDX12*>(rt);
if (rtDX12)
{
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);
if (depthBufferDX12)
{
SetResourceState(depthBufferDX12->GetResourceOwner(), D3D12_RESOURCE_STATE_DEPTH_WRITE, depthBufferDX12->SubresourceIndex);
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;
bool IsDepthBufferBinded() 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 uint32 value[4]) override;
void ClearUA(GPUTexture* texture, const uint32 value[4]) override;

View File

@@ -568,7 +568,6 @@ bool GPUDeviceDX12::Init()
// Static samplers
D3D12_STATIC_SAMPLER_DESC staticSamplers[6];
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
staticSamplers[0].Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
staticSamplers[0].AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
@@ -650,8 +649,6 @@ bool GPUDeviceDX12::Init()
staticSamplers[5].RegisterSpace = 0;
staticSamplers[5].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
// TODO: static samplers for the shadow pass change into bindable samplers or sth?
// Init
D3D12_ROOT_SIGNATURE_DESC rootSignatureDesc;
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);
if (rtVulkan)
{
// TODO: detect if inside render pass and use ClearAttachments
@@ -815,7 +814,7 @@ void GPUContextVulkan::ClearDepth(GPUTextureView* depthBuffer, float depthValue)
VkClearDepthStencilValue clear;
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);
}
}

View File

@@ -151,7 +151,7 @@ public:
void* GetNativePtr() const override;
bool IsDepthBufferBinded() 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 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