Refactor engine to support double-precision vectors
This commit is contained in:
@@ -341,11 +341,11 @@ void AmbientOcclusionPass::UpdateCB(const RenderContext& renderContext, GPUConte
|
||||
GBufferPass::SetInputs(view, _constantsBufferData.GBuffer);
|
||||
Matrix::Transpose(view.View, _constantsBufferData.ViewMatrix);
|
||||
|
||||
_constantsBufferData.ViewportPixelSize = Vector2(1.0f / m_sizeX, 1.0f / m_sizeY);
|
||||
_constantsBufferData.HalfViewportPixelSize = Vector2(1.0f / m_halfSizeX, 1.0f / m_halfSizeY);
|
||||
_constantsBufferData.ViewportPixelSize = Float2(1.0f / m_sizeX, 1.0f / m_sizeY);
|
||||
_constantsBufferData.HalfViewportPixelSize = Float2(1.0f / m_halfSizeX, 1.0f / m_halfSizeY);
|
||||
|
||||
_constantsBufferData.Viewport2xPixelSize = Vector2(_constantsBufferData.ViewportPixelSize.X * 2.0f, _constantsBufferData.ViewportPixelSize.Y * 2.0f);
|
||||
_constantsBufferData.Viewport2xPixelSize_x_025 = Vector2(_constantsBufferData.Viewport2xPixelSize.X * 0.25f, _constantsBufferData.Viewport2xPixelSize.Y * 0.25f);
|
||||
_constantsBufferData.Viewport2xPixelSize = Float2(_constantsBufferData.ViewportPixelSize.X * 2.0f, _constantsBufferData.ViewportPixelSize.Y * 2.0f);
|
||||
_constantsBufferData.Viewport2xPixelSize_x_025 = Float2(_constantsBufferData.Viewport2xPixelSize.X * 0.25f, _constantsBufferData.Viewport2xPixelSize.Y * 0.25f);
|
||||
|
||||
const float tanHalfFOVY = 1.0f / proj.Values[1][1];
|
||||
|
||||
@@ -403,7 +403,7 @@ void AmbientOcclusionPass::UpdateCB(const RenderContext& renderContext, GPUConte
|
||||
const float sa = Math::Sin(angle0);
|
||||
|
||||
const float scale = 1.0f + (a - 1.5f + (b - (subPassCount - 1.0f) * 0.5f) / static_cast<float>(subPassCount)) * 0.07f;
|
||||
_constantsBufferData.PatternRotScaleMatrices[subPass] = Vector4(scale * ca, scale * -sa, -scale * sa, -scale * ca);
|
||||
_constantsBufferData.PatternRotScaleMatrices[subPass] = Float4(scale * ca, scale * -sa, -scale * sa, -scale * ca);
|
||||
}
|
||||
|
||||
// Update buffer
|
||||
|
||||
@@ -22,16 +22,16 @@ private:
|
||||
PACK_STRUCT(struct ASSAOConstants {
|
||||
GBufferData GBuffer;
|
||||
|
||||
Vector2 ViewportPixelSize;
|
||||
Vector2 HalfViewportPixelSize;
|
||||
Float2 ViewportPixelSize;
|
||||
Float2 HalfViewportPixelSize;
|
||||
|
||||
int32 PerPassFullResCoordOffsetX;
|
||||
int32 PerPassFullResCoordOffsetY;
|
||||
int32 PassIndex;
|
||||
float EffectMaxDistance;
|
||||
|
||||
Vector2 Viewport2xPixelSize;
|
||||
Vector2 Viewport2xPixelSize_x_025;
|
||||
Float2 Viewport2xPixelSize;
|
||||
Float2 Viewport2xPixelSize_x_025;
|
||||
|
||||
float EffectRadius;
|
||||
float EffectShadowStrength;
|
||||
@@ -48,7 +48,7 @@ private:
|
||||
float InvSharpness;
|
||||
float DetailAOStrength;
|
||||
|
||||
Vector4 PatternRotScaleMatrices[5];
|
||||
Float4 PatternRotScaleMatrices[5];
|
||||
|
||||
Matrix ViewMatrix;
|
||||
});
|
||||
|
||||
@@ -14,7 +14,7 @@ private:
|
||||
|
||||
PACK_STRUCT(struct Data
|
||||
{
|
||||
Vector4 ScreenSize;
|
||||
Float4 ScreenSize;
|
||||
});
|
||||
|
||||
AssetReference<Shader> _shader;
|
||||
|
||||
@@ -17,7 +17,7 @@ private:
|
||||
|
||||
PACK_STRUCT(struct Data
|
||||
{
|
||||
Vector4 RtSize;
|
||||
Float4 RtSize;
|
||||
});
|
||||
|
||||
AssetReference<Shader> _shader;
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include "TAA.h"
|
||||
#include "Engine/Content/Assets/Shader.h"
|
||||
#include "Engine/Content/Content.h"
|
||||
#include "Engine/Core/Config/GraphicsSettings.h"
|
||||
#include "Engine/Graphics/GPUContext.h"
|
||||
#include "Engine/Graphics/RenderTargetPool.h"
|
||||
#include "Engine/Graphics/RenderBuffers.h"
|
||||
@@ -13,8 +12,8 @@
|
||||
|
||||
PACK_STRUCT(struct Data
|
||||
{
|
||||
Vector2 ScreenSizeInv;
|
||||
Vector2 JitterInv;
|
||||
Float2 ScreenSizeInv;
|
||||
Float2 JitterInv;
|
||||
float Sharpness;
|
||||
float StationaryBlending;
|
||||
float MotionBlending;
|
||||
|
||||
@@ -67,7 +67,7 @@ PACK_STRUCT(struct Data
|
||||
float AtmosphereR;
|
||||
int AtmosphereLayer;
|
||||
float Dummy0;
|
||||
Vector4 dhdh;
|
||||
Float4 dhdh;
|
||||
});
|
||||
|
||||
namespace AtmospherePreComputeImpl
|
||||
@@ -367,7 +367,7 @@ void AtmospherePreComputeService::Dispose()
|
||||
release();
|
||||
}
|
||||
|
||||
void GetLayerValue(int32 layer, float& atmosphereR, Vector4& dhdh)
|
||||
void GetLayerValue(int32 layer, float& atmosphereR, Float4& dhdh)
|
||||
{
|
||||
float r = layer / Math::Max<float>(InscatterAltitudeSampleNum - 1.0f, 1.0f);
|
||||
r = r * r;
|
||||
@@ -377,7 +377,7 @@ void GetLayerValue(int32 layer, float& atmosphereR, Vector4& dhdh)
|
||||
const float dMinP = r - RadiusGround;
|
||||
const float dMaxP = Math::Sqrt(r * r - RadiusGround * RadiusGround);
|
||||
atmosphereR = r;
|
||||
dhdh = Vector4(dMin, dMax, dMinP, dMaxP);
|
||||
dhdh = Float4(dMin, dMax, dMinP, dMaxP);
|
||||
}
|
||||
|
||||
void AtmospherePreComputeImpl::onRender(RenderTask* task, GPUContext* context)
|
||||
@@ -597,7 +597,7 @@ bool DownloadJob::Run()
|
||||
{
|
||||
for (int x = 0; x < TransmittanceTexWidth; x++)
|
||||
{
|
||||
Vector4 t = ((Half4*)&in->Data[y * in->RowPitch + x * sizeof(Half4)])->ToVector4();
|
||||
Float4 t = ((Half4*)&in->Data[y * in->RowPitch + x * sizeof(Half4)])->ToFloat4();
|
||||
*p++ = Math::Saturate(t.Z) * 255;
|
||||
*p++ = Math::Saturate(t.Y) * 255;
|
||||
*p++ = Math::Saturate(t.X) * 255;
|
||||
@@ -630,7 +630,7 @@ bool DownloadJob::Run()
|
||||
{
|
||||
for (int x = 0; x < IrradianceTexWidth; x++)
|
||||
{
|
||||
Vector4 t = ((Half4*)&in->Data[y * in->RowPitch + x * sizeof(Half4)])->ToVector4();
|
||||
Float4 t = ((Half4*)&in->Data[y * in->RowPitch + x * sizeof(Half4)])->ToFloat4();
|
||||
*p++ = Math::Saturate(t.Z) * 255;
|
||||
*p++ = Math::Saturate(t.Y) * 255;
|
||||
*p++ = Math::Saturate(t.X) * 255;
|
||||
@@ -667,7 +667,7 @@ bool DownloadJob::Run()
|
||||
{
|
||||
for (int x = 0; x < InscatterWidth; x++)
|
||||
{
|
||||
Vector4 t = ((Half4*)&s[y * in->RowPitch + x * sizeof(Half4)])->ToVector4();
|
||||
Float4 t = ((Half4*)&s[y * in->RowPitch + x * sizeof(Half4)])->ToFloat4();
|
||||
*p++ = Math::Saturate(t.Z) * 255;
|
||||
*p++ = Math::Saturate(t.Y) * 255;
|
||||
*p++ = Math::Saturate(t.X) * 255;
|
||||
|
||||
@@ -9,30 +9,30 @@
|
||||
#include "Engine/Graphics/RenderTask.h"
|
||||
|
||||
PACK_STRUCT(struct Data {
|
||||
Vector4 ColorSaturationShadows;
|
||||
Vector4 ColorContrastShadows;
|
||||
Vector4 ColorGammaShadows;
|
||||
Vector4 ColorGainShadows;
|
||||
Vector4 ColorOffsetShadows;
|
||||
Float4 ColorSaturationShadows;
|
||||
Float4 ColorContrastShadows;
|
||||
Float4 ColorGammaShadows;
|
||||
Float4 ColorGainShadows;
|
||||
Float4 ColorOffsetShadows;
|
||||
|
||||
Vector4 ColorSaturationMidtones;
|
||||
Vector4 ColorContrastMidtones;
|
||||
Vector4 ColorGammaMidtones;
|
||||
Vector4 ColorGainMidtones;
|
||||
Vector4 ColorOffsetMidtones;
|
||||
Float4 ColorSaturationMidtones;
|
||||
Float4 ColorContrastMidtones;
|
||||
Float4 ColorGammaMidtones;
|
||||
Float4 ColorGainMidtones;
|
||||
Float4 ColorOffsetMidtones;
|
||||
|
||||
Vector4 ColorSaturationHighlights;
|
||||
Vector4 ColorContrastHighlights;
|
||||
Vector4 ColorGammaHighlights;
|
||||
Vector4 ColorGainHighlights;
|
||||
Vector4 ColorOffsetHighlights;
|
||||
Float4 ColorSaturationHighlights;
|
||||
Float4 ColorContrastHighlights;
|
||||
Float4 ColorGammaHighlights;
|
||||
Float4 ColorGainHighlights;
|
||||
Float4 ColorOffsetHighlights;
|
||||
|
||||
float ColorCorrectionShadowsMax;
|
||||
float ColorCorrectionHighlightsMin;
|
||||
float WhiteTemp;
|
||||
float WhiteTint;
|
||||
|
||||
Vector3 Dummy;
|
||||
Float3 Dummy;
|
||||
float LutWeight;
|
||||
});
|
||||
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
/// </summary>
|
||||
struct GBufferData
|
||||
{
|
||||
Vector4 ViewInfo;
|
||||
Vector4 ScreenSize;
|
||||
Vector3 ViewPos;
|
||||
Float4 ViewInfo;
|
||||
Float4 ScreenSize;
|
||||
Float3 ViewPos;
|
||||
float ViewFar;
|
||||
Matrix InvViewMatrix;
|
||||
Matrix InvProjectionMatrix;
|
||||
@@ -25,7 +25,7 @@ struct GBufferData
|
||||
/// </summary>
|
||||
struct ExponentialHeightFogData
|
||||
{
|
||||
Vector3 FogInscatteringColor;
|
||||
Float3 FogInscatteringColor;
|
||||
float FogMinOpacity;
|
||||
|
||||
float FogDensity;
|
||||
@@ -33,10 +33,10 @@ struct ExponentialHeightFogData
|
||||
float FogHeightFalloff;
|
||||
float FogAtViewPosition;
|
||||
|
||||
Vector3 InscatteringLightDirection;
|
||||
Float3 InscatteringLightDirection;
|
||||
float ApplyDirectionalInscattering;
|
||||
|
||||
Vector3 DirectionalInscatteringColor;
|
||||
Float3 DirectionalInscatteringColor;
|
||||
float DirectionalInscatteringExponent;
|
||||
|
||||
float FogCutoffDistance;
|
||||
@@ -60,10 +60,10 @@ struct AtmosphericFogData
|
||||
float AtmosphericFogPower;
|
||||
float AtmosphericFogDistanceOffset;
|
||||
|
||||
Vector3 AtmosphericFogSunDirection;
|
||||
Float3 AtmosphericFogSunDirection;
|
||||
float AtmosphericFogSunPower;
|
||||
|
||||
Vector3 AtmosphericFogSunColor;
|
||||
Float3 AtmosphericFogSunColor;
|
||||
float AtmosphericFogDensityOffset;
|
||||
};
|
||||
|
||||
@@ -71,14 +71,14 @@ struct AtmosphericFogData
|
||||
/// Structure that contains information about light for shaders.
|
||||
/// </summary>
|
||||
PACK_STRUCT(struct LightData {
|
||||
Vector2 SpotAngles;
|
||||
Float2 SpotAngles;
|
||||
float SourceRadius;
|
||||
float SourceLength;
|
||||
Vector3 Color;
|
||||
Float3 Color;
|
||||
float MinRoughness;
|
||||
Vector3 Position;
|
||||
Float3 Position;
|
||||
float CastShadows;
|
||||
Vector3 Direction;
|
||||
Float3 Direction;
|
||||
float Radius;
|
||||
float FalloffExponent;
|
||||
float InverseSquared;
|
||||
@@ -90,14 +90,14 @@ PACK_STRUCT(struct LightData {
|
||||
/// Structure that contains information about light for shaders.
|
||||
/// </summary>
|
||||
PACK_STRUCT(struct LightShadowData {
|
||||
Vector2 ShadowMapSize;
|
||||
Float2 ShadowMapSize;
|
||||
float Sharpness;
|
||||
float Fade;
|
||||
float NormalOffsetScale;
|
||||
float Bias;
|
||||
float FadeDistance;
|
||||
uint32 NumCascades;
|
||||
Vector4 CascadeSplits;
|
||||
Float4 CascadeSplits;
|
||||
Matrix ShadowVP[6];
|
||||
});
|
||||
|
||||
@@ -105,8 +105,8 @@ PACK_STRUCT(struct LightShadowData {
|
||||
/// Packed env probe data
|
||||
/// </summary>
|
||||
PACK_STRUCT(struct ProbeData {
|
||||
Vector4 Data0; // x - Position.x, y - Position.y, z - Position.z, w - unused
|
||||
Vector4 Data1; // x - Radius , y - 1 / Radius, z - Brightness, w - unused
|
||||
Float4 Data0; // x - Position.x, y - Position.y, z - Position.z, w - unused
|
||||
Float4 Data1; // x - Radius , y - 1 / Radius, z - Brightness, w - unused
|
||||
});
|
||||
|
||||
// Minimum roughness value used for shading (prevent 0 roughness which causes NaNs in Vis_SmithJointApprox)
|
||||
|
||||
@@ -16,34 +16,34 @@ class DepthOfFieldPass : public RendererPass<DepthOfFieldPass>
|
||||
private:
|
||||
|
||||
PACK_STRUCT(struct Data {
|
||||
Vector2 ProjectionAB;
|
||||
Float2 ProjectionAB;
|
||||
float BokehDepthCullThreshold;
|
||||
float BokehDepthCutoff;
|
||||
|
||||
Vector4 DOFDepths;
|
||||
Float4 DOFDepths;
|
||||
|
||||
float MaxBokehSize;
|
||||
float BokehBrightnessThreshold;
|
||||
float BokehBlurThreshold;
|
||||
float BokehFalloff;
|
||||
|
||||
Vector2 BokehTargetSize;
|
||||
Vector2 DOFTargetSize;
|
||||
Float2 BokehTargetSize;
|
||||
Float2 DOFTargetSize;
|
||||
|
||||
Vector2 InputSize;
|
||||
Float2 InputSize;
|
||||
float DepthLimit;
|
||||
float BlurStrength;
|
||||
|
||||
Vector3 Dummy;
|
||||
Float3 Dummy;
|
||||
float BokehBrightness;
|
||||
});
|
||||
|
||||
// Structure used for outputting bokeh points to an AppendStructuredBuffer
|
||||
struct BokehPoint
|
||||
{
|
||||
Vector3 Position;
|
||||
Float3 Position;
|
||||
float Blur;
|
||||
Vector3 Color;
|
||||
Float3 Color;
|
||||
};
|
||||
|
||||
bool _platformSupportsDoF = false;
|
||||
|
||||
@@ -55,7 +55,7 @@ struct VolumetricFogOptions
|
||||
Color Emissive;
|
||||
float ExtinctionScale;
|
||||
float Distance;
|
||||
Vector4 FogParameters;
|
||||
Float4 FogParameters;
|
||||
|
||||
bool UseVolumetricFog() const
|
||||
{
|
||||
@@ -184,7 +184,7 @@ struct DrawCall
|
||||
const Lightmap* Lightmap;
|
||||
Rectangle LightmapUVsArea;
|
||||
SkinnedMeshDrawData* Skinning;
|
||||
Vector3 GeometrySize; // Object geometry size in the world (unscaled).
|
||||
Float3 GeometrySize; // Object geometry size in the world (unscaled).
|
||||
float LODDitherFactor; // The model LOD transition dither progress.
|
||||
Matrix PrevWorld;
|
||||
} Surface;
|
||||
@@ -193,9 +193,9 @@ struct DrawCall
|
||||
{
|
||||
const Lightmap* Lightmap;
|
||||
Rectangle LightmapUVsArea;
|
||||
Vector4 HeightmapUVScaleBias;
|
||||
Vector4 NeighborLOD;
|
||||
Vector2 OffsetUV;
|
||||
Float4 HeightmapUVScaleBias;
|
||||
Float4 NeighborLOD;
|
||||
Float2 OffsetUV;
|
||||
float CurrentLOD;
|
||||
float ChunkSizeNextLOD;
|
||||
float TerrainChunkSizeLOD0;
|
||||
@@ -221,7 +221,7 @@ struct DrawCall
|
||||
|
||||
struct
|
||||
{
|
||||
Vector3 Position;
|
||||
Float3 Position;
|
||||
float Radius;
|
||||
int32 ParticleIndex;
|
||||
} VolumetricFog;
|
||||
@@ -231,7 +231,7 @@ struct DrawCall
|
||||
{
|
||||
GPUBuffer* SplineDeformation;
|
||||
Matrix LocalMatrix; // Geometry transformation applied before deformation.
|
||||
Vector3 GeometrySize; // Object geometry size in the world (unscaled).
|
||||
Float3 GeometrySize; // Object geometry size in the world (unscaled).
|
||||
float Segment;
|
||||
float ChunksPerSegment;
|
||||
float MeshMinZ;
|
||||
@@ -252,7 +252,7 @@ struct DrawCall
|
||||
/// <summary>
|
||||
/// Object location in the world used for draw calls sorting.
|
||||
/// </summary>
|
||||
Vector3 ObjectPosition;
|
||||
Float3 ObjectPosition;
|
||||
|
||||
/// <summary>
|
||||
/// The world matrix determinant sign (used for geometry that is two sided or has inverse scale - needs to flip normal vectors and change triangles culling).
|
||||
|
||||
@@ -21,9 +21,9 @@ PACK_STRUCT(struct LightmapUVsDensityMaterialShaderData {
|
||||
Matrix ViewProjectionMatrix;
|
||||
Matrix WorldMatrix;
|
||||
Rectangle LightmapArea;
|
||||
Vector3 WorldInvScale;
|
||||
Float3 WorldInvScale;
|
||||
float LightmapTexelsPerWorldUnit;
|
||||
Vector3 Dummy0;
|
||||
Float3 Dummy0;
|
||||
float LightmapSize;
|
||||
});
|
||||
|
||||
@@ -176,10 +176,10 @@ void LightmapUVsDensityMaterialShader::Bind(BindParameters& params)
|
||||
LightmapUVsDensityMaterialShaderData data;
|
||||
Matrix::Transpose(params.RenderContext.View.Frustum.GetMatrix(), data.ViewProjectionMatrix);
|
||||
Matrix::Transpose(drawCall.World, data.WorldMatrix);
|
||||
const float scaleX = Vector3(drawCall.World.M11, drawCall.World.M12, drawCall.World.M13).Length();
|
||||
const float scaleY = Vector3(drawCall.World.M21, drawCall.World.M22, drawCall.World.M23).Length();
|
||||
const float scaleZ = Vector3(drawCall.World.M31, drawCall.World.M32, drawCall.World.M33).Length();
|
||||
data.WorldInvScale = Vector3(
|
||||
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();
|
||||
data.WorldInvScale = Float3(
|
||||
scaleX > 0.00001f ? 1.0f / scaleX : 0.0f,
|
||||
scaleY > 0.00001f ? 1.0f / scaleY : 0.0f,
|
||||
scaleZ > 0.00001f ? 1.0f / scaleZ : 0.0f);
|
||||
@@ -203,14 +203,14 @@ void LightmapUVsDensityMaterialShader::Bind(BindParameters& params)
|
||||
}
|
||||
}
|
||||
BoundingBox box = drawCallModelLod->GetBox(drawCall.World);
|
||||
Vector3 size = box.GetSize();
|
||||
Float3 size = box.GetSize();
|
||||
float dimensionsCoeff = size.AverageArithmetic();
|
||||
if (size.X <= 1.0f)
|
||||
dimensionsCoeff = Vector2(size.Y, size.Z).AverageArithmetic();
|
||||
dimensionsCoeff = Float2(size.Y, size.Z).AverageArithmetic();
|
||||
else if (size.Y <= 1.0f)
|
||||
dimensionsCoeff = Vector2(size.X, size.Z).AverageArithmetic();
|
||||
dimensionsCoeff = Float2(size.X, size.Z).AverageArithmetic();
|
||||
else if (size.Z <= 1.0f)
|
||||
dimensionsCoeff = Vector2(size.Y, size.X).AverageArithmetic();
|
||||
dimensionsCoeff = Float2(size.Y, size.X).AverageArithmetic();
|
||||
float scale = globalObjectsScale * scaleInLightmap * ShadowsOfMordor::LightmapTexelsPerWorldUnit * dimensionsCoeff;
|
||||
if (scale <= ZeroTolerance)
|
||||
scale = 0.0f;
|
||||
|
||||
@@ -75,8 +75,8 @@ void QuadOverdrawPass::Render(RenderContext& renderContext, GPUContext* context,
|
||||
// Draw sky
|
||||
auto box = skyModel->GetBox();
|
||||
Matrix m1, m2;
|
||||
Matrix::Scaling(renderContext.View.Far / (box.GetSize().Y * 0.5f) * 0.95f, m1);
|
||||
Matrix::CreateWorld(renderContext.View.Position, Vector3::Up, Vector3::Backward, m2);
|
||||
Matrix::Scaling(renderContext.View.Far / ((float)box.GetSize().Y * 0.5f) * 0.95f, m1);
|
||||
Matrix::CreateWorld(renderContext.View.Position, Float3::Up, Float3::Backward, m2);
|
||||
m1 *= m2;
|
||||
drawCall.World = m1;
|
||||
drawCall.ObjectPosition = drawCall.World.GetTranslation();
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "EyeAdaptationPass.h"
|
||||
#include "HistogramPass.h"
|
||||
#include "RenderList.h"
|
||||
#include "Engine/Core/Math/Int2.h"
|
||||
#include "Engine/Core/Math/Vector2.h"
|
||||
#include "Engine/Content/Assets/Shader.h"
|
||||
#include "Engine/Content/Content.h"
|
||||
#include "Engine/Graphics/GPUDevice.h"
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
PACK_STRUCT(struct GBufferPassData{
|
||||
GBufferData GBuffer;
|
||||
Vector3 Dummy0;
|
||||
Float3 Dummy0;
|
||||
int32 ViewMode;
|
||||
});
|
||||
|
||||
@@ -229,8 +229,8 @@ void GBufferPass::Fill(RenderContext& renderContext, GPUTextureView* lightBuffer
|
||||
|
||||
// Calculate sphere model transform to cover far plane
|
||||
Matrix m1, m2;
|
||||
Matrix::Scaling(view.Far / (box.GetSize().Y * 0.5f) * 0.95f, m1); // Scale to fit whole view frustum
|
||||
Matrix::CreateWorld(view.Position, Vector3::Up, Vector3::Backward, m2); // Rotate sphere model
|
||||
Matrix::Scaling(view.Far / ((float)box.GetSize().Y * 0.5f) * 0.95f, m1); // Scale to fit whole view frustum
|
||||
Matrix::CreateWorld(view.Position, Float3::Up, Float3::Backward, m2); // Rotate sphere model
|
||||
m1 *= m2;
|
||||
|
||||
// Draw sky
|
||||
|
||||
@@ -34,13 +34,13 @@
|
||||
|
||||
PACK_STRUCT(struct Data0
|
||||
{
|
||||
Vector3 ViewWorldPos;
|
||||
Float3 ViewWorldPos;
|
||||
float ViewNearPlane;
|
||||
float Padding00;
|
||||
uint32 CulledObjectsCapacity;
|
||||
float LightShadowsStrength;
|
||||
float ViewFarPlane;
|
||||
Vector4 ViewFrustumWorldRays[4];
|
||||
Float4 ViewFrustumWorldRays[4];
|
||||
GlobalSignDistanceFieldPass::ConstantsData GlobalSDF;
|
||||
GlobalSurfaceAtlasPass::ConstantsData GlobalSurfaceAtlas;
|
||||
LightData Light;
|
||||
@@ -55,9 +55,9 @@ PACK_STRUCT(struct AtlasTileVertex
|
||||
|
||||
struct GlobalSurfaceAtlasTile : RectPack<GlobalSurfaceAtlasTile, uint16>
|
||||
{
|
||||
Vector3 ViewDirection;
|
||||
Vector3 ViewPosition;
|
||||
Vector3 ViewBoundsSize;
|
||||
Float3 ViewDirection;
|
||||
Float3 ViewPosition;
|
||||
Float3 ViewBoundsSize;
|
||||
Matrix ViewMatrix;
|
||||
uint32 Address;
|
||||
uint32 ObjectAddressOffset;
|
||||
@@ -133,7 +133,7 @@ public:
|
||||
// Cached data to be reused during RasterizeActor
|
||||
uint64 CurrentFrame;
|
||||
float ResolutionInv;
|
||||
Vector3 ViewPosition;
|
||||
Float3 ViewPosition;
|
||||
float TileTexelsPerWorldUnit;
|
||||
float DistanceScalingStart;
|
||||
float DistanceScalingEnd;
|
||||
@@ -354,10 +354,10 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
|
||||
_objectsBuffer = New<DynamicTypedBuffer>(256 * (GLOBAL_SURFACE_ATLAS_OBJECT_DATA_STRIDE + GLOBAL_SURFACE_ATLAS_TILE_DATA_STRIDE * 3 / 4), PixelFormat::R32G32B32A32_Float, false, TEXT("GlobalSurfaceAtlas.ObjectsBuffer"));
|
||||
|
||||
// Utility for writing into tiles vertex buffer
|
||||
const Vector2 posToClipMul(2.0f * resolutionInv, -2.0f * resolutionInv);
|
||||
const Vector2 posToClipAdd(-1.0f, 1.0f);
|
||||
const Float2 posToClipMul(2.0f * resolutionInv, -2.0f * resolutionInv);
|
||||
const Float2 posToClipAdd(-1.0f, 1.0f);
|
||||
#define VB_WRITE_TILE_POS_ONLY(tile) \
|
||||
Vector2 minPos((float)tile->X, (float)tile->Y), maxPos((float)(tile->X + tile->Width), (float)(tile->Y + tile->Height)); \
|
||||
Float2 minPos((float)tile->X, (float)tile->Y), maxPos((float)(tile->X + tile->Width), (float)(tile->Y + tile->Height)); \
|
||||
Half2 min(minPos * posToClipMul + posToClipAdd), max(maxPos * posToClipMul + posToClipAdd); \
|
||||
auto* quad = _vertexBuffer->WriteReserve<AtlasTileVertex>(6); \
|
||||
quad[0].Position = max; \
|
||||
@@ -367,9 +367,9 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
|
||||
quad[4].Position = { max.X, min.Y }; \
|
||||
quad[5].Position = quad[0].Position
|
||||
#define VB_WRITE_TILE(tile) \
|
||||
Vector2 minPos((float)tile->X, (float)tile->Y), maxPos((float)(tile->X + tile->Width), (float)(tile->Y + tile->Height)); \
|
||||
Float2 minPos((float)tile->X, (float)tile->Y), maxPos((float)(tile->X + tile->Width), (float)(tile->Y + tile->Height)); \
|
||||
Half2 min(minPos * posToClipMul + posToClipAdd), max(maxPos * posToClipMul + posToClipAdd); \
|
||||
Vector2 minUV(0, 0), maxUV(1, 1); \
|
||||
Float2 minUV(0, 0), maxUV(1, 1); \
|
||||
auto* quad = _vertexBuffer->WriteReserve<AtlasTileVertex>(6); \
|
||||
quad[0] = { { max }, { maxUV }, tile->Address }; \
|
||||
quad[1] = { { min.X, max.Y }, { minUV.X, maxUV.Y }, tile->Address }; \
|
||||
@@ -399,7 +399,7 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
|
||||
surfaceAtlasData.DistanceScaling = 0.1f; // The scale for tiles at distanceScalingEnd and further away
|
||||
// TODO: add DetailsScale param to adjust quality of scene details in Global Surface Atlas
|
||||
const uint32 viewMask = renderContext.View.RenderLayersMask;
|
||||
const Vector3 viewPosition = renderContext.View.Position;
|
||||
const Float3 viewPosition = renderContext.View.Position;
|
||||
const float minObjectRadius = 20.0f; // Skip too small objects
|
||||
for (auto* scene : renderContext.List->Scenes)
|
||||
{
|
||||
@@ -585,7 +585,7 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
|
||||
uint32 counter = data[surfaceAtlasData.CulledObjectsCounterIndex];
|
||||
_culledObjectsSizeBuffer->Unmap();
|
||||
if (counter > 0)
|
||||
objectsBufferCapacity = counter * sizeof(Vector4);
|
||||
objectsBufferCapacity = counter * sizeof(Float4);
|
||||
}
|
||||
}
|
||||
if (surfaceAtlasData.CulledObjectsCounterIndex == -1)
|
||||
@@ -614,7 +614,7 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
|
||||
surfaceAtlasData.CulledObjectsBuffer = GPUDevice::Instance->CreateBuffer(TEXT("GlobalSurfaceAtlas.CulledObjectsBuffer"));
|
||||
if (surfaceAtlasData.CulledObjectsBuffer->GetSize() < objectsBufferCapacity)
|
||||
{
|
||||
const GPUBufferDescription desc = GPUBufferDescription::Buffer(objectsBufferCapacity, GPUBufferFlags::UnorderedAccess | GPUBufferFlags::ShaderResource, PixelFormat::R32G32B32A32_Float, nullptr, sizeof(Vector4));
|
||||
const GPUBufferDescription desc = GPUBufferDescription::Buffer(objectsBufferCapacity, GPUBufferFlags::UnorderedAccess | GPUBufferFlags::ShaderResource, PixelFormat::R32G32B32A32_Float, nullptr, sizeof(Float4));
|
||||
if (surfaceAtlasData.CulledObjectsBuffer->Init(desc))
|
||||
return true;
|
||||
}
|
||||
@@ -648,11 +648,11 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
|
||||
{
|
||||
for (int32 x = 0; x < GLOBAL_SURFACE_ATLAS_CHUNKS_RESOLUTION; x++)
|
||||
{
|
||||
Vector3 chunkCoord(x, y, z);
|
||||
Vector3 chunkMin = result.GlobalSurfaceAtlas.ViewPos + (chunkCoord - (GLOBAL_SURFACE_ATLAS_CHUNKS_RESOLUTION * 0.5f)) * result.GlobalSurfaceAtlas.ChunkSize;
|
||||
Vector3 chunkMax = chunkMin + result.GlobalSurfaceAtlas.ChunkSize;
|
||||
Float3 chunkCoord(x, y, z);
|
||||
Float3 chunkMin = result.GlobalSurfaceAtlas.ViewPos + (chunkCoord - (GLOBAL_SURFACE_ATLAS_CHUNKS_RESOLUTION * 0.5f)) * result.GlobalSurfaceAtlas.ChunkSize;
|
||||
Float3 chunkMax = chunkMin + result.GlobalSurfaceAtlas.ChunkSize;
|
||||
BoundingBox chunkBounds(chunkMin, chunkMax);
|
||||
if (Vector3::Distance(chunkBounds.GetCenter(), result.GlobalSurfaceAtlas.ViewPos) >= 2000.0f)
|
||||
if (Float3::Distance(chunkBounds.GetCenter(), result.GlobalSurfaceAtlas.ViewPos) >= 2000.0f)
|
||||
continue;
|
||||
|
||||
int32 count = 0;
|
||||
@@ -725,7 +725,7 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
|
||||
for (int32 tileIndex = 0; tileIndex < 6; tileIndex++)
|
||||
{
|
||||
auto* tile = object.Tiles[tileIndex];
|
||||
if (!tile || Vector3::Dot(tile->ViewDirection, light.Direction) < ZeroTolerance)
|
||||
if (!tile || Float3::Dot(tile->ViewDirection, light.Direction) < ZeroTolerance)
|
||||
continue;
|
||||
VB_WRITE_TILE(tile);
|
||||
}
|
||||
@@ -747,7 +747,7 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
|
||||
for (const auto& e : surfaceAtlasData.Objects)
|
||||
{
|
||||
const auto& object = e.Value;
|
||||
Vector3 lightToObject = object.Bounds.GetCenter() - light.Position;
|
||||
Float3 lightToObject = object.Bounds.GetCenter() - light.Position;
|
||||
if (lightToObject.LengthSquared() >= Math::Square(object.Radius + light.Radius))
|
||||
continue;
|
||||
for (int32 tileIndex = 0; tileIndex < 6; tileIndex++)
|
||||
@@ -774,13 +774,13 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
|
||||
for (const auto& e : surfaceAtlasData.Objects)
|
||||
{
|
||||
const auto& object = e.Value;
|
||||
Vector3 lightToObject = object.Bounds.GetCenter() - light.Position;
|
||||
Float3 lightToObject = object.Bounds.GetCenter() - light.Position;
|
||||
if (lightToObject.LengthSquared() >= Math::Square(object.Radius + light.Radius))
|
||||
continue;
|
||||
for (int32 tileIndex = 0; tileIndex < 6; tileIndex++)
|
||||
{
|
||||
auto* tile = object.Tiles[tileIndex];
|
||||
if (!tile || Vector3::Dot(tile->ViewDirection, light.Direction) < ZeroTolerance)
|
||||
if (!tile || Float3::Dot(tile->ViewDirection, light.Direction) < ZeroTolerance)
|
||||
continue;
|
||||
VB_WRITE_TILE(tile);
|
||||
}
|
||||
@@ -817,14 +817,14 @@ void GlobalSurfaceAtlasPass::RenderDebug(RenderContext& renderContext, GPUContex
|
||||
}
|
||||
|
||||
PROFILE_GPU_CPU("Global Surface Atlas Debug");
|
||||
const Vector2 outputSize(output->Size());
|
||||
const Float2 outputSize(output->Size());
|
||||
{
|
||||
Data0 data;
|
||||
data.ViewWorldPos = renderContext.View.Position;
|
||||
data.ViewNearPlane = renderContext.View.Near;
|
||||
data.ViewFarPlane = renderContext.View.Far;
|
||||
for (int32 i = 0; i < 4; i++)
|
||||
data.ViewFrustumWorldRays[i] = Vector4(renderContext.List->FrustumCornersWs[i + 4], 0);
|
||||
data.ViewFrustumWorldRays[i] = Float4(renderContext.List->FrustumCornersWs[i + 4], 0);
|
||||
data.GlobalSDF = bindingDataSDF.Constants;
|
||||
data.GlobalSurfaceAtlas = bindingData.Constants;
|
||||
context->UpdateCB(_cb0, &data);
|
||||
@@ -841,8 +841,8 @@ void GlobalSurfaceAtlasPass::RenderDebug(RenderContext& renderContext, GPUContex
|
||||
context->SetState(_psDebug);
|
||||
context->SetRenderTarget(output->View());
|
||||
{
|
||||
Vector2 outputSizeThird = outputSize * 0.333f;
|
||||
Vector2 outputSizeTwoThird = outputSize * 0.666f;
|
||||
Float2 outputSizeThird = outputSize * 0.333f;
|
||||
Float2 outputSizeTwoThird = outputSize * 0.666f;
|
||||
|
||||
// Full screen - direct light
|
||||
context->BindSR(11, bindingData.AtlasLighting->View());
|
||||
@@ -870,8 +870,8 @@ void GlobalSurfaceAtlasPass::RenderDebug(RenderContext& renderContext, GPUContex
|
||||
void GlobalSurfaceAtlasPass::RasterizeActor(Actor* actor, void* actorObject, const BoundingSphere& actorObjectBounds, const Matrix& localToWorld, const BoundingBox& localBounds, uint32 tilesMask)
|
||||
{
|
||||
GlobalSurfaceAtlasCustomBuffer& surfaceAtlasData = *_surfaceAtlasData;
|
||||
Vector3 boundsSize = localBounds.GetSize() * actor->GetScale();
|
||||
const float distanceScale = Math::Lerp(1.0f, surfaceAtlasData.DistanceScaling, Math::InverseLerp(surfaceAtlasData.DistanceScalingStart, surfaceAtlasData.DistanceScalingEnd, CollisionsHelper::DistanceSpherePoint(actorObjectBounds, surfaceAtlasData.ViewPosition)));
|
||||
Float3 boundsSize = localBounds.GetSize() * actor->GetScale();
|
||||
const float distanceScale = Math::Lerp(1.0f, surfaceAtlasData.DistanceScaling, Math::InverseLerp(surfaceAtlasData.DistanceScalingStart, surfaceAtlasData.DistanceScalingEnd, (float)CollisionsHelper::DistanceSpherePoint(actorObjectBounds, surfaceAtlasData.ViewPosition)));
|
||||
const float tilesScale = surfaceAtlasData.TileTexelsPerWorldUnit * distanceScale;
|
||||
GlobalSurfaceAtlasObject* object = surfaceAtlasData.Objects.TryGet(actorObject);
|
||||
bool anyTile = false, dirty = false;
|
||||
@@ -881,7 +881,7 @@ void GlobalSurfaceAtlasPass::RasterizeActor(Actor* actor, void* actorObject, con
|
||||
continue;
|
||||
|
||||
// Calculate optimal tile resolution for the object side
|
||||
Vector3 boundsSizeTile = boundsSize;
|
||||
Float3 boundsSizeTile = boundsSize;
|
||||
boundsSizeTile.Raw[tileIndex / 2] = MAX_float; // Ignore depth size
|
||||
uint16 tileResolution = (uint16)(boundsSizeTile.GetAbsolute().MinValue() * tilesScale);
|
||||
if (tileResolution < 4)
|
||||
@@ -945,7 +945,7 @@ void GlobalSurfaceAtlasPass::RasterizeActor(Actor* actor, void* actorObject, con
|
||||
object->LastFrameUsed = surfaceAtlasData.CurrentFrame;
|
||||
object->Bounds = OrientedBoundingBox(localBounds);
|
||||
object->Bounds.Transform(localToWorld);
|
||||
object->Radius = actorObjectBounds.Radius;
|
||||
object->Radius = (float)actorObjectBounds.Radius;
|
||||
if (dirty || GLOBAL_SURFACE_ATLAS_DEBUG_FORCE_REDRAW_TILES)
|
||||
{
|
||||
object->LastFrameDirty = surfaceAtlasData.CurrentFrame;
|
||||
@@ -955,16 +955,16 @@ void GlobalSurfaceAtlasPass::RasterizeActor(Actor* actor, void* actorObject, con
|
||||
// Write to objects buffer (this must match unpacking logic in HLSL)
|
||||
Matrix worldToLocalBounds;
|
||||
Matrix::Invert(object->Bounds.Transformation, worldToLocalBounds);
|
||||
uint32 objectAddress = _objectsBuffer->Data.Count() / sizeof(Vector4);
|
||||
auto* objectData = _objectsBuffer->WriteReserve<Vector4>(GLOBAL_SURFACE_ATLAS_OBJECT_DATA_STRIDE);
|
||||
objectData[0] = *(Vector4*)&actorObjectBounds;
|
||||
objectData[1] = Vector4::Zero; // w unused
|
||||
objectData[2] = Vector4(worldToLocalBounds.M11, worldToLocalBounds.M12, worldToLocalBounds.M13, worldToLocalBounds.M41);
|
||||
objectData[3] = Vector4(worldToLocalBounds.M21, worldToLocalBounds.M22, worldToLocalBounds.M23, worldToLocalBounds.M42);
|
||||
objectData[4] = Vector4(worldToLocalBounds.M31, worldToLocalBounds.M32, worldToLocalBounds.M33, worldToLocalBounds.M43);
|
||||
objectData[5] = Vector4(object->Bounds.Extents, 0.0f); // w unused
|
||||
uint32 objectAddress = _objectsBuffer->Data.Count() / sizeof(Float4);
|
||||
auto* objectData = _objectsBuffer->WriteReserve<Float4>(GLOBAL_SURFACE_ATLAS_OBJECT_DATA_STRIDE);
|
||||
objectData[0] = *(Float4*)&actorObjectBounds;
|
||||
objectData[1] = Float4::Zero; // w unused
|
||||
objectData[2] = Float4(worldToLocalBounds.M11, worldToLocalBounds.M12, worldToLocalBounds.M13, worldToLocalBounds.M41);
|
||||
objectData[3] = Float4(worldToLocalBounds.M21, worldToLocalBounds.M22, worldToLocalBounds.M23, worldToLocalBounds.M42);
|
||||
objectData[4] = Float4(worldToLocalBounds.M31, worldToLocalBounds.M32, worldToLocalBounds.M33, worldToLocalBounds.M43);
|
||||
objectData[5] = Float4(object->Bounds.Extents, 0.0f); // w unused
|
||||
auto tileOffsets = reinterpret_cast<uint16*>(&objectData[1]); // xyz used for tile offsets packed into uint16
|
||||
auto objectDataSize = reinterpret_cast<uint32*>(&objectData[1].W); // w used for object size (count of Vector4s for object+tiles)
|
||||
auto objectDataSize = reinterpret_cast<uint32*>(&objectData[1].W); // w used for object size (count of Float4s for object+tiles)
|
||||
*objectDataSize = GLOBAL_SURFACE_ATLAS_OBJECT_DATA_STRIDE;
|
||||
for (int32 tileIndex = 0; tileIndex < 6; tileIndex++)
|
||||
{
|
||||
@@ -977,41 +977,41 @@ void GlobalSurfaceAtlasPass::RasterizeActor(Actor* actor, void* actorObject, con
|
||||
*objectDataSize += GLOBAL_SURFACE_ATLAS_TILE_DATA_STRIDE;
|
||||
|
||||
// Setup view to render object from the side
|
||||
Vector3 xAxis, yAxis, zAxis = Vector3::Zero;
|
||||
Float3 xAxis, yAxis, zAxis = Float3::Zero;
|
||||
zAxis.Raw[tileIndex / 2] = tileIndex & 1 ? 1.0f : -1.0f;
|
||||
yAxis = tileIndex == 2 || tileIndex == 3 ? Vector3::Right : Vector3::Up;
|
||||
Vector3::Cross(yAxis, zAxis, xAxis);
|
||||
Vector3 localSpaceOffset = -zAxis * object->Bounds.Extents;
|
||||
Vector3::TransformNormal(xAxis, object->Bounds.Transformation, xAxis);
|
||||
Vector3::TransformNormal(yAxis, object->Bounds.Transformation, yAxis);
|
||||
Vector3::TransformNormal(zAxis, object->Bounds.Transformation, zAxis);
|
||||
yAxis = tileIndex == 2 || tileIndex == 3 ? Float3::Right : Float3::Up;
|
||||
Float3::Cross(yAxis, zAxis, xAxis);
|
||||
Float3 localSpaceOffset = -zAxis * object->Bounds.Extents;
|
||||
Float3::TransformNormal(xAxis, object->Bounds.Transformation, xAxis);
|
||||
Float3::TransformNormal(yAxis, object->Bounds.Transformation, yAxis);
|
||||
Float3::TransformNormal(zAxis, object->Bounds.Transformation, zAxis);
|
||||
xAxis.NormalizeFast();
|
||||
yAxis.NormalizeFast();
|
||||
zAxis.NormalizeFast();
|
||||
Vector3::Transform(localSpaceOffset, object->Bounds.Transformation, tile->ViewPosition);
|
||||
Float3::Transform(localSpaceOffset, object->Bounds.Transformation, tile->ViewPosition);
|
||||
tile->ViewDirection = zAxis;
|
||||
|
||||
// Create view matrix
|
||||
tile->ViewMatrix.SetColumn1(Vector4(xAxis, -Vector3::Dot(xAxis, tile->ViewPosition)));
|
||||
tile->ViewMatrix.SetColumn2(Vector4(yAxis, -Vector3::Dot(yAxis, tile->ViewPosition)));
|
||||
tile->ViewMatrix.SetColumn3(Vector4(zAxis, -Vector3::Dot(zAxis, tile->ViewPosition)));
|
||||
tile->ViewMatrix.SetColumn4(Vector4(0, 0, 0, 1));
|
||||
tile->ViewMatrix.SetColumn1(Float4(xAxis, -Float3::Dot(xAxis, tile->ViewPosition)));
|
||||
tile->ViewMatrix.SetColumn2(Float4(yAxis, -Float3::Dot(yAxis, tile->ViewPosition)));
|
||||
tile->ViewMatrix.SetColumn3(Float4(zAxis, -Float3::Dot(zAxis, tile->ViewPosition)));
|
||||
tile->ViewMatrix.SetColumn4(Float4(0, 0, 0, 1));
|
||||
|
||||
// Calculate object bounds size in the view
|
||||
OrientedBoundingBox viewBounds(object->Bounds);
|
||||
viewBounds.Transform(tile->ViewMatrix);
|
||||
Vector3 viewExtent;
|
||||
Vector3::TransformNormal(viewBounds.Extents, viewBounds.Transformation, viewExtent);
|
||||
Float3 viewExtent;
|
||||
Float3::TransformNormal(viewBounds.Extents, viewBounds.Transformation, viewExtent);
|
||||
tile->ViewBoundsSize = viewExtent.GetAbsolute() * 2.0f;
|
||||
|
||||
// Per-tile data
|
||||
const float tileWidth = (float)tile->Width - GLOBAL_SURFACE_ATLAS_TILE_PADDING;
|
||||
const float tileHeight = (float)tile->Height - GLOBAL_SURFACE_ATLAS_TILE_PADDING;
|
||||
auto* tileData = _objectsBuffer->WriteReserve<Vector4>(GLOBAL_SURFACE_ATLAS_TILE_DATA_STRIDE);
|
||||
tileData[0] = Vector4(tile->X, tile->Y, tileWidth, tileHeight) * surfaceAtlasData.ResolutionInv;
|
||||
tileData[1] = Vector4(tile->ViewMatrix.M11, tile->ViewMatrix.M12, tile->ViewMatrix.M13, tile->ViewMatrix.M41);
|
||||
tileData[2] = Vector4(tile->ViewMatrix.M21, tile->ViewMatrix.M22, tile->ViewMatrix.M23, tile->ViewMatrix.M42);
|
||||
tileData[3] = Vector4(tile->ViewMatrix.M31, tile->ViewMatrix.M32, tile->ViewMatrix.M33, tile->ViewMatrix.M43);
|
||||
tileData[4] = Vector4(tile->ViewBoundsSize, 0.0f); // w unused
|
||||
auto* tileData = _objectsBuffer->WriteReserve<Float4>(GLOBAL_SURFACE_ATLAS_TILE_DATA_STRIDE);
|
||||
tileData[0] = Float4(tile->X, tile->Y, tileWidth, tileHeight) * surfaceAtlasData.ResolutionInv;
|
||||
tileData[1] = Float4(tile->ViewMatrix.M11, tile->ViewMatrix.M12, tile->ViewMatrix.M13, tile->ViewMatrix.M41);
|
||||
tileData[2] = Float4(tile->ViewMatrix.M21, tile->ViewMatrix.M22, tile->ViewMatrix.M23, tile->ViewMatrix.M42);
|
||||
tileData[3] = Float4(tile->ViewMatrix.M31, tile->ViewMatrix.M32, tile->ViewMatrix.M33, tile->ViewMatrix.M43);
|
||||
tileData[4] = Float4(tile->ViewBoundsSize, 0.0f); // w unused
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ public:
|
||||
// Constant buffer data for Global Surface Atlas access on a GPU.
|
||||
PACK_STRUCT(struct ConstantsData
|
||||
{
|
||||
Vector3 ViewPos;
|
||||
Float3 ViewPos;
|
||||
float Padding0;
|
||||
float Padding1;
|
||||
float Resolution;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include "GlobalSignDistanceFieldPass.h"
|
||||
#include "RenderList.h"
|
||||
#include "Engine/Core/Math/Int3.h"
|
||||
#include "Engine/Core/Math/Vector3.h"
|
||||
#include "Engine/Core/Collections/HashSet.h"
|
||||
#include "Engine/Engine/Engine.h"
|
||||
#include "Engine/Content/Content.h"
|
||||
@@ -37,21 +37,21 @@ PACK_STRUCT(struct ObjectRasterizeData
|
||||
{
|
||||
Matrix WorldToVolume; // TODO: use 3x4 matrix
|
||||
Matrix VolumeToWorld; // TODO: use 3x4 matrix
|
||||
Vector3 VolumeToUVWMul;
|
||||
Float3 VolumeToUVWMul;
|
||||
float MipOffset;
|
||||
Vector3 VolumeToUVWAdd;
|
||||
Float3 VolumeToUVWAdd;
|
||||
float DecodeMul;
|
||||
Vector3 VolumeLocalBoundsExtent;
|
||||
Float3 VolumeLocalBoundsExtent;
|
||||
float DecodeAdd;
|
||||
});
|
||||
|
||||
PACK_STRUCT(struct Data
|
||||
{
|
||||
Vector3 ViewWorldPos;
|
||||
Float3 ViewWorldPos;
|
||||
float ViewNearPlane;
|
||||
Vector3 Padding00;
|
||||
Float3 Padding00;
|
||||
float ViewFarPlane;
|
||||
Vector4 ViewFrustumWorldRays[4];
|
||||
Float4 ViewFrustumWorldRays[4];
|
||||
GlobalSignDistanceFieldPass::ConstantsData GlobalSDF;
|
||||
});
|
||||
|
||||
@@ -59,9 +59,9 @@ PACK_STRUCT(struct ModelsRasterizeData
|
||||
{
|
||||
Int3 ChunkCoord;
|
||||
float MaxDistance;
|
||||
Vector3 CascadeCoordToPosMul;
|
||||
Float3 CascadeCoordToPosMul;
|
||||
int ObjectsCount;
|
||||
Vector3 CascadeCoordToPosAdd;
|
||||
Float3 CascadeCoordToPosAdd;
|
||||
int32 CascadeResolution;
|
||||
float Padding0;
|
||||
float CascadeVoxelSize;
|
||||
@@ -74,9 +74,9 @@ struct RasterizeModel
|
||||
{
|
||||
Matrix WorldToVolume;
|
||||
Matrix VolumeToWorld;
|
||||
Vector3 VolumeToUVWMul;
|
||||
Vector3 VolumeToUVWAdd;
|
||||
Vector3 VolumeLocalBoundsExtent;
|
||||
Float4 VolumeToUVWMul;
|
||||
Float4 VolumeToUVWAdd;
|
||||
Float4 VolumeLocalBoundsExtent;
|
||||
float MipOffset;
|
||||
const ModelBase::SDFData* SDF;
|
||||
};
|
||||
@@ -430,8 +430,8 @@ bool GlobalSignDistanceFieldPass::Render(RenderContext& renderContext, GPUContex
|
||||
{
|
||||
cascade.NonEmptyChunks.Clear();
|
||||
cascade.StaticChunks.Clear();
|
||||
context->ClearUA(cascade.Texture, Vector4::One);
|
||||
context->ClearUA(cascade.Mip, Vector4::One);
|
||||
context->ClearUA(cascade.Texture, Float4::One);
|
||||
context->ClearUA(cascade.Mip, Float4::One);
|
||||
}
|
||||
LOG(Info, "Global SDF memory usage: {0} MB", (sdfData.Cascades[0].Texture->GetMemoryUsage() + sdfData.Cascades[0].Mip->GetMemoryUsage()) * ARRAY_COUNT(sdfData.Cascades) / 1024 / 1024);
|
||||
}
|
||||
@@ -517,8 +517,8 @@ bool GlobalSignDistanceFieldPass::Render(RenderContext& renderContext, GPUContex
|
||||
return true;
|
||||
}
|
||||
ModelsRasterizeData data;
|
||||
data.CascadeCoordToPosMul = cascadeBounds.GetSize() / resolution;
|
||||
data.CascadeCoordToPosAdd = cascadeBounds.Minimum + voxelSize * 0.5f;
|
||||
data.CascadeCoordToPosMul = (Float3)cascadeBounds.GetSize() / (float)resolution;
|
||||
data.CascadeCoordToPosAdd = (Float3)cascadeBounds.Minimum + voxelSize * 0.5f;
|
||||
data.MaxDistance = maxDistance;
|
||||
data.CascadeResolution = resolution;
|
||||
data.CascadeMipResolution = resolutionMip;
|
||||
@@ -752,7 +752,7 @@ void GlobalSignDistanceFieldPass::RenderDebug(RenderContext& renderContext, GPUC
|
||||
}
|
||||
|
||||
PROFILE_GPU_CPU("Global SDF Debug");
|
||||
const Vector2 outputSize(output->Size());
|
||||
const Float2 outputSize(output->Size());
|
||||
{
|
||||
Data data;
|
||||
data.ViewWorldPos = renderContext.View.Position;
|
||||
@@ -808,8 +808,8 @@ void GlobalSignDistanceFieldPass::RasterizeModelSDF(Actor* actor, const ModelBas
|
||||
mipLevelIndex--;
|
||||
|
||||
// Volume -> Local -> UVW
|
||||
Vector3 volumeToUVWMul = sdf.LocalToUVWMul;
|
||||
Vector3 volumeToUVWAdd = sdf.LocalToUVWAdd + (localVolumeBounds.Minimum + volumeLocalBoundsExtent) * sdf.LocalToUVWMul;
|
||||
Float3 volumeToUVWMul = sdf.LocalToUVWMul;
|
||||
Float3 volumeToUVWAdd = sdf.LocalToUVWAdd + (localVolumeBounds.Minimum + volumeLocalBoundsExtent) * sdf.LocalToUVWMul;
|
||||
|
||||
// Add object data for the GPU buffer
|
||||
uint16 objectIndex = _objectsBufferCount++;
|
||||
@@ -862,7 +862,7 @@ void GlobalSignDistanceFieldPass::RasterizeModelSDF(Actor* actor, const ModelBas
|
||||
}
|
||||
}
|
||||
|
||||
void GlobalSignDistanceFieldPass::RasterizeHeightfield(Actor* actor, GPUTexture* heightfield, const Matrix& localToWorld, const BoundingBox& objectBounds, const Vector4& localToUV)
|
||||
void GlobalSignDistanceFieldPass::RasterizeHeightfield(Actor* actor, GPUTexture* heightfield, const Matrix& localToWorld, const BoundingBox& objectBounds, const Float4& localToUV)
|
||||
{
|
||||
if (!heightfield || heightfield->ResidentMipLevels() == 0)
|
||||
return;
|
||||
@@ -885,8 +885,8 @@ void GlobalSignDistanceFieldPass::RasterizeHeightfield(Actor* actor, GPUTexture*
|
||||
Matrix::Invert(localToWorld, worldToLocal);
|
||||
Matrix::Transpose(worldToLocal, objectData.WorldToVolume);
|
||||
Matrix::Transpose(localToWorld, objectData.VolumeToWorld);
|
||||
objectData.VolumeToUVWMul = Vector3(localToUV.X, 1.0f, localToUV.Y);
|
||||
objectData.VolumeToUVWAdd = Vector3(localToUV.Z, 0.0f, localToUV.W);
|
||||
objectData.VolumeToUVWMul = Float3(localToUV.X, 1.0f, localToUV.Y);
|
||||
objectData.VolumeToUVWAdd = Float3(localToUV.Z, 0.0f, localToUV.W);
|
||||
objectData.MipOffset = (float)_cascadeIndex * 0.5f; // Use lower-quality mip for far cascades
|
||||
_objectsBuffer->Write(objectData);
|
||||
_objectsTextures.Add(heightfield->View());
|
||||
|
||||
@@ -13,9 +13,9 @@ public:
|
||||
// Constant buffer data for Global SDF access on a GPU.
|
||||
PACK_STRUCT(struct ConstantsData
|
||||
{
|
||||
Vector4 CascadePosDistance[4];
|
||||
Vector4 CascadeVoxelSize;
|
||||
Vector3 Padding;
|
||||
Float4 CascadePosDistance[4];
|
||||
Float4 CascadeVoxelSize;
|
||||
Float3 Padding;
|
||||
float Resolution;
|
||||
});
|
||||
|
||||
@@ -78,7 +78,7 @@ public:
|
||||
// Rasterize Model SDF into the Global SDF. Call it from actor Draw() method during DrawPass::GlobalSDF.
|
||||
void RasterizeModelSDF(Actor* actor, const ModelBase::SDFData& sdf, const Matrix& localToWorld, const BoundingBox& objectBounds);
|
||||
|
||||
void RasterizeHeightfield(Actor* actor, GPUTexture* heightfield, const Matrix& localToWorld, const BoundingBox& objectBounds, const Vector4& localToUV);
|
||||
void RasterizeHeightfield(Actor* actor, GPUTexture* heightfield, const Matrix& localToWorld, const BoundingBox& objectBounds, const Float4& localToUV);
|
||||
|
||||
private:
|
||||
#if COMPILE_WITH_DEV_ENV
|
||||
|
||||
@@ -233,7 +233,7 @@ void LightPass::RenderLight(RenderContext& renderContext, GPUTextureView* lightB
|
||||
// Cache data
|
||||
auto& light = mainCache->PointLights[lightIndex];
|
||||
float lightRadius = light.Radius;
|
||||
Vector3 lightPosition = light.Position;
|
||||
Float3 lightPosition = light.Position;
|
||||
const bool renderShadow = useShadows && CanRenderShadow(view, light) && ShadowsPass::Instance()->CanRenderShadow(renderContext, light);
|
||||
bool useIES = light.IESTexture != nullptr;
|
||||
|
||||
@@ -290,7 +290,7 @@ void LightPass::RenderLight(RenderContext& renderContext, GPUTextureView* lightB
|
||||
// Cache data
|
||||
auto& light = mainCache->SpotLights[lightIndex];
|
||||
float lightRadius = light.Radius;
|
||||
Vector3 lightPosition = light.Position;
|
||||
Float3 lightPosition = light.Position;
|
||||
const bool renderShadow = useShadows && CanRenderShadow(view, light) && ShadowsPass::Instance()->CanRenderShadow(renderContext, light);
|
||||
bool useIES = light.IESTexture != nullptr;
|
||||
|
||||
@@ -384,7 +384,7 @@ void LightPass::RenderLight(RenderContext& renderContext, GPUTextureView* lightB
|
||||
// Cache data
|
||||
auto& light = mainCache->SkyLights[lightIndex];
|
||||
float lightRadius = light.Radius;
|
||||
Vector3 lightPosition = light.Position;
|
||||
Float3 lightPosition = light.Position;
|
||||
|
||||
// Get distance from view center to light center less radius (check if view is inside a sphere)
|
||||
float distance = ViewToCenterLessRadius(view, lightPosition, lightRadius * sphereModelScale);
|
||||
|
||||
@@ -21,15 +21,15 @@ PACK_STRUCT(struct Data {
|
||||
GBufferData GBuffer;
|
||||
Matrix CurrentVP;
|
||||
Matrix PreviousVP;
|
||||
Vector4 TemporalAAJitter;
|
||||
Float4 TemporalAAJitter;
|
||||
|
||||
float VelocityScale;
|
||||
float Dummy0;
|
||||
int32 MaxBlurSamples;
|
||||
uint32 VariableTileLoopCount;
|
||||
|
||||
Vector2 Input0SizeInv;
|
||||
Vector2 Input2SizeInv;
|
||||
Float2 Input0SizeInv;
|
||||
Float2 Input2SizeInv;
|
||||
});
|
||||
|
||||
MotionBlurPass::MotionBlurPass()
|
||||
@@ -297,7 +297,7 @@ void MotionBlurPass::Render(RenderContext& renderContext, GPUTexture*& input, GP
|
||||
data.VelocityScale = settings.Scale * 0.5f * timeScale; // 2x samples in loop
|
||||
data.MaxBlurSamples = Math::Clamp(settings.SampleCount / 2, 1, 64); // 2x samples in loop
|
||||
data.VariableTileLoopCount = tileSize / 8;
|
||||
data.Input0SizeInv = Vector2(1.0f / (float)motionVectorsWidth, 1.0f / (float)motionVectorsWidth);
|
||||
data.Input0SizeInv = Float2(1.0f / (float)motionVectorsWidth, 1.0f / (float)motionVectorsWidth);
|
||||
const auto cb = _shader->GetShader()->GetCB(0);
|
||||
context->UpdateCB(cb, &data);
|
||||
context->BindCB(0, cb);
|
||||
@@ -319,7 +319,7 @@ void MotionBlurPass::Render(RenderContext& renderContext, GPUTexture*& input, GP
|
||||
context->SetRenderTarget(vMaxBuffer4->View());
|
||||
context->SetViewportAndScissors((float)rtDesc.Width, (float)rtDesc.Height);
|
||||
context->BindSR(0, vMaxBuffer2->View());
|
||||
data.Input0SizeInv = Vector2(1.0f / (float)vMaxBuffer2->Width(), 1.0f / (float)vMaxBuffer2->Height());
|
||||
data.Input0SizeInv = Float2(1.0f / (float)vMaxBuffer2->Width(), 1.0f / (float)vMaxBuffer2->Height());
|
||||
context->UpdateCB(cb, &data);
|
||||
context->SetState(_psTileMax);
|
||||
context->DrawFullscreenTriangle();
|
||||
@@ -333,7 +333,7 @@ void MotionBlurPass::Render(RenderContext& renderContext, GPUTexture*& input, GP
|
||||
context->SetRenderTarget(vMaxBuffer8->View());
|
||||
context->SetViewportAndScissors((float)rtDesc.Width, (float)rtDesc.Height);
|
||||
context->BindSR(0, vMaxBuffer4->View());
|
||||
data.Input0SizeInv = Vector2(1.0f / (float)vMaxBuffer4->Width(), 1.0f / (float)vMaxBuffer4->Height());
|
||||
data.Input0SizeInv = Float2(1.0f / (float)vMaxBuffer4->Width(), 1.0f / (float)vMaxBuffer4->Height());
|
||||
context->UpdateCB(cb, &data);
|
||||
context->SetState(_psTileMax);
|
||||
context->DrawFullscreenTriangle();
|
||||
@@ -347,7 +347,7 @@ void MotionBlurPass::Render(RenderContext& renderContext, GPUTexture*& input, GP
|
||||
context->SetRenderTarget(vMaxBuffer->View());
|
||||
context->SetViewportAndScissors((float)rtDesc.Width, (float)rtDesc.Height);
|
||||
context->BindSR(0, vMaxBuffer8->View());
|
||||
data.Input0SizeInv = Vector2(1.0f / (float)vMaxBuffer8->Width(), 1.0f / (float)vMaxBuffer8->Height());
|
||||
data.Input0SizeInv = Float2(1.0f / (float)vMaxBuffer8->Width(), 1.0f / (float)vMaxBuffer8->Height());
|
||||
context->UpdateCB(cb, &data);
|
||||
context->SetState(_psTileMaxVariable);
|
||||
context->DrawFullscreenTriangle();
|
||||
@@ -370,8 +370,8 @@ void MotionBlurPass::Render(RenderContext& renderContext, GPUTexture*& input, GP
|
||||
context->BindSR(1, motionVectors->View());
|
||||
context->BindSR(2, vMaxNeighborBuffer->View());
|
||||
context->BindSR(3, renderContext.Buffers->DepthBuffer->View());
|
||||
data.Input0SizeInv = Vector2(1.0f / (float)input->Width(), 1.0f / (float)input->Height());
|
||||
data.Input2SizeInv = Vector2(1.0f / (float)renderContext.Buffers->DepthBuffer->Width(), 1.0f / (float)renderContext.Buffers->DepthBuffer->Height());
|
||||
data.Input0SizeInv = Float2(1.0f / (float)input->Width(), 1.0f / (float)input->Height());
|
||||
data.Input2SizeInv = Float2(1.0f / (float)renderContext.Buffers->DepthBuffer->Width(), 1.0f / (float)renderContext.Buffers->DepthBuffer->Height());
|
||||
context->UpdateCB(cb, &data);
|
||||
context->SetState(_psMotionBlur);
|
||||
context->DrawFullscreenTriangle();
|
||||
|
||||
@@ -148,8 +148,8 @@ void PostProcessingPass::GB_ComputeKernel(float sigma, float width, float height
|
||||
// Calculate total weights sum
|
||||
total += weight;
|
||||
|
||||
GaussianBlurCacheH[index] = Vector4(weight, i * xOffset, 0, 0);
|
||||
GaussianBlurCacheV[index] = Vector4(weight, i * yOffset, 0, 0);
|
||||
GaussianBlurCacheH[index] = Float4(weight, i * xOffset, 0, 0);
|
||||
GaussianBlurCacheV[index] = Float4(weight, i * yOffset, 0, 0);
|
||||
}
|
||||
|
||||
// Normalize weights
|
||||
@@ -160,7 +160,7 @@ void PostProcessingPass::GB_ComputeKernel(float sigma, float width, float height
|
||||
}
|
||||
|
||||
// Assign size
|
||||
_gbData.Size = Vector2(width, height);
|
||||
_gbData.Size = Float2(width, height);
|
||||
}
|
||||
|
||||
void PostProcessingPass::Dispose()
|
||||
@@ -279,12 +279,12 @@ void PostProcessingPass::Render(RenderContext& renderContext, GPUTexture* input,
|
||||
|
||||
data.LensBias = settings.LensFlares.ThresholdBias;
|
||||
data.LensScale = settings.LensFlares.ThresholdScale;
|
||||
data.LensInputDistortion = Vector2(-(1.0f / w4) * settings.LensFlares.Distortion, (1.0f / w4) * settings.LensFlares.Distortion);
|
||||
data.LensInputDistortion = Float2(-(1.0f / w4) * settings.LensFlares.Distortion, (1.0f / w4) * settings.LensFlares.Distortion);
|
||||
|
||||
// Calculate star texture rotation matrix
|
||||
Vector3 camX = renderContext.View.View.GetRight();
|
||||
Vector3 camZ = renderContext.View.View.GetForward();
|
||||
float camRot = Vector3::Dot(camX, Vector3::Forward) + Vector3::Dot(camZ, Vector3::Up);
|
||||
Float3 camX = renderContext.View.View.GetRight();
|
||||
Float3 camZ = renderContext.View.View.GetForward();
|
||||
float camRot = Float3::Dot(camX, Float3::Forward) + Float3::Dot(camZ, Float3::Up);
|
||||
float camRotCos = Math::Cos(camRot) * 0.8f;
|
||||
float camRotSin = Math::Sin(camRot) * 0.8f;
|
||||
Matrix rotation(
|
||||
@@ -301,8 +301,8 @@ void PostProcessingPass::Render(RenderContext& renderContext, GPUTexture* input,
|
||||
data.LensDirtIntensity = 0;
|
||||
}
|
||||
data.PostExposure = Math::Exp2(settings.EyeAdaptation.PostExposure);
|
||||
data.InputSize = Vector2(static_cast<float>(w1), static_cast<float>(h1));
|
||||
data.InvInputSize = Vector2(1.0f / static_cast<float>(w1), 1.0f / static_cast<float>(h1));
|
||||
data.InputSize = Float2(static_cast<float>(w1), static_cast<float>(h1));
|
||||
data.InvInputSize = Float2(1.0f / static_cast<float>(w1), 1.0f / static_cast<float>(h1));
|
||||
data.InputAspect = static_cast<float>(w1) / h1;
|
||||
context->UpdateCB(cb0, &data);
|
||||
context->BindCB(0, cb0);
|
||||
|
||||
@@ -21,10 +21,10 @@ private:
|
||||
float BloomMagnitude;
|
||||
float BloomBlurSigma;
|
||||
|
||||
Vector3 VignetteColor;
|
||||
Float3 VignetteColor;
|
||||
float VignetteShapeFactor;
|
||||
|
||||
Vector2 InputSize;
|
||||
Float2 InputSize;
|
||||
float InputAspect;
|
||||
float GrainAmount;
|
||||
|
||||
@@ -38,11 +38,11 @@ private:
|
||||
float GhostDispersal;
|
||||
float LensFlareIntensity;
|
||||
|
||||
Vector2 LensInputDistortion;
|
||||
Float2 LensInputDistortion;
|
||||
float LensScale;
|
||||
float LensBias;
|
||||
|
||||
Vector2 InvInputSize;
|
||||
Float2 InvInputSize;
|
||||
float ChromaticDistortion;
|
||||
float Time;
|
||||
|
||||
@@ -57,10 +57,10 @@ private:
|
||||
});
|
||||
|
||||
PACK_STRUCT(struct GaussianBlurData {
|
||||
Vector2 Size;
|
||||
Float2 Size;
|
||||
float Dummy3;
|
||||
float Dummy4;
|
||||
Vector4 GaussianBlurCache[GB_KERNEL_SIZE]; // x-weight, y-offset
|
||||
Float4 GaussianBlurCache[GB_KERNEL_SIZE]; // x-weight, y-offset
|
||||
});
|
||||
|
||||
// Post Processing
|
||||
@@ -73,8 +73,8 @@ private:
|
||||
GPUPipelineStatePermutationsPs<3> _psComposite;
|
||||
|
||||
GaussianBlurData _gbData;
|
||||
Vector4 GaussianBlurCacheH[GB_KERNEL_SIZE];
|
||||
Vector4 GaussianBlurCacheV[GB_KERNEL_SIZE];
|
||||
Float4 GaussianBlurCacheH[GB_KERNEL_SIZE];
|
||||
Float4 GaussianBlurCacheV[GB_KERNEL_SIZE];
|
||||
|
||||
AssetReference<Texture> _defaultLensColor;
|
||||
AssetReference<Texture> _defaultLensStar;
|
||||
|
||||
@@ -88,14 +88,14 @@ protected:
|
||||
|
||||
PACK_STRUCT(struct Data
|
||||
{
|
||||
Vector2 Dummy0;
|
||||
Float2 Dummy0;
|
||||
int32 CubeFace;
|
||||
int32 SourceMipIndex;
|
||||
Vector4 Sample01;
|
||||
Vector4 Sample23;
|
||||
Vector4 CoefficientMask0;
|
||||
Vector4 CoefficientMask1;
|
||||
Vector3 Dummy1;
|
||||
Float4 Sample01;
|
||||
Float4 Sample23;
|
||||
Float4 CoefficientMask0;
|
||||
Float4 CoefficientMask1;
|
||||
Float3 Dummy1;
|
||||
float CoefficientMask2;
|
||||
});
|
||||
|
||||
@@ -429,10 +429,10 @@ bool fixFarPlaneTreeExecute(Actor* actor, const Vector3& position, float& farPla
|
||||
{
|
||||
if (auto* pointLight = dynamic_cast<PointLight*>(actor))
|
||||
{
|
||||
const float dst = Vector3::Distance(pointLight->GetPosition(), position) + pointLight->GetScaledRadius();
|
||||
const Real dst = Vector3::Distance(pointLight->GetPosition(), position) + pointLight->GetScaledRadius();
|
||||
if (dst > farPlane)
|
||||
{
|
||||
farPlane = dst;
|
||||
farPlane = (float)dst;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -415,7 +415,7 @@ void ReflectionsPass::Render(RenderContext& renderContext, GPUTextureView* light
|
||||
if (!probe->HasProbeLoaded())
|
||||
continue;
|
||||
float probeRadius = probe->GetScaledRadius();
|
||||
Vector3 probePosition = probe->GetPosition();
|
||||
Vector3 probePosition = probe->GetPosition(); // TODO: large-worlds
|
||||
|
||||
// Get distance from view center to light center less radius (check if view is inside a sphere)
|
||||
const float sphereModelScale = 2.0f;
|
||||
|
||||
@@ -49,7 +49,7 @@ void RendererDirectionalLightData::SetupLightData(LightData* data, bool useShado
|
||||
data->SourceLength = 0;
|
||||
data->Color = Color;
|
||||
data->MinRoughness = Math::Max(MinRoughness, MIN_ROUGHNESS);
|
||||
data->Position = Vector3::Zero;
|
||||
data->Position = Float3::Zero;
|
||||
data->CastShadows = useShadow ? 1.0f : 0.0f;
|
||||
data->Direction = -Direction;
|
||||
data->Radius = 0;
|
||||
@@ -102,7 +102,7 @@ void RendererSkyLightData::SetupLightData(LightData* data, bool useShadow) const
|
||||
data->MinRoughness = MIN_ROUGHNESS;
|
||||
data->Position = Position;
|
||||
data->CastShadows = useShadow ? 1.0f : 0.0f;
|
||||
data->Direction = Vector3::Forward;
|
||||
data->Direction = Float3::Forward;
|
||||
data->Radius = Radius;
|
||||
data->FalloffExponent = 0;
|
||||
data->InverseSquared = 0;
|
||||
@@ -388,7 +388,7 @@ void RenderList::Init(RenderContext& renderContext)
|
||||
{
|
||||
renderContext.View.Frustum.GetCorners(FrustumCornersWs);
|
||||
for (int32 i = 0; i < 8; i++)
|
||||
Vector3::Transform(FrustumCornersWs[i], renderContext.View.View, FrustumCornersVs[i]);
|
||||
Float3::Transform(FrustumCornersWs[i], renderContext.View.View, FrustumCornersVs[i]);
|
||||
}
|
||||
|
||||
void RenderList::Clear()
|
||||
@@ -477,7 +477,8 @@ void RenderList::SortDrawCalls(const RenderContext& renderContext, bool reverseD
|
||||
PROFILE_CPU();
|
||||
|
||||
const int32 listSize = (int32)list.Indices.Count();
|
||||
const Plane plane(renderContext.View.Position, renderContext.View.Direction);
|
||||
const Float3 planeNormal = renderContext.View.Direction;
|
||||
const float planePoint = -Float3::Dot(planeNormal, renderContext.View.Position);
|
||||
|
||||
// Peek shared memory
|
||||
#define PREPARE_CACHE(list) (list).Clear(); (list).Resize(listSize)
|
||||
@@ -492,7 +493,7 @@ void RenderList::SortDrawCalls(const RenderContext& renderContext, bool reverseD
|
||||
for (int32 i = 0; i < listSize; i++)
|
||||
{
|
||||
auto& drawCall = DrawCalls[list.Indices[i]];
|
||||
const auto distance = CollisionsHelper::DistancePlanePoint(plane, drawCall.ObjectPosition);
|
||||
const float distance = Float3::Dot(planeNormal, drawCall.ObjectPosition) - planePoint;
|
||||
const uint32 sortKey = RenderTools::ComputeDistanceSortKey(distance) ^ sortKeyXor;
|
||||
int32 batchKey = GetHash(drawCall.Geometry.IndexBuffer);
|
||||
batchKey = (batchKey * 397) ^ GetHash(drawCall.Geometry.VertexBuffers[0]);
|
||||
@@ -771,13 +772,13 @@ DRAW:
|
||||
auto& instance = batch.Instances[j];
|
||||
drawCall.ObjectPosition = instance.InstanceOrigin;
|
||||
drawCall.PerInstanceRandom = instance.PerInstanceRandom;
|
||||
auto lightmapArea = instance.InstanceLightmapArea.ToVector4();
|
||||
auto lightmapArea = instance.InstanceLightmapArea.ToFloat4();
|
||||
drawCall.Surface.LightmapUVsArea = *(Rectangle*)&lightmapArea;
|
||||
drawCall.Surface.LODDitherFactor = instance.LODDitherFactor;
|
||||
drawCall.World.SetRow1(Vector4(instance.InstanceTransform1, 0.0f));
|
||||
drawCall.World.SetRow2(Vector4(instance.InstanceTransform2, 0.0f));
|
||||
drawCall.World.SetRow3(Vector4(instance.InstanceTransform3, 0.0f));
|
||||
drawCall.World.SetRow4(Vector4(instance.InstanceOrigin, 1.0f));
|
||||
drawCall.World.SetRow1(Float4(instance.InstanceTransform1, 0.0f));
|
||||
drawCall.World.SetRow2(Float4(instance.InstanceTransform2, 0.0f));
|
||||
drawCall.World.SetRow3(Float4(instance.InstanceTransform3, 0.0f));
|
||||
drawCall.World.SetRow4(Float4(instance.InstanceOrigin, 1.0f));
|
||||
drawCall.Material->Bind(bindParams);
|
||||
|
||||
context->BindIB(drawCall.Geometry.IndexBuffer);
|
||||
@@ -824,11 +825,11 @@ bool SurfaceDrawCallHandler::CanBatch(const DrawCall& a, const DrawCall& b)
|
||||
|
||||
void SurfaceDrawCallHandler::WriteDrawCall(InstanceData* instanceData, const DrawCall& drawCall)
|
||||
{
|
||||
instanceData->InstanceOrigin = Vector3(drawCall.World.M41, drawCall.World.M42, drawCall.World.M43);
|
||||
instanceData->InstanceOrigin = Float3(drawCall.World.M41, drawCall.World.M42, drawCall.World.M43);
|
||||
instanceData->PerInstanceRandom = drawCall.PerInstanceRandom;
|
||||
instanceData->InstanceTransform1 = Vector3(drawCall.World.M11, drawCall.World.M12, drawCall.World.M13);
|
||||
instanceData->InstanceTransform1 = Float3(drawCall.World.M11, drawCall.World.M12, drawCall.World.M13);
|
||||
instanceData->LODDitherFactor = drawCall.Surface.LODDitherFactor;
|
||||
instanceData->InstanceTransform2 = Vector3(drawCall.World.M21, drawCall.World.M22, drawCall.World.M23);
|
||||
instanceData->InstanceTransform3 = Vector3(drawCall.World.M31, drawCall.World.M32, drawCall.World.M33);
|
||||
instanceData->InstanceTransform2 = Float3(drawCall.World.M21, drawCall.World.M22, drawCall.World.M23);
|
||||
instanceData->InstanceTransform3 = Float3(drawCall.World.M31, drawCall.World.M32, drawCall.World.M33);
|
||||
instanceData->InstanceLightmapArea = Half4(drawCall.Surface.LightmapUVsArea);
|
||||
}
|
||||
|
||||
@@ -20,13 +20,13 @@ struct RenderContext;
|
||||
|
||||
struct RendererDirectionalLightData
|
||||
{
|
||||
Vector3 Position;
|
||||
Float3 Position;
|
||||
float MinRoughness;
|
||||
|
||||
Vector3 Color;
|
||||
Float3 Color;
|
||||
float ShadowsStrength;
|
||||
|
||||
Vector3 Direction;
|
||||
Float3 Direction;
|
||||
float ShadowsFadeDistance;
|
||||
|
||||
float ShadowsNormalOffsetScale;
|
||||
@@ -47,13 +47,13 @@ struct RendererDirectionalLightData
|
||||
|
||||
struct RendererSpotLightData
|
||||
{
|
||||
Vector3 Position;
|
||||
Float3 Position;
|
||||
float MinRoughness;
|
||||
|
||||
Vector3 Color;
|
||||
Float3 Color;
|
||||
float ShadowsStrength;
|
||||
|
||||
Vector3 Direction;
|
||||
Float3 Direction;
|
||||
float ShadowsFadeDistance;
|
||||
|
||||
float ShadowsNormalOffsetScale;
|
||||
@@ -66,7 +66,7 @@ struct RendererSpotLightData
|
||||
float FallOffExponent;
|
||||
float SourceRadius;
|
||||
|
||||
Vector3 UpVector;
|
||||
Float3 UpVector;
|
||||
float OuterConeAngle;
|
||||
|
||||
float CosOuterCone;
|
||||
@@ -85,13 +85,13 @@ struct RendererSpotLightData
|
||||
|
||||
struct RendererPointLightData
|
||||
{
|
||||
Vector3 Position;
|
||||
Float3 Position;
|
||||
float MinRoughness;
|
||||
|
||||
Vector3 Color;
|
||||
Float3 Color;
|
||||
float ShadowsStrength;
|
||||
|
||||
Vector3 Direction;
|
||||
Float3 Direction;
|
||||
float ShadowsFadeDistance;
|
||||
|
||||
float ShadowsNormalOffsetScale;
|
||||
@@ -119,13 +119,13 @@ struct RendererPointLightData
|
||||
|
||||
struct RendererSkyLightData
|
||||
{
|
||||
Vector3 Position;
|
||||
Float3 Position;
|
||||
float VolumetricScatteringIntensity;
|
||||
|
||||
Vector3 Color;
|
||||
Float3 Color;
|
||||
float Radius;
|
||||
|
||||
Vector3 AdditiveColor;
|
||||
Float3 AdditiveColor;
|
||||
|
||||
int8 CastVolumetricShadow : 1;
|
||||
int8 RenderedVolumetricFog : 1;
|
||||
@@ -446,12 +446,12 @@ public:
|
||||
/// <summary>
|
||||
/// Camera frustum corners in World Space
|
||||
/// </summary>
|
||||
Vector3 FrustumCornersWs[8];
|
||||
Float3 FrustumCornersWs[8];
|
||||
|
||||
/// <summary>
|
||||
/// Camera frustum corners in View Space
|
||||
/// </summary>
|
||||
Vector3 FrustumCornersVs[8];
|
||||
Float3 FrustumCornersVs[8];
|
||||
|
||||
private:
|
||||
|
||||
@@ -590,12 +590,12 @@ public:
|
||||
/// </summary>
|
||||
struct FLAXENGINE_API InstanceData
|
||||
{
|
||||
Vector3 InstanceOrigin;
|
||||
Float3 InstanceOrigin;
|
||||
float PerInstanceRandom;
|
||||
Vector3 InstanceTransform1;
|
||||
Float3 InstanceTransform1;
|
||||
float LODDitherFactor;
|
||||
Vector3 InstanceTransform2;
|
||||
Vector3 InstanceTransform3;
|
||||
Float3 InstanceTransform2;
|
||||
Float3 InstanceTransform3;
|
||||
Half4 InstanceLightmapArea;
|
||||
};
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ PACK_STRUCT(struct Data
|
||||
float MaxTraceSamples;
|
||||
float RoughnessFade;
|
||||
|
||||
Vector2 SSRtexelSize;
|
||||
Float2 SSRtexelSize;
|
||||
float TemporalTime;
|
||||
float BRDFBias;
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ PACK_STRUCT(struct Data{
|
||||
LightShadowData LightShadow;
|
||||
Matrix WVP;
|
||||
Matrix ViewProjectionMatrix;
|
||||
Vector2 Dummy0;
|
||||
Float2 Dummy0;
|
||||
float ContactShadowsDistance;
|
||||
float ContactShadowsLength;
|
||||
});
|
||||
@@ -206,8 +206,8 @@ void ShadowsPass::Dispose()
|
||||
|
||||
bool ShadowsPass::CanRenderShadow(RenderContext& renderContext, const RendererPointLightData& light)
|
||||
{
|
||||
const Vector3 lightPosition = light.Position;
|
||||
const float dstLightToView = Vector3::Distance(lightPosition, renderContext.View.Position);
|
||||
const Float3 lightPosition = light.Position;
|
||||
const float dstLightToView = Float3::Distance(lightPosition, renderContext.View.Position);
|
||||
|
||||
// Fade shadow on distance
|
||||
const float fadeDistance = Math::Max(light.ShadowsFadeDistance, 0.1f);
|
||||
@@ -218,8 +218,8 @@ bool ShadowsPass::CanRenderShadow(RenderContext& renderContext, const RendererPo
|
||||
|
||||
bool ShadowsPass::CanRenderShadow(RenderContext& renderContext, const RendererSpotLightData& light)
|
||||
{
|
||||
const Vector3 lightPosition = light.Position;
|
||||
const float dstLightToView = Vector3::Distance(lightPosition, renderContext.View.Position);
|
||||
const Float3 lightPosition = light.Position;
|
||||
const float dstLightToView = Float3::Distance(lightPosition, renderContext.View.Position);
|
||||
|
||||
// Fade shadow on distance
|
||||
const float fadeDistance = Math::Max(light.ShadowsFadeDistance, 0.1f);
|
||||
@@ -273,9 +273,9 @@ void ShadowsPass::RenderShadow(RenderContext& renderContext, RendererPointLightD
|
||||
auto shader = _shader->GetShader();
|
||||
Data sperLight;
|
||||
float lightRadius = light.Radius;
|
||||
Vector3 lightPosition = light.Position;
|
||||
Vector3 lightDirection = light.Direction;
|
||||
float dstLightToView = Vector3::Distance(lightPosition, view.Position);
|
||||
Float3 lightPosition = light.Position;
|
||||
Float3 lightDirection = light.Direction;
|
||||
float dstLightToView = Float3::Distance(lightPosition, view.Position);
|
||||
|
||||
// TODO: here we can use lower shadows quality based on light distance to view (LOD switching) and per light setting for max quality
|
||||
int32 shadowQuality = maxShadowsQuality;
|
||||
@@ -288,7 +288,7 @@ void ShadowsPass::RenderShadow(RenderContext& renderContext, RendererPointLightD
|
||||
const auto shadowMapsSizeCube = (float)_shadowMapsSizeCube;
|
||||
context->SetViewportAndScissors(shadowMapsSizeCube, shadowMapsSizeCube);
|
||||
_shadowContext.View.SetUpCube(PointLight_NearPlane, lightRadius, lightPosition);
|
||||
_shadowContext.View.PrepareCache(_shadowContext, shadowMapsSizeCube, shadowMapsSizeCube, Vector2::Zero);
|
||||
_shadowContext.View.PrepareCache(_shadowContext, shadowMapsSizeCube, shadowMapsSizeCube, Float2::Zero);
|
||||
|
||||
// Render depth to all 6 faces of the cube map
|
||||
for (int32 faceIndex = 0; faceIndex < 6; faceIndex++)
|
||||
@@ -333,7 +333,7 @@ void ShadowsPass::RenderShadow(RenderContext& renderContext, RendererPointLightD
|
||||
sperLight.LightShadow.Bias = light.ShadowsDepthBias;
|
||||
sperLight.LightShadow.FadeDistance = Math::Max(light.ShadowsFadeDistance, 0.1f);
|
||||
sperLight.LightShadow.NumCascades = 1;
|
||||
sperLight.LightShadow.CascadeSplits = Vector4::Zero;
|
||||
sperLight.LightShadow.CascadeSplits = Float4::Zero;
|
||||
Matrix::Transpose(view.ViewProjection(), sperLight.ViewProjectionMatrix);
|
||||
sperLight.ContactShadowsDistance = light.ShadowsDistance;
|
||||
sperLight.ContactShadowsLength = view.Flags & ViewFlags::ContactShadows ? light.ContactShadowsLength : 0.0f;
|
||||
@@ -376,9 +376,9 @@ void ShadowsPass::RenderShadow(RenderContext& renderContext, RendererSpotLightDa
|
||||
auto shader = _shader->GetShader();
|
||||
Data sperLight;
|
||||
float lightRadius = light.Radius;
|
||||
Vector3 lightPosition = light.Position;
|
||||
Vector3 lightDirection = light.Direction;
|
||||
float dstLightToView = Vector3::Distance(lightPosition, view.Position);
|
||||
Float3 lightPosition = light.Position;
|
||||
Float3 lightDirection = light.Direction;
|
||||
float dstLightToView = Float3::Distance(lightPosition, view.Position);
|
||||
|
||||
// TODO: here we can use lower shadows quality based on light distance to view (LOD switching) and per light setting for max quality
|
||||
int32 shadowQuality = maxShadowsQuality;
|
||||
@@ -391,7 +391,7 @@ void ShadowsPass::RenderShadow(RenderContext& renderContext, RendererSpotLightDa
|
||||
const auto shadowMapsSizeCube = (float)_shadowMapsSizeCube;
|
||||
context->SetViewportAndScissors(shadowMapsSizeCube, shadowMapsSizeCube);
|
||||
_shadowContext.View.SetProjector(SpotLight_NearPlane, lightRadius, lightPosition, lightDirection, light.UpVector, light.OuterConeAngle * 2.0f);
|
||||
_shadowContext.View.PrepareCache(_shadowContext, shadowMapsSizeCube, shadowMapsSizeCube, Vector2::Zero);
|
||||
_shadowContext.View.PrepareCache(_shadowContext, shadowMapsSizeCube, shadowMapsSizeCube, Float2::Zero);
|
||||
|
||||
// Render depth to all 1 face of the cube map
|
||||
const int32 cubeFaceIndex = 0;
|
||||
@@ -435,7 +435,7 @@ void ShadowsPass::RenderShadow(RenderContext& renderContext, RendererSpotLightDa
|
||||
sperLight.LightShadow.Bias = light.ShadowsDepthBias;
|
||||
sperLight.LightShadow.FadeDistance = Math::Max(light.ShadowsFadeDistance, 0.1f);
|
||||
sperLight.LightShadow.NumCascades = 1;
|
||||
sperLight.LightShadow.CascadeSplits = Vector4::Zero;
|
||||
sperLight.LightShadow.CascadeSplits = Float4::Zero;
|
||||
Matrix::Transpose(view.ViewProjection(), sperLight.ViewProjectionMatrix);
|
||||
sperLight.ContactShadowsDistance = light.ShadowsDistance;
|
||||
sperLight.ContactShadowsLength = view.Flags & ViewFlags::ContactShadows ? light.ContactShadowsLength : 0.0f;
|
||||
@@ -476,7 +476,7 @@ void ShadowsPass::RenderShadow(RenderContext& renderContext, RendererDirectional
|
||||
auto mainCache = renderContext.List;
|
||||
auto shader = _shader->GetShader();
|
||||
Data sperLight;
|
||||
Vector3 lightDirection = light.Direction;
|
||||
Float3 lightDirection = light.Direction;
|
||||
float shadowsDistance = Math::Min(view.Far, light.ShadowsDistance);
|
||||
int32 csmCount = Math::Clamp(light.CascadeCount, 0, MAX_CSM_CASCADES);
|
||||
bool blendCSM = Graphics::AllowCSMBlending;
|
||||
@@ -566,28 +566,28 @@ void ShadowsPass::RenderShadow(RenderContext& renderContext, RendererDirectional
|
||||
}
|
||||
|
||||
// Select best Up vector
|
||||
Vector3 side = Vector3::UnitX;
|
||||
Vector3 upDirection = Vector3::UnitX;
|
||||
Vector3 VectorUps[] = { Vector3::UnitY, Vector3::UnitX, Vector3::UnitZ };
|
||||
for (int32 i = 0; i < ARRAY_COUNT(VectorUps); i++)
|
||||
Float3 side = Float3::UnitX;
|
||||
Float3 upDirection = Float3::UnitX;
|
||||
Float3 vectorUps[] = { Float3::UnitY, Float3::UnitX, Float3::UnitZ };
|
||||
for (int32 i = 0; i < ARRAY_COUNT(vectorUps); i++)
|
||||
{
|
||||
const Vector3 vectorUp = VectorUps[i];
|
||||
if (Math::Abs(Vector3::Dot(lightDirection, vectorUp)) < (1.0f - 0.0001f))
|
||||
const Float3 vectorUp = vectorUps[i];
|
||||
if (Math::Abs(Float3::Dot(lightDirection, vectorUp)) < (1.0f - 0.0001f))
|
||||
{
|
||||
side = Vector3::Normalize(Vector3::Cross(vectorUp, lightDirection));
|
||||
upDirection = Vector3::Normalize(Vector3::Cross(lightDirection, side));
|
||||
side = Float3::Normalize(Float3::Cross(vectorUp, lightDirection));
|
||||
upDirection = Float3::Normalize(Float3::Cross(lightDirection, side));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Temporary data
|
||||
Vector3 frustumCorners[8];
|
||||
Float3 frustumCorners[8];
|
||||
Matrix shadowView, shadowProjection, shadowVP;
|
||||
|
||||
// Set up GPU context and render view
|
||||
const auto shadowMapsSizeCSM = (float)_shadowMapsSizeCSM;
|
||||
context->SetViewportAndScissors(shadowMapsSizeCSM, shadowMapsSizeCSM);
|
||||
_shadowContext.View.PrepareCache(_shadowContext, shadowMapsSizeCSM, shadowMapsSizeCSM, Vector2::Zero);
|
||||
_shadowContext.View.PrepareCache(_shadowContext, shadowMapsSizeCSM, shadowMapsSizeCSM, Float2::Zero);
|
||||
|
||||
// Create the different view and projection matrices for each split
|
||||
float splitMinRatio = 0;
|
||||
@@ -618,26 +618,27 @@ void ShadowsPass::RenderShadow(RenderContext& renderContext, RendererDirectional
|
||||
ViewSnapping,
|
||||
};
|
||||
const StabilizationMode stabilization = ViewSnapping; // TODO: expose to graphics settings maybe
|
||||
Vector3 cascadeMinBoundLS;
|
||||
Vector3 cascadeMaxBoundLS;
|
||||
Vector3 target;
|
||||
Float3 cascadeMinBoundLS;
|
||||
Float3 cascadeMaxBoundLS;
|
||||
Float3 target;
|
||||
{
|
||||
// Make sure we are using the same direction when stabilizing
|
||||
BoundingSphere boundingVS;
|
||||
BoundingSphere::FromPoints(frustumCorners, ARRAY_COUNT(frustumCorners), boundingVS);
|
||||
|
||||
// Compute bounding box center
|
||||
Vector3::TransformCoordinate(boundingVS.Center, view.IV, target);
|
||||
cascadeMaxBoundLS = Vector3(boundingVS.Radius);
|
||||
Float3::TransformCoordinate(boundingVS.Center, view.IV, target);
|
||||
float boundingVSRadius = (float)boundingVS.Radius;
|
||||
cascadeMaxBoundLS = Float3(boundingVSRadius);
|
||||
cascadeMinBoundLS = -cascadeMaxBoundLS;
|
||||
|
||||
if (stabilization == ViewSnapping)
|
||||
{
|
||||
// Snap the target to the texel units (reference: ShaderX7 - Practical Cascaded Shadows Maps)
|
||||
float shadowMapHalfSize = shadowMapsSizeCSM * 0.5f;
|
||||
float x = Math::Ceil(Vector3::Dot(target, upDirection) * shadowMapHalfSize / boundingVS.Radius) * boundingVS.Radius / shadowMapHalfSize;
|
||||
float y = Math::Ceil(Vector3::Dot(target, side) * shadowMapHalfSize / boundingVS.Radius) * boundingVS.Radius / shadowMapHalfSize;
|
||||
float z = Vector3::Dot(target, lightDirection);
|
||||
float x = Math::Ceil(Float3::Dot(target, upDirection) * shadowMapHalfSize / boundingVSRadius) * boundingVSRadius / shadowMapHalfSize;
|
||||
float y = Math::Ceil(Float3::Dot(target, side) * shadowMapHalfSize / boundingVSRadius) * boundingVSRadius / shadowMapHalfSize;
|
||||
float z = Float3::Dot(target, lightDirection);
|
||||
target = upDirection * x + side * y + lightDirection * z;
|
||||
}
|
||||
}
|
||||
@@ -665,10 +666,10 @@ void ShadowsPass::RenderShadow(RenderContext& renderContext, RendererDirectional
|
||||
// Stabilize the shadow matrix on the projection
|
||||
if (stabilization == ProjectionSnapping)
|
||||
{
|
||||
Vector3 shadowPixelPosition = shadowVP.GetTranslation() * (shadowMapsSizeCSM * 0.5f);
|
||||
Float3 shadowPixelPosition = shadowVP.GetTranslation() * (shadowMapsSizeCSM * 0.5f);
|
||||
shadowPixelPosition.Z = 0;
|
||||
const Vector3 shadowPixelPositionRounded(Math::Round(shadowPixelPosition.X), Math::Round(shadowPixelPosition.Y), 0.0f);
|
||||
const Vector4 shadowPixelOffset((shadowPixelPositionRounded - shadowPixelPosition) * (2.0f / shadowMapsSizeCSM), 0.0f);
|
||||
const Float3 shadowPixelPositionRounded(Math::Round(shadowPixelPosition.X), Math::Round(shadowPixelPosition.Y), 0.0f);
|
||||
const Float4 shadowPixelOffset((shadowPixelPositionRounded - shadowPixelPosition) * (2.0f / shadowMapsSizeCSM), 0.0f);
|
||||
shadowProjection.SetRow4(shadowProjection.GetRow4() + shadowPixelOffset);
|
||||
Matrix::Multiply(shadowView, shadowProjection, shadowVP);
|
||||
}
|
||||
@@ -727,7 +728,7 @@ void ShadowsPass::RenderShadow(RenderContext& renderContext, RendererDirectional
|
||||
sperLight.LightShadow.Bias = light.ShadowsDepthBias;
|
||||
sperLight.LightShadow.FadeDistance = Math::Max(light.ShadowsFadeDistance, 0.1f);
|
||||
sperLight.LightShadow.NumCascades = csmCount;
|
||||
sperLight.LightShadow.CascadeSplits = view.Near + Vector4(cascadeSplits) * cameraRange;
|
||||
sperLight.LightShadow.CascadeSplits = view.Near + Float4(cascadeSplits) * cameraRange;
|
||||
Matrix::Transpose(view.ViewProjection(), sperLight.ViewProjectionMatrix);
|
||||
sperLight.ContactShadowsDistance = light.ShadowsDistance;
|
||||
sperLight.ContactShadowsLength = view.Flags & ViewFlags::ContactShadows ? light.ContactShadowsLength : 0.0f;
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
#include "Engine/Content/Content.h"
|
||||
|
||||
PACK_STRUCT(struct Data {
|
||||
Vector2 TexelSize;
|
||||
Vector2 Padding;
|
||||
Float2 TexelSize;
|
||||
Float2 Padding;
|
||||
});
|
||||
|
||||
String MultiScaler::ToString() const
|
||||
|
||||
@@ -182,7 +182,7 @@ bool VolumetricFogPass::Init(RenderContext& renderContext, GPUContext* context,
|
||||
// Prepare
|
||||
const int32 width = renderContext.Buffers->GetWidth();
|
||||
const int32 height = renderContext.Buffers->GetHeight();
|
||||
_cache.GridSize = Vector3(
|
||||
_cache.GridSize = Float3(
|
||||
(float)Math::DivideAndRoundUp(width, _cache.GridPixelSize),
|
||||
(float)Math::DivideAndRoundUp(height, _cache.GridPixelSize),
|
||||
(float)_cache.GridSizeZ);
|
||||
@@ -191,9 +191,9 @@ bool VolumetricFogPass::Init(RenderContext& renderContext, GPUContext* context,
|
||||
|
||||
// Init data (partial, without directional light or sky light data);
|
||||
GBufferPass::SetInputs(renderContext.View, _cache.Data.GBuffer);
|
||||
_cache.Data.GlobalAlbedo = options.Albedo.ToVector3() * options.Albedo.A;
|
||||
_cache.Data.GlobalAlbedo = options.Albedo.ToFloat3() * options.Albedo.A;
|
||||
_cache.Data.GlobalExtinctionScale = options.ExtinctionScale;
|
||||
_cache.Data.GlobalEmissive = options.Emissive.ToVector3() * options.Emissive.A;
|
||||
_cache.Data.GlobalEmissive = options.Emissive.ToFloat3() * options.Emissive.A;
|
||||
_cache.Data.GridSize = _cache.GridSize;
|
||||
_cache.Data.GridSizeIntX = (uint32)_cache.GridSize.X;
|
||||
_cache.Data.GridSizeIntY = (uint32)_cache.GridSize.Y;
|
||||
@@ -209,7 +209,7 @@ bool VolumetricFogPass::Init(RenderContext& renderContext, GPUContext* context,
|
||||
_cache.Data.SkyLight.VolumetricScatteringIntensity = 0;
|
||||
|
||||
// Fill frame jitter history
|
||||
const Vector4 defaultOffset = Vector4(0.5f, 0.5f, 0.5f, 0.0f);
|
||||
const Float4 defaultOffset(0.5f, 0.5f, 0.5f, 0.0f);
|
||||
for (int32 i = 0; i < ARRAY_COUNT(_cache.Data.FrameJitterOffsets); i++)
|
||||
{
|
||||
_cache.Data.FrameJitterOffsets[i] = defaultOffset;
|
||||
@@ -219,7 +219,7 @@ bool VolumetricFogPass::Init(RenderContext& renderContext, GPUContext* context,
|
||||
for (int32 i = 0; i < _cache.MissedHistorySamplesCount; i++)
|
||||
{
|
||||
const uint64 frameNumber = renderContext.Task->LastUsedFrame - i;
|
||||
_cache.Data.FrameJitterOffsets[i] = Vector4(
|
||||
_cache.Data.FrameJitterOffsets[i] = Float4(
|
||||
RendererUtils::TemporalHalton(frameNumber & 1023, 2),
|
||||
RendererUtils::TemporalHalton(frameNumber & 1023, 3),
|
||||
RendererUtils::TemporalHalton(frameNumber & 1023, 5),
|
||||
@@ -234,7 +234,7 @@ bool VolumetricFogPass::Init(RenderContext& renderContext, GPUContext* context,
|
||||
// Clear local lights scattering table if was used and will be probably reused later
|
||||
if (renderContext.Buffers->LocalShadowedLightScattering)
|
||||
{
|
||||
if (Vector3::NearEqual(renderContext.Buffers->LocalShadowedLightScattering->Size3(), _cache.GridSize))
|
||||
if (Float3::NearEqual(renderContext.Buffers->LocalShadowedLightScattering->Size3(), _cache.GridSize))
|
||||
{
|
||||
context->Clear(renderContext.Buffers->LocalShadowedLightScattering->ViewVolume(), Color::Transparent);
|
||||
}
|
||||
@@ -274,15 +274,16 @@ void VolumetricFogPass::RenderRadialLight(RenderContext& renderContext, GPUConte
|
||||
auto& view = renderContext.View;
|
||||
|
||||
// Calculate light volume bounds in camera frustum depth range (min and max)
|
||||
BoundingSphere bounds(light.Position, light.Radius);
|
||||
Vector3 viewSpaceLightBoundsOrigin = Vector3::Transform(bounds.Center, view.View);
|
||||
float furthestSliceIndexUnclamped = ComputeZSliceFromDepth(viewSpaceLightBoundsOrigin.Z + bounds.Radius, options, _cache.GridSizeZ);
|
||||
float closestSliceIndexUnclamped = ComputeZSliceFromDepth(viewSpaceLightBoundsOrigin.Z - bounds.Radius, options, _cache.GridSizeZ);
|
||||
const Float3 center = light.Position;
|
||||
const float radius = light.Radius;
|
||||
Float3 viewSpaceLightBoundsOrigin = Float3::Transform(center, view.View);
|
||||
float furthestSliceIndexUnclamped = ComputeZSliceFromDepth(viewSpaceLightBoundsOrigin.Z + radius, options, _cache.GridSizeZ);
|
||||
float closestSliceIndexUnclamped = ComputeZSliceFromDepth(viewSpaceLightBoundsOrigin.Z - radius, options, _cache.GridSizeZ);
|
||||
int32 volumeZBoundsMin = (int32)Math::Clamp(closestSliceIndexUnclamped, 0.0f, _cache.GridSize.Z - 1.0f);
|
||||
int32 volumeZBoundsMax = (int32)Math::Clamp(furthestSliceIndexUnclamped, 0.0f, _cache.GridSize.Z - 1.0f);
|
||||
|
||||
// Cull light
|
||||
if ((view.Position - bounds.Center).LengthSquared() >= (options.Distance + bounds.Radius) * (options.Distance + bounds.Radius) || volumeZBoundsMin >= volumeZBoundsMax)
|
||||
if ((view.Position - center).LengthSquared() >= (options.Distance + radius) * (options.Distance + radius) || volumeZBoundsMin >= volumeZBoundsMax)
|
||||
return;
|
||||
|
||||
PROFILE_GPU_CPU("Volumetric Fog Light");
|
||||
@@ -304,7 +305,7 @@ void VolumetricFogPass::RenderRadialLight(RenderContext& renderContext, GPUConte
|
||||
perLight.SliceToDepth.Y = _cache.Data.VolumetricFogMaxDistance;
|
||||
perLight.MinZ = volumeZBoundsMin;
|
||||
perLight.LocalLightScatteringIntensity = light.VolumetricScatteringIntensity;
|
||||
perLight.ViewSpaceBoundingSphere = Vector4(viewSpaceLightBoundsOrigin, bounds.Radius);
|
||||
perLight.ViewSpaceBoundingSphere = Float4(viewSpaceLightBoundsOrigin, radius);
|
||||
Matrix::Transpose(view.Projection, perLight.ViewToVolumeClip);
|
||||
light.SetupLightData(&perLight.LocalLight, true);
|
||||
perLight.LocalLightShadow = shadow;
|
||||
@@ -343,13 +344,15 @@ void VolumetricFogPass::RenderRadialLight(RenderContext& renderContext, GPUConte
|
||||
template<typename T>
|
||||
void VolumetricFogPass::RenderRadialLight(RenderContext& renderContext, GPUContext* context, RenderView& view, VolumetricFogOptions& options, T& light, PerLight& perLight, GPUConstantBuffer* cb1)
|
||||
{
|
||||
const BoundingSphere bounds(light.Position, light.Radius);
|
||||
const Float3 center = light.Position;
|
||||
const float radius = light.Radius;
|
||||
ASSERT(!center.IsNanOrInfinity() && !isnan(radius) && !isinf(radius));
|
||||
auto& cache = _cache;
|
||||
|
||||
// Calculate light volume bounds in camera frustum depth range (min and max)
|
||||
const Vector3 viewSpaceLightBoundsOrigin = Vector3::Transform(bounds.Center, view.View);
|
||||
const float furthestSliceIndexUnclamped = ComputeZSliceFromDepth(viewSpaceLightBoundsOrigin.Z + bounds.Radius, options, cache.GridSizeZ);
|
||||
const float closestSliceIndexUnclamped = ComputeZSliceFromDepth(viewSpaceLightBoundsOrigin.Z - bounds.Radius, options, cache.GridSizeZ);
|
||||
const Float3 viewSpaceLightBoundsOrigin = Float3::Transform(center, view.View);
|
||||
const float furthestSliceIndexUnclamped = ComputeZSliceFromDepth(viewSpaceLightBoundsOrigin.Z + radius, options, cache.GridSizeZ);
|
||||
const float closestSliceIndexUnclamped = ComputeZSliceFromDepth(viewSpaceLightBoundsOrigin.Z - radius, options, cache.GridSizeZ);
|
||||
const int32 volumeZBoundsMin = (int32)Math::Clamp(closestSliceIndexUnclamped, 0.0f, cache.GridSize.Z - 1.0f);
|
||||
const int32 volumeZBoundsMax = (int32)Math::Clamp(furthestSliceIndexUnclamped, 0.0f, cache.GridSize.Z - 1.0f);
|
||||
|
||||
@@ -363,7 +366,7 @@ void VolumetricFogPass::RenderRadialLight(RenderContext& renderContext, GPUConte
|
||||
perLight.SliceToDepth.Y = cache.Data.VolumetricFogMaxDistance;
|
||||
perLight.MinZ = volumeZBoundsMin;
|
||||
perLight.LocalLightScatteringIntensity = light.VolumetricScatteringIntensity;
|
||||
perLight.ViewSpaceBoundingSphere = Vector4(viewSpaceLightBoundsOrigin, bounds.Radius);
|
||||
perLight.ViewSpaceBoundingSphere = Float4(viewSpaceLightBoundsOrigin, radius);
|
||||
Matrix::Transpose(renderContext.View.Projection, perLight.ViewToVolumeClip);
|
||||
light.SetupLightData(&perLight.LocalLight, withShadow);
|
||||
|
||||
@@ -480,7 +483,7 @@ void VolumetricFogPass::Render(RenderContext& renderContext)
|
||||
const bool temporalHistoryIsValid = cache.TemporalReprojection
|
||||
&& renderContext.Buffers->VolumetricFogHistory
|
||||
&& !renderContext.Task->IsCameraCut
|
||||
&& Vector3::NearEqual(renderContext.Buffers->VolumetricFogHistory->Size3(), cache.GridSize);
|
||||
&& Float3::NearEqual(renderContext.Buffers->VolumetricFogHistory->Size3(), cache.GridSize);
|
||||
|
||||
// Allocate buffers
|
||||
const GPUTextureDescription volumeDesc = GPUTextureDescription::New3D(cache.GridSize, PixelFormat::R16G16B16A16_Float, GPUTextureFlags::RenderTarget | GPUTextureFlags::ShaderResource | GPUTextureFlags::UnorderedAccess);
|
||||
@@ -530,18 +533,19 @@ void VolumetricFogPass::Render(RenderContext& renderContext)
|
||||
|
||||
for (auto& drawCall : renderContext.List->VolumetricFogParticles)
|
||||
{
|
||||
const BoundingSphere bounds(drawCall.Particle.VolumetricFog.Position, drawCall.Particle.VolumetricFog.Radius);
|
||||
ASSERT(!bounds.Center.IsNanOrInfinity() && !isnan(bounds.Radius) && !isinf(bounds.Radius));
|
||||
const Float3 center = drawCall.Particle.VolumetricFog.Position;
|
||||
const float radius = drawCall.Particle.VolumetricFog.Radius;
|
||||
ASSERT(!center.IsNanOrInfinity() && !isnan(radius) && !isinf(radius));
|
||||
|
||||
// Calculate light volume bounds in camera frustum depth range (min and max)
|
||||
const Vector3 viewSpaceLightBoundsOrigin = Vector3::Transform(bounds.Center, view.View);
|
||||
const float furthestSliceIndexUnclamped = ComputeZSliceFromDepth(viewSpaceLightBoundsOrigin.Z + bounds.Radius, options, cache.GridSizeZ);
|
||||
const float closestSliceIndexUnclamped = ComputeZSliceFromDepth(viewSpaceLightBoundsOrigin.Z - bounds.Radius, options, cache.GridSizeZ);
|
||||
const Float3 viewSpaceLightBoundsOrigin = Float3::Transform(center, view.View);
|
||||
const float furthestSliceIndexUnclamped = ComputeZSliceFromDepth(viewSpaceLightBoundsOrigin.Z + radius, options, cache.GridSizeZ);
|
||||
const float closestSliceIndexUnclamped = ComputeZSliceFromDepth(viewSpaceLightBoundsOrigin.Z - radius, options, cache.GridSizeZ);
|
||||
const int32 volumeZBoundsMin = (int32)Math::Clamp(closestSliceIndexUnclamped, 0.0f, cache.GridSize.Z - 1.0f);
|
||||
const int32 volumeZBoundsMax = (int32)Math::Clamp(furthestSliceIndexUnclamped, 0.0f, cache.GridSize.Z - 1.0f);
|
||||
|
||||
// Culling
|
||||
if ((view.Position - bounds.Center).LengthSquared() >= (options.Distance + bounds.Radius) * (options.Distance + bounds.Radius) || volumeZBoundsMin >= volumeZBoundsMax)
|
||||
if ((view.Position - center).LengthSquared() >= (options.Distance + radius) * (options.Distance + radius) || volumeZBoundsMin >= volumeZBoundsMax)
|
||||
continue;
|
||||
|
||||
// Setup material shader data
|
||||
@@ -555,7 +559,7 @@ void VolumetricFogPass::Render(RenderContext& renderContext)
|
||||
perLight.SliceToDepth.X = cache.Data.GridSize.Z;
|
||||
perLight.SliceToDepth.Y = cache.Data.VolumetricFogMaxDistance;
|
||||
perLight.MinZ = volumeZBoundsMin;
|
||||
perLight.ViewSpaceBoundingSphere = Vector4(viewSpaceLightBoundsOrigin, bounds.Radius);
|
||||
perLight.ViewSpaceBoundingSphere = Float4(viewSpaceLightBoundsOrigin, radius);
|
||||
Matrix::Transpose(renderContext.View.Projection, perLight.ViewToVolumeClip);
|
||||
|
||||
// Upload data
|
||||
@@ -672,7 +676,7 @@ void VolumetricFogPass::Render(RenderContext& renderContext)
|
||||
|
||||
// Get buffer for the integrated light scattering (try to reuse the previous frame if it's valid)
|
||||
GPUTexture* integratedLightScattering = renderContext.Buffers->VolumetricFog;
|
||||
if (integratedLightScattering == nullptr || !Vector3::NearEqual(integratedLightScattering->Size3(), cache.GridSize))
|
||||
if (integratedLightScattering == nullptr || !Float3::NearEqual(integratedLightScattering->Size3(), cache.GridSize))
|
||||
{
|
||||
if (integratedLightScattering)
|
||||
{
|
||||
@@ -710,14 +714,14 @@ void VolumetricFogPass::InitCircleBuffer()
|
||||
const int32 triangles = vertices - 2;
|
||||
const int32 rings = vertices;
|
||||
const float radiansPerRingSegment = PI / (float)rings;
|
||||
Vector2 vbData[vertices];
|
||||
Float2 vbData[vertices];
|
||||
uint16 ibData[triangles * 3];
|
||||
|
||||
const float radiusScale = 1.0f / Math::Cos(radiansPerRingSegment);
|
||||
for (int32 vertexIndex = 0; vertexIndex < vertices; vertexIndex++)
|
||||
{
|
||||
const float angle = vertexIndex / static_cast<float>(vertices - 1) * 2 * PI;
|
||||
vbData[vertexIndex] = Vector2(radiusScale * Math::Cos(angle) * 0.5f + 0.5f, radiusScale * Math::Sin(angle) * 0.5f + 0.5f);
|
||||
vbData[vertexIndex] = Float2(radiusScale * Math::Cos(angle) * 0.5f + 0.5f, radiusScale * Math::Sin(angle) * 0.5f + 0.5f);
|
||||
}
|
||||
int32 ibIndex = 0;
|
||||
for (int32 triangleIndex = 0; triangleIndex < triangles; triangleIndex++)
|
||||
@@ -732,7 +736,7 @@ void VolumetricFogPass::InitCircleBuffer()
|
||||
ASSERT(_vbCircleRasterize == nullptr && _ibCircleRasterize == nullptr);
|
||||
_vbCircleRasterize = GPUDevice::Instance->CreateBuffer(TEXT("VolumetricFog.CircleRasterize.VB"));
|
||||
_ibCircleRasterize = GPUDevice::Instance->CreateBuffer(TEXT("VolumetricFog.CircleRasterize.IB"));
|
||||
if (_vbCircleRasterize->Init(GPUBufferDescription::Vertex(sizeof(Vector2), vertices, vbData))
|
||||
if (_vbCircleRasterize->Init(GPUBufferDescription::Vertex(sizeof(Float2), vertices, vbData))
|
||||
|| _ibCircleRasterize->Init(GPUBufferDescription::Index(sizeof(uint16), triangles * 3, ibData)))
|
||||
{
|
||||
LOG(Fatal, "Failed to setup volumetric fog buffers.");
|
||||
|
||||
@@ -20,7 +20,7 @@ public:
|
||||
struct CustomData
|
||||
{
|
||||
GPUShader* Shader;
|
||||
Vector3 GridSize;
|
||||
Float3 GridSize;
|
||||
float VolumetricFogMaxDistance;
|
||||
int32 ParticleIndex;
|
||||
};
|
||||
@@ -28,22 +28,22 @@ public:
|
||||
private:
|
||||
|
||||
PACK_STRUCT(struct SkyLightData {
|
||||
Vector3 MultiplyColor;
|
||||
Float3 MultiplyColor;
|
||||
float VolumetricScatteringIntensity;
|
||||
Vector3 AdditiveColor;
|
||||
Float3 AdditiveColor;
|
||||
float Dummt0;
|
||||
});
|
||||
|
||||
PACK_STRUCT(struct Data {
|
||||
GBufferData GBuffer;
|
||||
|
||||
Vector3 GlobalAlbedo;
|
||||
Float3 GlobalAlbedo;
|
||||
float GlobalExtinctionScale;
|
||||
|
||||
Vector3 GlobalEmissive;
|
||||
Float3 GlobalEmissive;
|
||||
float HistoryWeight;
|
||||
|
||||
Vector3 GridSize;
|
||||
Float3 GridSize;
|
||||
uint32 MissedHistorySamplesCount;
|
||||
|
||||
uint32 GridSizeIntX;
|
||||
@@ -51,15 +51,15 @@ private:
|
||||
uint32 GridSizeIntZ;
|
||||
float PhaseG;
|
||||
|
||||
Vector2 Dummy0;
|
||||
Float2 Dummy0;
|
||||
float VolumetricFogMaxDistance;
|
||||
float InverseSquaredLightDistanceBiasScale;
|
||||
|
||||
Vector4 FogParameters;
|
||||
Float4 FogParameters;
|
||||
|
||||
Matrix PrevWorldToClip;
|
||||
|
||||
Vector4 FrameJitterOffsets[8];
|
||||
Float4 FrameJitterOffsets[8];
|
||||
|
||||
LightData DirectionalLight;
|
||||
LightShadowData DirectionalLightShadow;
|
||||
@@ -67,11 +67,11 @@ private:
|
||||
});
|
||||
|
||||
PACK_STRUCT(struct PerLight {
|
||||
Vector2 SliceToDepth;
|
||||
Float2 SliceToDepth;
|
||||
int32 MinZ;
|
||||
float LocalLightScatteringIntensity;
|
||||
|
||||
Vector4 ViewSpaceBoundingSphere;
|
||||
Float4 ViewSpaceBoundingSphere;
|
||||
Matrix ViewToVolumeClip;
|
||||
|
||||
LightData LocalLight;
|
||||
@@ -131,7 +131,7 @@ private:
|
||||
/// <summary>
|
||||
/// The calculated size of the volume texture.
|
||||
/// </summary>
|
||||
Vector3 GridSize;
|
||||
Float3 GridSize;
|
||||
|
||||
/// <summary>
|
||||
/// The cached per-frame data for the constant buffer.
|
||||
|
||||
Reference in New Issue
Block a user