Browse Source

Initial implementation of accumulation pass. It's doing... something but it's definitely not correct yet.

Changed scene luminance into a persistent RT, since that makes it easier to control mipmaps and bind specific mip levels.
mac-autoexp
Nico de Poel 3 years ago
parent
commit
13eb24289e
  1. 4
      Assets/Resources/FSR2/ffx_fsr2_accumulate_pass.compute
  2. 4
      Assets/Scripts/Fsr2Context.cs
  3. 49
      Assets/Scripts/Fsr2Pipeline.cs
  4. 48
      Assets/Scripts/Fsr2Resources.cs

4
Assets/Resources/FSR2/ffx_fsr2_accumulate_pass.compute

@ -17,4 +17,8 @@
#define FFX_FSR2_OPTION_REPROJECT_USE_LANCZOS_TYPE 1 #define FFX_FSR2_OPTION_REPROJECT_USE_LANCZOS_TYPE 1
#endif #endif
// Monkey-patch SRV names to match the UAV names from the shaders that output them
#define r_dilated_reactive_masks rw_dilated_reactive_masks
#define r_prepared_input_color rw_prepared_input_color
#include "shaders/ffx_fsr2_accumulate_pass.hlsl" #include "shaders/ffx_fsr2_accumulate_pass.hlsl"

4
Assets/Scripts/Fsr2Context.cs

@ -177,10 +177,6 @@ namespace FidelityFX
int threadGroupsY = (Screen.height + threadGroupWorkRegionDimRcas - 1) / threadGroupWorkRegionDimRcas; int threadGroupsY = (Screen.height + threadGroupWorkRegionDimRcas - 1) / threadGroupWorkRegionDimRcas;
_rcasPipeline.ScheduleDispatch(_commandBuffer, dispatchParams, frameIndex, threadGroupsX, threadGroupsY); _rcasPipeline.ScheduleDispatch(_commandBuffer, dispatchParams, frameIndex, threadGroupsX, threadGroupsY);
} }
else
{
_commandBuffer.Blit(dispatchParams.ColorDepth, dispatchParams.Output);
}
_resourceFrameIndex = (_resourceFrameIndex + 1) % MaxQueuedFrames; _resourceFrameIndex = (_resourceFrameIndex + 1) % MaxQueuedFrames;

49
Assets/Scripts/Fsr2Pipeline.cs

@ -28,6 +28,13 @@ namespace FidelityFX
protected static readonly int SrvReactiveMask = Shader.PropertyToID("r_reactive_mask"); protected static readonly int SrvReactiveMask = Shader.PropertyToID("r_reactive_mask");
protected static readonly int SrvTransparencyAndCompositionMask = Shader.PropertyToID("r_transparency_and_composition_mask"); protected static readonly int SrvTransparencyAndCompositionMask = Shader.PropertyToID("r_transparency_and_composition_mask");
protected static readonly int SrvPrevDilatedMotionVectors = Shader.PropertyToID("r_previous_dilated_motion_vectors"); protected static readonly int SrvPrevDilatedMotionVectors = Shader.PropertyToID("r_previous_dilated_motion_vectors");
protected static readonly int SrvInternalUpscaled = Shader.PropertyToID("r_internal_upscaled_color");
protected static readonly int SrvLockStatus = Shader.PropertyToID("r_lock_status");
protected static readonly int SrvLanczosLut = Shader.PropertyToID("r_lanczos_lut");
protected static readonly int SrvUpscaleMaximumBiasLut = Shader.PropertyToID("r_upsample_maximum_bias_lut");
protected static readonly int SrvSceneLuminanceMips = Shader.PropertyToID("r_imgMips");
protected static readonly int SrvAutoExposure = Shader.PropertyToID("r_auto_exposure");
protected static readonly int SrvLumaHistory = Shader.PropertyToID("r_luma_history");
protected static readonly int SrvRcasInput = Shader.PropertyToID("r_rcas_input"); protected static readonly int SrvRcasInput = Shader.PropertyToID("r_rcas_input");
// Unordered access views, i.e. random read/write bindings // Unordered access views, i.e. random read/write bindings
@ -43,6 +50,9 @@ namespace FidelityFX
protected static readonly int UavDilatedReactiveMasks = Shader.PropertyToID("rw_dilated_reactive_masks"); protected static readonly int UavDilatedReactiveMasks = Shader.PropertyToID("rw_dilated_reactive_masks");
protected static readonly int UavPreparedInputColor = Shader.PropertyToID("rw_prepared_input_color"); protected static readonly int UavPreparedInputColor = Shader.PropertyToID("rw_prepared_input_color");
protected static readonly int UavNewLocks = Shader.PropertyToID("rw_new_locks"); protected static readonly int UavNewLocks = Shader.PropertyToID("rw_new_locks");
protected static readonly int UavInternalUpscaled = Shader.PropertyToID("rw_internal_upscaled_color");
protected static readonly int UavLockStatus = Shader.PropertyToID("rw_lock_status");
protected static readonly int UavLumaHistory = Shader.PropertyToID("rw_luma_history");
// Constant buffer bindings // Constant buffer bindings
protected static readonly int CbFsr2 = Shader.PropertyToID("cbFSR2"); protected static readonly int CbFsr2 = Shader.PropertyToID("cbFSR2");
@ -77,11 +87,6 @@ namespace FidelityFX
// Resource FSR2_SpdAtomicCounter: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R32_UINT, FFX_RESOURCE_FLAGS_ALIASABLE // Resource FSR2_SpdAtomicCounter: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R32_UINT, FFX_RESOURCE_FLAGS_ALIASABLE
commandBuffer.GetTemporaryRT(UavSpdAtomicCount, 1, 1, 0, FilterMode.Point, GraphicsFormat.R32_UInt, 1, true); commandBuffer.GetTemporaryRT(UavSpdAtomicCount, 1, 1, 0, FilterMode.Point, GraphicsFormat.R32_UInt, 1, true);
// Resource FSR2_ExposureMips: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16_FLOAT, FFX_RESOURCE_FLAGS_ALIASABLE, has mipmap chain
const int lumaMip = ShadingChangeMipLevel + 1;
commandBuffer.GetTemporaryRT(UavExposureMipLumaChange, maxRenderSize.x >> lumaMip, maxRenderSize.y >> lumaMip, 0, FilterMode.Point, GraphicsFormat.R16_SFloat, 1, true);
commandBuffer.GetTemporaryRT(UavExposureMip5, maxRenderSize.x >> 6, maxRenderSize.y >> 6, 0, FilterMode.Point, GraphicsFormat.R16_SFloat, 1, true);
// FSR2_ReconstructedPrevNearestDepth: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R32_UINT, FFX_RESOURCE_FLAGS_ALIASABLE // FSR2_ReconstructedPrevNearestDepth: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R32_UINT, FFX_RESOURCE_FLAGS_ALIASABLE
commandBuffer.GetTemporaryRT(UavReconstructedPrevNearestDepth, maxRenderSize.x, maxRenderSize.y, 0, FilterMode.Point, GraphicsFormat.R32_UInt, 1, true); commandBuffer.GetTemporaryRT(UavReconstructedPrevNearestDepth, maxRenderSize.x, maxRenderSize.y, 0, FilterMode.Point, GraphicsFormat.R32_UInt, 1, true);
@ -106,8 +111,6 @@ namespace FidelityFX
{ {
// Release all of the aliasable resources used this frame // Release all of the aliasable resources used this frame
commandBuffer.ReleaseTemporaryRT(UavSpdAtomicCount); commandBuffer.ReleaseTemporaryRT(UavSpdAtomicCount);
commandBuffer.ReleaseTemporaryRT(UavExposureMipLumaChange);
commandBuffer.ReleaseTemporaryRT(UavExposureMip5);
commandBuffer.ReleaseTemporaryRT(UavReconstructedPrevNearestDepth); commandBuffer.ReleaseTemporaryRT(UavReconstructedPrevNearestDepth);
commandBuffer.ReleaseTemporaryRT(UavDilatedDepth); commandBuffer.ReleaseTemporaryRT(UavDilatedDepth);
commandBuffer.ReleaseTemporaryRT(UavLockInputLuma); commandBuffer.ReleaseTemporaryRT(UavLockInputLuma);
@ -175,7 +178,11 @@ namespace FidelityFX
// - Shouldn't we use a ComputeBuffer for resources that are one-dimensional and clearly not image data? e.g. SPD atomic counter & Lanczos LUT data // - Shouldn't we use a ComputeBuffer for resources that are one-dimensional and clearly not image data? e.g. SPD atomic counter & Lanczos LUT data
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputColor, dispatchParams.ColorDepth, 0, RenderTextureSubElement.Color); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputColor, dispatchParams.ColorDepth, 0, RenderTextureSubElement.Color);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavExposureMipLumaChange, Resources.SceneLuminance, ShadingChangeMipLevel);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavExposureMip5, Resources.SceneLuminance, 5);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavAutoExposure, Resources.AutoExposure); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavAutoExposure, Resources.AutoExposure);
commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbFsr2, Constants, 0, Marshal.SizeOf<Fsr2.Fsr2Constants>()); commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbFsr2, Constants, 0, Marshal.SizeOf<Fsr2.Fsr2Constants>());
commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbSpd, _spdConstants, 0, Marshal.SizeOf<Fsr2.SpdConstants>()); commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbSpd, _spdConstants, 0, Marshal.SizeOf<Fsr2.SpdConstants>());
@ -218,7 +225,7 @@ namespace FidelityFX
{ {
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvReactiveMask, dispatchParams.Reactive); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvReactiveMask, dispatchParams.Reactive);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvTransparencyAndCompositionMask, dispatchParams.Reactive); // Default reactive mask, as we don't support TCR (yet)
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvTransparencyAndCompositionMask, Resources.DefaultReactive); // Default reactive mask, as we don't support TCR (yet)
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvPrevDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex ^ 1]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvPrevDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex ^ 1]);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputMotionVectors, dispatchParams.MotionVectors); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputMotionVectors, dispatchParams.MotionVectors);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputColor, dispatchParams.ColorDepth, 0, RenderTextureSubElement.Color); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputColor, dispatchParams.ColorDepth, 0, RenderTextureSubElement.Color);
@ -257,7 +264,28 @@ namespace FidelityFX
public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY)
{ {
//throw new NotImplementedException();
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputExposure, dispatchParams.Exposure);
if ((ContextDescription.Flags & Fsr2.InitializationFlags.EnableDisplayResolutionMotionVectors) == 0)
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]);
else
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputMotionVectors, dispatchParams.MotionVectors);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInternalUpscaled, Resources.InternalUpscaled[frameIndex ^ 1]);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvLockStatus, Resources.LockStatus[frameIndex ^ 1]);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvLanczosLut, Resources.LanczosLut);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvUpscaleMaximumBiasLut, Resources.MaximumBiasLut);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvSceneLuminanceMips, Resources.SceneLuminance);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvAutoExposure, Resources.AutoExposure);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvLumaHistory, Resources.LumaHistory[frameIndex ^ 1]);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavInternalUpscaled, Resources.InternalUpscaled[frameIndex]);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavLockStatus, Resources.LockStatus[frameIndex]);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavUpscaledOutput, dispatchParams.Output);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavLumaHistory, Resources.LumaHistory[frameIndex]);
commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbFsr2, Constants, 0, Marshal.SizeOf<Fsr2.Fsr2Constants>());
commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, 1);
} }
} }
@ -309,9 +337,8 @@ namespace FidelityFX
public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY) public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY)
{ {
// Run the RCAS sharpening filter on the upscaled image
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputExposure, dispatchParams.Exposure); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputExposure, dispatchParams.Exposure);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvRcasInput, dispatchParams.ColorDepth, 0, RenderTextureSubElement.Color); // TODO: should be output from accumulate pass
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvRcasInput, Resources.InternalUpscaled[frameIndex]);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavUpscaledOutput, dispatchParams.Output); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavUpscaledOutput, dispatchParams.Output);
commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbFsr2, Constants, 0, Marshal.SizeOf<Fsr2.Fsr2Constants>()); commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbFsr2, Constants, 0, Marshal.SizeOf<Fsr2.Fsr2Constants>());
commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbRcas, _rcasConstants, 0, Marshal.SizeOf<Fsr2.RcasConstants>()); commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbRcas, _rcasConstants, 0, Marshal.SizeOf<Fsr2.RcasConstants>());

48
Assets/Scripts/Fsr2Resources.cs

@ -1,4 +1,5 @@
using UnityEngine;
using System;
using UnityEngine;
using UnityEngine.Experimental.Rendering; using UnityEngine.Experimental.Rendering;
namespace FidelityFX namespace FidelityFX
@ -8,7 +9,9 @@ namespace FidelityFX
public Texture2D DefaultExposure; public Texture2D DefaultExposure;
public Texture2D DefaultReactive; public Texture2D DefaultReactive;
public Texture2D LanczosLut; public Texture2D LanczosLut;
public Texture2D MaximumBiasLut;
public RenderTexture AutoExposure; public RenderTexture AutoExposure;
public RenderTexture SceneLuminance;
public readonly RenderTexture[] DilatedMotionVectors = new RenderTexture[2]; public readonly RenderTexture[] DilatedMotionVectors = new RenderTexture[2];
public readonly RenderTexture[] LockStatus = new RenderTexture[2]; public readonly RenderTexture[] LockStatus = new RenderTexture[2];
public readonly RenderTexture[] InternalUpscaled = new RenderTexture[2]; public readonly RenderTexture[] InternalUpscaled = new RenderTexture[2];
@ -26,6 +29,12 @@ namespace FidelityFX
lanczos2Weights[currentLanczosWidthIndex] = y; lanczos2Weights[currentLanczosWidthIndex] = y;
} }
float[] maximumBias = new float[MaximumBiasTextureWidth * MaximumBiasTextureHeight];
for (int i = 0; i < maximumBias.Length; ++i)
{
maximumBias[i] = MaximumBias[i] / 2.0f;
}
// TODO: create resources, i.e. render textures used for intermediate results. // TODO: create resources, i.e. render textures used for intermediate results.
// Note that "aliasable" resources should be equivalent to GetTemporary render textures // Note that "aliasable" resources should be equivalent to GetTemporary render textures
// UAVs *may* be an issue with the PS4 not handling simultaneous reading and writing to an RT properly // UAVs *may* be an issue with the PS4 not handling simultaneous reading and writing to an RT properly
@ -38,6 +47,11 @@ namespace FidelityFX
LanczosLut.SetPixelData(lanczos2Weights, 0); LanczosLut.SetPixelData(lanczos2Weights, 0);
LanczosLut.Apply(); LanczosLut.Apply();
// Resource FSR2_MaximumUpsampleBias: FFX_RESOURCE_USAGE_READ_ONLY, FFX_SURFACE_FORMAT_R16_SNORM, FFX_RESOURCE_FLAGS_NONE
MaximumBiasLut = new Texture2D(MaximumBiasTextureWidth, MaximumBiasTextureHeight, GraphicsFormat.R16_SFloat, TextureCreationFlags.None) { name = "FSR2_MaximumUpsampleBias" };
MaximumBiasLut.SetPixelData(maximumBias, 0);
MaximumBiasLut.Apply();
// Resource FSR2_DefaultExposure: FFX_RESOURCE_USAGE_READ_ONLY, FFX_SURFACE_FORMAT_R32G32_FLOAT, FFX_RESOURCE_FLAGS_NONE // Resource FSR2_DefaultExposure: FFX_RESOURCE_USAGE_READ_ONLY, FFX_SURFACE_FORMAT_R32G32_FLOAT, FFX_RESOURCE_FLAGS_NONE
DefaultExposure = new Texture2D(1, 1, GraphicsFormat.R32G32_SFloat, TextureCreationFlags.None) { name = "FSR2_DefaultExposure" }; DefaultExposure = new Texture2D(1, 1, GraphicsFormat.R32G32_SFloat, TextureCreationFlags.None) { name = "FSR2_DefaultExposure" };
DefaultExposure.SetPixel(0, 0, Color.black); DefaultExposure.SetPixel(0, 0, Color.black);
@ -52,6 +66,13 @@ namespace FidelityFX
AutoExposure = new RenderTexture(1, 1, 1, GraphicsFormat.R32G32_SFloat) { name = "FSR2_AutoExposure", enableRandomWrite = true }; AutoExposure = new RenderTexture(1, 1, 1, GraphicsFormat.R32G32_SFloat) { name = "FSR2_AutoExposure", enableRandomWrite = true };
AutoExposure.Create(); AutoExposure.Create();
// Resource FSR2_ExposureMips: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16_FLOAT, FFX_RESOURCE_FLAGS_ALIASABLE
// This is a rather special case: it's an aliasable resource, but because we require a mipmap chain and bind specific mip levels per shader, we can't easily use temporary RTs for this.
int w = contextDescription.MaxRenderSize.x / 2, h = contextDescription.MaxRenderSize.y / 2;
int mipCount = 1 + Mathf.FloorToInt(Mathf.Log(Math.Max(w, h), 2.0f));
SceneLuminance = new RenderTexture(w, h, 0, GraphicsFormat.R16_SFloat, mipCount) { name = "FSR2_ExposureMips", enableRandomWrite = true, useMipMap = true, autoGenerateMips = false };
SceneLuminance.Create();
// Resources FSR2_InternalDilatedVelocity1/2: FFX_RESOURCE_USAGE_RENDERTARGET | FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16G16_FLOAT, FFX_RESOURCE_FLAGS_NONE // Resources FSR2_InternalDilatedVelocity1/2: FFX_RESOURCE_USAGE_RENDERTARGET | FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16G16_FLOAT, FFX_RESOURCE_FLAGS_NONE
CreateDoubleBufferedResource(DilatedMotionVectors, "FSR2_InternalDilatedVelocity", contextDescription.MaxRenderSize, GraphicsFormat.R16G16_SFloat); CreateDoubleBufferedResource(DilatedMotionVectors, "FSR2_InternalDilatedVelocity", contextDescription.MaxRenderSize, GraphicsFormat.R16G16_SFloat);
@ -80,6 +101,7 @@ namespace FidelityFX
DestroyResource(InternalUpscaled); DestroyResource(InternalUpscaled);
DestroyResource(LockStatus); DestroyResource(LockStatus);
DestroyResource(DilatedMotionVectors); DestroyResource(DilatedMotionVectors);
DestroyResource(ref SceneLuminance);
DestroyResource(ref AutoExposure); DestroyResource(ref AutoExposure);
DestroyResource(ref DefaultReactive); DestroyResource(ref DefaultReactive);
DestroyResource(ref DefaultExposure); DestroyResource(ref DefaultExposure);
@ -90,7 +112,7 @@ namespace FidelityFX
if (resource == null) if (resource == null)
return; return;
Object.Destroy(resource);
UnityEngine.Object.Destroy(resource);
resource = null; resource = null;
} }
@ -108,5 +130,27 @@ namespace FidelityFX
for (int i = 0; i < resource.Length; ++i) for (int i = 0; i < resource.Length; ++i)
DestroyResource(ref resource[i]); DestroyResource(ref resource[i]);
} }
private const int MaximumBiasTextureWidth = 16;
private const int MaximumBiasTextureHeight = 16;
private static readonly float[] MaximumBias =
{
2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.876f, 1.809f, 1.772f, 1.753f, 1.748f,
2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.869f, 1.801f, 1.764f, 1.745f, 1.739f,
2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.976f, 1.841f, 1.774f, 1.737f, 1.716f, 1.71f,
2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.914f, 1.784f, 1.716f, 1.673f, 1.649f, 1.641f,
2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.793f, 1.676f, 1.604f, 1.562f, 1.54f, 1.533f,
2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.802f, 1.619f, 1.536f, 1.492f, 1.467f, 1.454f, 1.449f,
2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.812f, 1.575f, 1.496f, 1.456f, 1.432f, 1.416f, 1.408f, 1.405f,
2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.555f, 1.479f, 1.438f, 1.413f, 1.398f, 1.387f, 1.381f, 1.379f,
2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.812f, 1.555f, 1.474f, 1.43f, 1.404f, 1.387f, 1.376f, 1.368f, 1.363f, 1.362f,
2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.802f, 1.575f, 1.479f, 1.43f, 1.401f, 1.382f, 1.369f, 1.36f, 1.354f, 1.351f, 1.35f,
2.0f, 2.0f, 1.976f, 1.914f, 1.793f, 1.619f, 1.496f, 1.438f, 1.404f, 1.382f, 1.367f, 1.357f, 1.349f, 1.344f, 1.341f, 1.34f,
1.876f, 1.869f, 1.841f, 1.784f, 1.676f, 1.536f, 1.456f, 1.413f, 1.387f, 1.369f, 1.357f, 1.347f, 1.341f, 1.336f, 1.333f, 1.332f,
1.809f, 1.801f, 1.774f, 1.716f, 1.604f, 1.492f, 1.432f, 1.398f, 1.376f, 1.36f, 1.349f, 1.341f, 1.335f, 1.33f, 1.328f, 1.327f,
1.772f, 1.764f, 1.737f, 1.673f, 1.562f, 1.467f, 1.416f, 1.387f, 1.368f, 1.354f, 1.344f, 1.336f, 1.33f, 1.326f, 1.323f, 1.323f,
1.753f, 1.745f, 1.716f, 1.649f, 1.54f, 1.454f, 1.408f, 1.381f, 1.363f, 1.351f, 1.341f, 1.333f, 1.328f, 1.323f, 1.321f, 1.32f,
1.748f, 1.739f, 1.71f, 1.641f, 1.533f, 1.449f, 1.405f, 1.379f, 1.362f, 1.35f, 1.34f, 1.332f, 1.327f, 1.323f, 1.32f, 1.319f,
};
} }
} }
Loading…
Cancel
Save