// FRenderResource interface.
	virtual void InitRHI() override
	{
		uint32 TextureStride = sizeof(FVector2D);
		EPixelFormat TextureFormat = PF_G32R32F;

		if (Use16bitTexCoord)
		{
			TextureStride = sizeof(FVector2DHalf);
			TextureFormat = PF_G16R16F;
		}

		if (!buffersAllocated)
		{
			PositionBuffer.VertexBufferRHI = AllocVertexBuffer(sizeof(FVector), Vertices.Num());
			TangentBuffer.VertexBufferRHI = AllocVertexBuffer(sizeof(FPackedNormal), 2 * Vertices.Num());
			TexCoordBuffer.VertexBufferRHI = AllocVertexBuffer(TextureStride, NumTexCoords * Vertices.Num());
			ColorBuffer.VertexBufferRHI = AllocVertexBuffer(sizeof(FColor), Vertices.Num());

			TangentBufferSRV = RHICreateShaderResourceView(TangentBuffer.VertexBufferRHI, 4, PF_R8G8B8A8);
			TexCoordBufferSRV = RHICreateShaderResourceView(TexCoordBuffer.VertexBufferRHI, TextureStride, TextureFormat);
			ColorBufferSRV = RHICreateShaderResourceView(ColorBuffer.VertexBufferRHI, 4, PF_R8G8B8A8);
			PositionBufferSRV = RHICreateShaderResourceView(PositionBuffer.VertexBufferRHI, sizeof(float), PF_R32_FLOAT);
			buffersAllocated = true;
		}

		void* TexCoordBufferData = RHILockVertexBuffer(TexCoordBuffer.VertexBufferRHI, 0, NumTexCoords * TextureStride * Vertices.Num(), RLM_WriteOnly);
		FVector2D* TexCoordBufferData32 = !Use16bitTexCoord ? static_cast<FVector2D*>(TexCoordBufferData) : nullptr;
		FVector2DHalf* TexCoordBufferData16 = Use16bitTexCoord ? static_cast<FVector2DHalf*>(TexCoordBufferData) : nullptr;

		// Copy the vertex data into the vertex buffers.
		FVector* PositionBufferData = static_cast<FVector*>(RHILockVertexBuffer(PositionBuffer.VertexBufferRHI, 0, sizeof(FVector) * Vertices.Num(), RLM_WriteOnly));
		FPackedNormal* TangentBufferData = static_cast<FPackedNormal*>(RHILockVertexBuffer(TangentBuffer.VertexBufferRHI, 0, 2 * sizeof(FPackedNormal) * Vertices.Num(), RLM_WriteOnly));
		FColor* ColorBufferData = static_cast<FColor*>(RHILockVertexBuffer(ColorBuffer.VertexBufferRHI, 0, sizeof(FColor) * Vertices.Num(), RLM_WriteOnly));

		for (int32 i = 0; i < Vertices.Num(); i++)
		{
			PositionBufferData[i] = Vertices[i].Position;
			TangentBufferData[2 * i + 0] = Vertices[i].TangentX;
			TangentBufferData[2 * i + 1] = Vertices[i].TangentZ;
			ColorBufferData[i] = Vertices[i].Color;

			for (uint32 j = 0; j < NumTexCoords; j++)
			{
				if (Use16bitTexCoord)
				{
					TexCoordBufferData16[NumTexCoords * i + j] = FVector2DHalf(Vertices[i].TextureCoordinate[j]);
				}
				else
				{
					TexCoordBufferData32[NumTexCoords * i + j] = Vertices[i].TextureCoordinate[j];
				}
			}
		}

		RHIUnlockVertexBuffer(PositionBuffer.VertexBufferRHI);
		RHIUnlockVertexBuffer(TangentBuffer.VertexBufferRHI);
		RHIUnlockVertexBuffer(TexCoordBuffer.VertexBufferRHI);
		RHIUnlockVertexBuffer(ColorBuffer.VertexBufferRHI);
	}
void RadixCreatePlan(FRadixPlan512* Plan, uint32 Slices)
{
	Plan->Slices = Slices;

	// Create 6 param sets for 512x512 transform
	const uint32 thread_count = Plan->Slices * (512 * 512) / 8;
	uint32 ostride = 512 * 512 / 8;
	uint32 istride = ostride;
	uint32 pstride = 512;
	double phase_base = -TWO_PI / (512.0 * 512.0);

	RadixSetPerFrameParams(Plan, 0, thread_count, ostride, istride, pstride, (float)phase_base);

	for (int i = 1; i < FFT_PARAM_SETS; i++)
	{
		istride /= 8;
		phase_base *= 8.0;

		if (i == 3)
		{
			ostride /= 512;
			pstride = 1;
		}

		RadixSetPerFrameParams(Plan, i, thread_count, ostride, istride, pstride, (float)phase_base);
	}
	
	// Temp buffers
	uint32 BytesPerElement = sizeof(float) * 2;
	uint32 NumElements = (512 * Plan->Slices) * 512; 
	Plan->pBuffer_Tmp = RHICreateStructuredBuffer(BytesPerElement, BytesPerElement * NumElements, NULL, (BUF_UnorderedAccess | BUF_ShaderResource));
	Plan->pUAV_Tmp = RHICreateUnorderedAccessView(Plan->pBuffer_Tmp, false, false);
	Plan->pSRV_Tmp = RHICreateShaderResourceView(Plan->pBuffer_Tmp);
}
void UVaOceanSimulatorComponent::CreateBufferAndUAV(FResourceArrayInterface* Data, uint32 byte_width, uint32 byte_stride,
	FStructuredBufferRHIRef* ppBuffer, FUnorderedAccessViewRHIRef* ppUAV, FShaderResourceViewRHIRef* ppSRV)
{
	*ppBuffer = RHICreateStructuredBuffer(byte_stride, Data->GetResourceDataSize(), Data, (BUF_UnorderedAccess | BUF_ShaderResource));
	*ppUAV = RHICreateUnorderedAccessView(*ppBuffer, false, false);
	*ppSRV = RHICreateShaderResourceView(*ppBuffer);
}
/*-----------------------------------------------------------------------------
 FBoneBufferPoolPolicy
 -----------------------------------------------------------------------------*/
FBoneBufferTypeRef FBoneBufferPoolPolicy::CreateResource(CreationArguments Args)
{
	uint32 BufferSize = GetPoolBucketSize(GetPoolBucketIndex(Args));
	FBoneBuffer Buffer;
	FRHIResourceCreateInfo CreateInfo;
	Buffer.VertexBufferRHI = RHICreateVertexBuffer( BufferSize, (BUF_Dynamic | BUF_ShaderResource), CreateInfo );
	Buffer.VertexBufferSRV = RHICreateShaderResourceView( Buffer.VertexBufferRHI, sizeof(FVector4), PF_A32B32G32R32F );
	return Buffer;
}
	/**
	 * Initialize the RHI for this rendering resource
	 */
	virtual void InitRHI() override
	{
		// create a static vertex buffer
		FRHIResourceCreateInfo CreateInfo;
		void* BufferData = nullptr;
		VertexBufferRHI = RHICreateAndLockVertexBuffer(sizeof(FVector2D) * 4, BUF_Static | BUF_ShaderResource, CreateInfo, BufferData);
		FMemory::Memzero(BufferData, sizeof(FVector2D) * 4);
		RHIUnlockVertexBuffer(VertexBufferRHI);
		
		VertexBufferSRV = RHICreateShaderResourceView(VertexBufferRHI, sizeof(FVector2D), PF_G32R32F);
	}
void FUniformMeshBuffers::Initialize()
{
	if (MaxElements > 0)
	{
		const int32 VertexStride = ComputeUniformVertexStride();
		FRHIResourceCreateInfo CreateInfo;
		TriangleData = RHICreateVertexBuffer(MaxElements * VertexStride * GPixelFormats[PF_R32_FLOAT].BlockBytes, BUF_ShaderResource | BUF_StreamOutput, CreateInfo);
		TriangleDataSRV = RHICreateShaderResourceView(TriangleData, GPixelFormats[PF_R32_FLOAT].BlockBytes, PF_R32_FLOAT);

		TriangleAreas.Initialize(sizeof(float), MaxElements, PF_R32_FLOAT);
		TriangleCDFs.Initialize(sizeof(float), MaxElements, PF_R32_FLOAT);
	}
}
/**
 * Creates a scratch vertex buffer available for dynamic draw calls.
 */
void FParticleScratchVertexBuffer::InitRHI()
{
	// Create a scratch vertex buffer for injecting particles and rendering tiles.
	uint32 Flags = BUF_Volatile;
	if (GRHIFeatureLevel >= ERHIFeatureLevel::SM4)
	{
		Flags |= BUF_ShaderResource;
	}
	VertexBufferRHI = RHICreateVertexBuffer(GParticleScratchVertexBufferSize, NULL, Flags);
	if (GRHIFeatureLevel >= ERHIFeatureLevel::SM4)
	{
		VertexBufferSRV_G32R32F = RHICreateShaderResourceView( VertexBufferRHI, /*Stride=*/ sizeof(FVector2D), PF_G32R32F );
	}
}
/**
 * Creates a scratch vertex buffer available for dynamic draw calls.
 */
void FParticleScratchVertexBuffer::InitRHI()
{
    // Create a scratch vertex buffer for injecting particles and rendering tiles.
    uint32 Flags = BUF_Volatile;
    if (GSupportsResourceView)
    {
        Flags |= BUF_ShaderResource;
    }
    FRHIResourceCreateInfo CreateInfo;
    VertexBufferRHI = RHICreateVertexBuffer(GParticleScratchVertexBufferSize, Flags, CreateInfo);
    if (GSupportsResourceView)
    {
        VertexBufferSRV_G32R32F = RHICreateShaderResourceView( VertexBufferRHI, /*Stride=*/ sizeof(FVector2D), PF_G32R32F );
    }
}
FFluidSimulationShaderInstance::FFluidSimulationShaderInstance(int32 SizeX, int32 SizeY, int32 SizeZ, ERHIFeatureLevel::Type ShaderFeatureLevel)
{
	FeatureLevel = ShaderFeatureLevel;

	ConstantParameters = FFluidSimulationShaderConstantParameters();
	VariableParameters = FFluidSimulationShaderVariableParameters();

	bIsShaderExecuting = false;
	bIsUnloading = false;
	
	FRHIResourceCreateInfo CreateInfo;
	
	PressureIn = RHICreateTexture3D(SizeX, SizeY, SizeZ, PF_R32_UINT, 1, TexCreate_ShaderResource | TexCreate_UAV, CreateInfo);
	PressureOut = RHICreateTexture3D(SizeX, SizeY, SizeZ, PF_R32_UINT, 1, TexCreate_ShaderResource | TexCreate_UAV, CreateInfo);
	Divergence = RHICreateTexture3D(SizeX, SizeY, SizeZ, PF_R32_UINT, 1, TexCreate_ShaderResource | TexCreate_UAV, CreateInfo);
	VelocityIn = RHICreateTexture3D(SizeX, SizeY, SizeZ, PF_A32B32G32R32F, 1, TexCreate_ShaderResource | TexCreate_UAV, CreateInfo);
	VelocityOut = RHICreateTexture3D(SizeX, SizeY, SizeZ, PF_A32B32G32R32F, 1, TexCreate_ShaderResource | TexCreate_UAV, CreateInfo);
	DensityIn = RHICreateTexture3D(SizeX, SizeY, SizeZ, PF_A32B32G32R32F, 1, TexCreate_ShaderResource | TexCreate_UAV, CreateInfo);
	DensityOut = RHICreateTexture3D(SizeX, SizeY, SizeZ, PF_A32B32G32R32F, 1, TexCreate_ShaderResource | TexCreate_UAV, CreateInfo);
	TemperatureIn = RHICreateTexture3D(SizeX, SizeY, SizeZ, PF_R32_UINT, 1, TexCreate_ShaderResource | TexCreate_UAV, CreateInfo);
	TemperatureOut = RHICreateTexture3D(SizeX, SizeY, SizeZ, PF_R32_UINT, 1, TexCreate_ShaderResource | TexCreate_UAV, CreateInfo);
	Obstacle = RHICreateTexture3D(SizeX, SizeY, SizeZ, PF_R32_UINT, 1, TexCreate_ShaderResource | TexCreate_UAV, CreateInfo);
	VorticityIn = RHICreateTexture3D(SizeX, SizeY, SizeZ, PF_A32B32G32R32F, 1, TexCreate_ShaderResource | TexCreate_UAV, CreateInfo);
	VorticityOut = RHICreateTexture3D(SizeX, SizeY, SizeZ, PF_A32B32G32R32F, 1, TexCreate_ShaderResource | TexCreate_UAV, CreateInfo);

	PressureInUAV = RHICreateUnorderedAccessView(PressureIn);
	PressureOutUAV = RHICreateUnorderedAccessView(PressureOut);
	DivergenceUAV = RHICreateUnorderedAccessView(Divergence);
	VelocityInUAV = RHICreateUnorderedAccessView(VelocityIn);
	VelocityOutUAV = RHICreateUnorderedAccessView(VelocityOut);
	DensityInUAV = RHICreateUnorderedAccessView(DensityIn);
	DensityOutUAV = RHICreateUnorderedAccessView(DensityOut);
	TemperatureInUAV = RHICreateUnorderedAccessView(TemperatureIn);
	TemperatureOutUAV = RHICreateUnorderedAccessView(TemperatureOut);
	ObstacleUAV = RHICreateUnorderedAccessView(Obstacle);
	VorticityInUAV = RHICreateUnorderedAccessView(VorticityIn);
	VorticityOutUAV = RHICreateUnorderedAccessView(VorticityOut);

	PressureInSRV = RHICreateShaderResourceView(PressureIn, 0);
	PressureOutSRV = RHICreateShaderResourceView(PressureOut, 0);
	DivergenceSRV = RHICreateShaderResourceView(Divergence, 0);
	VelocityInSRV = RHICreateShaderResourceView(VelocityIn, 0);
	VelocityOutSRV = RHICreateShaderResourceView(VelocityOut, 0);
	DensityInSRV = RHICreateShaderResourceView(DensityIn, 0);
	DensityOutSRV = RHICreateShaderResourceView(DensityOut, 0);
	TemperatureInSRV = RHICreateShaderResourceView(TemperatureIn, 0);
	TemperatureOutSRV = RHICreateShaderResourceView(TemperatureOut, 0);
	ObstacleSRV = RHICreateShaderResourceView(Obstacle, 0);
	VorticityInSRV = RHICreateShaderResourceView(VorticityIn, 0);
	VorticityOutSRV = RHICreateShaderResourceView(VorticityOut, 0);

	GEngine->FluidSimDensitySRV = RHICreateShaderResourceView(DensityIn, 0);

	// Set up walls of simulation
	ExecuteObstaclesShader();
}
void FVisualizeTexture::GenerateContent(const FSceneRenderTargetItem& RenderTargetItem, const FPooledRenderTargetDesc& Desc)
{
	// otherwise StartFrame() wasn't called
	check(ViewRect != FIntRect(0, 0, 0, 0))

	FTexture2DRHIRef VisTexture = (FTexture2DRHIRef&)RenderTargetItem.ShaderResourceTexture;

	if(!IsValidRef(VisTexture) || !Desc.IsValid())
	{
		// todo: improve
		return;
	}

	FIntRect VisualizeTextureRect = ComputeVisualizeTextureRect(Desc.Extent);

	FIntPoint Size = VisualizeTextureRect.Size();

	// clamp to reasonable value to prevent crash
	Size.X = FMath::Max(Size.X, 1);
	Size.Y = FMath::Max(Size.Y, 1);

	FPooledRenderTargetDesc OutputDesc(FPooledRenderTargetDesc::Create2DDesc(Size, PF_B8G8R8A8, TexCreate_None, TexCreate_RenderTargetable | TexCreate_ShaderResource, false));
	
	GRenderTargetPool.FindFreeElement(OutputDesc, VisualizeTextureContent, TEXT("VisualizeTexture"));

	if(!VisualizeTextureContent)
	{
		return;
	}

	const FSceneRenderTargetItem& DestRenderTarget = VisualizeTextureContent->GetRenderTargetItem();

	RHISetRenderTarget(DestRenderTarget.TargetableTexture, FTextureRHIRef());	
	RHIClear(true, FLinearColor(1,1,0,1), false, 0.0f, false, 0, FIntRect());
	RHISetBlendState(TStaticBlendState<>::GetRHI());
	RHISetRasterizerState(TStaticRasterizerState<>::GetRHI());
	RHISetDepthStencilState(TStaticDepthStencilState<false,CF_Always>::GetRHI());

	FIntPoint RTExtent = GSceneRenderTargets.GetBufferSizeXY();

	FVector2D Tex00 = FVector2D(0, 0);
	FVector2D Tex11 = FVector2D(1, 1);

	uint32 LocalVisualizeTextureInputMapping = UVInputMapping;

	if(!Desc.Is2DTexture())
	{
		LocalVisualizeTextureInputMapping = 1;
	}

	// set UV
	switch(LocalVisualizeTextureInputMapping)
	{
		// UV in left top
		case 0:
			Tex11 = FVector2D((float)ViewRect.Width() / RTExtent.X, (float)ViewRect.Height() / RTExtent.Y);
			break;

		// whole texture
		default:
			break;
	}

	bool bIsDefault = StencilSRVSrc == GBlackTexture->TextureRHI;
	bool bDepthStencil = Desc.Is2DTexture() && Desc.Format == PF_DepthStencil;

	//clear if this is a new different Stencil buffer, or it's not a stencil buffer and we haven't switched to the default yet.
	bool bNeedsClear = bDepthStencil && (StencilSRVSrc != RenderTargetItem.TargetableTexture);
	bNeedsClear |= !bDepthStencil && !bIsDefault;
	if (bNeedsClear)
	{
		StencilSRVSrc = nullptr;
		StencilSRV.SafeRelease();
	}

	//always set something into the StencilSRV slot for platforms that require a full resource binding, even if
	//dynamic branching will cause them not to be used.	
	if(bDepthStencil && !StencilSRVSrc)
	{
		StencilSRVSrc = RenderTargetItem.TargetableTexture;
		StencilSRV = RHICreateShaderResourceView((FTexture2DRHIRef&) RenderTargetItem.TargetableTexture, 0, 1, PF_X24_G8);
	}
	else if(!StencilSRVSrc)
	{
		StencilSRVSrc = GBlackTexture->TextureRHI;
		StencilSRV = RHICreateShaderResourceView((FTexture2DRHIRef&) GBlackTexture->TextureRHI, 0, 1, PF_B8G8R8A8);
	}	

	FVisualizeTextureData VisualizeTextureData(RenderTargetItem, Desc);

	bool bDepthTexture = (Desc.TargetableFlags & TexCreate_DepthStencilTargetable) != 0;
	
	VisualizeTextureData.RGBMul = RGBMul;
	VisualizeTextureData.AMul = AMul;
	VisualizeTextureData.Tex00 = Tex00;
	VisualizeTextureData.Tex11 = Tex11;
	VisualizeTextureData.bSaturateInsteadOfFrac = (Flags & 1) != 0;
	VisualizeTextureData.InputValueMapping = bDepthTexture ? 1 : 0;
	VisualizeTextureData.ArrayIndex = ArrayIndex;
	VisualizeTextureData.CustomMip = CustomMip;
	VisualizeTextureData.StencilSRV = StencilSRV;

	{	
		SCOPED_DRAW_EVENT(VisualizeTexture, DEC_SCENE_ITEMS);
		// continue rendering to HDR if necessary
		RenderVisualizeTexture(VisualizeTextureData);
	}
	RHICopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams());

	VisualizeTextureDesc = Desc;

	// save to disk
	if(bSaveBitmap)
	{
		bSaveBitmap = false;

		uint32 MipAdjustedExtentX = FMath::Clamp(Desc.Extent.X >> CustomMip, 0, Desc.Extent.X);
		uint32 MipAdjustedExtentY = FMath::Clamp(Desc.Extent.Y >> CustomMip, 0, Desc.Extent.Y);
		FIntPoint Extent(MipAdjustedExtentX, MipAdjustedExtentY);

		FReadSurfaceDataFlags ReadDataFlags;
		ReadDataFlags.SetLinearToGamma(false);
		ReadDataFlags.SetOutputStencil(bOutputStencil);		
		ReadDataFlags.SetMip(CustomMip);

		FTextureRHIRef Texture = RenderTargetItem.TargetableTexture ? RenderTargetItem.TargetableTexture : RenderTargetItem.ShaderResourceTexture;

		check(Texture);

		TArray<FColor> Bitmap;
		
		
		
		
		RHIReadSurfaceData(Texture, FIntRect(0, 0, Extent.X, Extent.Y), Bitmap, ReadDataFlags);

		// if the format and texture type is supported
		if(Bitmap.Num())
		{
			// Create screenshot folder if not already present.
			IFileManager::Get().MakeDirectory(*FPaths::ScreenShotDir(), true);

			const FString ScreenFileName(FPaths::ScreenShotDir() / TEXT("VisualizeTexture"));

			uint32 ExtendXWithMSAA = Bitmap.Num() / Extent.Y;

			// Save the contents of the array to a bitmap file. (24bit only so alpha channel is dropped)
			FFileHelper::CreateBitmap(*ScreenFileName, ExtendXWithMSAA, Extent.Y, Bitmap.GetTypedData());	

			UE_LOG(LogConsoleResponse, Display, TEXT("Content was saved to \"%s\""), *FPaths::ScreenShotDir());
		}
		else
		{
			UE_LOG(LogConsoleResponse, Error, TEXT("Failed to save BMP for VisualizeTexture, format or texture type is not supported"));
		}
	}
}
	void SetPS(const FRenderingCompositePassContext& Context)
	{
		const FPixelShaderRHIParamRef ShaderRHI = GetPixelShader();

		FGlobalShader::SetParameters(Context.RHICmdList, ShaderRHI, Context.View);

		DeferredParameters.Set(Context.RHICmdList, ShaderRHI, Context.View);

		const FPostProcessSettings& Settings = Context.View.FinalPostProcessSettings;
		const FSceneViewFamily& ViewFamily = *(Context.View.Family);
		FSceneViewState* ViewState = (FSceneViewState*)Context.View.State;

		PostprocessParameter.SetPS(ShaderRHI, Context, TStaticSamplerState<SF_Point,AM_Clamp,AM_Clamp,AM_Clamp>::GetRHI());

		// PostprocessInput1MS and EditorPrimitivesStencil
		{
			FRenderingCompositeOutputRef* OutputRef = Context.Pass->GetInput(ePId_Input1);

			check(OutputRef);

			FRenderingCompositeOutput* Input = OutputRef->GetOutput();

			check(Input);

			TRefCountPtr<IPooledRenderTarget> InputPooledElement = Input->RequestInput();

			check(InputPooledElement);

			FTexture2DRHIRef& TargetableTexture = (FTexture2DRHIRef&)InputPooledElement->GetRenderTargetItem().TargetableTexture;

			SetTextureParameter(Context.RHICmdList, ShaderRHI, PostprocessInput1MS, TargetableTexture);

			if(EditorPrimitivesStencil.IsBound())
			{
				// cache the stencil SRV to avoid create calls each frame (the cache element is stored in the state)
				if(ViewState->SelectionOutlineCacheKey != TargetableTexture)
				{
					// release if not the right one (as the internally SRV stores a pointer to the texture we cannot get a false positive)
					ViewState->SelectionOutlineCacheKey.SafeRelease();
					ViewState->SelectionOutlineCacheValue.SafeRelease();
				}

				if(!ViewState->SelectionOutlineCacheValue)
				{
					// create if needed
					ViewState->SelectionOutlineCacheKey = TargetableTexture;
					ViewState->SelectionOutlineCacheValue = RHICreateShaderResourceView(TargetableTexture, 0, 1, PF_X24_G8);
				}

				SetSRVParameter(Context.RHICmdList, ShaderRHI, EditorPrimitivesStencil, ViewState->SelectionOutlineCacheValue);
		}
		}

#if WITH_EDITOR
		{
			FLinearColor OutlineColorValue = Context.View.SelectionOutlineColor;
			FLinearColor SubduedOutlineColorValue = Context.View.SubduedSelectionOutlineColor;
			OutlineColorValue.A = GEngine->SelectionHighlightIntensity;

			SetShaderValue(Context.RHICmdList, ShaderRHI, OutlineColor, OutlineColorValue);
			SetShaderValue(Context.RHICmdList, ShaderRHI, SubduedOutlineColor, SubduedOutlineColorValue);
			SetShaderValue(Context.RHICmdList, ShaderRHI, BSPSelectionIntensity, GEngine->BSPSelectionHighlightIntensity);
		}
#else
		check(!"This shader is not used outside of the Editor.");
#endif

		{
			static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataFloat(TEXT("r.Editor.MovingPattern"));
		
			FLinearColor Value(0, CVar->GetValueOnRenderThread(), 0, 0);

			if(!ViewFamily.bRealtimeUpdate)
			{
				// no animation if realtime update is disabled
				Value.G = 0;
			}

			SetShaderValue(Context.RHICmdList, ShaderRHI, EditorRenderParams, Value);
		}
	}