/** Binds the mesh paint vertex and pixel shaders to the graphics device */
	void SetMeshPaintDilateShaders(FRHICommandList& RHICmdList, ERHIFeatureLevel::Type InFeatureLevel, const FMatrix& InTransform,
												 const float InGamma,
												 const FMeshPaintDilateShaderParameters& InShaderParams )
	{
		TShaderMapRef< TMeshPaintDilateVertexShader > VertexShader(GetGlobalShaderMap(InFeatureLevel));
		TShaderMapRef< TMeshPaintDilatePixelShader > PixelShader(GetGlobalShaderMap(InFeatureLevel));

		
		static FGlobalBoundShaderState BoundShaderState;
		SetGlobalBoundShaderState(RHICmdList, InFeatureLevel, BoundShaderState, GMeshPaintDilateVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);

		// Set vertex shader parameters
		VertexShader->SetParameters(RHICmdList, InTransform );

		// Set pixel shader parameters
		PixelShader->SetParameters(RHICmdList, InGamma, InShaderParams );
	}
void FRCPassPostProcessEyeAdaptation::Process(FRenderingCompositePassContext& Context)
{
	SCOPED_DRAW_EVENT(Context.RHICmdList, PostProcessEyeAdaptation, DEC_SCENE_ITEMS);

	const FSceneView& View = Context.View;
	const FSceneViewFamily& ViewFamily = *(View.Family);

	IPooledRenderTarget* EyeAdaptation = Context.View.GetEyeAdaptation();
	check(EyeAdaptation);

	FIntPoint DestSize = EyeAdaptation->GetDesc().Extent;

	// we render to our own output render target, not the intermediate one created by the compositing system
	// Set the view family's render target/viewport.
	SetRenderTarget(Context.RHICmdList, EyeAdaptation->GetRenderTargetItem().TargetableTexture, FTextureRHIRef());
	Context.SetViewportAndCallRHI(0, 0, 0.0f, DestSize.X, DestSize.Y, 1.0f );

	// set the state
	Context.RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI());
	Context.RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI());
	Context.RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI());

	TShaderMapRef<FPostProcessVS> VertexShader(Context.GetShaderMap());
	TShaderMapRef<FPostProcessEyeAdaptationPS> PixelShader(Context.GetShaderMap());

	static FGlobalBoundShaderState BoundShaderState;
	

	SetGlobalBoundShaderState(Context.RHICmdList, Context.GetFeatureLevel(), BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);

	PixelShader->SetPS(Context);

	// Draw a quad mapping scene color to the view's render target
	DrawRectangle(
		Context.RHICmdList,
		0, 0,
		DestSize.X, DestSize.Y,
		0, 0,
		DestSize.X, DestSize.Y,
		DestSize,
		DestSize,
		*VertexShader,
		EDRF_UseTriangleOptimization);

	Context.RHICmdList.CopyToResolveTarget(EyeAdaptation->GetRenderTargetItem().TargetableTexture, EyeAdaptation->GetRenderTargetItem().ShaderResourceTexture, false, FResolveParams());
}
示例#3
0
void FD3D11DynamicRHI::IssueLongGPUTask()
{
	if (GMaxRHIFeatureLevel >= ERHIFeatureLevel::SM4)
	{
		int32 LargestViewportIndex = INDEX_NONE;
		int32 LargestViewportPixels = 0;

		for (int32 ViewportIndex = 0; ViewportIndex < Viewports.Num(); ViewportIndex++)
		{
			FD3D11Viewport* Viewport = Viewports[ViewportIndex];

			if (Viewport->GetSizeXY().X * Viewport->GetSizeXY().Y > LargestViewportPixels)
			{
				LargestViewportPixels = Viewport->GetSizeXY().X * Viewport->GetSizeXY().Y;
				LargestViewportIndex = ViewportIndex;
			}
		}

		if (LargestViewportIndex >= 0)
		{
			FD3D11Viewport* Viewport = Viewports[LargestViewportIndex];

			FRHICommandList_RecursiveHazardous RHICmdList(this);

			SetRenderTarget(RHICmdList, Viewport->GetBackBuffer(), FTextureRHIRef());
			RHICmdList.SetBlendState(TStaticBlendState<CW_RGBA, BO_Add, BF_One, BF_One>::GetRHI(), FLinearColor::Black);
			RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI(), 0);
			RHICmdList.SetRasterizerState(TStaticRasterizerState<FM_Solid, CM_None>::GetRHI());

			auto ShaderMap = GetGlobalShaderMap(GMaxRHIFeatureLevel);
			TShaderMapRef<TOneColorVS<true> > VertexShader(ShaderMap);
			TShaderMapRef<FLongGPUTaskPS> PixelShader(ShaderMap);

			RHICmdList.SetLocalBoundShaderState(RHICmdList.BuildLocalBoundShaderState(GD3D11Vector4VertexDeclaration.VertexDeclarationRHI, VertexShader->GetVertexShader(), FHullShaderRHIRef(), FDomainShaderRHIRef(), PixelShader->GetPixelShader(), FGeometryShaderRHIRef()));

			// Draw a fullscreen quad
			FVector4 Vertices[4];
			Vertices[0].Set( -1.0f,  1.0f, 0, 1.0f );
			Vertices[1].Set(  1.0f,  1.0f, 0, 1.0f );
			Vertices[2].Set( -1.0f, -1.0f, 0, 1.0f );
			Vertices[3].Set(  1.0f, -1.0f, 0, 1.0f );
			DrawPrimitiveUP(RHICmdList, PT_TriangleStrip, 2, Vertices, sizeof(Vertices[0]));
			// Implicit flush. Always call flush when using a command list in RHI implementations before doing anything else. This is super hazardous.
		}
	}
}
示例#4
0
//trace a ray
_float4 CPURayTracer::Trace( _float4 ori , _float4 dir )
{
	//current color
	_float4 d( 0 , 0 , 0 , 0 );

	//traverse a ray
	if( TraverseRay( ori , dir , &d ) )
	{
		//the final color
		_float4 color = PixelShader( &d , ori );

		//shade the pixel
		return color;
	}

	//return back ground color
	return d;
}
/** Updates the downsized depth buffer with the current full resolution depth buffer. */
void FDeferredShadingSceneRenderer::UpdateDownsampledDepthSurface()
{
	if (GSceneRenderTargets.UseDownsizedOcclusionQueries() && IsFeatureLevelSupported(GRHIShaderPlatform, ERHIFeatureLevel::SM3))
	{
		RHISetRenderTarget(NULL, GSceneRenderTargets.GetSmallDepthSurface());

		SCOPED_DRAW_EVENT(DownsampleDepth, DEC_SCENE_ITEMS);

		for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++)
		{
			const FViewInfo& View = Views[ViewIndex];
			// Set shaders and texture
			TShaderMapRef<FScreenVS> ScreenVertexShader(GetGlobalShaderMap());
			TShaderMapRef<FDownsampleSceneDepthPS> PixelShader(GetGlobalShaderMap());

			extern TGlobalResource<FFilterVertexDeclaration> GFilterVertexDeclaration;

			SetGlobalBoundShaderState(DownsampleDepthBoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *ScreenVertexShader, *PixelShader);

			RHISetBlendState(TStaticBlendState<CW_NONE>::GetRHI());
			RHISetRasterizerState(TStaticRasterizerState<FM_Solid,CM_None>::GetRHI());
			RHISetDepthStencilState(TStaticDepthStencilState<true,CF_Always>::GetRHI());

			PixelShader->SetParameters(View);

			const uint32 DownsampledX = FMath::Trunc(View.ViewRect.Min.X / GSceneRenderTargets.GetSmallColorDepthDownsampleFactor());
			const uint32 DownsampledY = FMath::Trunc(View.ViewRect.Min.Y / GSceneRenderTargets.GetSmallColorDepthDownsampleFactor());
			const uint32 DownsampledSizeX = FMath::Trunc(View.ViewRect.Width() / GSceneRenderTargets.GetSmallColorDepthDownsampleFactor());
			const uint32 DownsampledSizeY = FMath::Trunc(View.ViewRect.Height() / GSceneRenderTargets.GetSmallColorDepthDownsampleFactor());

			RHISetViewport(DownsampledX, DownsampledY, 0.0f, DownsampledX + DownsampledSizeX, DownsampledY + DownsampledSizeY, 1.0f);

			DrawRectangle(
				0, 0,
				DownsampledSizeX, DownsampledSizeY,
				View.ViewRect.Min.X, View.ViewRect.Min.Y,
				View.ViewRect.Width(), View.ViewRect.Height(),
				FIntPoint(DownsampledSizeX, DownsampledSizeY),
				GSceneRenderTargets.GetBufferSizeXY(),
				EDRF_UseTriangleOptimization);
		}
	}
}
void FRCPassPostProcessBusyWait::Process(FRenderingCompositePassContext& Context)
{
	SCOPED_DRAW_EVENT(BusyWait, DEC_SCENE_ITEMS);

	const FSceneView& View = Context.View;
	
	FIntRect SrcRect = View.ViewRect;
	FIntRect DestRect = View.UnscaledViewRect;
	
	const FSceneRenderTargetItem& DestRenderTarget = GSceneRenderTargets.LightAttenuation->GetRenderTargetItem();

	// Set the view family's render target/viewport.
	RHISetRenderTarget(DestRenderTarget.TargetableTexture, FTextureRHIRef());	
	Context.SetViewportAndCallRHI(DestRect);

	// set the state
	RHISetBlendState(TStaticBlendState<>::GetRHI());
	RHISetRasterizerState(TStaticRasterizerState<>::GetRHI());
	RHISetDepthStencilState(TStaticDepthStencilState<false,CF_Always>::GetRHI());

	TShaderMapRef<FPostProcessVS> VertexShader(GetGlobalShaderMap());
	TShaderMapRef<FPostProcessBusyWaitPS> PixelShader(GetGlobalShaderMap());

	static FGlobalBoundShaderState BoundShaderState;

	SetGlobalBoundShaderState(BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);

	PixelShader->SetPS(Context);

	// Draw a quad mapping scene color to the view's render target
	DrawRectangle(
		0, 0,
		DestRect.Width(), DestRect.Height(),
		SrcRect.Min.X, SrcRect.Min.Y,
		SrcRect.Width(), SrcRect.Height(),
		DestRect.Size(),
		SrcRect.Size(),
		EDRF_UseTriangleOptimization);

	RHICopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams());
}
示例#7
0
文件: Shader.cpp 项目: Clever-Boy/XLE
    ShaderProgram::ShaderProgram(   const CompiledShaderByteCode& compiledVertexShader, 
                                    const CompiledShaderByteCode& compiledFragmentShader)
    :   _compiledVertexShader(&compiledVertexShader)
    ,   _compiledPixelShader(&compiledFragmentShader)
    ,   _compiledGeometryShader(nullptr)
    {
            //  make sure both the vertex shader and the pixel shader
            //  have completed compiling. If one completes early, we don't
            //  want to create the vertex shader object, and then just delete it.
        compiledVertexShader.GetByteCode();
        compiledFragmentShader.GetByteCode();

        auto vertexShader = VertexShader(compiledVertexShader);
        auto pixelShader = PixelShader(compiledFragmentShader);

        _vertexShader = std::move(vertexShader);
        _pixelShader = std::move(pixelShader);
        _validationCallback = std::make_shared<Assets::DependencyValidation>();
        Assets::RegisterAssetDependency(_validationCallback, _compiledVertexShader->GetDependencyValidation());
        Assets::RegisterAssetDependency(_validationCallback, _compiledPixelShader->GetDependencyValidation());
    }
示例#8
0
void RunBenchmarkShader(FRHICommandList& RHICmdList, const FSceneView& View, TRefCountPtr<IPooledRenderTarget>& Src, float WorkScale)
{
	auto ShaderMap = GetGlobalShaderMap(View.GetFeatureLevel());

	TShaderMapRef<FPostProcessBenchmarkVS> VertexShader(ShaderMap);
	TShaderMapRef<FPostProcessBenchmarkPS<Method> > PixelShader(ShaderMap);

	static FGlobalBoundShaderState BoundShaderState;
	

	SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);

	PixelShader->SetParameters(RHICmdList, View, Src);
	VertexShader->SetParameters(RHICmdList, View);

	// single pass was not fine grained enough so we reduce the pass size based on the fractional part of WorkScale
	float TotalHeight = GBenchmarkResolution * WorkScale;

	// rounds up
	uint32 PassCount = (uint32)FMath::CeilToFloat(TotalHeight / GBenchmarkResolution);

	for(uint32 i = 0; i < PassCount; ++i)
	{
		float Top = i * GBenchmarkResolution;
		float Bottom = FMath::Min(Top + GBenchmarkResolution, TotalHeight);
		float LocalHeight = Bottom - Top;

		DrawRectangle(
			RHICmdList,
			0, 0,
			GBenchmarkResolution, LocalHeight,
			0, 0,
			GBenchmarkResolution, LocalHeight,
			FIntPoint(GBenchmarkResolution, GBenchmarkResolution),
			FIntPoint(GBenchmarkResolution, GBenchmarkResolution),
			*VertexShader,
			EDRF_Default);
	}
}
示例#9
0
//----------------------------------------------------------------------------
void Smoke2D::CreatePoissonSolverEffect (VisualEffect*& effect,
    VisualEffectInstance*& instance)
{
    PixelShader* pshader = new0 PixelShader("Wm5.PoissonSolver2",
        1, 1, 2, 2, false);
    pshader->SetInput(0, "vertexTCoord", Shader::VT_FLOAT2,
        Shader::VS_TEXCOORD0);
    pshader->SetOutput(0, "pixelColor", Shader::VT_FLOAT4,
        Shader::VS_COLOR0);
    pshader->SetConstant(0, "SpaceParam", 1);
    pshader->SetConstant(1, "EpsilonParam", 1);
    pshader->SetSampler(0, "DivergenceSampler", Shader::ST_2D);
    pshader->SetSampler(1, "PoissonSampler", Shader::ST_2D);
    pshader->SetBaseRegisters(msPoissonSolverPRegisters);
    pshader->SetTextureUnits(msPoissonSolverPTextureUnits);
    pshader->SetPrograms(msPoissonSolverPPrograms);

    mIP->CreateEffect(pshader, effect, instance);

    ShaderFloat* spaceParamConstant = new0 ShaderFloat(1);
    float* spaceParam = spaceParamConstant->GetData();
    spaceParam[0] = mDx;
    spaceParam[1] = mDy;
    instance->SetPixelConstant(0, "SpaceParam", spaceParamConstant);

    ShaderFloat* epsilonParamConstant = new0 ShaderFloat(1);
    float* epsilonParam = epsilonParamConstant->GetData();
    epsilonParam[0] = mEpsilonX;
    epsilonParam[1] = mEpsilonY;
    epsilonParam[2] = mEpsilon0;
    instance->SetPixelConstant(0, "EpsilonParam", epsilonParamConstant);

    instance->SetPixelTexture(0, "DivergenceSampler",
        mIP->GetTarget(2)->GetColorTexture(0));
    instance->SetPixelTexture(0, "PoissonSampler",
        mIP->GetTarget(0)->GetColorTexture(0));
}
template<uint32 TextureType> void VisualizeTextureForTextureType(const FVisualizeTextureData& Data)
{
	TShaderMapRef<FScreenVS> VertexShader(GetGlobalShaderMap());
	TShaderMapRef<VisualizeTexturePS<TextureType> > PixelShader(GetGlobalShaderMap());

	static FGlobalBoundShaderState BoundShaderState;
	SetGlobalBoundShaderState(BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);
	PixelShader->SetParameters(Data);

	DrawRectangle(
		// XY
		0, 0,
		// SizeXY
		GSceneRenderTargets.GetBufferSizeXY().X, GSceneRenderTargets.GetBufferSizeXY().Y,
		// UV
		Data.Tex00.X, Data.Tex00.Y,
		// SizeUV
		Data.Tex11.X - Data.Tex00.X, Data.Tex11.Y - Data.Tex00.Y,
		// TargetSize
		GSceneRenderTargets.GetBufferSizeXY(),
		// TextureSize
		FIntPoint(1, 1),
		EDRF_UseTriangleOptimization);
}
示例#11
0
void RunBenchmarkShader(const FSceneView& View, TRefCountPtr<IPooledRenderTarget>& Src, uint32 Count)
{
	TShaderMapRef<FPostProcessBenchmarkVS> VertexShader(GetGlobalShaderMap());
	TShaderMapRef<FPostProcessBenchmarkPS<Method> > PixelShader(GetGlobalShaderMap());

	static FGlobalBoundShaderState BoundShaderState;

	SetGlobalBoundShaderState(BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);

	PixelShader->SetParameters(View, Src);
	VertexShader->SetParameters(View);

	for(uint32 i = 0; i < Count; ++i)
	{
		DrawRectangle(
			0, 0,
			GBenchmarkResolution, GBenchmarkResolution,
			0, 0,
			GBenchmarkResolution, GBenchmarkResolution,
			FIntPoint(GBenchmarkResolution, GBenchmarkResolution),
			FIntPoint(GBenchmarkResolution, GBenchmarkResolution),
			EDRF_Default);
	}
}
void FLightPropagationVolume::Visualise(FRHICommandList& RHICmdList, const FViewInfo& View) const
{
    SCOPED_DRAW_EVENT(RHICmdList, LpvVisualise);
    check(View.GetFeatureLevel() == ERHIFeatureLevel::SM5);

    TShaderMapRef<FLpvVisualiseVS> VertexShader(View.ShaderMap);
    TShaderMapRef<FLpvVisualiseGS> GeometryShader(View.ShaderMap);
    TShaderMapRef<FLpvVisualisePS> PixelShader(View.ShaderMap);

    RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI());
    RHICmdList.SetRasterizerState(TStaticRasterizerState<FM_Solid, CM_None>::GetRHI());
    RHICmdList.SetBlendState(TStaticBlendState<CW_RGB, BO_Add, BF_One, BF_One>::GetRHI());

    SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), LpvVisBoundShaderState, GSimpleElementVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader, *GeometryShader);

    VertexShader->SetParameters(RHICmdList, View);
    GeometryShader->SetParameters(RHICmdList, View);
    PixelShader->SetParameters(RHICmdList, this, View);

    RHICmdList.SetStreamSource(0, NULL, 0, 0);
    RHICmdList.DrawPrimitive(PT_PointList, 0, 1, 32 * 3);

    PixelShader->UnbindBuffers(RHICmdList);
}
void FRCPassPostProcessVisualizeShadingModels::Process(FRenderingCompositePassContext& Context)
{
	SCOPED_DRAW_EVENT(Context.RHICmdList, PostProcessVisualizeShadingModels);
	const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0);

	const FSceneView& View = Context.View;
	const FViewInfo& ViewInfo = Context.View;
	const FSceneViewFamily& ViewFamily = *(View.Family);
	
	FIntRect SrcRect = View.ViewRect;
	FIntRect DestRect = View.ViewRect;
	FIntPoint SrcSize = InputDesc->Extent;

	const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context);

	// Set the view family's render target/viewport.
	SetRenderTarget(Context.RHICmdList, DestRenderTarget.TargetableTexture, FTextureRHIRef());
	Context.SetViewportAndCallRHI(DestRect);

	// set the state
	Context.RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI());
	Context.RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI());
	Context.RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI());

	TShaderMapRef<FPostProcessVS> VertexShader(Context.GetShaderMap());
	TShaderMapRef<FPostProcessVisualizeShadingModelsPS> PixelShader(Context.GetShaderMap());

	static FGlobalBoundShaderState BoundShaderState;	

	SetGlobalBoundShaderState(Context.RHICmdList, Context.GetFeatureLevel(), BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);

	PixelShader->SetPS(Context, ((FViewInfo&)View).ShadingModelMaskInView);

	// Draw a quad mapping scene color to the view's render target
	DrawRectangle(
		Context.RHICmdList,
		DestRect.Min.X, DestRect.Min.Y,
		DestRect.Width(), DestRect.Height(),
		SrcRect.Min.X, SrcRect.Min.Y,
		SrcRect.Width(), SrcRect.Height(),
		DestRect.Size(),
		SrcSize,
		*VertexShader,
		EDRF_UseTriangleOptimization);

	FRenderTargetTemp TempRenderTarget(View, (const FTexture2DRHIRef&)DestRenderTarget.TargetableTexture);
	FCanvas Canvas(&TempRenderTarget, NULL, 0, 0, 0, Context.GetFeatureLevel());

	float X = 30;
	float Y = 28;
	const float YStep = 14;
	const float ColumnWidth = 250;

	FString Line;

	Canvas.DrawShadowedString( X, Y += YStep, TEXT("Visualize ShadingModels (mostly to track down bugs)"), GetStatsFont(), FLinearColor(1, 1, 1));

	Y = 160 - YStep - 4;
	
	uint32 Value = ((FViewInfo&)View).ShadingModelMaskInView;

	Line = FString::Printf(TEXT("View.ShadingModelMaskInView = 0x%x"), Value);
	Canvas.DrawShadowedString( X, Y, *Line, GetStatsFont(), FLinearColor(0.5f, 0.5f, 0.5f));
	Y += YStep;

	UEnum* Enum = FindObject<UEnum>(NULL, TEXT("Engine.EMaterialShadingModel"));
	check(Enum);

	Y += 5;

	for(uint32 i = 0; i < MSM_MAX; ++i)
	{
		FString Name = Enum->GetEnumName(i);
		Line = FString::Printf(TEXT("%d.  %s"), i, *Name);

		bool bThere = (Value & (1 << i)) != 0;

		Canvas.DrawShadowedString(X + 30, Y, *Line, GetStatsFont(), bThere ? FLinearColor(1, 1, 1) : FLinearColor(0, 0, 0) );
		Y += 20;
	}

	Line = FString::Printf(TEXT("(On CPU, based on what gets rendered)"));
	Canvas.DrawShadowedString( X, Y, *Line, GetStatsFont(), FLinearColor(0.5f, 0.5f, 0.5f)); Y += YStep;

	Canvas.Flush_RenderThread(Context.RHICmdList);

	Context.RHICmdList.CopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams());

	// AdjustGBufferRefCount(1) call is done in constructor
	FSceneRenderTargets::Get(Context.RHICmdList).AdjustGBufferRefCount(Context.RHICmdList, -1);
}
void UpdateSceneCaptureContent_RenderThread(FRHICommandListImmediate& RHICmdList, FSceneRenderer* SceneRenderer, FTextureRenderTargetResource* TextureRenderTarget, const FName OwnerName, const FResolveParams& ResolveParams, bool bUseSceneColorTexture)
{
	FMemMark MemStackMark(FMemStack::Get());

	// update any resources that needed a deferred update
	FDeferredUpdateResource::UpdateResources(RHICmdList);

	{
#if WANTS_DRAW_MESH_EVENTS
		FString EventName;
		OwnerName.ToString(EventName);
		SCOPED_DRAW_EVENTF(RHICmdList, SceneCapture, DEC_SCENE_ITEMS, TEXT("SceneCapture %s"), *EventName);
#endif

		// Render the scene normally
		const FRenderTarget* Target = SceneRenderer->ViewFamily.RenderTarget;
		FViewInfo& View = SceneRenderer->Views[0];
		FIntRect ViewRect = View.ViewRect;
		FIntRect UnconstrainedViewRect = View.UnconstrainedViewRect;
		SetRenderTarget(RHICmdList, Target->GetRenderTargetTexture(), NULL);
		RHICmdList.Clear(true, FLinearColor::Black, false, 1.0f, false, 0, ViewRect);
		SceneRenderer->Render(RHICmdList);

		// Copy the captured scene into the destination texture
		if (bUseSceneColorTexture)
		{
			// Copy the captured scene into the destination texture
			SetRenderTarget(RHICmdList, Target->GetRenderTargetTexture(), NULL);

			RHICmdList.SetRasterizerState(TStaticRasterizerState<FM_Solid, CM_None>::GetRHI());
			RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI());
			RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI());

			TShaderMapRef<FScreenVS> VertexShader(View.ShaderMap);
			TShaderMapRef<FScreenPS> PixelShader(View.ShaderMap);
			static FGlobalBoundShaderState BoundShaderState;
			SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);

			FRenderingCompositePassContext Context(RHICmdList, View);

			VertexShader->SetParameters(RHICmdList, View);
			PixelShader->SetParameters(RHICmdList, TStaticSamplerState<SF_Point>::GetRHI(), GSceneRenderTargets.GetSceneColorTexture());

			FIntPoint TargetSize(UnconstrainedViewRect.Width(), UnconstrainedViewRect.Height());

			DrawRectangle(
				RHICmdList,
				ViewRect.Min.X, ViewRect.Min.Y,
				ViewRect.Width(), ViewRect.Height(),
				ViewRect.Min.X, ViewRect.Min.Y,
				ViewRect.Width(), ViewRect.Height(),
				TargetSize,
				GSceneRenderTargets.GetBufferSizeXY(),
				*VertexShader,
				EDRF_UseTriangleOptimization);
		}

		RHICmdList.CopyToResolveTarget(TextureRenderTarget->GetRenderTargetTexture(), TextureRenderTarget->TextureRHI, false, ResolveParams);
	}

	delete SceneRenderer;
}
void FRCPassPostProcessVisualizeBuffer::Process(FRenderingCompositePassContext& Context)
{
	SCOPED_DRAW_EVENT(VisualizeBuffer, DEC_SCENE_ITEMS);
	const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0);

	if(!InputDesc)
	{
		// input is not hooked up correctly
		return;
	}

	const FSceneView& View = Context.View;
	const FSceneViewFamily& ViewFamily = *(View.Family);
	
	FIntRect SrcRect = View.ViewRect;
	FIntRect DestRect = View.ViewRect;
	FIntPoint SrcSize = InputDesc->Extent;

	const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context);

	// Set the view family's render target/viewport.
	RHISetRenderTarget(DestRenderTarget.TargetableTexture, FTextureRHIRef());	
	Context.SetViewportAndCallRHI(DestRect);

	// set the state
	RHISetBlendState(TStaticBlendState<>::GetRHI());
	RHISetRasterizerState(TStaticRasterizerState<>::GetRHI());
	RHISetDepthStencilState(TStaticDepthStencilState<false,CF_Always>::GetRHI());

	SetShaderTempl<false>(Context);

	// Draw a quad mapping scene color to the view's render target
	DrawRectangle(
		0, 0,
		DestRect.Width(), DestRect.Height(),
		SrcRect.Min.X, SrcRect.Min.Y,
		SrcRect.Width(), SrcRect.Height(),
		DestRect.Size(),
		SrcSize,
		EDRF_UseTriangleOptimization);

	// Now draw the requested tiles into the grid
	TShaderMapRef<FPostProcessVS> VertexShader(GetGlobalShaderMap());
	TShaderMapRef<FPostProcessVisualizeBufferPS<true> > PixelShader(GetGlobalShaderMap());

	RHISetBlendState(TStaticBlendState<CW_RGB, BO_Add, BF_SourceAlpha, BF_InverseSourceAlpha>::GetRHI());
	static FGlobalBoundShaderState BoundShaderState;

	SetGlobalBoundShaderState(BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);

	PixelShader->SetPS(Context);

	// Track the name and position of each tile we draw so we can write text labels over them
	struct LabelRecord
	{
		FString Label;
		int32 LocationX;
		int32 LocationY;
	};

	TArray<LabelRecord> Labels;

	const int32 MaxTilesX = 4;
	const int32 MaxTilesY = 4;
	const int32 TileWidth = DestRect.Width() / MaxTilesX;
	const int32 TileHeight = DestRect.Height() / MaxTilesY;
	int32 CurrentTileIndex = 0; 

	for (TArray<TileData>::TConstIterator It = Tiles.CreateConstIterator(); It; ++It, ++CurrentTileIndex)
	{
		FRenderingCompositeOutputRef Tile = It->Source;

		if (Tile.IsValid())
		{
			FTextureRHIRef Texture = Tile.GetOutput()->PooledRenderTarget->GetRenderTargetItem().TargetableTexture;

			int32 TileX = CurrentTileIndex % MaxTilesX;
			int32 TileY = CurrentTileIndex / MaxTilesX;

			PixelShader->SetSourceTexture(Texture);

			DrawRectangle(
				TileX * TileWidth, TileY * TileHeight,
				TileWidth, TileHeight,
				SrcRect.Min.X, SrcRect.Min.Y,
				SrcRect.Width(), SrcRect.Height(),
				DestRect.Size(),
				SrcSize,
				EDRF_Default);

			Labels.Add(LabelRecord());
			Labels.Last().Label = It->Name;
			Labels.Last().LocationX = 8 + TileX * TileWidth;
			Labels.Last().LocationY = (TileY + 1) * TileHeight - 19;
		}
	}

	// Draw tile labels

	// this is a helper class for FCanvas to be able to get screen size
	class FRenderTargetTemp : public FRenderTarget
	{
	public:
		const FSceneView& View;
		const FTexture2DRHIRef Texture;

		FRenderTargetTemp(const FSceneView& InView, const FTexture2DRHIRef InTexture)
			: View(InView), Texture(InTexture)
		{
		}
		virtual FIntPoint GetSizeXY() const
		{
			return View.ViewRect.Size();
		};
		virtual const FTexture2DRHIRef& GetRenderTargetTexture() const
		{
			return Texture;
		}
	} TempRenderTarget(View, (const FTexture2DRHIRef&)DestRenderTarget.TargetableTexture);

	FCanvas Canvas(&TempRenderTarget, NULL, ViewFamily.CurrentRealTime, ViewFamily.CurrentWorldTime, ViewFamily.DeltaWorldTime);
	FLinearColor LabelColor(1, 1, 0);
	for (auto It = Labels.CreateConstIterator(); It; ++It)
	{
		Canvas.DrawShadowedString(It->LocationX, It->LocationY, *It->Label, GetStatsFont(), LabelColor);
	}
	Canvas.Flush();


	RHICopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams());
}
void FRCPassPostProcessMotionBlurSetup::Process(FRenderingCompositePassContext& Context)
{
	SCOPED_DRAW_EVENT(MotionBlurSetup, DEC_SCENE_ITEMS);

	const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0);

	if(!InputDesc)
	{
		// input is not hooked up correctly
		return;
	}

	const FSceneView& View = Context.View;
	const FSceneViewFamily& ViewFamily = *(View.Family);

	FIntPoint SrcSize = InputDesc->Extent;
	FIntPoint DestSize = PassOutputs[0].RenderTargetDesc.Extent;

	// e.g. 4 means the input texture is 4x smaller than the buffer size
	uint32 ScaleFactor = GSceneRenderTargets.GetBufferSizeXY().X / SrcSize.X;

	FIntRect SrcRect = View.ViewRect / ScaleFactor;

	// Viewport size not even also causes issue
	FIntRect DestRect = FIntRect::DivideAndRoundUp(SrcRect, 2);

	const FSceneRenderTargetItem& DestRenderTarget0 = PassOutputs[0].RequestSurface(Context);
	const FSceneRenderTargetItem& DestRenderTarget1 = PassOutputs[1].RequestSurface(Context);

	// Set the view family's render target/viewport.
	FTextureRHIParamRef RenderTargets[] =
	{
		DestRenderTarget0.TargetableTexture,
		DestRenderTarget1.TargetableTexture
	};
	RHISetRenderTargets( ARRAY_COUNT(RenderTargets), RenderTargets, FTextureRHIParamRef(), 0, NULL );

	// is optimized away if possible (RT size=view size, )
	FLinearColor ClearColors[2] = {FLinearColor(0,0,0,0), FLinearColor(0,0,0,0)};
	RHIClearMRT(true, 2, ClearColors, false, 1.0f, false, 0, DestRect);

	Context.SetViewportAndCallRHI(0, 0, 0.0f, DestSize.X, DestSize.Y, 1.0f );

	// set the state
	RHISetBlendState(TStaticBlendState<>::GetRHI());
	RHISetRasterizerState(TStaticRasterizerState<>::GetRHI());
	RHISetDepthStencilState(TStaticDepthStencilState<false,CF_Always>::GetRHI());

	{
		TShaderMapRef<FPostProcessVS> VertexShader(GetGlobalShaderMap());
		TShaderMapRef<FPostProcessMotionBlurSetupPS > PixelShader(GetGlobalShaderMap());

		static FGlobalBoundShaderState BoundShaderState;

		SetGlobalBoundShaderState(BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);

		PixelShader->SetParameters(Context);
		VertexShader->SetParameters(Context);
	}

	// Draw a quad mapping scene color to the view's render target
	DrawRectangle(
		DestRect.Min.X, DestRect.Min.Y,
		DestRect.Width(), DestRect.Height(),
		SrcRect.Min.X, SrcRect.Min.Y,
		SrcRect.Width(), SrcRect.Height(),
		DestSize,
		SrcSize,
		EDRF_UseTriangleOptimization);

	RHICopyToResolveTarget(DestRenderTarget0.TargetableTexture, DestRenderTarget0.ShaderResourceTexture, false, FResolveParams());
	RHICopyToResolveTarget(DestRenderTarget1.TargetableTexture, DestRenderTarget1.ShaderResourceTexture, false, FResolveParams());
}
// TODO: REMOVE if no longer needed:
void FSceneRenderer::GammaCorrectToViewportRenderTarget(const FViewInfo* View, float OverrideGamma)
{
    // Set the view family's render target/viewport.
    RHISetRenderTarget(ViewFamily.RenderTarget->GetRenderTargetTexture(),FTextureRHIRef());

    // Deferred the clear until here so the garbage left in the non rendered regions by the post process effects do not show up
    if( ViewFamily.bDeferClear )
    {
        RHIClear(true, FLinearColor::Black, false, 0.0f, false, 0, FIntRect());
        ViewFamily.bDeferClear = false;
    }

    SCOPED_DRAW_EVENT(GammaCorrection, DEC_SCENE_ITEMS);

    // turn off culling and blending
    RHISetRasterizerState(TStaticRasterizerState<FM_Solid,CM_None>::GetRHI());
    RHISetBlendState(TStaticBlendState<>::GetRHI());

    // turn off depth reads/writes
    RHISetDepthStencilState(TStaticDepthStencilState<false,CF_Always>::GetRHI());

    TShaderMapRef<FGammaCorrectionVS> VertexShader(GetGlobalShaderMap());
    TShaderMapRef<FGammaCorrectionPS> PixelShader(GetGlobalShaderMap());

    static FGlobalBoundShaderState PostProcessBoundShaderState;
    SetGlobalBoundShaderState( PostProcessBoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);

    float InvDisplayGamma = 1.0f / ViewFamily.RenderTarget->GetDisplayGamma();

    if (OverrideGamma != 0)
    {
        InvDisplayGamma = 1 / OverrideGamma;
    }

    SetShaderValue(
        PixelShader->GetPixelShader(),
        PixelShader->InverseGamma,
        InvDisplayGamma
    );
    SetShaderValue(PixelShader->GetPixelShader(),PixelShader->ColorScale,View->ColorScale);
    SetShaderValue(PixelShader->GetPixelShader(),PixelShader->OverlayColor,View->OverlayColor);

    const FTexture2DRHIRef DesiredSceneColorTexture = GSceneRenderTargets.GetSceneColorTexture();

    SetTextureParameter(
        PixelShader->GetPixelShader(),
        PixelShader->SceneTexture,
        PixelShader->SceneTextureSampler,
        TStaticSamplerState<SF_Bilinear>::GetRHI(),
        DesiredSceneColorTexture
    );

    // Draw a quad mapping scene color to the view's render target
    DrawRectangle(
        View->UnscaledViewRect.Min.X,View->UnscaledViewRect.Min.Y,
        View->UnscaledViewRect.Width(),View->UnscaledViewRect.Height(),
        View->ViewRect.Min.X,View->ViewRect.Min.Y,
        View->ViewRect.Width(),View->ViewRect.Height(),
        ViewFamily.RenderTarget->GetSizeXY(),
        GSceneRenderTargets.GetBufferSizeXY(),
        EDRF_UseTriangleOptimization);
}
示例#18
0
void FRCPassPostProcessLensFlares::Process(FRenderingCompositePassContext& Context)
{
	SCOPED_DRAW_EVENT(Context.RHICmdList, LensFlares);

	const FPooledRenderTargetDesc* InputDesc1 = GetInputDesc(ePId_Input0);
	const FPooledRenderTargetDesc* InputDesc2 = GetInputDesc(ePId_Input1);
	
	if(!InputDesc1 || !InputDesc2)
	{
		// input is not hooked up correctly
		return;
	}

	const FSceneView& View = Context.View;
	const FSceneViewFamily& ViewFamily = *(View.Family);

	FIntPoint TexSize1 = InputDesc1->Extent;
	FIntPoint TexSize2 = InputDesc2->Extent;

	uint32 ScaleToFullRes1 = GSceneRenderTargets.GetBufferSizeXY().X / TexSize1.X;
	uint32 ScaleToFullRes2 = GSceneRenderTargets.GetBufferSizeXY().X / TexSize2.X;

	FIntRect ViewRect1 = FIntRect::DivideAndRoundUp(View.ViewRect, ScaleToFullRes1);
	FIntRect ViewRect2 = FIntRect::DivideAndRoundUp(View.ViewRect, ScaleToFullRes2);

	FIntPoint ViewSize1 = ViewRect1.Size();
	FIntPoint ViewSize2 = ViewRect2.Size();

	const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context);

	// Set the view family's render target/viewport.
	SetRenderTarget(Context.RHICmdList, DestRenderTarget.TargetableTexture, FTextureRHIRef());
		
	// is optimized away if possible (RT size=view size, )
	Context.RHICmdList.Clear(true, FLinearColor::Black, false, 1.0f, false, 0, ViewRect1);

	Context.SetViewportAndCallRHI(ViewRect1);

	// set the state
	Context.RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI());
	Context.RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI());
	Context.RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI());

	TShaderMapRef<FPostProcessVS> VertexShader(Context.GetShaderMap());

	
	// setup background (bloom), can be implemented to use additive blending to avoid the read here
	{
		TShaderMapRef<FPostProcessLensFlareBasePS> PixelShader(Context.GetShaderMap());

		static FGlobalBoundShaderState BoundShaderState;
		
		SetGlobalBoundShaderState(Context.RHICmdList, Context.GetFeatureLevel(), BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);

		VertexShader->SetParameters(Context);
		PixelShader->SetParameters(Context);

		// Draw a quad mapping scene color to the view's render target
		DrawRectangle(
			Context.RHICmdList,
			0, 0,
			ViewSize1.X, ViewSize1.Y,
			ViewRect1.Min.X, ViewRect1.Min.Y,
			ViewSize1.X, ViewSize1.Y,
			ViewSize1,
			TexSize1,
			*VertexShader,
			EDRF_UseTriangleOptimization);
	}

	// additive blend
	Context.RHICmdList.SetBlendState(TStaticBlendState<CW_RGB, BO_Add, BF_One, BF_One>::GetRHI());

	// add lens flares on top of that
	{
		TShaderMapRef<FPostProcessLensFlaresPS> PixelShader(Context.GetShaderMap());

		static FGlobalBoundShaderState BoundShaderState;
		
		SetGlobalBoundShaderState(Context.RHICmdList, Context.GetFeatureLevel(), BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);

		FVector2D TexScaleValue = FVector2D(TexSize2) / ViewSize2;

		VertexShader->SetParameters(Context);
		PixelShader->SetParameters(Context, TexScaleValue);

		// todo: expose
		const uint32 Count = 8;

		// we assume the center of the view is the center of the lens (would not be correct for tiled rendering)
		FVector2D Center = FVector2D(ViewSize1) * 0.5f;

		FLinearColor LensFlareHDRColor = Context.View.FinalPostProcessSettings.LensFlareTint * Context.View.FinalPostProcessSettings.LensFlareIntensity;
	
		// to get the same brightness with 4x more quads (TileSize=1 in LensBlur)
		LensFlareHDRColor.R *= 0.25f;
		LensFlareHDRColor.G *= 0.25f;
		LensFlareHDRColor.B *= 0.25f;

		for(uint32 i = 0; i < Count; ++i)
		{
			FLinearColor FlareColor = Context.View.FinalPostProcessSettings.LensFlareTints[i % 8];
			float NormalizedAlpha = FlareColor.A;
			float Alpha = NormalizedAlpha * 7.0f - 3.5f; 

			// scale to blur outside of the view (only if we use LensBlur)
			Alpha *= SizeScale;
			
			// set the individual flare color
			SetShaderValue(Context.RHICmdList, PixelShader->GetPixelShader(), PixelShader->FlareColor, FlareColor * LensFlareHDRColor);

			// Draw a quad mapping scene color to the view's render target
			DrawRectangle(
				Context.RHICmdList,
				Center.X - 0.5f * ViewSize1.X * Alpha, Center.Y - 0.5f * ViewSize1.Y * Alpha,
				ViewSize1.X * Alpha, ViewSize1.Y * Alpha,
				ViewRect2.Min.X, ViewRect2.Min.Y,
				ViewSize2.X, ViewSize2.Y,
				ViewSize1,
				TexSize2,
				*VertexShader,
				EDRF_Default);
		}
	}

	Context.RHICmdList.CopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams());
}
示例#19
0
void FRCPassPostProcessDOFRecombine::Process(FRenderingCompositePassContext& Context)
{
	SCOPED_DRAW_EVENT(Context.RHICmdList, DOFRecombine);

	const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input1);

	if(!InputDesc)
	{
		// input is not hooked up correctly
		return;
	}

	const FSceneView& View = Context.View;

	const auto FeatureLevel = Context.GetFeatureLevel();
	auto ShaderMap = Context.GetShaderMap();

	FIntPoint TexSize = InputDesc->Extent;

	// usually 1, 2, 4 or 8
	uint32 ScaleToFullRes = FSceneRenderTargets::Get(Context.RHICmdList).GetBufferSizeXY().X / TexSize.X;

	FIntRect HalfResViewRect = View.ViewRect / ScaleToFullRes;

	const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context);

	// Set the view family's render target/viewport.
	SetRenderTarget(Context.RHICmdList, DestRenderTarget.TargetableTexture, FTextureRHIRef());

	// is optimized away if possible (RT size=view size, )
	Context.RHICmdList.Clear(true, FLinearColor::Black, false, 1.0f, false, 0, View.ViewRect);

	Context.SetViewportAndCallRHI(View.ViewRect);

	// set the state
	Context.RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI());
	Context.RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI());
	Context.RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI());

	TShaderMapRef<FPostProcessVS> VertexShader(ShaderMap);

	if (bNearBlurEnabled)
	{
		static FGlobalBoundShaderState BoundShaderState;
		
		TShaderMapRef< FPostProcessDOFRecombinePS<1> > PixelShader(ShaderMap);
		SetGlobalBoundShaderState(Context.RHICmdList, FeatureLevel, BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);
		PixelShader->SetParameters(Context);
	}
	else
	{
		static FGlobalBoundShaderState BoundShaderState;
		
		TShaderMapRef< FPostProcessDOFRecombinePS<0> > PixelShader(ShaderMap);
		SetGlobalBoundShaderState(Context.RHICmdList, FeatureLevel, BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);
		PixelShader->SetParameters(Context);
	}

	VertexShader->SetParameters(Context);

	DrawPostProcessPass(
		Context.RHICmdList,
		0, 0,
		View.ViewRect.Width(), View.ViewRect.Height(),
		HalfResViewRect.Min.X, HalfResViewRect.Min.Y,
		HalfResViewRect.Width(), HalfResViewRect.Height(),
		View.ViewRect.Size(),
		TexSize,
		*VertexShader,
		View.StereoPass,
		Context.HasHmdMesh(),
		EDRF_UseTriangleOptimization);

	Context.RHICmdList.CopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams());
}
void FRCPassPostProcessLpvIndirect::Process(FRenderingCompositePassContext& Context)
{
	SCOPED_DRAW_EVENT(PostProcessLpvIndirect, DEC_SCENE_ITEMS);

	const FPostProcessSettings& PostprocessSettings = Context.View.FinalPostProcessSettings;
	const FSceneView& View = Context.View;
	const FSceneViewFamily& ViewFamily = *(View.Family);

	FIntRect SrcRect = View.ViewRect;
	// todo: view size should scale with input texture size so we can do SSAO in half resolution as well
	FIntRect DestRect = View.ViewRect;
	FIntPoint DestSize = DestRect.Size();

	uint32 NumReflectionCaptures = ViewFamily.Scene->GetRenderScene()->ReflectionSceneData.RegisteredReflectionCaptures.Num();

	const FSceneRenderTargetItem& DestColorRenderTarget = GSceneRenderTargets.SceneColor->GetRenderTargetItem();

	// Set the view family's render target/viewport.
	FTextureRHIParamRef RenderTargets[] =
	{
		DestColorRenderTarget.TargetableTexture,
	};

	// Set the view family's render target/viewport.
	RHISetRenderTargets(1, RenderTargets, GSceneRenderTargets.GetSceneDepthSurface(), 0, NULL);

	Context.SetViewportAndCallRHI(View.ViewRect);

	// set the state
	if ( ViewFamily.EngineShowFlags.LpvLightingOnly )
	{
		RHISetBlendState( TStaticBlendState<>::GetRHI() );
	}
	else
	{
		// additive blending
		RHISetBlendState(TStaticBlendState<CW_RGB,BO_Add,BF_One,BF_One>::GetRHI());
	}
	RHISetRasterizerState(TStaticRasterizerState<>::GetRHI());
	RHISetDepthStencilState(TStaticDepthStencilState<false,CF_Always>::GetRHI());

	TShaderMapRef<FPostProcessVS> VertexShader(GetGlobalShaderMap());

	FSceneViewState* ViewState = (FSceneViewState*)View.State;
	FLightPropagationVolume* Lpv = NULL;
	bool bUseLpv = false;
	if ( ViewState )
	{
		Lpv = ViewState->GetLightPropagationVolume();

		bUseLpv = Lpv && PostprocessSettings.LPVIntensity > 0.0f;
	}

	if ( !bUseLpv )
	{
		return;
	}

	TShaderMapRef<FPostProcessLpvIndirectPS> PixelShader(GetGlobalShaderMap());

	static FGlobalBoundShaderState BoundShaderState;

	// call it once after setting up the shader data to avoid the warnings in the function
	SetGlobalBoundShaderState(BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);

	FLpvReadUniformBufferParameters	LpvReadUniformBufferParams;
	FLpvReadUniformBufferRef LpvReadUniformBuffer;

	LpvReadUniformBufferParams = Lpv->GetReadUniformBufferParams();
	LpvReadUniformBuffer = FLpvReadUniformBufferRef::CreateUniformBufferImmediate( LpvReadUniformBufferParams, UniformBuffer_SingleUse ); 

#if LPV_VOLUME_TEXTURE
	FTextureRHIParamRef LpvBufferSrvs[7];
	for ( int i = 0; i < 7; i++ ) 
	{
		LpvBufferSrvs[i] = Lpv->GetLpvBufferSrv(i);
	}
	PixelShader->SetParameters(LpvBufferSrvs, LpvReadUniformBuffer, Context );
#else
	FShaderResourceViewRHIParamRef LpvBufferSrv = Lpv->GetLpvBufferSrv();
	PixelShader->SetParameters(LpvBufferSrv, LpvReadUniformBuffer, Context );
#endif

	// Draw a quad mapping scene color to the view's render target
	DrawRectangle( 
		0, 0,
		View.ViewRect.Width(), View.ViewRect.Height(),
		View.ViewRect.Min.X, View.ViewRect.Min.Y, 
		View.ViewRect.Width(), View.ViewRect.Height(),
		View.ViewRect.Size(),
		GSceneRenderTargets.SceneColor->GetDesc().Extent);

	RHICopyToResolveTarget(DestColorRenderTarget.TargetableTexture, DestColorRenderTarget.ShaderResourceTexture, false, FResolveParams());
}
void FRCPassPostProcessVisualizeHDR::Process(FRenderingCompositePassContext& Context)
{
	SCOPED_DRAW_EVENT(PostProcessVisualizeHDR, DEC_SCENE_ITEMS);
	const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0);

	if(!InputDesc)
	{
		// input is not hooked up correctly
		return;
	}

	const FSceneView& View = Context.View;
	const FSceneViewFamily& ViewFamily = *(View.Family);
	
	FIntRect SrcRect = View.ViewRect;
	FIntRect DestRect = View.ViewRect;
	FIntPoint SrcSize = InputDesc->Extent;

	const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context);

	// Set the view family's render target/viewport.
	RHISetRenderTarget(DestRenderTarget.TargetableTexture, FTextureRHIRef());	
	Context.SetViewportAndCallRHI(DestRect);

	// set the state
	RHISetBlendState(TStaticBlendState<>::GetRHI());
	RHISetRasterizerState(TStaticRasterizerState<>::GetRHI());
	RHISetDepthStencilState(TStaticDepthStencilState<false,CF_Always>::GetRHI());

	TShaderMapRef<FPostProcessVS> VertexShader(GetGlobalShaderMap());
	TShaderMapRef<FPostProcessVisualizeHDRPS> PixelShader(GetGlobalShaderMap());

	static FGlobalBoundShaderState BoundShaderState;

	SetGlobalBoundShaderState(BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);

	PixelShader->SetPS(Context);

	// Draw a quad mapping scene color to the view's render target
	DrawRectangle(
		DestRect.Min.X, DestRect.Min.Y,
		DestRect.Width(), DestRect.Height(),
		SrcRect.Min.X, SrcRect.Min.Y,
		SrcRect.Width(), SrcRect.Height(),
		DestRect.Size(),
		SrcSize,
		EDRF_UseTriangleOptimization);


	// this is a helper class for FCanvas to be able to get screen size
	class FRenderTargetTemp : public FRenderTarget
	{
	public:
		const FSceneView& View;
		const FTexture2DRHIRef Texture;

		FRenderTargetTemp(const FSceneView& InView, const FTexture2DRHIRef InTexture)
			: View(InView), Texture(InTexture)
		{
		}
		virtual FIntPoint GetSizeXY() const
		{
			return View.ViewRect.Size();
		};
		virtual const FTexture2DRHIRef& GetRenderTargetTexture() const
		{
			return Texture;
		}
	} TempRenderTarget(View, (const FTexture2DRHIRef&)DestRenderTarget.TargetableTexture);

	FCanvas Canvas(&TempRenderTarget, NULL, ViewFamily.CurrentRealTime, ViewFamily.CurrentWorldTime, ViewFamily.DeltaWorldTime);

	float X = 30;
	float Y = 8;
	const float YStep = 14;
	const float ColumnWidth = 250;

	FString Line;

	Line = FString::Printf(TEXT("HDR Histogram (Logarithmic, max of RGB)"));
	Canvas.DrawShadowedString( X, Y += YStep, *Line, GetStatsFont(), FLinearColor(1, 1, 1));
	
	Y += 160;

	float MinX = 64 + 10;
	float MaxY = View.ViewRect.Max.Y - 64;
	float SizeX = View.ViewRect.Size().X - 64 * 2 - 20;

	for(uint32 i = 0; i <= 4; ++i)
	{
		int XAdd = (int)(i * SizeX / 4);
		float HistogramPosition =  i / 4.0f;
		float LogValue = FMath::Lerp(View.FinalPostProcessSettings.HistogramLogMin, View.FinalPostProcessSettings.HistogramLogMax, HistogramPosition);

		Line = FString::Printf(TEXT("%.2g"), LogValue);
		Canvas.DrawShadowedString( MinX + XAdd - 5, MaxY, *Line, GetStatsFont(), FLinearColor(1, 0.3f, 0.3f));
		Line = LogToString(LogValue);
		Canvas.DrawShadowedString( MinX + XAdd - 5, MaxY + YStep, *Line, GetStatsFont(), FLinearColor(0.3f, 0.3f, 1));
	}
	Y += 3 * YStep;
	
	Line = FString::Printf(TEXT("%g%% .. %g%%"), View.FinalPostProcessSettings.AutoExposureLowPercent, View.FinalPostProcessSettings.AutoExposureHighPercent);
	Canvas.DrawShadowedString( X, Y += YStep, TEXT("EyeAdaptationPercent Low/High:"), GetStatsFont(), FLinearColor(1, 1, 1));
	Canvas.DrawShadowedString( X + ColumnWidth, Y, *Line, GetStatsFont(), FLinearColor(1, 1, 1));

	Line = FString::Printf(TEXT("%g .. %g"), View.FinalPostProcessSettings.AutoExposureMinBrightness, View.FinalPostProcessSettings.AutoExposureMaxBrightness);
	Canvas.DrawShadowedString( X, Y += YStep, TEXT("EyeAdaptationBrightness Min/Max:"), GetStatsFont(), FLinearColor(1, 1, 1));
	Canvas.DrawShadowedString( X + ColumnWidth, Y, *Line, GetStatsFont(), FLinearColor(0.3f, 0.3f, 1));

	Line = FString::Printf(TEXT("%g / %g"), View.FinalPostProcessSettings.AutoExposureSpeedUp, View.FinalPostProcessSettings.AutoExposureSpeedDown);
	Canvas.DrawShadowedString( X, Y += YStep, TEXT("EyeAdaptionSpeed Up/Down:"), GetStatsFont(), FLinearColor(1, 1, 1));
	Canvas.DrawShadowedString( X + ColumnWidth, Y, *Line, GetStatsFont(), FLinearColor(1, 1, 1));

	Line = FString::Printf(TEXT("%g"), View.FinalPostProcessSettings.AutoExposureBias);
	Canvas.DrawShadowedString( X, Y += YStep, TEXT("Exposure Offset: "), GetStatsFont(), FLinearColor(1, 1, 1));
	Canvas.DrawShadowedString( X + ColumnWidth, Y, *Line, GetStatsFont(), FLinearColor(1, 0.3f, 0.3f));

	Line = FString::Printf(TEXT("%g .. %g (log2)"),
		View.FinalPostProcessSettings.HistogramLogMin, View.FinalPostProcessSettings.HistogramLogMax);
	Canvas.DrawShadowedString( X, Y += YStep, TEXT("HistogramLog Min/Max:"), GetStatsFont(), FLinearColor(1, 1, 1));
	Canvas.DrawShadowedString( X + ColumnWidth, Y, *Line, GetStatsFont(), FLinearColor(1, 0.3f, 0.3f));
	Line = FString::Printf(TEXT("%s .. %s (Value)"),
		*LogToString(View.FinalPostProcessSettings.HistogramLogMin), *LogToString(View.FinalPostProcessSettings.HistogramLogMax));
	Canvas.DrawShadowedString( X + ColumnWidth, Y+= YStep, *Line, GetStatsFont(), FLinearColor(0.3f, 0.3f, 1));

	Canvas.Flush();

	RHICopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams());
}
void FRCPassPostProcessGBufferHints::Process(FRenderingCompositePassContext& Context)
{
	SCOPED_DRAW_EVENT(Context.RHICmdList, GBufferHints);
	const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0);

	if(!InputDesc)
	{
		// input is not hooked up correctly
		return;
	}

	const FSceneView& View = Context.View;
	const FSceneViewFamily& ViewFamily = *(View.Family);
	
	FIntRect SrcRect = View.ViewRect;
	FIntRect DestRect = View.ViewRect;
	FIntPoint SrcSize = InputDesc->Extent;

	const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context);

	// Set the view family's render target/viewport.
	SetRenderTarget(Context.RHICmdList, DestRenderTarget.TargetableTexture, FTextureRHIRef());
	Context.SetViewportAndCallRHI(DestRect);

	// set the state
	Context.RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI());
	Context.RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI());
	Context.RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI());

	TShaderMapRef<FPostProcessVS> VertexShader(Context.GetShaderMap());
	TShaderMapRef<FPostProcessGBufferHintsPS> PixelShader(Context.GetShaderMap());

	static FGlobalBoundShaderState BoundShaderState;
	

	SetGlobalBoundShaderState(Context.RHICmdList, Context.GetFeatureLevel(), BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);

	PixelShader->SetPS(Context);

	// Draw a quad mapping scene color to the view's render target
	DrawRectangle(
		Context.RHICmdList,
		0, 0,
		DestRect.Width(), DestRect.Height(),
		SrcRect.Min.X, SrcRect.Min.Y,
		SrcRect.Width(), SrcRect.Height(),
		DestRect.Size(),
		SrcSize,
		*VertexShader,
		EDRF_UseTriangleOptimization);


	// this is a helper class for FCanvas to be able to get screen size
	class FRenderTargetTemp : public FRenderTarget
	{
	public:
		const FSceneView& View;
		const FTexture2DRHIRef Texture;

		FRenderTargetTemp(const FSceneView& InView, const FTexture2DRHIRef InTexture)
			: View(InView), Texture(InTexture)
		{
		}
		virtual FIntPoint GetSizeXY() const
		{
			return View.ViewRect.Size();
		};
		virtual const FTexture2DRHIRef& GetRenderTargetTexture() const
		{
			return Texture;
		}
	} TempRenderTarget(View, (const FTexture2DRHIRef&)DestRenderTarget.TargetableTexture);

	FCanvas Canvas(&TempRenderTarget, NULL, ViewFamily.CurrentRealTime, ViewFamily.CurrentWorldTime, ViewFamily.DeltaWorldTime, View.GetFeatureLevel());

	float X = 30;
	float Y = 8;
	const float YStep = 14;
	const float ColumnWidth = 250;

	FString Line;

	Line = FString::Printf(TEXT("GBufferHints"));
	Canvas.DrawShadowedString( X, Y += YStep, *Line, GetStatsFont(), FLinearColor(1, 1, 1));

	Y += YStep;
	
	Line = FString::Printf(TEXT("Yellow: Unrealistic material (In nature even black materials reflect quite some light)"));
	Canvas.DrawShadowedString( X, Y += YStep, *Line, GetStatsFont(), FLinearColor(0.8f, 0.8f, 0));

	Line = FString::Printf(TEXT("Red: Impossive material (this material emits more light than it receives)"));
	Canvas.DrawShadowedString( X, Y += YStep, *Line, GetStatsFont(), FLinearColor(1, 0, 0));

	Canvas.Flush_RenderThread(Context.RHICmdList);

	Context.RHICmdList.CopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams());

	// AdjustGBufferRefCount(1) call is done in constructor
	FSceneRenderTargets::Get(Context.RHICmdList).AdjustGBufferRefCount(-1);
}
void FRCPassPostProcessScreenSpaceReflections::Process(FRenderingCompositePassContext& Context)
{
	auto& RHICmdList = Context.RHICmdList;
	FSceneRenderTargets& SceneContext = FSceneRenderTargets::Get(RHICmdList);

	const FSceneView& View = Context.View;
	const auto FeatureLevel = Context.GetFeatureLevel();

	int32 SSRQuality = ComputeSSRQuality(View.FinalPostProcessSettings.ScreenSpaceReflectionQuality);
	uint32 iPreFrame = bPrevFrame ? 1 : 0;

	SSRQuality = FMath::Clamp(SSRQuality, 1, 4);
	
	const bool VisualizeSSR = View.Family->EngineShowFlags.VisualizeSSR;
	const bool SSRStencilPrePass = CVarSSRStencil.GetValueOnRenderThread() != 0 && !VisualizeSSR;

	FRenderingCompositeOutputRef* Input2 = GetInput(ePId_Input2);

	const bool SSRConeTracing = Input2 && Input2->GetOutput();
	
	if (VisualizeSSR)
	{
		iPreFrame = 0;
		SSRQuality = 0;
	}
	else if (SSRConeTracing)
	{
		SSRQuality = SSRConeQuality;
	}
	
	const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context);
	
	if (SSRStencilPrePass)
	{ // ScreenSpaceReflectionsStencil draw event
		SCOPED_DRAW_EVENT(RHICmdList, ScreenSpaceReflectionsStencil);

		TShaderMapRef< FPostProcessVS > VertexShader(Context.GetShaderMap());
		TShaderMapRef< FPostProcessScreenSpaceReflectionsStencilPS > PixelShader(Context.GetShaderMap());
		
		// bind the dest render target and the depth stencil render target
		SetRenderTarget(RHICmdList, DestRenderTarget.TargetableTexture, SceneContext.GetSceneDepthSurface(), ESimpleRenderTargetMode::EUninitializedColorAndDepth, FExclusiveDepthStencil::DepthRead_StencilWrite);
		Context.SetViewportAndCallRHI(View.ViewRect);

		// Clear stencil to 0
		RHICmdList.Clear(false, FLinearColor::White, false, (float)ERHIZBuffer::FarPlane, true, 0, View.ViewRect);
		
		// bind shader
		static FGlobalBoundShaderState BoundShaderState;
		SetGlobalBoundShaderState(Context.RHICmdList, FeatureLevel, BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);
		VertexShader->SetParameters(Context);
		PixelShader->SetParameters(Context, SSRQuality, true);
		
		// Clobers the stencil to pixel that should not compute SSR
		RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always, true, CF_Always, SO_Replace, SO_Replace, SO_Replace>::GetRHI(), 0x80);

		// Set rasterizer state to solid
		RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI());

		// disable blend mode
		RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI());
	
		// Draw a quad mapping scene color to the view's render target to set stencil to set the stencil mask where it needs to be
		DrawRectangle( 
			Context.RHICmdList,
			0, 0,
			View.ViewRect.Width(), View.ViewRect.Height(),
			View.ViewRect.Min.X, View.ViewRect.Min.Y, 
			View.ViewRect.Width(), View.ViewRect.Height(),
			View.ViewRect.Size(),
			SceneContext.GetBufferSizeXY(),
			*VertexShader,
			EDRF_UseTriangleOptimization);
	} // ScreenSpaceReflectionsStencil draw event

	{ // ScreenSpaceReflections draw event
		SCOPED_DRAW_EVENT(Context.RHICmdList, ScreenSpaceReflections);

		if (SSRStencilPrePass)
		{
			// set up the stencil test to match 0, meaning FPostProcessScreenSpaceReflectionsStencilPS has been discarded
			RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always, true, CF_Equal, SO_Keep, SO_Keep, SO_Keep>::GetRHI(), 0);
		}
		else
		{
			// bind only the dest render target
			SetRenderTarget(RHICmdList, DestRenderTarget.TargetableTexture, FTextureRHIRef());
			Context.SetViewportAndCallRHI(View.ViewRect);

			RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI());
		}

		// clear DestRenderTarget only outside of the view's rectangle
		RHICmdList.Clear(true, FLinearColor::Black, false, (float)ERHIZBuffer::FarPlane, false, 0, View.ViewRect);
		
		// set the state
		RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI());
		RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI());

		TShaderMapRef< FPostProcessVS > VertexShader(Context.GetShaderMap());

		#define CASE(A, B) \
			case (A + 2 * (B + 3 * 0 )): \
			{ \
				TShaderMapRef< FPostProcessScreenSpaceReflectionsPS<A, B> > PixelShader(Context.GetShaderMap()); \
				static FGlobalBoundShaderState BoundShaderState; \
				SetGlobalBoundShaderState(RHICmdList, FeatureLevel, BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); \
				VertexShader->SetParameters(Context); \
				PixelShader->SetParameters(Context); \
			}; \
			break

		switch (iPreFrame + 2 * (SSRQuality + 3 * 0))
		{
			CASE(0,0);
			CASE(0,1);	CASE(1,1);
			CASE(0,2);	CASE(1,2);
			CASE(0,3);	CASE(1,3);
			CASE(0,4);	CASE(1,4);
			CASE(0,5);	CASE(1,5); //SSRConeQuality
			default:
				check(!"Missing case in FRCPassPostProcessScreenSpaceReflections");
		}
		#undef CASE


		// Draw a quad mapping scene color to the view's render target
		DrawRectangle( 
			RHICmdList,
			0, 0,
			View.ViewRect.Width(), View.ViewRect.Height(),
			View.ViewRect.Min.X, View.ViewRect.Min.Y, 
			View.ViewRect.Width(), View.ViewRect.Height(),
			View.ViewRect.Size(),
			FSceneRenderTargets::Get(Context.RHICmdList).GetBufferSizeXY(),
			*VertexShader,
			EDRF_UseTriangleOptimization);

		RHICmdList.CopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams());
	} // ScreenSpaceReflections
}
void FRCPassPostProcessMotionBlurRecombine::Process(FRenderingCompositePassContext& Context)
{
	SCOPED_DRAW_EVENT(MotionBlurRecombine, DEC_SCENE_ITEMS);

	const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0);

	if(!InputDesc)
	{
		// input is not hooked up correctly
		return;
	}

	const FSceneView& View = Context.View;

	FIntPoint TexSize = InputDesc->Extent;

	// we assume the input and output is full resolution

	FIntPoint SrcSize = InputDesc->Extent;
	FIntPoint DestSize = PassOutputs[0].RenderTargetDesc.Extent;

	// e.g. 4 means the input texture is 4x smaller than the buffer size
	uint32 ScaleFactor = GSceneRenderTargets.GetBufferSizeXY().X / SrcSize.X;

	FIntRect SrcRect = View.ViewRect / ScaleFactor;
	FIntRect DestRect = SrcRect;

	const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context);

	// Set the view family's render target/viewport.
	RHISetRenderTarget(DestRenderTarget.TargetableTexture, FTextureRHIRef());	

	// is optimized away if possible (RT size=view size, )
	RHIClear(true, FLinearColor::Black, false, 1.0f, false, 0, SrcRect);

	Context.SetViewportAndCallRHI(SrcRect);

	// set the state
	RHISetBlendState(TStaticBlendState<>::GetRHI());
	RHISetRasterizerState(TStaticRasterizerState<>::GetRHI());
	RHISetDepthStencilState(TStaticDepthStencilState<false,CF_Always>::GetRHI());

	TShaderMapRef<FPostProcessVS> VertexShader(GetGlobalShaderMap());
	TShaderMapRef<FPostProcessMotionBlurRecombinePS> PixelShader(GetGlobalShaderMap());

	static FGlobalBoundShaderState BoundShaderState;

	SetGlobalBoundShaderState(BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);

	VertexShader->SetParameters(Context);
	PixelShader->SetParameters(Context);

	// Draw a quad mapping scene color to the view's render target
	DrawRectangle(
		0, 0,
		SrcRect.Width(), SrcRect.Height(),
		SrcRect.Min.X, SrcRect.Min.Y, 
		SrcRect.Width(), SrcRect.Height(),
		SrcRect.Size(),
		SrcSize,
		EDRF_UseTriangleOptimization);

	RHICopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams());
}
void FGoogleVRHMD::RenderTexture_RenderThread(FRHICommandListImmediate& RHICmdList, FTexture2DRHIParamRef BackBuffer, FTexture2DRHIParamRef SrcTexture) const
{
	check(IsInRenderingThread());

	const uint32 ViewportWidth = BackBuffer->GetSizeX();
	const uint32 ViewportHeight = BackBuffer->GetSizeY();
	const uint32 TextureWidth = SrcTexture->GetSizeX();
	const uint32 TextureHeight = SrcTexture->GetSizeY();
	
	//UE_LOG(LogHMD, Log, TEXT("RenderTexture_RenderThread() Viewport:(%d, %d) Texture:(%d, %d) BackBuffer=%p SrcTexture=%p"), ViewportWidth, ViewportHeight, TextureWidth, TextureHeight, BackBuffer, SrcTexture);

	RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI());
	RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI());
	RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI());
	
#if GOOGLEVRHMD_SUPPORTED_PLATFORMS

	if(IsUsingGVRApiDistortionCorrection())
	{
		if(!bDistortionCorrectionEnabled)
		{
			return;
		}

		// Perform render
		if(!bUseOffscreenFramebuffers)
		{
			// With proper resolution scaling, this should always be true!
			check(ViewportWidth == TextureWidth);
			check(ViewportHeight == TextureHeight);

			// Set target to back buffer
			SetRenderTarget(RHICmdList, BackBuffer, FTextureRHIRef());
			RHICmdList.SetViewport(0, 0, 0, ViewportWidth, ViewportHeight, 1.0f);
			ResolvePendingRenderTarget(RHICmdList, RendererModule);

			gvr_distort_to_screen(GVRAPI, *reinterpret_cast<GLuint*>(SrcTexture->GetNativeResource()),
				CachedDistortedRenderTextureParams,
				&CachedPose,
				&CachedFuturePoseTime);
		}
		else
		{
			if(!IsDeviceScanlineRacingEnabled())
			{
				// With proper resolution scaling, this should always be true!
				check(ViewportWidth == TextureWidth);
				check(ViewportHeight == TextureHeight);

				// Set target to back buffer
				SetRenderTarget(RHICmdList, BackBuffer, FTextureRHIRef());
				RHICmdList.SetViewport(0, 0, 0, ViewportWidth, ViewportHeight, 1.0f);
				ResolvePendingRenderTarget(RHICmdList, RendererModule);
			}

			gvr_distort_offscreen_framebuffer_to_screen(GVRAPI, CustomPresent->GetFrameBufferId(),
				CachedDistortedRenderTextureParams,
				&CachedPose,
				&CachedFuturePoseTime);
		}
	}
	else // falls through on purpose

#endif // GOOGLEVRHMD_SUPPORTED_PLATFORMS

	// Just render directly to output
	{
		SetRenderTarget(RHICmdList, BackBuffer, FTextureRHIRef());
		RHICmdList.SetViewport(0, 0, 0, ViewportWidth, ViewportHeight, 1.0f);

		const auto FeatureLevel = GMaxRHIFeatureLevel;
		auto ShaderMap = GetGlobalShaderMap(FeatureLevel);

		TShaderMapRef<FScreenVS> VertexShader(ShaderMap);
		TShaderMapRef<FScreenPS> PixelShader(ShaderMap);

		static FGlobalBoundShaderState BoundShaderState;
		SetGlobalBoundShaderState(RHICmdList, FeatureLevel, BoundShaderState, RendererModule->GetFilterVertexDeclaration().VertexDeclarationRHI, *VertexShader, *PixelShader);

		PixelShader->SetParameters(RHICmdList, TStaticSamplerState<SF_Bilinear>::GetRHI(), SrcTexture);

		RendererModule->DrawRectangle(
			RHICmdList,
			0, 0,
			ViewportWidth, ViewportHeight,
			0.0f, 0.0f,
			1.0f, 1.0f,
			FIntPoint(ViewportWidth, ViewportHeight),
			FIntPoint(1, 1),
			*VertexShader,
			EDRF_Default);
	}
}
示例#26
0
//----------------------------------------------------------------------------
VisualEffectInstance* GeodesicHeightField::CreateEffectInstance ()
{
	// Create the vertex shader.
	VertexShader* vshader = new0 VertexShader("Wm5.DLight2MatTex",
	                        3, 3, 16, 0, false);
	vshader->SetInput(0, "modelPosition", Shader::VT_FLOAT3,
	                  Shader::VS_POSITION);
	vshader->SetInput(1, "modelNormal", Shader::VT_FLOAT3,
	                  Shader::VS_NORMAL);
	vshader->SetInput(2, "modelTCoord", Shader::VT_FLOAT2,
	                  Shader::VS_TEXCOORD0);
	vshader->SetOutput(0, "clipPosition", Shader::VT_FLOAT4,
	                   Shader::VS_POSITION);
	vshader->SetOutput(1, "vertexColor", Shader::VT_FLOAT4,
	                   Shader::VS_COLOR0);
	vshader->SetOutput(2, "vertexTCoord", Shader::VT_FLOAT2,
	                   Shader::VS_TEXCOORD0);
	vshader->SetConstant( 0, "PVWMatrix", 4);
	vshader->SetConstant( 1, "CameraModelPosition", 1);
	vshader->SetConstant( 2, "MaterialEmissive", 1);
	vshader->SetConstant( 3, "MaterialAmbient", 1);
	vshader->SetConstant( 4, "MaterialDiffuse", 1);
	vshader->SetConstant( 5, "MaterialSpecular", 1);
	vshader->SetConstant( 6, "Light0ModelDirection", 1);
	vshader->SetConstant( 7, "Light0Ambient", 1);
	vshader->SetConstant( 8, "Light0Diffuse", 1);
	vshader->SetConstant( 9, "Light0Specular", 1);
	vshader->SetConstant(10, "Light0Attenuation", 1);
	vshader->SetConstant(11, "Light1ModelDirection", 1);
	vshader->SetConstant(12, "Light1Ambient", 1);
	vshader->SetConstant(13, "Light1Diffuse", 1);
	vshader->SetConstant(14, "Light1Specular", 1);
	vshader->SetConstant(15, "Light1Attenuation", 1);
	vshader->SetBaseRegisters(msVRegisters);
	vshader->SetPrograms(msVPrograms);

	// Create the pixel shader.
	PixelShader* pshader = new0 PixelShader("Wm5.DLight2MatTex",
	                                        2, 1, 0, 1, false);
	pshader->SetInput(0, "vertexColor", Shader::VT_FLOAT4,
	                  Shader::VS_COLOR0);
	pshader->SetInput(1, "vertexTCoord", Shader::VT_FLOAT2,
	                  Shader::VS_TEXCOORD0);
	pshader->SetOutput(0, "pixelColor", Shader::VT_FLOAT4,
	                   Shader::VS_COLOR0);
	pshader->SetSampler(0, "BaseSampler", Shader::ST_2D);
	pshader->SetFilter(0, Shader::SF_LINEAR /*_LINEAR */);
	pshader->SetCoordinate(0, 0, Shader::SC_CLAMP_EDGE);
	pshader->SetCoordinate(0, 1, Shader::SC_CLAMP_EDGE);
	pshader->SetTextureUnits(msPTextureUnits);
	pshader->SetPrograms(msPPrograms);

	VisualPass* pass = new0 VisualPass();
	pass->SetVertexShader(vshader);
	pass->SetPixelShader(pshader);
	pass->SetAlphaState(new0 AlphaState());
	pass->SetCullState(new0 CullState());
	pass->SetDepthState(new0 DepthState());
	pass->SetOffsetState(new0 OffsetState());
	pass->SetStencilState(new0 StencilState());
	pass->SetWireState(new0 WireState());

	// Create the effect.
	VisualTechnique* technique = new0 VisualTechnique();
	technique->InsertPass(pass);
	VisualEffect* effect = new0 VisualEffect();
	effect->InsertTechnique(technique);

	// Create the material for the effect.
	Float4 black(0.0f, 0.0f, 0.0f, 1.0f);
	Float4 white(1.0f, 1.0f, 1.0f, 1.0f);
	Material* material = new0 Material();
	material->Emissive = black;
	material->Ambient = Float4(0.24725f, 0.2245f, 0.0645f, 1.0f);
	material->Diffuse = Float4(0.34615f, 0.3143f, 0.0903f, 1.0f);
	material->Specular = Float4(0.797357f, 0.723991f, 0.208006f, 83.2f);

	// Create the lights for the effect.
	Light* light0 = new0 Light(Light::LT_DIRECTIONAL);
	light0->SetDirection(AVector(0.0f, 0.0f, -1.0f));
	light0->Ambient = white;
	light0->Diffuse = white;
	light0->Specular = black;

	Light* light1 = new0 Light(Light::LT_DIRECTIONAL);
	light1->SetDirection(AVector(0.0f, 0.0f, 1.0f));
	light1->Ambient = white;
	light1->Diffuse = white;
	light1->Specular = black;

	// Create a texture for the effect.
	mTexture = new0 Texture2D(Texture::TF_A8R8G8B8, 512, 512, 0);
	unsigned char* data = (unsigned char*)mTexture->GetData(0);
	memset(data, 0xFF, mTexture->GetNumLevelBytes(0));

	// Create an instance of the effect.
	VisualEffectInstance* instance = new0 VisualEffectInstance(effect, 0);
	instance->SetVertexConstant(0, 0,
	                            new0 PVWMatrixConstant());
	instance->SetVertexConstant(0, 1,
	                            new0 CameraModelPositionConstant());
	instance->SetVertexConstant(0, 2,
	                            new0 MaterialEmissiveConstant(material));
	instance->SetVertexConstant(0, 3,
	                            new0 MaterialAmbientConstant(material));
	instance->SetVertexConstant(0, 4,
	                            new0 MaterialDiffuseConstant(material));
	instance->SetVertexConstant(0, 5,
	                            new0 MaterialSpecularConstant(material));
	instance->SetVertexConstant(0, 6,
	                            new0 LightModelDVectorConstant(light0));
	instance->SetVertexConstant(0, 7,
	                            new0 LightAmbientConstant(light0));
	instance->SetVertexConstant(0, 8,
	                            new0 LightDiffuseConstant(light0));
	instance->SetVertexConstant(0, 9,
	                            new0 LightSpecularConstant(light0));
	instance->SetVertexConstant(0, 10,
	                            new0 LightAttenuationConstant(light0));
	instance->SetVertexConstant(0, 11,
	                            new0 LightModelDVectorConstant(light1));
	instance->SetVertexConstant(0, 12,
	                            new0 LightAmbientConstant(light1));
	instance->SetVertexConstant(0, 13,
	                            new0 LightDiffuseConstant(light1));
	instance->SetVertexConstant(0, 14,
	                            new0 LightSpecularConstant(light1));
	instance->SetVertexConstant(0, 15,
	                            new0 LightAttenuationConstant(light1));

	instance->SetPixelTexture(0, 0, mTexture);

	return instance;
}
void FRCPassPostProcessPassThrough::Process(FRenderingCompositePassContext& Context)
{
	SCOPED_DRAW_EVENT(PassThrough, DEC_SCENE_ITEMS);

	const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0);

	if(!InputDesc)
	{
		// input is not hooked up correctly
		return;
	}

	const FSceneView& View = Context.View;

	FIntPoint TexSize = InputDesc->Extent;

	// we assume the input and output is full resolution

	FIntPoint SrcSize = InputDesc->Extent;
	FIntPoint DestSize = Dest ? Dest->GetDesc().Extent : PassOutputs[0].RenderTargetDesc.Extent;

	// e.g. 4 means the input texture is 4x smaller than the buffer size
	uint32 InputScaleFactor = GSceneRenderTargets.GetBufferSizeXY().X / SrcSize.X;
	uint32 OutputScaleFactor = GSceneRenderTargets.GetBufferSizeXY().X / DestSize.X;

	FIntRect SrcRect = View.ViewRect / InputScaleFactor;
	FIntRect DestRect = View.ViewRect / OutputScaleFactor;

	const FSceneRenderTargetItem& DestRenderTarget = Dest ? Dest->GetRenderTargetItem() : PassOutputs[0].RequestSurface(Context);

	// Set the view family's render target/viewport.
	RHISetRenderTarget(DestRenderTarget.TargetableTexture, FTextureRHIRef());	
	Context.SetViewportAndCallRHI(0, 0, 0.0f, DestSize.X, DestSize.Y, 1.0f);

	// set the state
	if(bAdditiveBlend)
	{
		RHISetBlendState(TStaticBlendState<CW_RGB,BO_Add,BF_One,BF_One,BO_Add,BF_One,BF_One>::GetRHI());
	}
	else
	{
		RHISetBlendState(TStaticBlendState<>::GetRHI());
	}

	RHISetRasterizerState(TStaticRasterizerState<>::GetRHI());
	RHISetDepthStencilState(TStaticDepthStencilState<false,CF_Always>::GetRHI());

	TShaderMapRef<FPostProcessVS> VertexShader(GetGlobalShaderMap());
	TShaderMapRef<FPostProcessPassThroughPS> PixelShader(GetGlobalShaderMap());

	static FGlobalBoundShaderState BoundShaderState;

	SetGlobalBoundShaderState(BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);

	VertexShader->SetParameters(Context);
	PixelShader->SetParameters(Context);

	// Draw a quad mapping scene color to the view's render target
	DrawRectangle(
		DestRect.Min.X, DestRect.Min.Y,
		DestRect.Width(), DestRect.Height(),
		SrcRect.Min.X, SrcRect.Min.Y,
		SrcRect.Width(), SrcRect.Height(),
		DestSize,
		SrcSize,
		EDRF_UseTriangleOptimization);


	RHICopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams());
}
void FRCPassPostProcessTestImage::Process(FRenderingCompositePassContext& Context)
{
	SCOPED_DRAW_EVENT(Context.RHICmdList, TestImage, DEC_SCENE_ITEMS);

	const FSceneView& View = Context.View;
	const FSceneViewFamily& ViewFamily = *(View.Family);
	
	FIntRect SrcRect = View.ViewRect;
	FIntRect DestRect = View.ViewRect;

	const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context);

	// Set the view family's render target/viewport.
	SetRenderTarget(Context.RHICmdList, DestRenderTarget.TargetableTexture, FTextureRHIRef());
	Context.SetViewportAndCallRHI(DestRect);

	// set the state
	Context.RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI());
	Context.RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI());
	Context.RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI());

	TShaderMapRef<FPostProcessVS> VertexShader(Context.GetShaderMap());
	TShaderMapRef<FPostProcessTestImagePS> PixelShader(Context.GetShaderMap());

	static FGlobalBoundShaderState BoundShaderState;
	

	SetGlobalBoundShaderState(Context.RHICmdList, Context.GetFeatureLevel(), BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);

	PixelShader->SetPS(Context);

	// Draw a quad mapping scene color to the view's render target
	DrawRectangle(
		Context.RHICmdList,
		0, 0,
		DestRect.Width(), DestRect.Height(),
		SrcRect.Min.X, SrcRect.Min.Y,
		SrcRect.Width(), SrcRect.Height(),
		DestRect.Size(),
		GSceneRenderTargets.GetBufferSizeXY(),
		*VertexShader,
		EDRF_UseTriangleOptimization);

	{
		// this is a helper class for FCanvas to be able to get screen size
		class FRenderTargetTemp : public FRenderTarget
		{
		public:
			const FSceneView& View;
			const FTexture2DRHIRef Texture;

			FRenderTargetTemp(const FSceneView& InView, const FTexture2DRHIRef InTexture)
				: View(InView), Texture(InTexture)
			{
			}
			virtual FIntPoint GetSizeXY() const
			{
				return View.ViewRect.Size();
			};
			virtual const FTexture2DRHIRef& GetRenderTargetTexture() const
			{
				return Texture;
			}
		} TempRenderTarget(View, (const FTexture2DRHIRef&)DestRenderTarget.TargetableTexture);

		FCanvas Canvas(&TempRenderTarget, NULL, ViewFamily.CurrentRealTime, ViewFamily.CurrentWorldTime, ViewFamily.DeltaWorldTime, Context.GetFeatureLevel());

		float X = 30;
		float Y = 8;
		const float YStep = 14;
		const float ColumnWidth = 250;

		FString Line;

		Line = FString::Printf(TEXT("Top bars:"));
		Canvas.DrawShadowedString( X, Y += YStep, *Line, GetStatsFont(), FLinearColor(1, 1, 1));
		Line = FString::Printf(TEXT("   Moving bars using FrameTime"));
		Canvas.DrawShadowedString( X, Y += YStep, *Line, GetStatsFont(), FLinearColor(1, 1, 1));
		Line = FString::Printf(TEXT("   Black and white raster, Pixel sized, Watch for Moire pattern"));
		Canvas.DrawShadowedString( X, Y += YStep, *Line, GetStatsFont(), FLinearColor(1, 1, 1));
		Line = FString::Printf(TEXT("   Black and white raster, 2x2 block sized"));
		Canvas.DrawShadowedString( X, Y += YStep, *Line, GetStatsFont(), FLinearColor(1, 1, 1));
		Line = FString::Printf(TEXT("Bottom bars:"));
		Canvas.DrawShadowedString( X, Y += YStep, *Line, GetStatsFont(), FLinearColor(1, 1, 1));
		Line = FString::Printf(TEXT("   8 bars near white, 4 right bars should appear as one (HDTV)"));
		Canvas.DrawShadowedString( X, Y += YStep, *Line, GetStatsFont(), FLinearColor(1, 1, 1));
		Line = FString::Printf(TEXT("   8 bars near black, 4 left bars should appear as one (HDTV)"));
		Canvas.DrawShadowedString( X, Y += YStep, *Line, GetStatsFont(), FLinearColor(1, 1, 1));
		Line = FString::Printf(TEXT("   Linear Greyscale in sRGB from 0 to 255"));
		Canvas.DrawShadowedString( X, Y += YStep, *Line, GetStatsFont(), FLinearColor(1, 1, 1));
		Line = FString::Printf(TEXT("Color bars:"));
		Canvas.DrawShadowedString( X, Y += YStep, *Line, GetStatsFont(), FLinearColor(1, 1, 1));
		Line = FString::Printf(TEXT("   Red, Green, Blue"));
		Canvas.DrawShadowedString( X, Y += YStep, *Line, GetStatsFont(), FLinearColor(1, 1, 1));
		Line = FString::Printf(TEXT("Outside:"));
		Canvas.DrawShadowedString( X, Y += YStep, *Line, GetStatsFont(), FLinearColor(1, 1, 1));
		Line = FString::Printf(TEXT("   Moving bars using FrameNumber, Tearing without VSync"));
		Canvas.DrawShadowedString( X, Y += YStep, *Line, GetStatsFont(), FLinearColor(1, 1, 1));
		Line = FString::Printf(TEXT("Circles:"));
		Canvas.DrawShadowedString( X, Y += YStep, *Line, GetStatsFont(), FLinearColor(1, 1, 1));
		Line = FString::Printf(TEXT("   Should be round and centered"));
		Canvas.DrawShadowedString( X, Y += YStep, *Line, GetStatsFont(), FLinearColor(1, 1, 1));
		Line = FString::Printf(TEXT("Border:"));
		Canvas.DrawShadowedString( X, Y += YStep, *Line, GetStatsFont(), FLinearColor(1, 1, 1));
		Line = FString::Printf(TEXT("   4 white pixel sized lines (only visible without overscan)"));
		Canvas.DrawShadowedString( X, Y += YStep, *Line, GetStatsFont(), FLinearColor(1, 1, 1));

		Canvas.Flush_RenderThread(Context.RHICmdList);
	}


	Context.RHICmdList.CopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams());
}
示例#29
0
void FRCPassPostProcessDOFSetup::Process(FRenderingCompositePassContext& Context)
{
	SCOPED_DRAW_EVENT(Context.RHICmdList, DOFSetup);

	const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0);

	if(!InputDesc)
	{
		// input is not hooked up correctly
		return;
	}

	uint32 NumRenderTargets = bNearBlurEnabled ? 2 : 1;

	const FSceneView& View = Context.View;
	const FSceneViewFamily& ViewFamily = *(View.Family);

	const auto FeatureLevel = Context.GetFeatureLevel();
	auto ShaderMap = Context.GetShaderMap();

	FIntPoint SrcSize = InputDesc->Extent;
	FIntPoint DestSize = PassOutputs[0].RenderTargetDesc.Extent;

	// e.g. 4 means the input texture is 4x smaller than the buffer size
	uint32 ScaleFactor = FSceneRenderTargets::Get(Context.RHICmdList).GetBufferSizeXY().X / SrcSize.X;

	FIntRect SrcRect = View.ViewRect / ScaleFactor;
	FIntRect DestRect = SrcRect / 2;

	const FSceneRenderTargetItem& DestRenderTarget0 = PassOutputs[0].RequestSurface(Context);
	const FSceneRenderTargetItem& DestRenderTarget1 = bNearBlurEnabled ? PassOutputs[1].RequestSurface(Context) : FSceneRenderTargetItem();

	// Set the view family's render target/viewport.
	FTextureRHIParamRef RenderTargets[2] =
	{
		DestRenderTarget0.TargetableTexture,
		DestRenderTarget1.TargetableTexture
	};
	SetRenderTargets(Context.RHICmdList, NumRenderTargets, RenderTargets, FTextureRHIParamRef(), 0, NULL);
	
	FLinearColor ClearColors[2] = 
	{
		FLinearColor(0, 0, 0, 0),
		FLinearColor(0, 0, 0, 0)
	};
	// is optimized away if possible (RT size=view size, )
	Context.RHICmdList.ClearMRT(true, NumRenderTargets, ClearColors, false, 1.0f, false, 0, DestRect);

	Context.SetViewportAndCallRHI(0, 0, 0.0f, DestSize.X, DestSize.Y, 1.0f );

	// set the state
	Context.RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI());
	Context.RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI());
	Context.RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI());
	
	TShaderMapRef<FPostProcessVS> VertexShader(ShaderMap);

	if (bNearBlurEnabled)
	{
		static FGlobalBoundShaderState BoundShaderState;
		

		TShaderMapRef< FPostProcessDOFSetupPS<1> > PixelShader(ShaderMap);
		SetGlobalBoundShaderState(Context.RHICmdList, FeatureLevel, BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);
		
		PixelShader->SetParameters(Context);
	}
	else
	{
		static FGlobalBoundShaderState BoundShaderState;
		
		TShaderMapRef< FPostProcessDOFSetupPS<0> > PixelShader(ShaderMap);
		SetGlobalBoundShaderState(Context.RHICmdList, FeatureLevel, BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);

		PixelShader->SetParameters(Context);
	}

	VertexShader->SetParameters(Context);

	DrawPostProcessPass(
		Context.RHICmdList,
		DestRect.Min.X, DestRect.Min.Y,
		DestRect.Width() + 1, DestRect.Height() + 1,
		SrcRect.Min.X, SrcRect.Min.Y,
		SrcRect.Width() + 1, SrcRect.Height() + 1,
		DestSize,
		SrcSize,
		*VertexShader,
		View.StereoPass,
		Context.HasHmdMesh(),
		EDRF_UseTriangleOptimization);

	Context.RHICmdList.CopyToResolveTarget(DestRenderTarget0.TargetableTexture, DestRenderTarget0.ShaderResourceTexture, false, FResolveParams());
	Context.RHICmdList.CopyToResolveTarget(DestRenderTarget1.TargetableTexture, DestRenderTarget1.ShaderResourceTexture, false, FResolveParams());
}
示例#30
0
//----------------------------------------------------------------------------
void Smoke2D::CreateBoundaryMixedEffect (VisualEffect*& effect,
    VisualEffectInstance*& instance)
{
    PixelShader* pshader = new0 PixelShader("Wm5.BoundaryMixed2",
        1, 1, 0, 3, false);
    pshader->SetInput(0, "vertexTCoord", Shader::VT_FLOAT2,
        Shader::VS_TEXCOORD0);
    pshader->SetOutput(0, "pixelColor", Shader::VT_FLOAT4,
        Shader::VS_COLOR0);
    pshader->SetSampler(0, "MaskSampler", Shader::ST_2D);
    pshader->SetSampler(1, "OffsetSampler", Shader::ST_2D);
    pshader->SetSampler(2, "StateSampler", Shader::ST_2D);
    pshader->SetTextureUnits(msBoundaryMixedPTextureUnits);
    pshader->SetPrograms(msBoundaryMixedPPrograms);

    mIP->CreateEffect(pshader, effect, instance);

    // Create the mask and offset textures.
    Texture2D* maskMixed = new0 Texture2D(Texture::TF_A32B32G32R32F,
        mIMaxP1, mJMaxP1, 1);
    Texture2D* offsetMixed = new0 Texture2D(Texture::TF_A32B32G32R32F,
        mIMaxP1, mJMaxP1, 1);

    Float4* mask = (Float4*)maskMixed->GetData(0);
    Float4* offset = (Float4*)offsetMixed->GetData(0);
    Float4 one(1.0f, 1.0f, 1.0f, 1.0f);
    Float4 zero(0.0f, 0.0f, 0.0f, 0.0f);
    Float4 xEdgeMask(0.0f, 1.0f, 0.0f, 0.0f);
    Float4 x0EdgeOffset(+mDx, 0.0f, 0.0f, 0.0f);
    Float4 x1EdgeOffset(-mDx, 0.0f, 0.0f, 0.0f);
    Float4 yEdgeMask(1.0f, 0.0f, 0.0f, 0.0f);
    Float4 y0EdgeOffset(0.0f, +mDy, 0.0f, 0.0f);
    Float4 y1EdgeOffset(0.0f, -mDy, 0.0f, 0.0f);
    int x, y;

    // Interior.
    for (y = 1; y < mJMax; ++y)
    {
        for (x = 1; x < mIMax; ++x)
        {
            mask[Index(x,y)] = one;
            offset[Index(x,y)] = zero;
        }
    }

    // Edge-interior.
    for (x = 1; x < mIMax; ++x)
    {
        mask[Index(x,0)] = yEdgeMask;
        offset[Index(x,0)] = y0EdgeOffset;
        mask[Index(x,mJMax)] = yEdgeMask;
        offset[Index(x,mJMax)] = y1EdgeOffset;
    }
    for (y = 1; y < mJMax; ++y)
    {
        mask[Index(0,y)] = xEdgeMask;
        offset[Index(0,y)] = x0EdgeOffset;
        mask[Index(mIMax,y)] = xEdgeMask;
        offset[Index(mIMax,y)] = x1EdgeOffset;
    }

    // Corners.
    mask[Index(0,0)] = zero;
    mask[Index(mIMax,0)] = zero;
    mask[Index(0,mJMax)] = zero;
    mask[Index(mIMax,mJMax)] = zero;
    offset[Index(0,0)] = zero;
    offset[Index(mIMax,0)] = zero;
    offset[Index(0,mJMax)] = zero;
    offset[Index(mIMax,mJMax)] = zero;

    instance->SetPixelTexture(0, "MaskSampler", maskMixed);
    instance->SetPixelTexture(0, "OffsetSampler", offsetMixed);
    instance->SetPixelTexture(0, "StateSampler",
        mIP->GetTarget(2)->GetColorTexture(0));

    mRenderer->Bind(maskMixed);
    mRenderer->Bind(offsetMixed);
}