/** * 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 (GetFeatureLevel() >= ERHIFeatureLevel::ES3_1) { Flags |= BUF_ShaderResource; } FRHIResourceCreateInfo CreateInfo; VertexBufferRHI = RHICreateVertexBuffer(GParticleScratchVertexBufferSize, Flags, CreateInfo); if (GetFeatureLevel() >= ERHIFeatureLevel::ES3_1) { VertexBufferSRV_G32R32F = RHICreateShaderResourceView( VertexBufferRHI, /*Stride=*/ sizeof(FVector2D), PF_G32R32F ); } }
void FHZBOcclusionTester::ReleaseDynamicRHI() { if (GetFeatureLevel() >= ERHIFeatureLevel::SM4) { GRenderTargetPool.FreeUnusedResource( ResultsTextureCPU ); } }
FSceneViewFamily::FSceneViewFamily( const ConstructionValues& CVS ) : FamilySizeX(0), FamilySizeY(0), RenderTarget(CVS.RenderTarget), bUseSeparateRenderTarget(false), Scene(CVS.Scene), EngineShowFlags(CVS.EngineShowFlags), CurrentWorldTime(CVS.CurrentWorldTime), DeltaWorldTime(CVS.DeltaWorldTime), CurrentRealTime(CVS.CurrentRealTime), FrameNumber(UINT_MAX), bRealtimeUpdate(CVS.bRealtimeUpdate), bDeferClear(CVS.bDeferClear), bResolveScene(CVS.bResolveScene), GammaCorrection(CVS.GammaCorrection) { // If we do not pass a valid scene pointer then SetWorldTimes must be called to initialized with valid times. ensure(CVS.bTimesSet); #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) int32 Value = CVarRenderTimeFrozen.GetValueOnAnyThread(); if(Value) { CurrentWorldTime = 0; CurrentRealTime = 0; } #endif #if !WITH_EDITOR // Console shader compilers don't set instruction count, // Also various console-specific rendering paths haven't been tested with shader complexity check(!EngineShowFlags.ShaderComplexity); check(!EngineShowFlags.StationaryLightOverlap); #else // instead of checking IsGameWorld on rendering thread to see if we allow this flag to be disabled // we force it on in the game thread. if(IsInGameThread()) { if ( Scene && Scene->GetWorld() && Scene->GetWorld()->IsGameWorld() ) { EngineShowFlags.LOD = 1; } } LandscapeLODOverride = -1; bDrawBaseInfo = true; #endif // Not supported in ES2. auto FeatureLevel = GetFeatureLevel(); if (FeatureLevel == ERHIFeatureLevel::ES2 || FeatureLevel == ERHIFeatureLevel::ES3_1) { EngineShowFlags.ScreenPercentage = false; } }
void FHZBOcclusionTester::InitDynamicRHI() { if (GetFeatureLevel() >= ERHIFeatureLevel::SM4) { FRHICommandListImmediate& RHICmdList = FRHICommandListExecutor::GetImmediateCommandList(); FPooledRenderTargetDesc Desc( FPooledRenderTargetDesc::Create2DDesc( FIntPoint( SizeX, SizeY ), PF_B8G8R8A8, FClearValueBinding::None, TexCreate_CPUReadback | TexCreate_HideInVisualizeTexture, TexCreate_None, false ) ); GRenderTargetPool.FindFreeElement(RHICmdList, Desc, ResultsTextureCPU, TEXT("HZBResultsCPU") ); } }
bool FIndirectLightingCache::IndirectLightingAllowed(FScene* Scene, FSceneRenderer& Renderer) const { bool bAnyViewAllowsIndirectLightingCache = false; if (IsIndirectLightingCacheAllowed(GetFeatureLevel()) && Scene->PrecomputedLightVolumes.Num() > 0) { for (int32 ViewIndex = 0; ViewIndex < Renderer.Views.Num(); ViewIndex++) { bAnyViewAllowsIndirectLightingCache |= (bool)Renderer.Views[ViewIndex].Family->EngineShowFlags.IndirectLightingCache; } } return bAnyViewAllowsIndirectLightingCache; }
void FIndirectLightingCache::InitDynamicRHI() { if (CanIndirectLightingCacheUseVolumeTexture(GetFeatureLevel())) { uint32 Flags = TexCreate_ShaderResource | TexCreate_NoTiling; FPooledRenderTargetDesc Desc(FPooledRenderTargetDesc::CreateVolumeDesc( CacheSize, CacheSize, CacheSize, PF_FloatRGBA, Flags, TexCreate_None, false, 1)); GRenderTargetPool.FindFreeElement(Desc, Texture0, TEXT("IndirectLightingCache_0")); GRenderTargetPool.FindFreeElement(Desc, Texture1, TEXT("IndirectLightingCache_1")); GRenderTargetPool.FindFreeElement(Desc, Texture2, TEXT("IndirectLightingCache_2")); } }
void FParticleSpriteVertexFactory::InitStreams() { const bool bInstanced = GetFeatureLevel() >= ERHIFeatureLevel::SM4; check(Streams.Num() == 0); if(bInstanced) { FVertexStream* TexCoordStream = new(Streams) FVertexStream; TexCoordStream->VertexBuffer = &GParticleTexCoordVertexBuffer; TexCoordStream->Stride = sizeof(FVector2D); TexCoordStream->Offset = 0; } FVertexStream* InstanceStream = new(Streams) FVertexStream; InstanceStream->VertexBuffer = 0; InstanceStream->Stride = 0; InstanceStream->Offset = 0; FVertexStream* DynamicParameterStream = new(Streams) FVertexStream; DynamicParameterStream->VertexBuffer = 0; DynamicParameterStream->Stride = 0; DynamicParameterStream->Offset = 0; }
void FIndirectLightingCache::InitDynamicRHI() { if (CanIndirectLightingCacheUseVolumeTexture(GetFeatureLevel())) { FRHICommandListImmediate& RHICmdList = FRHICommandListExecutor::GetImmediateCommandList(); uint32 Flags = TexCreate_ShaderResource | TexCreate_NoTiling; FPooledRenderTargetDesc Desc(FPooledRenderTargetDesc::CreateVolumeDesc( CacheSize, CacheSize, CacheSize, PF_FloatRGBA, FClearValueBinding::None, Flags, TexCreate_None, false, 1)); GRenderTargetPool.FindFreeElement(RHICmdList, Desc, Texture0, TEXT("IndirectLightingCache_0")); GRenderTargetPool.FindFreeElement(RHICmdList, Desc, Texture1, TEXT("IndirectLightingCache_1")); GRenderTargetPool.FindFreeElement(RHICmdList, Desc, Texture2, TEXT("IndirectLightingCache_2")); } }
void FReflectionEnvironmentCubemapArray::InitDynamicRHI() { if (GetFeatureLevel() >= ERHIFeatureLevel::SM5) { const int32 NumReflectionCaptureMips = FMath::CeilLogTwo(GReflectionCaptureSize) + 1; ReleaseCubeArray(); FPooledRenderTargetDesc Desc(FPooledRenderTargetDesc::CreateCubemapDesc( GReflectionCaptureSize, //@todo - get rid of the alpha channel (currently stores brightness which is a constant), could use PF_FloatRGB for half memory, would need to implement RHIReadSurface support PF_FloatRGBA, TexCreate_None, TexCreate_None, false, // Cubemap array of 1 produces a regular cubemap, so guarantee it will be allocated as an array FMath::Max<uint32>(MaxCubemaps, 2), NumReflectionCaptureMips)); // Allocate TextureCubeArray for the scene's reflection captures GRenderTargetPool.FindFreeElement(Desc, ReflectionEnvs, TEXT("ReflectionEnvs")); } }
//-------------------------------------------------------------------------------------- // void RenderState::Impl::CreateSamplerState( // D3D11_FILTER filter, //フィルター // D3D11_TEXTURE_ADDRESS_MODE addressMode //アドレスモード // ID3D11SamplerState** pResult //受け取るインターフェイス // ); // 用途: サンプラーステートを作成するヘルパー関数 // 戻り値: なし //-------------------------------------------------------------------------------------- void RenderState::Impl::CreateSamplerState(D3D11_FILTER filter, D3D11_TEXTURE_ADDRESS_MODE addressMode, ID3D11SamplerState** pResult){ try{ auto Dev = App::GetApp()->GetDeviceResources(); auto pDx11Device = Dev->GetD3DDevice(); D3D11_SAMPLER_DESC desc; ZeroMemory(&desc, sizeof(desc)); desc.Filter = filter; desc.AddressU = addressMode; desc.AddressV = addressMode; desc.AddressW = addressMode; desc.MaxAnisotropy = (pDx11Device->GetFeatureLevel() > D3D_FEATURE_LEVEL_9_1) ? 16 : 2; desc.MaxLOD = FLT_MAX; desc.ComparisonFunc = D3D11_COMPARISON_NEVER; HRESULT hr = pDx11Device->CreateSamplerState(&desc, pResult); if (FAILED(hr)){ // 初期化失敗 throw BaseException( L"サンプラーステート作成に失敗しました。", L"if(FAILED(pDx11Device->CreateSamplerState()))", L"RenderState::Impl::CreateSamplerState()" ); } } catch (...){ throw; } }
D3D10_FEATURE_LEVEL1 WINAPI D3D10DeviceProxy::GetFeatureLevel() { auto const device = static_cast<ID3D10Device1*>(device_); return device->GetFeatureLevel(); }
void FMeshParticleVertexFactory::InitRHI() { FVertexDeclarationElementList Elements; const bool bInstanced = GetFeatureLevel() >= ERHIFeatureLevel::SM4; if (Data.bInitialized) { if(bInstanced) { // Stream 0 - Instance data { checkf(DynamicVertexStride != -1, TEXT("FMeshParticleVertexFactory does not have a valid DynamicVertexStride - likely an empty one was made, but SetStrides was not called")); FVertexStream VertexStream; VertexStream.VertexBuffer = NULL; VertexStream.Stride = 0; VertexStream.Offset = 0; Streams.Add(VertexStream); // @todo metal: this will need a valid stride when we get to instanced meshes! Elements.Add(FVertexElement(0, Data.TransformComponent[0].Offset, Data.TransformComponent[0].Type, 8, DynamicVertexStride, Data.TransformComponent[0].bUseInstanceIndex)); Elements.Add(FVertexElement(0, Data.TransformComponent[1].Offset, Data.TransformComponent[1].Type, 9, DynamicVertexStride, Data.TransformComponent[1].bUseInstanceIndex)); Elements.Add(FVertexElement(0, Data.TransformComponent[2].Offset, Data.TransformComponent[2].Type, 10, DynamicVertexStride, Data.TransformComponent[2].bUseInstanceIndex)); Elements.Add(FVertexElement(0, Data.SubUVs.Offset, Data.SubUVs.Type, 11, DynamicVertexStride, Data.SubUVs.bUseInstanceIndex)); Elements.Add(FVertexElement(0, Data.SubUVLerpAndRelTime.Offset, Data.SubUVLerpAndRelTime.Type, 12, DynamicVertexStride, Data.SubUVLerpAndRelTime.bUseInstanceIndex)); Elements.Add(FVertexElement(0, Data.ParticleColorComponent.Offset, Data.ParticleColorComponent.Type, 14, DynamicVertexStride, Data.ParticleColorComponent.bUseInstanceIndex)); Elements.Add(FVertexElement(0, Data.VelocityComponent.Offset, Data.VelocityComponent.Type, 15, DynamicVertexStride, Data.VelocityComponent.bUseInstanceIndex)); } // Stream 1 - Dynamic parameter { checkf(DynamicParameterVertexStride != -1, TEXT("FMeshParticleVertexFactory does not have a valid DynamicParameterVertexStride - likely an empty one was made, but SetStrides was not called")); FVertexStream VertexStream; VertexStream.VertexBuffer = NULL; VertexStream.Stride = 0; VertexStream.Offset = 0; Streams.Add(VertexStream); Elements.Add(FVertexElement(1, 0, VET_Float4, 13, DynamicParameterVertexStride, true)); } } if(Data.PositionComponent.VertexBuffer != NULL) { Elements.Add(AccessStreamComponent(Data.PositionComponent,0)); } // only tangent,normal are used by the stream. the binormal is derived in the shader uint8 TangentBasisAttributes[2] = { 1, 2 }; for(int32 AxisIndex = 0;AxisIndex < 2;AxisIndex++) { if(Data.TangentBasisComponents[AxisIndex].VertexBuffer != NULL) { Elements.Add(AccessStreamComponent(Data.TangentBasisComponents[AxisIndex],TangentBasisAttributes[AxisIndex])); } } // Vertex color if(Data.VertexColorComponent.VertexBuffer != NULL) { Elements.Add(AccessStreamComponent(Data.VertexColorComponent,3)); } else { //If the mesh has no color component, set the null color buffer on a new stream with a stride of 0. //This wastes 4 bytes of bandwidth per vertex, but prevents having to compile out twice the number of vertex factories. FVertexStreamComponent NullColorComponent(&GNullColorVertexBuffer, 0, 0, VET_Color); Elements.Add(AccessStreamComponent(NullColorComponent,3)); } if(Data.TextureCoordinates.Num()) { const int32 BaseTexCoordAttribute = 4; for(int32 CoordinateIndex = 0;CoordinateIndex < Data.TextureCoordinates.Num();CoordinateIndex++) { Elements.Add(AccessStreamComponent( Data.TextureCoordinates[CoordinateIndex], BaseTexCoordAttribute + CoordinateIndex )); } for(int32 CoordinateIndex = Data.TextureCoordinates.Num();CoordinateIndex < MAX_TEXCOORDS;CoordinateIndex++) { Elements.Add(AccessStreamComponent( Data.TextureCoordinates[Data.TextureCoordinates.Num() - 1], BaseTexCoordAttribute + CoordinateIndex )); } } if(Streams.Num() > 0) { InitDeclaration(Elements,Data); check(IsValidRef(GetDeclaration())); } } }
void FIndirectLightingCache::UpdateCache(FScene* Scene, FSceneRenderer& Renderer, bool bAllowUnbuiltPreview) { if (IsIndirectLightingCacheAllowed(GetFeatureLevel())) { bool bAnyViewAllowsIndirectLightingCache = false; for (int32 ViewIndex = 0; ViewIndex < Renderer.Views.Num(); ViewIndex++) { bAnyViewAllowsIndirectLightingCache |= Renderer.Views[ViewIndex].Family->EngineShowFlags.IndirectLightingCache; } if (bAnyViewAllowsIndirectLightingCache) { SCOPE_CYCLE_COUNTER(STAT_UpdateIndirectLightingCache); TMap<FIntVector, FBlockUpdateInfo> BlocksToUpdate; TArray<FIndirectLightingCacheAllocation*> TransitionsOverTimeToUpdate; if (bUpdateAllCacheEntries) { const uint32 PrimitiveCount = Scene->Primitives.Num(); for (uint32 PrimitiveIndex = 0; PrimitiveIndex < PrimitiveCount; ++PrimitiveIndex) { FPrimitiveSceneInfo* PrimitiveSceneInfo = Scene->Primitives[PrimitiveIndex]; UpdateCachePrimitive(Scene, PrimitiveSceneInfo, false, true, BlocksToUpdate, TransitionsOverTimeToUpdate); } } // Go over the views and operate on any relevant visible primitives for (int32 ViewIndex = 0; ViewIndex < Renderer.Views.Num(); ViewIndex++) { FViewInfo& View = Renderer.Views[ViewIndex]; if (!bUpdateAllCacheEntries) { for (FSceneSetBitIterator BitIt(View.PrimitiveVisibilityMap); BitIt; ++BitIt) { uint32 PrimitiveIndex = BitIt.GetIndex(); FPrimitiveSceneInfo* PrimitiveSceneInfo = Scene->Primitives[PrimitiveIndex]; const FPrimitiveViewRelevance& PrimitiveRelevance = View.PrimitiveViewRelevanceMap[PrimitiveIndex]; UpdateCachePrimitive(Scene, PrimitiveSceneInfo, bAllowUnbuiltPreview, PrimitiveRelevance.bOpaqueRelevance, BlocksToUpdate, TransitionsOverTimeToUpdate); } } } UpdateBlocks(Scene, Renderer.Views.GetData(), BlocksToUpdate); UpdateTransitionsOverTime(TransitionsOverTimeToUpdate, Renderer.ViewFamily.DeltaWorldTime); if (GCacheDrawLightingSamples || Renderer.ViewFamily.EngineShowFlags.VolumeLightingSamples || GCacheDrawDirectionalShadowing) { FViewElementPDI DebugPDI(Renderer.Views.GetData(), NULL); for (int32 VolumeIndex = 0; VolumeIndex < Scene->PrecomputedLightVolumes.Num(); VolumeIndex++) { const FPrecomputedLightVolume* PrecomputedLightVolume = Scene->PrecomputedLightVolumes[VolumeIndex]; PrecomputedLightVolume->DebugDrawSamples(&DebugPDI, GCacheDrawDirectionalShadowing != 0); } } } bUpdateAllCacheEntries = false; } }
EShaderPlatform FSceneView::GetShaderPlatform() const { return GShaderPlatformForFeatureLevel[GetFeatureLevel()]; }
void FSceneView::EndFinalPostprocessSettings(const FSceneViewInitOptions& ViewInitOptions) { { static const auto CVarMobileMSAA = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.MobileMSAA")); if(CVarMobileMSAA ? CVarMobileMSAA->GetValueOnGameThread() > 1 : false) { // Turn off various features which won't work with mobile MSAA. FinalPostProcessSettings.DepthOfFieldScale = 0.0f; FinalPostProcessSettings.AntiAliasingMethod = AAM_None; } } { static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.BloomQuality")); int Value = CVar->GetValueOnGameThread(); if(Value <= 0) { FinalPostProcessSettings.BloomIntensity = 0.0f; } } if(!Family->EngineShowFlags.Bloom) { FinalPostProcessSettings.BloomIntensity = 0.0f; } if(!Family->EngineShowFlags.GlobalIllumination) { FinalPostProcessSettings.LPVIntensity = 0.0f; } { static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.DepthOfFieldQuality")); int Value = CVar->GetValueOnGameThread(); if(Value <= 0) { FinalPostProcessSettings.DepthOfFieldScale = 0.0f; } } if(!Family->EngineShowFlags.DepthOfField) { FinalPostProcessSettings.DepthOfFieldScale = 0; } if(!Family->EngineShowFlags.Vignette) { FinalPostProcessSettings.VignetteIntensity = 0; FinalPostProcessSettings.VignetteColor = FLinearColor(0.0f, 0.0f, 0.0f); } if(!Family->EngineShowFlags.Grain) { FinalPostProcessSettings.GrainIntensity = 0; FinalPostProcessSettings.GrainJitter = 0; } if(!Family->EngineShowFlags.CameraImperfections) { FinalPostProcessSettings.BloomDirtMaskIntensity = 0; } if(!Family->EngineShowFlags.AmbientCubemap) { FinalPostProcessSettings.ContributingCubemaps.Empty(); } if(!Family->EngineShowFlags.LensFlares) { FinalPostProcessSettings.LensFlareIntensity = 0; } #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) { float Value = CVarExposureOffset.GetValueOnGameThread(); FinalPostProcessSettings.AutoExposureBias += Value; } #endif { static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataFloat(TEXT("r.ScreenPercentage")); float Value = CVar->GetValueOnGameThread(); if(Value >= 0.0) { FinalPostProcessSettings.ScreenPercentage = Value; } } #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) { float Value = CVarSSRMaxRoughness.GetValueOnGameThread(); if(Value >= 0.0f) { FinalPostProcessSettings.ScreenSpaceReflectionMaxRoughness = Value; } } #endif { static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataFloat(TEXT("r.AmbientOcclusionStaticFraction")); float Value = CVar->GetValueOnGameThread(); if(Value >= 0.0) { FinalPostProcessSettings.AmbientOcclusionStaticFraction = Value; } } if(!Family->EngineShowFlags.ScreenPercentage || bIsSceneCapture || bIsReflectionCapture) { FinalPostProcessSettings.ScreenPercentage = 100; } if(!Family->EngineShowFlags.AmbientOcclusion) { FinalPostProcessSettings.AmbientOcclusionIntensity = 0; } { static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataFloat(TEXT("r.AmbientOcclusionRadiusScale")); float Scale = FMath::Clamp(CVar->GetValueOnGameThread(), 0.1f, 5.0f); FinalPostProcessSettings.AmbientOcclusionRadius *= Scale; } { float Scale = FMath::Clamp(CVarSSAOFadeRadiusScale.GetValueOnGameThread(), 0.01f, 50.0f); FinalPostProcessSettings.AmbientOcclusionDistance *= Scale; } { float Value = FMath::Clamp(CVarMotionBlurScale.GetValueOnGameThread(), 0.0f, 50.0f); FinalPostProcessSettings.MotionBlurAmount *= Value; } { float Value = CVarMotionBlurMax.GetValueOnGameThread(); if(Value >= 0.0f) { FinalPostProcessSettings.MotionBlurMax = FMath::Min(FinalPostProcessSettings.MotionBlurMax, Value); } } { float Value = CVarSceneColorFringeMax.GetValueOnGameThread(); if (Value >= 0.0f) { FinalPostProcessSettings.SceneFringeIntensity = FMath::Min(FinalPostProcessSettings.SceneFringeIntensity, Value); } } if (!Family->EngineShowFlags.Lighting || !Family->EngineShowFlags.GlobalIllumination) { FinalPostProcessSettings.IndirectLightingColor = FLinearColor(0,0,0,0); FinalPostProcessSettings.IndirectLightingIntensity = 0.0f; } // Anti-Aliasing { const auto FeatureLevel = GetFeatureLevel(); static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.PostProcessAAQuality")); static auto* MobileHDRCvar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.MobileHDR")); static auto* MobileMSAACvar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.MobileMSAA")); static uint32 MSAAValue = GShaderPlatformForFeatureLevel[FeatureLevel] == SP_OPENGL_ES2_IOS ? 1 : MobileMSAACvar->GetValueOnGameThread(); int32 Quality = FMath::Clamp(CVar->GetValueOnGameThread(), 0, 6); if( !Family->EngineShowFlags.PostProcessing || !Family->EngineShowFlags.AntiAliasing || Quality <= 0 // Disable antialiasing in GammaLDR mode to avoid jittering. || (FeatureLevel == ERHIFeatureLevel::ES2 && MobileHDRCvar->GetValueOnGameThread() == 0) || (FeatureLevel <= ERHIFeatureLevel::ES3_1 && (MSAAValue > 1))) { FinalPostProcessSettings.AntiAliasingMethod = AAM_None; } if( FinalPostProcessSettings.AntiAliasingMethod == AAM_TemporalAA) { if( !Family->EngineShowFlags.TemporalAA || !Family->bRealtimeUpdate || Quality < 3 ) { FinalPostProcessSettings.AntiAliasingMethod = AAM_FXAA; } } } if (AllowDebugViewmodes()) { ConfigureBufferVisualizationSettings(); } #if WITH_EDITOR FHighResScreenshotConfig& Config = GetHighResScreenshotConfig(); // Pass highres screenshot materials through post process settings FinalPostProcessSettings.HighResScreenshotMaterial = Config.HighResScreenshotMaterial; FinalPostProcessSettings.HighResScreenshotMaskMaterial = Config.HighResScreenshotMaskMaterial; FinalPostProcessSettings.HighResScreenshotCaptureRegionMaterial = NULL; // If the highres screenshot UI is open and we're not taking a highres screenshot this frame if (Config.bDisplayCaptureRegion && !GIsHighResScreenshot) { // Only enable the capture region effect if the capture region is different from the view rectangle... if ((Config.UnscaledCaptureRegion != ViewRect) && (Config.UnscaledCaptureRegion.Area() > 0) && (State != NULL)) { // ...and if this is the viewport associated with the highres screenshot UI auto ConfigViewport = Config.TargetViewport.Pin(); if (ConfigViewport.IsValid() && Family && Family->RenderTarget == ConfigViewport->GetViewport()) { static const FName ParamName = "RegionRect"; FLinearColor NormalizedCaptureRegion; // Normalize capture region into view rectangle NormalizedCaptureRegion.R = (float)Config.UnscaledCaptureRegion.Min.X / (float)ViewRect.Width(); NormalizedCaptureRegion.G = (float)Config.UnscaledCaptureRegion.Min.Y / (float)ViewRect.Height(); NormalizedCaptureRegion.B = (float)Config.UnscaledCaptureRegion.Max.X / (float)ViewRect.Width(); NormalizedCaptureRegion.A = (float)Config.UnscaledCaptureRegion.Max.Y / (float)ViewRect.Height(); // Get a MID for drawing this frame and push the capture region into the shader parameter FinalPostProcessSettings.HighResScreenshotCaptureRegionMaterial = State->GetReusableMID(Config.HighResScreenshotCaptureRegionMaterial); FinalPostProcessSettings.HighResScreenshotCaptureRegionMaterial->SetVectorParameterValue(ParamName, NormalizedCaptureRegion); } } } #endif // WITH_EDITOR // Upscaling or Super sampling { float LocalScreenPercentage = FinalPostProcessSettings.ScreenPercentage; float Fraction = 1.0f; // apply ScreenPercentage if (LocalScreenPercentage != 100.f) { Fraction = FMath::Clamp(LocalScreenPercentage / 100.0f, 0.1f, 4.0f); } // Window full screen mode with upscaling bool bFullscreen = false; if (GEngine && GEngine->GameViewport && GEngine->GameViewport->GetWindow().IsValid()) { bFullscreen = GEngine->GameViewport->GetWindow()->GetWindowMode() != EWindowMode::Windowed; } check(Family->RenderTarget); if (bFullscreen) { // CVar mode 2 is fullscreen with upscale if(GSystemResolution.WindowMode == EWindowMode::WindowedFullscreen) { // FIntPoint WindowSize = Viewport->GetSizeXY(); FIntPoint WindowSize = Family->RenderTarget->GetSizeXY(); // allow only upscaling float FractionX = FMath::Clamp((float)GSystemResolution.ResX / WindowSize.X, 0.1f, 4.0f); float FractionY = FMath::Clamp((float)GSystemResolution.ResY / WindowSize.Y, 0.1f, 4.0f); // maintain a pixel aspect ratio of 1:1 for easier internal computations Fraction *= FMath::Max(FractionX, FractionY); } } #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) if(CVarScreenPercentageEditor.GetValueOnAnyThread() == 0) { bool bNotInGame = GEngine && GEngine->GameViewport == 0; if(bNotInGame) { Fraction = 1.0f; } } #endif // Upscale if needed if (Fraction != 1.0f) { // compute the view rectangle with the ScreenPercentage applied const FIntRect ScreenPercentageAffectedViewRect = ViewInitOptions.GetConstrainedViewRect().Scale(Fraction); SetScaledViewRect(ScreenPercentageAffectedViewRect); } } }
void FIndirectLightingCache::UpdateBlock(FScene* Scene, FViewInfo* DebugDrawingView, FBlockUpdateInfo& BlockInfo) { const int32 NumSamplesPerBlock = BlockInfo.Block.TexelSize * BlockInfo.Block.TexelSize * BlockInfo.Block.TexelSize; FSHVectorRGB3 SingleSample; float DirectionalShadowing = 1; FVector SkyBentNormal(0, 0, 1); //always do point interpolation to get valid 3band single sample and directional data. InterpolatePoint(Scene, BlockInfo.Block, DirectionalShadowing, SingleSample, SkyBentNormal); if (CanIndirectLightingCacheUseVolumeTexture(GetFeatureLevel()) && !BlockInfo.Allocation->bPointSample) { static TArray<float> AccumulatedWeight; AccumulatedWeight.Reset(NumSamplesPerBlock); AccumulatedWeight.AddZeroed(NumSamplesPerBlock); //volume textures are encoded as two band, so no reason to waste perf interpolating 3 bands. static TArray<FSHVectorRGB2> AccumulatedIncidentRadiance; AccumulatedIncidentRadiance.Reset(NumSamplesPerBlock); AccumulatedIncidentRadiance.AddZeroed(NumSamplesPerBlock); // Interpolate SH samples from precomputed lighting samples and accumulate lighting data for an entire block InterpolateBlock(Scene, BlockInfo.Block, AccumulatedWeight, AccumulatedIncidentRadiance); static TArray<FFloat16Color> Texture0Data; static TArray<FFloat16Color> Texture1Data; static TArray<FFloat16Color> Texture2Data; Texture0Data.Reset(NumSamplesPerBlock); Texture1Data.Reset(NumSamplesPerBlock); Texture2Data.Reset(NumSamplesPerBlock); Texture0Data.AddUninitialized(NumSamplesPerBlock); Texture1Data.AddUninitialized(NumSamplesPerBlock); Texture2Data.AddUninitialized(NumSamplesPerBlock); const int32 FormatSize = GPixelFormats[PF_FloatRGBA].BlockBytes; check(FormatSize == sizeof(FFloat16Color)); // Encode the SH samples into a texture format // Note the single sample is updated even if this is a volume allocation, because translucent materials only use the single sample EncodeBlock(DebugDrawingView, BlockInfo.Block, AccumulatedWeight, AccumulatedIncidentRadiance, Texture0Data, Texture1Data, Texture2Data); // Setup an update region const FUpdateTextureRegion3D UpdateRegion( BlockInfo.Block.MinTexel.X, BlockInfo.Block.MinTexel.Y, BlockInfo.Block.MinTexel.Z, 0, 0, 0, BlockInfo.Block.TexelSize, BlockInfo.Block.TexelSize, BlockInfo.Block.TexelSize); // Update the volume texture atlas RHIUpdateTexture3D((const FTexture3DRHIRef&)GetTexture0().ShaderResourceTexture, 0, UpdateRegion, BlockInfo.Block.TexelSize * FormatSize, BlockInfo.Block.TexelSize * BlockInfo.Block.TexelSize * FormatSize, (const uint8*)Texture0Data.GetData()); RHIUpdateTexture3D((const FTexture3DRHIRef&)GetTexture1().ShaderResourceTexture, 0, UpdateRegion, BlockInfo.Block.TexelSize * FormatSize, BlockInfo.Block.TexelSize * BlockInfo.Block.TexelSize * FormatSize, (const uint8*)Texture1Data.GetData()); RHIUpdateTexture3D((const FTexture3DRHIRef&)GetTexture2().ShaderResourceTexture, 0, UpdateRegion, BlockInfo.Block.TexelSize * FormatSize, BlockInfo.Block.TexelSize * BlockInfo.Block.TexelSize * FormatSize, (const uint8*)Texture2Data.GetData()); } else { if (GCacheDrawInterpolationPoints != 0 && DebugDrawingView) { FViewElementPDI DebugPDI(DebugDrawingView, NULL); const FVector WorldPosition = BlockInfo.Block.Min; DebugPDI.DrawPoint(WorldPosition, FLinearColor(0, 0, 1), 10, SDPG_World); } } // Record the position that the sample was taken at BlockInfo.Allocation->TargetPosition = BlockInfo.Block.Min + BlockInfo.Block.Size / 2; BlockInfo.Allocation->TargetSamplePacked0[0] = FVector4(SingleSample.R.V[0], SingleSample.R.V[1], SingleSample.R.V[2], SingleSample.R.V[3]) / PI; BlockInfo.Allocation->TargetSamplePacked0[1] = FVector4(SingleSample.G.V[0], SingleSample.G.V[1], SingleSample.G.V[2], SingleSample.G.V[3]) / PI; BlockInfo.Allocation->TargetSamplePacked0[2] = FVector4(SingleSample.B.V[0], SingleSample.B.V[1], SingleSample.B.V[2], SingleSample.B.V[3]) / PI; BlockInfo.Allocation->TargetSamplePacked1[0] = FVector4(SingleSample.R.V[4], SingleSample.R.V[5], SingleSample.R.V[6], SingleSample.R.V[7]) / PI; BlockInfo.Allocation->TargetSamplePacked1[1] = FVector4(SingleSample.G.V[4], SingleSample.G.V[5], SingleSample.G.V[6], SingleSample.G.V[7]) / PI; BlockInfo.Allocation->TargetSamplePacked1[2] = FVector4(SingleSample.B.V[4], SingleSample.B.V[5], SingleSample.B.V[6], SingleSample.B.V[7]) / PI; BlockInfo.Allocation->TargetSamplePacked2 = FVector4(SingleSample.R.V[8], SingleSample.G.V[8], SingleSample.B.V[8], 0) / PI; BlockInfo.Allocation->TargetDirectionalShadowing = DirectionalShadowing; const float BentNormalLength = SkyBentNormal.Size(); BlockInfo.Allocation->TargetSkyBentNormal = FVector4(SkyBentNormal / FMath::Max(BentNormalLength, .0001f), BentNormalLength); if (!BlockInfo.Allocation->bHasEverUpdatedSingleSample) { // If this is the first update, also set the interpolated state to match the new target //@todo - detect and handle teleports in the same way BlockInfo.Allocation->SingleSamplePosition = BlockInfo.Allocation->TargetPosition; for (int32 VectorIndex = 0; VectorIndex < 3; VectorIndex++) // RGB { BlockInfo.Allocation->SingleSamplePacked0[VectorIndex] = BlockInfo.Allocation->TargetSamplePacked0[VectorIndex]; BlockInfo.Allocation->SingleSamplePacked1[VectorIndex] = BlockInfo.Allocation->TargetSamplePacked1[VectorIndex]; } BlockInfo.Allocation->SingleSamplePacked2 = BlockInfo.Allocation->TargetSamplePacked2; BlockInfo.Allocation->CurrentDirectionalShadowing = BlockInfo.Allocation->TargetDirectionalShadowing; BlockInfo.Allocation->CurrentSkyBentNormal = BlockInfo.Allocation->TargetSkyBentNormal; BlockInfo.Allocation->bHasEverUpdatedSingleSample = true; } BlockInfo.Block.bHasEverBeenUpdated = true; }
/** * Initialize the Render Hardware Interface for this vertex factory */ void FParticleSpriteVertexFactory::InitRHI() { InitStreams(); SetDeclaration(GetParticleSpriteVertexDeclaration(GetFeatureLevel()).VertexDeclarationRHI); }