You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#lockdown Nick.Penwarden #rb none ========================== MAJOR FEATURES + CHANGES ========================== Change 3148067 on 2016/10/01 by Daniel.Wright Support for ReflectionEnvironment and light type show flags with ForwardShading Change 3149085 on 2016/10/03 by Daniel.Wright Support for ReflectionEnvironment show flag in base pass reflections without any shader overhead Change 3162206 on 2016/10/13 by Chris.Bunner Merging Dev-MaterialLayers to Dev-Rendering, CL 3161593: Material expressions; Trig, fast-trig, saturate, round, truncate, pre-skinned normal. Added CustomEyeTangent to material attributes. Resolved some hard-coded attribute typing and other minor fixes. Change 3186067 on 2016/11/03 by Daniel.Wright Updated Stationary primitive tooltip to indicate that it allows the primitive to be changed, but not moved Change3186069on 2016/11/03 by Daniel.Wright Using a weighted geometric mean to combine multiple Distance Field Indirect Shadows, greatly reduces over-occlusion when overlap is high Change 3186084 on 2016/11/03 by Mark.Satterthwaite Duplicate 3172511: Don't set Metal resource option fields on texture descriptors when running on an OS that doesn't support them. #jira UE-37481 Change 3186089 on 2016/11/03 by Mark.Satterthwaite Duplicate CL #3169764: Fixed automatic conversion of G8_sRGB into RGBA8_sRGB required for Mac Metal, which fixes FORT-27627. #jira FORT-27627 Change 3186113 on 2016/11/03 by Mark.Satterthwaite Duplicate CL #3183807: Change the way we access the Metal viewport's backbuffer, to reduce possible causes of FORT-31649: - Added console variable "rhi.Metal.SupportsIntermediateBackBuffer" to control whether to use an extra render-target so we can support screenshots & movie capture, or render directly to the back-buffer to save memory & GPU performance. Still defaults to ON for Mac & OFF for iOS/tvOS. - Change the way we handle updates to the back-buffer size to ensure that the different threads access their intended version. #jira FORT-31649 Change 3186116 on 2016/11/03 by Mark.Satterthwaite Duplicate CL #3183823: Record Metal resource & state objects used in a command-buffer when rhi.Metal.RuntimeDebugLevel is set to 3 or higher. The object labels, types & descriptions will be printed on failure - if the object is deleted prior to this then we have a lifetime error and it will crash at this point and can be debugged further using our -metalretainrefs command-line option or Xcode's zombie-objects. Used to verify that FORT-31649 is not a simple resource lifetime error and thereby speed up Apple/vendor investigations. #jira FORT-31649 Change 3186818 on 2016/11/04 by Chris.Bunner PR #2907 Export UMaterialExpressionNoise (contributed by kayosiii). Change 3186979 on 2016/11/04 by Rolando.Caloca DR - Misc minor cleanup Change 3187169 on 2016/11/04 by Uriel.Doyon Incremental insertion of level data between PostLoad and AddToWorld Change 3187205 on 2016/11/04 by Mark.Satterthwaite Compile fixes for iOS. Change 3187389 on 2016/11/04 by Uriel.Doyon Fix for possible stall when loading hidden level Change 3187598 on 2016/11/04 by Michael.Trepka MetalViewport compile fix Change 3187678 on 2016/11/04 by Uriel.Doyon Fix for landscape grass textures not being streamed in correctly. Change 3187731 on 2016/11/04 by Rolando.Caloca DR - Start making type safe some cross compiler enums Change 3187824 on 2016/11/04 by Rolando.Caloca DR - clang compile fix Change 3187953 on 2016/11/04 by Rolando.Caloca DR - vk - Mac compile fix Change 3188696 on 2016/11/07 by Mark.Satterthwaite Another iOS compile fix for new MetalViewport validation code. Change 3188906 on 2016/11/07 by Rolando.Caloca DR - Show permutation of LUTBlender Change 3189094 on 2016/11/07 by Chris.Bunner Fix RemoveAAJitter from projection matrix. #jira UE-37701, UE-38003 Change 3189134 on 2016/11/07 by Daniel.Wright Fix for CreateRenderTarget2D called in construction script during cooking Change 3189145 on 2016/11/07 by Chris.Bunner Follow-up to CL 3186818, export UMaterialExpressionVectorNoise. Change 3189239 on 2016/11/07 by Daniel.Wright Added show flag for Contact Shadows, disabled in planar reflections Change 3189252 on 2016/11/07 by Daniel.Wright Support for Reflection Capture intensity with simple reflections, which are the default with Forward Shading Change 3189406 on 2016/11/07 by Mark.Satterthwaite Really fix the last of the iOS compile errors from changes to the MetalViewport code. Change 3190854 on 2016/11/08 by Ben.Woodhouse XB1: Fix memory corruption with RHICreateVertexBuffer and RHICreateIndexBuffer when using initial data (Procedural Mesh Component crash) #jira UE-34264 #fyi james.golding #fyi keith.judge Change 3190962 on 2016/11/08 by Olaf.Piesche Unshelved from pending changelist '3176615' - Gil's fix for race condiiton with particle vertex factory reuse across different passes; potential to fix a number of issues Change 3191959 on 2016/11/09 by Uriel.Doyon Removed some static primitives from the dynamic primitive handler for texture streaming. Change 3193122 on 2016/11/10 by Chris.Bunner Always update non-preview material resources for use in code preview. #jira UE-38223 Change 3193190 on 2016/11/10 by Gil.Gribb UE4 - Fixed rare bug with shadow groups rendering things that have not been setup to render this frame. #jira UE-36379 Change 3193523 on 2016/11/10 by Uriel.Doyon Fixed incorrect section bounds used for texture streaming. Change 3193962 on 2016/11/10 by Uriel.Doyon Added defrag of dynamic bounds used for the texture streaming. Allows to remove unused bounds over time. Change 3193974 on 2016/11/10 by Uriel.Doyon New "Required Texture Resolution" view mode. Showing the ratio between the currently streamed texture resolution and the resolution wanted by the GPU. Change 3194109 on 2016/11/10 by Uriel.Doyon Another patch on material bounds used for texture streaming. Change 3194665 on 2016/11/11 by Chris.Bunner Duplicated behavior for inherited velocity scaling scaling to vert/surface spawned particles. Change 3194734 on 2016/11/11 by Rolando.Caloca DR - vk - Simplified some texture casting Change 3194867 on 2016/11/11 by Rolando.Caloca DR - vk - SM5 fixes Change 3195176 on 2016/11/11 by Chris.Bunner Fixed incorrectly updated NVAPI error. Change 3195425 on 2016/11/11 by Uriel.Doyon Fixed possible invalid level reference in the texture streamer Change 3196512 on 2016/11/14 by Gil.Gribb Merging //UE4/Dev-Main@3196156 to Dev-Rendering (//UE4/Dev-Rendering) Change 3196750 on 2016/11/14 by Marcus.Wassmer Fix ordering problem with GPU cache transitions Change 3196815 on 2016/11/14 by Daniel.Wright Suppressed 'Instanced stereo rendering is not supported' warning showing up in CIS Change 3196818 on 2016/11/14 by Daniel.Wright Fixed FIndirectLightingCache::UpdateCachePrimitivesInternal churning through a bunch of temporary memory Change 3196819 on 2016/11/14 by Daniel.Wright Volume lighting samples are allowed outside of the importance volume if their influence affects the volume. Fixes black indirect lighting on movable components in maps with small importance volumes. Volume lighting samples placed on surfaces use a radius that covers the layer height spacing, which prevents an uncovered region between layers Change 3197243 on 2016/11/14 by Uriel.Doyon Async Task For Updating static component LastRender time #jira UE-24268 Change 3197359 on 2016/11/14 by Daniel.Wright Added Inscattering Texture controls to ExponentialHeightFog * When InscatteringColorCubemap is specified, directional light inscattering is disabled * Lerps betwen 1x1 mip at NonDirectionalInscatteringColorDistance to mip 0 at FullyDirectionalInscatteringColorDistance * Added FogCutoffDistance, so artists can prevent fog on skyboxes (requires fog to be setup matching the fog that was rendered into the sky texture so that distant mountains match) * Fog shader permutations based on what feature is enabled Change 3198419 on 2016/11/15 by Chris.Bunner PS4 HDR: Runtime toggle (backbuffer recreation on resize matching), UI composition. Matches PC behavior and controls. HDR: Generalized buffer formats, cvar consistency pass, LUT for UI composition, refactoring common functions. Exposed RHICreateTargetableShaderResource3D. Moved some (translucent) volume rendering helpers to allow access in Slate. Change 3198822 on 2016/11/15 by Daniel.Wright Mac compile fix Change 3199509 on 2016/11/15 by Uriel.Doyon Added support for viewmode param asset name (and note just param value). Used to investigate texture streamer behavior. Change 3199578 on 2016/11/15 by Rolando.Caloca DR - Add some shader resource tables to SCW when running with -directcompile Change 3199698 on 2016/11/15 by Rolando.Caloca DR - vk - Refactor shader & descriptor bindings Change 3199712 on 2016/11/15 by Rolando.Caloca DR - vk - r.Vulkan.StripGlsl to always strip glsl at runtime to save memory per shader Change 3199717 on 2016/11/15 by Rolando.Caloca DR - vk - Show hitching PSO info again Change 3199750 on 2016/11/15 by Rolando.Caloca DR - SCW clang compile fixes Change 3200353 on 2016/11/16 by Rolando.Caloca DR - vk - Mac fix Change 3200358 on 2016/11/16 by Chris.Bunner Only allow UI composition on platforms we currently use it. Change 3200823 on 2016/11/16 by Chris.Bunner Remove expression key attribute ID when not translating an attribute output to allow intended expression sharing. #jira UE-38699 Change 3200947 on 2016/11/16 by Mark.Satterthwaite Fix UE-38695 by not trying to resize the viewport on the wrong thread. #jira UE-38695 Change 3201069 on 2016/11/16 by Daniel.Wright Fog inscattering texture limited to SM4 and above, fixes ES2 compile errors Change 3201346 on 2016/11/16 by Brian.Karis Temporal AA fix for correct edge gradients. Filtering now combined with importance sampling. Enabled Catmull-Rom resolve filter. Results are now slightly sharper. Fixed antighosting. Will yet require a dilation to be perfect. Optimized bicubic filtering to 5 taps instead of 9. Cleaned out unused code. Change 3201369 on 2016/11/16 by Brian.Karis Bicubic texture sample Change 3201522 on 2016/11/16 by Rolando.Caloca DR - vk - Fix static analysis issues Change 3201878 on 2016/11/17 by Chris.Bunner Temporarily disable Nvapi HDR error logging. #jira UE-38529 Change 3202108 on 2016/11/17 by Simon.Tovey Assets with easy repro for flickering particles bug Change 3202181 on 2016/11/17 by Rolando.Caloca DR - vk - CIS android fix Change 3202325 on 2016/11/17 by Ben.Woodhouse Integrate 4.14.1 fix from 14 //UE4/Release-4.14 (@3201850) Fix CreateVertexbuffer and CreateIndexBuffer memory corruption (Procedural Mesh Component crash) #jira UE-34264 Change 3204394 on 2016/11/18 by Guillaume.Abadie PR #2808: AlphaComposite Fog Opacity fix (Contributed by moritz-wundke) #br Ben.Woodhouse Change 3204428 on 2016/11/18 by Guillaume.Abadie Fixes a couple of issues in decals: * Crash in FDecalDrawingPolicyFactory::DrawMesh() * ActorPostion material expression * PixelNormalWS material expression * Missing renaming from DEFERRED_DECAL to DECAL_PRIMITIVE #jira UE-38327, UE-38158, UE-37818, UE-37350 Change 3204429 on 2016/11/18 by Uriel.Doyon Darker default undefined accuracy. Reenabled the texture streaming build in the build all. Change 3204458 on 2016/11/18 by Chris.Bunner Shader truncation warnings fix. Change 3204459 on 2016/11/18 by Chris.Bunner Engine 'Passthrough' material fuction fix. V4 is now actually a V4. Change 3204460 on 2016/11/18 by Chris.Bunner Correctly handle some known Nvapi warnings. #jira UE-38529 Change 3204653 on 2016/11/18 by Marc.Olano Helper functions for tiled textures Checking in for Ryan Brucks Change 3204863 on 2016/11/18 by Arne.Schober DR - Replaced ENQUEUE_UNIQUE_RENDER_COMMAND with a Debuggable template Implementation Change 3204939 on 2016/11/18 by Arne.Schober DR - Make clang happy Change 3204968 on 2016/11/18 by Arne.Schober DR - UE-38494 - Fixed SpeedTree Wind crash, when force deleting the Asset. Change 3206293 on 2016/11/21 by Uriel.Doyon New member bHasStreamingUpdatePending in UTexture2D to delay update of global distance fields. Set to true when the streamer can possibly load a mip in the near future. #jira UE-37787 Change 3206551 on 2016/11/21 by Chris.Bunner Added material update context when forcing all shaders to recompile. #jira UE-38481 Change 3206644 on 2016/11/21 by Benjamin.Hyder Updating Planar Reflection example in TM-Shadermodels. Change 3206899 on 2016/11/21 by Rolando.Caloca DR - vk - SM5 fixes Change 3206900 on 2016/11/21 by Rolando.Caloca DR - Added missing strings for shader formats Change 3206983 on 2016/11/21 by Rolando.Caloca DR - vk - Support for SV_Coverage Change 3207237 on 2016/11/22 by Simon.Tovey Exporting particle module base and a couple of child classes as it's commonly requested. #test compiles Change 3207241 on 2016/11/22 by Gil.Gribb Merging //UE4/Dev-Main@3206998 to Dev-Rendering (//UE4/Dev-Rendering) Change 3207520 on 2016/11/22 by Ben.Woodhouse Cherry picked from //Fortnite/Main@3206301 Fixed GPU hang in Zone Map view. Was an issue with RenderThread using the device context without appropriate RHIThread flushes. #jira FORT-31616 #code_review keith.judge Change 3207541 on 2016/11/22 by Ben.Woodhouse Cherry picked from //fortnite/Main@3207422 * Fix UpdateTexture3D to create a staging texture of the region to update rather than the whole texture. This prevents distance fields crashing during update (allocating 18GB per frame in some cases) * Put UpdateTexture2D DMA support onto a cvar, disabled by default (corruption issues reported by licensees, plus not sure it's actually faster - could be slower due to reduced bandwidth; issues reported by licensees) * Fix UpdateTexture2D to only create a staging texture of the region to update, saving memory #jira UE-38609 Change 3207654 on 2016/11/22 by Chris.Bunner Don't flag 16-bit PNG/JPG textures as sRGB on import. #jira UE-30279 Change 3208434 on 2016/11/22 by Rolando.Caloca DR - vk - UAV transitions Change 3208490 on 2016/11/22 by Chris.Bunner Break material code sharing when we detect an unresolvable loop. By default change IsResultMA loop detection to stop on functions as we can determine type definitively. Unified IsResultMA detection across switch nodes. Change 3208860 on 2016/11/23 by Rolando.Caloca DR - vk - Fix some format issues Change 3209265 on 2016/11/23 by Arne.Schober DR - originally unshelved from 3153924 - Made Depth and Velocity Rendering Passes to use PSO only RHI interface, We are now passing down two structs that collect all the necessary information for the drawing policies to construct a PSO object. One during construction of the Policy, which contains information abouyt the CullMode, FillMode and PrimType. And another during rendering that passes infomation like BlendState and DepthStencilState down to the low levelrenderer into SetSharedState. Performance of the static drawlist ist slightly slower (less than 0.1ms on Consoles) due to some addtional branches and copies. The branches in the FDrawingPolicyRenderState will go away as soon as everything is converted to use the PSO interface. Performace of the GPU is slightly better due to less context rolls (mainly CullMode sorts in differently now) Change 3209305 on 2016/11/23 by Guillaume.Abadie Fix contact shadow's assemption on objects thickness Change 3209334 on 2016/11/23 by Brian.Karis Fixed TAA handling of alpha. Switched the meaning of AA_ALPHA to make sense. Change 3209903 on 2016/11/24 by Guillaume.Abadie Cherry picks alpha through post processing changelists 3201959, 3204143 and 3209883 from //UE4/Private-Partner-NREAL Change 3209973 on 2016/11/24 by Ben.Woodhouse Fix D3D11 and 12 static analysis warnings reported by Rob Troughton of Coconut Lizard (http://coconutlizard.co.uk/blog/ue4/pvs-studio-part5/) Change 3210023 on 2016/11/24 by Uriel.Doyon Fixed an issue with DropDetail when FixedFrameRate was set to a value smaller than MinDesiredFrameRate. #jira UE-37210 Change 3210026 on 2016/11/24 by Ben.Woodhouse Disable renderthread hang detection if a debugger is present, so we can debug the renderthread without crashing Change 3210049 on 2016/11/24 by Ben.Woodhouse Fix mac build Change 3210071 on 2016/11/24 by Uriel.Doyon Fixed an issue with masked materials and shader complexity viewmode when DBuffer Decals are enabled. #jira UE-37542 Change 3210374 on 2016/11/25 by Ben.Woodhouse * Fix issues with fast cleared dbuffer targets not being resolved when no decals are in the scene. This caused graphical corruption on XB1 and ensure failures on PS4 (with RHIThread disabled) * Move Decal rendertarget manager function implementations out of the header. #jira UE-38879 Change 3210390 on 2016/11/25 by Uriel.Doyon Fixed cubemap resourcesize not taking into account mipgen settings #jira UE-37045 Change 3210407 on 2016/11/25 by Uriel.Doyon "resavepackages" commandlet now supports -buildtexturestreaming that rebuilds the map texture streaming data. That can be used in combination with -buildlighting. Change 3210563 on 2016/11/27 by Rolando.Caloca DR - vk - Integrate cached memory fixes and PF_D24 format fix #jira UE-39025 PR #2974 Change 3210564 on 2016/11/27 by Rolando.Caloca DR - Fix for GL linker PR #2975 #jira UE-39029 Change 3210592 on 2016/11/27 by Rolando.Caloca DR - vk - SM5 fixes Change 3210597 on 2016/11/27 by Rolando.Caloca DR - vk - Prep for staging UB copies to GPU memory Change 3210600 on 2016/11/27 by Rolando.Caloca DR - vk - Extract generic range code Change 3210613 on 2016/11/27 by Rolando.Caloca DR - vk - Added r.Vulkan.SubmitOnDispatch Change 3211054 on 2016/11/28 by Rolando.Caloca DR - vk - Missing reference Change 3211330 on 2016/11/28 by Chris.Bunner Shader compile error for max texture coordinate count on skinned meshes. Change 3211384 on 2016/11/28 by Arne.Schober DR - Enforce move on EnqueueRenderCommand Lambda Change 3211431 on 2016/11/28 by Gil.Gribb Merging //UE4/Dev-Main@3211016 to Dev-Rendering (//UE4/Dev-Rendering) Change 3211738 on 2016/11/28 by Gil.Gribb IWYU fixes after merge Change 3212231 on 2016/11/28 by Richard.Wallis Fix build errors Change 3212253 on 2016/11/28 by Richard.Wallis Remove MacGraphicsSwitching plugin. #jira UE-37640 Change 3212310 on 2016/11/28 by Rolando.Caloca DR - vk - Update glslang to 1.0.33.0 Change 3212446 on 2016/11/28 by Guillaume.Abadie Implements PreviousFrameSwitch material expression Change 3212594 on 2016/11/28 by Arne.Schober DR - Fix missing include Change 3212681 on 2016/11/29 by Rolando.Caloca DR - vk - Auto flush for compute shader Change 3213000 on 2016/11/29 by Gil.Gribb temp fix for PF_MAX Change 3213161 on 2016/11/29 by Ben.Woodhouse Integrate latest D3D12 changes from //depot/Partners/Microsoft/UE4-DX12/...@3211714 Using: - p4 integrate //depot/Partners/Microsoft/UE4-DX12/Engine/Source/Runtime/D3D12RHI/...@3211714 //UE4/Dev-Rendering/Engine/Source/Runtime/D3D12RHI/... - p4 integrate //depot/Partners/Microsoft/UE4-DX12/Engine/Source/ThirdParty/Windows/DirectX/...@3211714 //UE4/Dev-Rendering/Engine/Source/ThirdParty/Windows/DirectX/... - p4 integrate //depot/Partners/Microsoft/UE4-DX12/Engine/Source/Programs/UnrealBuildTool/...@3211714 //UE4/Dev-Rendering/Engine/Source/Programs/UnrealBuildTool/... Changes from UE4-DX12: *** CL 3183818 *** Update D3D12 RHI to 4.14: - Merged changes from Epic up until 10/20/16 - Fixed an issue where command allocators where resetting too early. I changed to aggressive command list batching by default now that more SubmitCommandListHint calls exist in the upper engine, we don't need to worry about starving the GPU. Fewer ExecuteCommandLists calls means better performance and fewer Signals() so this change provides a GPU perf win. I had to fix an issue with aggressive batching where we would sometimes hold on to a command list long enough (in the pending list) but hadn't executed it yet. The command allocator was being put back in the queue of allocators during ReleaseCommandAllocator() without a syncpoint set and was thus being reset too early. I added a simple counter to the command allocator so it could track how many command lists were using it. It doesn't need to be thread safe since only one thread uses a command allocator at a time. I also added some stats around the # command lists and # command allocators since it would be possible to leak command allocators now if it's pending command list count isn't decremented correctly. In that case we'd keep creating new command allocators and eventually run out of memory. -Remove clear during allocate in the FD3D12FastConstantAllocator and FD3D12FastAllocator. The supplied resource locations are assumed to be new and thus don't need to be cleared. -Cleanup D3D12RHI stats. There were some unused stats as well as some missing ones. -Mark shader resource table uniform buffers as dirty only when the shader changes. Cleanup SetComputeShader calls and Dispatch calls to not set/unset the CS for each Dispatch. -Remove unused Check SRV resolved code that epic added to the D3D11 RHI and was brought over. We dont need it and we won't use this. -Remove "always on" cycle counters for high frequency RHI methods like RHISetShaderTexture. These should use the engine's stat macros as they are removed on TEST + SHIPPING builds. On Xbox a significant amount of CPU time is spent in things like QueryPerformanceCounter even when STATS aren't enabled. Currently 1% of an entire capture on XBOX is spent inside this call. I improved and cleaned up high freqency call stacks like: - RHISetShaderTexture - RHISetShaderResourceViewParameter - RHISetShaderParameter - RHISetUAVParameter In general I moved to use templated functions, removed unused parameters, unnecessary copies, etc. -Change D3D12 PIX profiling enable/disable to match Xbox and handle logic in the UEBuildWindows.cs for UBT. Also add a static assert to inform the developer when PIX profiling is requested but the engine is compiling out draw events. -Resources should be associated with the rendering thread's frame that it's currently recording command lists for and they shouldnt be cleaned up until those command lists have been translated to D3D12 command lists on the RHI thread AND completed executing on the GPU. This was confirmed to resolve an issue where CBV resources were being released too early. This work involved a couple changes: 1) Move the "frame" fence to be incremented on the rendering thread (during RHIAdvanceFrameForGetViewportBackBuffer()) so that resources that are deleted from the rendering thread are assosicated with the correct frame count 2) Queue up a command from the rendering thread to signal the "frame" fence. It needs to be queued to ensure that it's signaled at the correct time on the RHI thread (after that frame's command lists have been executed). -Disable GRHIRequiresEarlyBackBufferRenderTarget. Metal/Vulkan/Xbox11.x already do this. This is used by the Slate renderer during BeginRenderFrame and avoids a SetRenderTargets call. -Enable GRHISupportsMSAADepthSampleAccess (used in the Editor). This was enabled for D3D11 on SM5, but not for D3D12. -Delay load D3D12.dll and add root signature 1.1 support. -Add explicit flush calls to improve resource barrier batching instead of implict flushes inside FConditionalScopeResourceBarrier and FScopeResourceBarrier. Also update those classes with const members. *** CL 3183824 *** Fix the D3D12 RHI after integrating UE 4.14 updates: - Fixed a bug where we would try to get the PSO of a nullptr in SetPipelineState if we needed to reset the current PSO on the cmd list. - Fixed a spelling error - Removed the need for bForceState, we use dirty bits now *** CL 3183830 *** - GetDebugFlags RHI extension, needed by XB1 movie player. - Only query memory info if stats are enabled - Add support for the engine's new RHISubmitCommandsAndFlushGPU function - Update CommitPendingPipelineState to be Graphics/Compute specific and avoid the need for a IsCompute parameter. *** CL 3183837 *** Made PipelineState caches contain pointers to FD3D12PipelineState objects to avoid issues with using pointers to after Find/Add to the maps. TMap indicates that the pointer to the value associated with a key "is only valid until the next change to any key in the map." The lifetime of the PSO pointers is managed by the low level caches (graphics and compute). Added stat for the number of Pipeline State Objects. *** CL 3183931 *** Update Windows D3D12 headers and libs to RS1 release bits (10.0.14393.0) *** CL 3183978 *** Update UBT Windows build settings: - Change D3D12 PIX profiling enable/disable to match Xbox and handle logic in the UEBuildWindows.cs for UBT. Also add a static assert to inform the developer when PIX profiling is requested but the engine is compiling out draw events. -Delay load D3D12.dll and add root signature 1.1 support. *** CL 3184132 *** Fix Xbox PSO cache code where it could leak PSOs. Related to change 3183837. *** Changelist 3211714 *** Update D3D12 RHI with fixes: - Check if we can reserve slots in GatherUniqueSamplerTables - DirtyState more often in StateCache - Remove InternalSetSamplerState. The alternate function isn't used. - Allow MRTClear for arrays with holes in them - Fix uninitialized descriptors. This was causing a GPU hang on Xbox. We need to set dirty bits for resources bound to slots outside of the current descriptor table's range - Cleanup SetDescriptorHeap code. Move setting descriptor heap logic to the descriptor cache since it also owns things like the sampler maps. Added members to the descriptor cache to track the last heaps that were set on the command list to avoid dirtying bit unnecessarily. - Resource transitions: go through Common between queues (3D <--> Compute) - Fix initial state for placed resources. - Merging epic Change 3213250 on 2016/11/29 by Chris.Bunner GBufferHints tooltip fix. #jira UE-39103 Change 3213345 on 2016/11/29 by Gil.Gribb more IWYU fallout Change 3213676 on 2016/11/29 by Rolando.Caloca DR - Fix incorrect texture getting cleared Change 3213728 on 2016/11/29 by Rolando.Caloca DR - Lambda-ize Change 3214461 on 2016/11/29 by Ben.Woodhouse Rollout August QFE4 XDK (required for latest DX12 changes on XB1) Change 3215317 on 2016/11/30 by Daniel.Wright PS4 compile fix Change 3216343 on 2016/11/30 by Arne.Schober DR - UE-39155 - after talking to Brian it occurred to us that flipping the world space normal is non sensical. And indeed the Grass was using world space normals. Change 3216844 on 2016/12/01 by Ben.Woodhouse Fix for static analysis warnings after discussion with Microsoft Change 3216916 on 2016/12/01 by Gil.Gribb Merging //UE4/Dev-Main@3216539 to Dev-Rendering (//UE4/Dev-Rendering) Change 3217385 on 2016/12/01 by Arne.Schober DR - UE-39218, UE-39221, UE-39224 and potentially UE-39214 - The Stencil bits for Light channels and decal application were not set in the dynamic basepass Change 3217464 on 2016/12/01 by Ben.Woodhouse Fix for reflection capture resize assert. The assert is only valid in cooked builds, so disable it in editor #jira UE-39225 Change 3217534 on 2016/12/01 by Arne.Schober DR - Fix Merge conflict Change 3217581 on 2016/12/01 by Rolando.Caloca DR - Fix assert on debug Change 3217741 on 2016/12/01 by Benjamin.Hyder Duplicate audio fix. Change 3217890 on 2016/12/01 by Rolando.Caloca DR - Fix widget not rendering properly when hidden #jira UE-39221 Change3218129on 2016/12/01 by Arne.Schober DR - UE-39214 - Lod dither value as accidently cached accross the static draw list. Change 3218759 on 2016/12/02 by Guillaume.Abadie Fixes editor compositing bug caused by alpha through post processing change 3209903 #jira UE-39221 [CL 3219854 by Marcus Wassmer in Main branch]
1854 lines
64 KiB
C++
1854 lines
64 KiB
C++
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================
|
|
PostProcessTonemap.cpp: Post processing tone mapping implementation.
|
|
=============================================================================*/
|
|
|
|
#include "PostProcess/PostProcessTonemap.h"
|
|
#include "EngineGlobals.h"
|
|
#include "ScenePrivate.h"
|
|
#include "PostProcess/SceneFilterRendering.h"
|
|
#include "PostProcess/PostProcessCombineLUTs.h"
|
|
#include "PostProcess/PostProcessMobile.h"
|
|
|
|
static TAutoConsoleVariable<float> CVarTonemapperSharpen(
|
|
TEXT("r.Tonemapper.Sharpen"),
|
|
0,
|
|
TEXT("Sharpening in the tonemapper (not for ES2), actual implementation is work in progress, clamped at 10\n")
|
|
TEXT(" 0: off(default)\n")
|
|
TEXT(" 0.5: half strength\n")
|
|
TEXT(" 1: full strength"),
|
|
ECVF_Scalability | ECVF_RenderThreadSafe);
|
|
|
|
static TAutoConsoleVariable<int32> CVarDisplayColorGamut(
|
|
TEXT("r.HDR.Display.ColorGamut"),
|
|
0,
|
|
TEXT("Color gamut of the output display:\n")
|
|
TEXT("0: Rec709 / sRGB, D65 (default)\n")
|
|
TEXT("1: DCI-P3, D65\n")
|
|
TEXT("2: Rec2020 / BT2020, D65\n")
|
|
TEXT("3: ACES, D60\n")
|
|
TEXT("4: ACEScg, D60\n"),
|
|
ECVF_Scalability | ECVF_RenderThreadSafe);
|
|
|
|
static TAutoConsoleVariable<int32> CVarDisplayOutputDevice(
|
|
TEXT("r.HDR.Display.OutputDevice"),
|
|
0,
|
|
TEXT("Device format of the output display:\n")
|
|
TEXT("0: sRGB\n")
|
|
TEXT("1: Rec709\n")
|
|
TEXT("2: Explicit gamma mapping\n")
|
|
TEXT("3: ACES 1000 nit ST-2084 (Dolby PQ) for HDR displays\n")
|
|
TEXT("4: ACES 2000 nit ST-2084 (Dolby PQ) for HDR displays\n"),
|
|
ECVF_Scalability | ECVF_RenderThreadSafe);
|
|
|
|
static TAutoConsoleVariable<int32> CVarHDROutputEnabled(
|
|
TEXT("r.HDR.EnableHDROutput"),
|
|
0,
|
|
TEXT("Creates an HDR compatible swap-chain and enables HDR display output.")
|
|
TEXT("0: Disabled (default)\n")
|
|
TEXT("1: Enable hardware-specific implementation\n"),
|
|
ECVF_RenderThreadSafe
|
|
);
|
|
|
|
static TAutoConsoleVariable<float> CVarTonemapperGamma(
|
|
TEXT("r.TonemapperGamma"),
|
|
0.0f,
|
|
TEXT("0: Default behavior\n")
|
|
TEXT("#: Use fixed gamma # instead of sRGB or Rec709 transform"),
|
|
ECVF_Scalability | ECVF_RenderThreadSafe);
|
|
|
|
//
|
|
// TONEMAPPER PERMUTATION CONTROL
|
|
//
|
|
|
|
// Tonemapper option bitmask.
|
|
// Adjusting this requires adjusting TonemapperCostTab[].
|
|
typedef enum {
|
|
TonemapperGammaOnly = (1<<0),
|
|
TonemapperColorMatrix = (1<<1),
|
|
TonemapperShadowTint = (1<<2),
|
|
TonemapperContrast = (1<<3),
|
|
TonemapperGrainJitter = (1<<4),
|
|
TonemapperGrainIntensity = (1<<5),
|
|
TonemapperGrainQuantization = (1<<6),
|
|
TonemapperBloom = (1<<7),
|
|
TonemapperDOF = (1<<8),
|
|
TonemapperVignette = (1<<9),
|
|
TonemapperLightShafts = (1<<10),
|
|
Tonemapper32BPPHDR = (1<<11),
|
|
TonemapperColorFringe = (1<<12),
|
|
TonemapperMsaa = (1<<13),
|
|
TonemapperSharpen = (1<<14),
|
|
TonemapperInverseTonemapping = (1 << 15),
|
|
} TonemapperOption;
|
|
|
|
// Tonemapper option cost (0 = no cost, 255 = max cost).
|
|
// Suggested cost should be
|
|
// These need a 1:1 mapping with TonemapperOption enum,
|
|
static uint8 TonemapperCostTab[] = {
|
|
1, //TonemapperGammaOnly
|
|
1, //TonemapperColorMatrix
|
|
1, //TonemapperShadowTint
|
|
1, //TonemapperContrast
|
|
1, //TonemapperGrainJitter
|
|
1, //TonemapperGrainIntensity
|
|
1, //TonemapperGrainQuantization
|
|
1, //TonemapperBloom
|
|
1, //TonemapperDOF
|
|
1, //TonemapperVignette
|
|
1, //TonemapperLightShafts
|
|
1, //TonemapperMosaic
|
|
1, //TonemapperColorFringe
|
|
1, //TonemapperMsaa
|
|
1, //TonemapperSharpen
|
|
1, //TonemapperInverseTonemapping
|
|
};
|
|
|
|
// Edit the following to add and remove configurations.
|
|
// This is a white list of the combinations which are compiled.
|
|
// Place most common first (faster when searching in TonemapperFindLeastExpensive()).
|
|
|
|
// List of configurations compiled for PC.
|
|
static uint32 TonemapperConfBitmaskPC[15] = {
|
|
|
|
TonemapperBloom +
|
|
TonemapperGrainJitter +
|
|
TonemapperGrainIntensity +
|
|
TonemapperGrainQuantization +
|
|
TonemapperVignette +
|
|
TonemapperColorFringe +
|
|
TonemapperSharpen +
|
|
0,
|
|
|
|
TonemapperBloom +
|
|
TonemapperGrainJitter +
|
|
TonemapperGrainIntensity +
|
|
TonemapperGrainQuantization +
|
|
TonemapperVignette +
|
|
TonemapperSharpen +
|
|
0,
|
|
|
|
TonemapperBloom +
|
|
TonemapperGrainJitter +
|
|
TonemapperGrainIntensity +
|
|
TonemapperGrainQuantization +
|
|
TonemapperVignette +
|
|
TonemapperColorFringe +
|
|
0,
|
|
|
|
TonemapperBloom +
|
|
TonemapperVignette +
|
|
TonemapperGrainQuantization +
|
|
TonemapperColorFringe +
|
|
0,
|
|
|
|
TonemapperBloom +
|
|
TonemapperVignette +
|
|
TonemapperGrainQuantization +
|
|
0,
|
|
|
|
TonemapperBloom +
|
|
TonemapperSharpen +
|
|
0,
|
|
|
|
// same without TonemapperGrainQuantization
|
|
|
|
TonemapperBloom +
|
|
TonemapperGrainJitter +
|
|
TonemapperGrainIntensity +
|
|
TonemapperVignette +
|
|
TonemapperColorFringe +
|
|
0,
|
|
|
|
TonemapperBloom +
|
|
TonemapperVignette +
|
|
TonemapperColorFringe +
|
|
0,
|
|
|
|
TonemapperBloom +
|
|
TonemapperVignette +
|
|
0,
|
|
|
|
// with TonemapperInverseTonemapping
|
|
|
|
TonemapperBloom +
|
|
TonemapperGrainJitter +
|
|
TonemapperGrainIntensity +
|
|
TonemapperGrainQuantization +
|
|
TonemapperVignette +
|
|
TonemapperColorFringe +
|
|
TonemapperSharpen +
|
|
TonemapperInverseTonemapping +
|
|
0,
|
|
|
|
TonemapperBloom +
|
|
TonemapperGrainJitter +
|
|
TonemapperGrainIntensity +
|
|
TonemapperGrainQuantization +
|
|
TonemapperVignette +
|
|
TonemapperColorFringe +
|
|
TonemapperInverseTonemapping +
|
|
0,
|
|
|
|
TonemapperBloom +
|
|
TonemapperVignette +
|
|
TonemapperGrainQuantization +
|
|
TonemapperColorFringe +
|
|
TonemapperInverseTonemapping +
|
|
0,
|
|
|
|
TonemapperBloom +
|
|
TonemapperVignette +
|
|
TonemapperGrainQuantization +
|
|
TonemapperInverseTonemapping +
|
|
0,
|
|
|
|
TonemapperBloom +
|
|
TonemapperSharpen +
|
|
TonemapperInverseTonemapping +
|
|
0,
|
|
|
|
//
|
|
|
|
TonemapperGammaOnly +
|
|
0,
|
|
};
|
|
|
|
// List of configurations compiled for Mobile.
|
|
static uint32 TonemapperConfBitmaskMobile[39] = {
|
|
|
|
//
|
|
// 15 for NON-MOSAIC
|
|
//
|
|
|
|
TonemapperGammaOnly +
|
|
0,
|
|
|
|
// Not supporting grain jitter or grain quantization on mobile.
|
|
|
|
// Bloom, LightShafts, Vignette all off.
|
|
TonemapperContrast +
|
|
0,
|
|
|
|
TonemapperContrast +
|
|
TonemapperColorMatrix +
|
|
0,
|
|
|
|
// Bloom, LightShafts, Vignette, and Vignette Color all use the same shader code in the tonemapper.
|
|
TonemapperContrast +
|
|
TonemapperBloom +
|
|
TonemapperLightShafts +
|
|
TonemapperVignette +
|
|
0,
|
|
|
|
TonemapperContrast +
|
|
TonemapperColorMatrix +
|
|
TonemapperBloom +
|
|
TonemapperLightShafts +
|
|
TonemapperVignette +
|
|
0,
|
|
|
|
TonemapperContrast +
|
|
TonemapperColorMatrix +
|
|
TonemapperShadowTint +
|
|
TonemapperBloom +
|
|
TonemapperLightShafts +
|
|
TonemapperVignette +
|
|
0,
|
|
|
|
// DOF enabled.
|
|
TonemapperContrast +
|
|
TonemapperColorMatrix +
|
|
TonemapperBloom +
|
|
TonemapperLightShafts +
|
|
TonemapperVignette +
|
|
TonemapperDOF +
|
|
0,
|
|
|
|
TonemapperContrast +
|
|
TonemapperColorMatrix +
|
|
TonemapperShadowTint +
|
|
TonemapperBloom +
|
|
TonemapperLightShafts +
|
|
TonemapperVignette +
|
|
TonemapperDOF +
|
|
0,
|
|
|
|
// Same with grain.
|
|
|
|
TonemapperContrast +
|
|
TonemapperGrainIntensity +
|
|
0,
|
|
|
|
TonemapperContrast +
|
|
TonemapperColorMatrix +
|
|
TonemapperGrainIntensity +
|
|
0,
|
|
|
|
TonemapperContrast +
|
|
TonemapperBloom +
|
|
TonemapperLightShafts +
|
|
TonemapperVignette +
|
|
TonemapperGrainIntensity +
|
|
0,
|
|
|
|
TonemapperContrast +
|
|
TonemapperColorMatrix +
|
|
TonemapperBloom +
|
|
TonemapperLightShafts +
|
|
TonemapperVignette +
|
|
TonemapperGrainIntensity +
|
|
0,
|
|
|
|
TonemapperContrast +
|
|
TonemapperColorMatrix +
|
|
TonemapperShadowTint +
|
|
TonemapperBloom +
|
|
TonemapperLightShafts +
|
|
TonemapperVignette +
|
|
TonemapperGrainIntensity +
|
|
0,
|
|
|
|
// DOF enabled.
|
|
TonemapperContrast +
|
|
TonemapperColorMatrix +
|
|
TonemapperBloom +
|
|
TonemapperLightShafts +
|
|
TonemapperVignette +
|
|
TonemapperDOF +
|
|
TonemapperGrainIntensity +
|
|
0,
|
|
|
|
TonemapperContrast +
|
|
TonemapperColorMatrix +
|
|
TonemapperShadowTint +
|
|
TonemapperBloom +
|
|
TonemapperLightShafts +
|
|
TonemapperVignette +
|
|
TonemapperDOF +
|
|
TonemapperGrainIntensity +
|
|
0,
|
|
|
|
|
|
//
|
|
// 14 for 32 bit HDR PATH
|
|
//
|
|
|
|
// This is 32bpp hdr without film post.
|
|
Tonemapper32BPPHDR +
|
|
TonemapperGammaOnly +
|
|
0,
|
|
|
|
Tonemapper32BPPHDR +
|
|
0,
|
|
|
|
Tonemapper32BPPHDR +
|
|
TonemapperContrast +
|
|
0,
|
|
|
|
Tonemapper32BPPHDR +
|
|
TonemapperContrast +
|
|
TonemapperColorMatrix +
|
|
0,
|
|
|
|
Tonemapper32BPPHDR +
|
|
TonemapperContrast +
|
|
TonemapperColorMatrix +
|
|
TonemapperShadowTint +
|
|
TonemapperBloom +
|
|
0,
|
|
|
|
Tonemapper32BPPHDR +
|
|
TonemapperContrast +
|
|
TonemapperVignette +
|
|
TonemapperBloom +
|
|
0,
|
|
|
|
Tonemapper32BPPHDR +
|
|
TonemapperContrast +
|
|
TonemapperColorMatrix +
|
|
TonemapperVignette +
|
|
TonemapperBloom +
|
|
0,
|
|
|
|
Tonemapper32BPPHDR +
|
|
TonemapperContrast +
|
|
TonemapperColorMatrix +
|
|
TonemapperShadowTint +
|
|
TonemapperVignette +
|
|
TonemapperBloom +
|
|
0,
|
|
|
|
// With grain
|
|
|
|
Tonemapper32BPPHDR +
|
|
TonemapperContrast +
|
|
TonemapperGrainIntensity +
|
|
0,
|
|
|
|
Tonemapper32BPPHDR +
|
|
TonemapperContrast +
|
|
TonemapperColorMatrix +
|
|
TonemapperGrainIntensity +
|
|
0,
|
|
|
|
Tonemapper32BPPHDR +
|
|
TonemapperContrast +
|
|
TonemapperColorMatrix +
|
|
TonemapperShadowTint +
|
|
TonemapperGrainIntensity +
|
|
TonemapperBloom +
|
|
0,
|
|
|
|
Tonemapper32BPPHDR +
|
|
TonemapperContrast +
|
|
TonemapperVignette +
|
|
TonemapperGrainIntensity +
|
|
TonemapperBloom +
|
|
0,
|
|
|
|
Tonemapper32BPPHDR +
|
|
TonemapperContrast +
|
|
TonemapperColorMatrix +
|
|
TonemapperVignette +
|
|
TonemapperGrainIntensity +
|
|
TonemapperBloom +
|
|
0,
|
|
|
|
Tonemapper32BPPHDR +
|
|
TonemapperContrast +
|
|
TonemapperColorMatrix +
|
|
TonemapperShadowTint +
|
|
TonemapperVignette +
|
|
TonemapperGrainIntensity +
|
|
TonemapperBloom +
|
|
0,
|
|
|
|
|
|
//
|
|
// 10 for MSAA
|
|
//
|
|
|
|
TonemapperMsaa +
|
|
TonemapperContrast +
|
|
0,
|
|
|
|
TonemapperMsaa +
|
|
TonemapperContrast +
|
|
TonemapperColorMatrix +
|
|
0,
|
|
|
|
TonemapperMsaa +
|
|
TonemapperContrast +
|
|
TonemapperBloom +
|
|
TonemapperVignette +
|
|
0,
|
|
|
|
TonemapperMsaa +
|
|
TonemapperContrast +
|
|
TonemapperColorMatrix +
|
|
TonemapperBloom +
|
|
TonemapperVignette +
|
|
0,
|
|
|
|
TonemapperMsaa +
|
|
TonemapperContrast +
|
|
TonemapperColorMatrix +
|
|
TonemapperShadowTint +
|
|
TonemapperBloom +
|
|
TonemapperVignette +
|
|
0,
|
|
|
|
// Same with grain.
|
|
TonemapperMsaa +
|
|
TonemapperContrast +
|
|
TonemapperGrainIntensity +
|
|
0,
|
|
|
|
TonemapperMsaa +
|
|
TonemapperContrast +
|
|
TonemapperColorMatrix +
|
|
TonemapperGrainIntensity +
|
|
0,
|
|
|
|
TonemapperMsaa +
|
|
TonemapperContrast +
|
|
TonemapperBloom +
|
|
TonemapperVignette +
|
|
TonemapperGrainIntensity +
|
|
0,
|
|
|
|
TonemapperMsaa +
|
|
TonemapperContrast +
|
|
TonemapperColorMatrix +
|
|
TonemapperBloom +
|
|
TonemapperVignette +
|
|
TonemapperGrainIntensity +
|
|
0,
|
|
|
|
TonemapperMsaa +
|
|
TonemapperContrast +
|
|
TonemapperColorMatrix +
|
|
TonemapperShadowTint +
|
|
TonemapperBloom +
|
|
TonemapperVignette +
|
|
TonemapperGrainIntensity +
|
|
0,
|
|
|
|
};
|
|
|
|
// Returns 1 if option is defined otherwise 0.
|
|
static uint32 TonemapperIsDefined(uint32 ConfigBitmask, TonemapperOption Option)
|
|
{
|
|
return (ConfigBitmask & Option) ? 1 : 0;
|
|
}
|
|
|
|
// This finds the least expensive configuration which supports all selected options in bitmask.
|
|
static uint32 TonemapperFindLeastExpensive(uint32* RESTRICT Table, uint32 TableEntries, uint8* RESTRICT CostTable, uint32 RequiredOptionsBitmask)
|
|
{
|
|
// Custom logic to insure fail cases do not happen.
|
|
uint32 MustNotHaveBitmask = 0;
|
|
MustNotHaveBitmask += ((RequiredOptionsBitmask & TonemapperDOF) == 0) ? TonemapperDOF : 0;
|
|
MustNotHaveBitmask += ((RequiredOptionsBitmask & Tonemapper32BPPHDR) == 0) ? Tonemapper32BPPHDR : 0;
|
|
MustNotHaveBitmask += ((RequiredOptionsBitmask & TonemapperMsaa) == 0) ? TonemapperMsaa : 0;
|
|
|
|
// Search for exact match first.
|
|
uint32 Index;
|
|
for(Index = 0; Index < TableEntries; ++Index)
|
|
{
|
|
if(Table[Index] == RequiredOptionsBitmask)
|
|
{
|
|
return Index;
|
|
}
|
|
}
|
|
// Search through list for best entry.
|
|
uint32 BestIndex = TableEntries;
|
|
uint32 BestCost = ~0;
|
|
uint32 NotRequiredOptionsBitmask = ~RequiredOptionsBitmask;
|
|
for(Index = 0; Index < TableEntries; ++Index)
|
|
{
|
|
uint32 Bitmask = Table[Index];
|
|
if((Bitmask & MustNotHaveBitmask) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
if((Bitmask & RequiredOptionsBitmask) != RequiredOptionsBitmask)
|
|
{
|
|
// A match requires a minimum set of bits set.
|
|
continue;
|
|
}
|
|
uint32 BitExtra = Bitmask & NotRequiredOptionsBitmask;
|
|
uint32 Cost = 0;
|
|
while(BitExtra)
|
|
{
|
|
uint32 Bit = FMath::FloorLog2(BitExtra);
|
|
Cost += CostTable[Bit];
|
|
if(Cost > BestCost)
|
|
{
|
|
// Poor match.
|
|
goto PoorMatch;
|
|
}
|
|
BitExtra &= ~(1<<Bit);
|
|
}
|
|
// Better match.
|
|
BestCost = Cost;
|
|
BestIndex = Index;
|
|
PoorMatch:
|
|
;
|
|
}
|
|
// Fail returns 0, the gamma only shader.
|
|
if(BestIndex == TableEntries) BestIndex = 0;
|
|
return BestIndex;
|
|
}
|
|
|
|
// Common conversion of engine settings into a bitmask which describes the shader options required.
|
|
static uint32 TonemapperGenerateBitmask(const FViewInfo* RESTRICT View, bool bGammaOnly, bool bMobile)
|
|
{
|
|
check(View);
|
|
|
|
const FSceneViewFamily* RESTRICT Family = View->Family;
|
|
if(
|
|
bGammaOnly ||
|
|
(Family->EngineShowFlags.Tonemapper == 0) ||
|
|
(Family->EngineShowFlags.PostProcessing == 0))
|
|
{
|
|
return TonemapperGammaOnly;
|
|
}
|
|
|
|
uint32 Bitmask = 0;
|
|
|
|
const FPostProcessSettings* RESTRICT Settings = &(View->FinalPostProcessSettings);
|
|
|
|
FVector MixerR(Settings->FilmChannelMixerRed);
|
|
FVector MixerG(Settings->FilmChannelMixerGreen);
|
|
FVector MixerB(Settings->FilmChannelMixerBlue);
|
|
uint32 useColorMatrix = 0;
|
|
if(
|
|
(Settings->FilmSaturation != 1.0f) ||
|
|
((MixerR - FVector(1.0f,0.0f,0.0f)).GetAbsMax() != 0.0f) ||
|
|
((MixerG - FVector(0.0f,1.0f,0.0f)).GetAbsMax() != 0.0f) ||
|
|
((MixerB - FVector(0.0f,0.0f,1.0f)).GetAbsMax() != 0.0f))
|
|
{
|
|
Bitmask += TonemapperColorMatrix;
|
|
}
|
|
|
|
FVector Tint(Settings->FilmWhitePoint);
|
|
FVector TintShadow(Settings->FilmShadowTint);
|
|
|
|
float Sharpen = CVarTonemapperSharpen.GetValueOnRenderThread();
|
|
|
|
Bitmask += (Settings->FilmShadowTintAmount > 0.0f) ? TonemapperShadowTint : 0;
|
|
Bitmask += (Settings->FilmContrast > 0.0f) ? TonemapperContrast : 0;
|
|
Bitmask += (Settings->GrainIntensity > 0.0f) ? TonemapperGrainIntensity : 0;
|
|
Bitmask += (Settings->VignetteIntensity > 0.0f) ? TonemapperVignette : 0;
|
|
Bitmask += (Sharpen > 0.0f) ? TonemapperSharpen : 0;
|
|
|
|
return Bitmask;
|
|
}
|
|
|
|
// Common post.
|
|
// These are separated because mosiac mode doesn't support them.
|
|
static uint32 TonemapperGenerateBitmaskPost(const FViewInfo* RESTRICT View)
|
|
{
|
|
const FPostProcessSettings* RESTRICT Settings = &(View->FinalPostProcessSettings);
|
|
const FSceneViewFamily* RESTRICT Family = View->Family;
|
|
|
|
uint32 Bitmask = (Settings->GrainJitter > 0.0f) ? TonemapperGrainJitter : 0;
|
|
|
|
Bitmask += (Settings->BloomIntensity > 0.0f) ? TonemapperBloom : 0;
|
|
|
|
return Bitmask;
|
|
}
|
|
|
|
// PC only.
|
|
static uint32 TonemapperGenerateBitmaskPC(const FViewInfo* RESTRICT View, bool bGammaOnly)
|
|
{
|
|
uint32 Bitmask = TonemapperGenerateBitmask(View, bGammaOnly, false);
|
|
|
|
// PC doesn't support these
|
|
Bitmask &= ~TonemapperContrast;
|
|
Bitmask &= ~TonemapperColorMatrix;
|
|
Bitmask &= ~TonemapperShadowTint;
|
|
|
|
// Must early exit if gamma only.
|
|
if(Bitmask == TonemapperGammaOnly)
|
|
{
|
|
return Bitmask;
|
|
}
|
|
|
|
// Grain Quantization
|
|
{
|
|
static TConsoleVariableData<int32>* CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.Tonemapper.GrainQuantization"));
|
|
int32 Value = CVar->GetValueOnRenderThread();
|
|
|
|
if(Value > 0)
|
|
{
|
|
Bitmask |= TonemapperGrainQuantization;
|
|
}
|
|
}
|
|
|
|
// Inverse Tonemapping
|
|
{
|
|
static TConsoleVariableData<int32>* CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.BufferVisualizationDumpFramesAsHDR"));
|
|
int32 Value = CVar->GetValueOnRenderThread();
|
|
|
|
if (Value > 0)
|
|
{
|
|
Bitmask |= TonemapperInverseTonemapping;
|
|
}
|
|
}
|
|
|
|
if( View->FinalPostProcessSettings.SceneFringeIntensity > 0.01f)
|
|
{
|
|
Bitmask |= TonemapperColorFringe;
|
|
}
|
|
|
|
return Bitmask + TonemapperGenerateBitmaskPost(View);
|
|
}
|
|
|
|
// Mobile only.
|
|
static uint32 TonemapperGenerateBitmaskMobile(const FViewInfo* RESTRICT View, bool bGammaOnly)
|
|
{
|
|
check(View);
|
|
|
|
uint32 Bitmask = TonemapperGenerateBitmask(View, bGammaOnly, true);
|
|
|
|
bool bUse32BPPHDR = IsMobileHDR32bpp();
|
|
bool bUseMosaic = IsMobileHDRMosaic();
|
|
|
|
// Must early exit if gamma only.
|
|
if(Bitmask == TonemapperGammaOnly)
|
|
{
|
|
return Bitmask + (bUse32BPPHDR ? Tonemapper32BPPHDR : 0);
|
|
}
|
|
|
|
if (bUseMosaic)
|
|
{
|
|
return Bitmask + Tonemapper32BPPHDR;
|
|
}
|
|
|
|
static const auto CVarMobileMSAA = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.MobileMSAA"));
|
|
const EShaderPlatform ShaderPlatform = GShaderPlatformForFeatureLevel[View->GetFeatureLevel()];
|
|
if ((GSupportsShaderFramebufferFetch && (ShaderPlatform == SP_METAL || ShaderPlatform == SP_VULKAN_PCES3_1)) && (CVarMobileMSAA ? CVarMobileMSAA->GetValueOnAnyThread() > 1 : false))
|
|
{
|
|
Bitmask += TonemapperMsaa;
|
|
}
|
|
|
|
if (bUse32BPPHDR)
|
|
{
|
|
// add limited post for 32 bit encoded hdr.
|
|
Bitmask += Tonemapper32BPPHDR;
|
|
Bitmask += TonemapperGenerateBitmaskPost(View);
|
|
}
|
|
else if (GSupportsRenderTargetFormat_PF_FloatRGBA)
|
|
{
|
|
// add full mobile post if FP16 is supported.
|
|
Bitmask += TonemapperGenerateBitmaskPost(View);
|
|
|
|
bool bUseDof = GetMobileDepthOfFieldScale(*View) > 0.0f && (!View->FinalPostProcessSettings.bMobileHQGaussian || (View->GetFeatureLevel() < ERHIFeatureLevel::ES3_1));
|
|
|
|
Bitmask += (bUseDof) ? TonemapperDOF : 0;
|
|
Bitmask += (View->bLightShaftUse) ? TonemapperLightShafts : 0;
|
|
}
|
|
|
|
// Mobile is not supporting grain quantization and grain jitter currently.
|
|
Bitmask &= ~(TonemapperGrainQuantization | TonemapperGrainJitter);
|
|
return Bitmask;
|
|
}
|
|
|
|
void GrainPostSettings(FVector* RESTRICT const Constant, const FPostProcessSettings* RESTRICT const Settings)
|
|
{
|
|
float GrainJitter = Settings->GrainJitter;
|
|
float GrainIntensity = Settings->GrainIntensity;
|
|
Constant->X = GrainIntensity;
|
|
Constant->Y = 1.0f + (-0.5f * GrainIntensity);
|
|
Constant->Z = GrainJitter;
|
|
}
|
|
|
|
// This code is shared by PostProcessTonemap and VisualizeHDR.
|
|
void FilmPostSetConstants(FVector4* RESTRICT const Constants, const uint32 ConfigBitmask, const FPostProcessSettings* RESTRICT const FinalPostProcessSettings, bool bMobile)
|
|
{
|
|
uint32 UseColorMatrix = TonemapperIsDefined(ConfigBitmask, TonemapperColorMatrix);
|
|
uint32 UseShadowTint = TonemapperIsDefined(ConfigBitmask, TonemapperShadowTint);
|
|
uint32 UseContrast = TonemapperIsDefined(ConfigBitmask, TonemapperContrast);
|
|
|
|
// Must insure inputs are in correct range (else possible generation of NaNs).
|
|
float InExposure = 1.0f;
|
|
FVector InWhitePoint(FinalPostProcessSettings->FilmWhitePoint);
|
|
float InSaturation = FMath::Clamp(FinalPostProcessSettings->FilmSaturation, 0.0f, 2.0f);
|
|
FVector InLuma = FVector(1.0f/3.0f, 1.0f/3.0f, 1.0f/3.0f);
|
|
FVector InMatrixR(FinalPostProcessSettings->FilmChannelMixerRed);
|
|
FVector InMatrixG(FinalPostProcessSettings->FilmChannelMixerGreen);
|
|
FVector InMatrixB(FinalPostProcessSettings->FilmChannelMixerBlue);
|
|
float InContrast = FMath::Clamp(FinalPostProcessSettings->FilmContrast, 0.0f, 1.0f) + 1.0f;
|
|
float InDynamicRange = powf(2.0f, FMath::Clamp(FinalPostProcessSettings->FilmDynamicRange, 1.0f, 4.0f));
|
|
float InToe = (1.0f - FMath::Clamp(FinalPostProcessSettings->FilmToeAmount, 0.0f, 1.0f)) * 0.18f;
|
|
InToe = FMath::Clamp(InToe, 0.18f/8.0f, 0.18f * (15.0f/16.0f));
|
|
float InHeal = 1.0f - (FMath::Max(1.0f/32.0f, 1.0f - FMath::Clamp(FinalPostProcessSettings->FilmHealAmount, 0.0f, 1.0f)) * (1.0f - 0.18f));
|
|
FVector InShadowTint(FinalPostProcessSettings->FilmShadowTint);
|
|
float InShadowTintBlend = FMath::Clamp(FinalPostProcessSettings->FilmShadowTintBlend, 0.0f, 1.0f) * 64.0f;
|
|
|
|
// Shadow tint amount enables turning off shadow tinting.
|
|
float InShadowTintAmount = FMath::Clamp(FinalPostProcessSettings->FilmShadowTintAmount, 0.0f, 1.0f);
|
|
InShadowTint = InWhitePoint + (InShadowTint - InWhitePoint) * InShadowTintAmount;
|
|
|
|
// Make sure channel mixer inputs sum to 1 (+ smart dealing with all zeros).
|
|
InMatrixR.X += 1.0f / (256.0f*256.0f*32.0f);
|
|
InMatrixG.Y += 1.0f / (256.0f*256.0f*32.0f);
|
|
InMatrixB.Z += 1.0f / (256.0f*256.0f*32.0f);
|
|
InMatrixR *= 1.0f / FVector::DotProduct(InMatrixR, FVector(1.0f));
|
|
InMatrixG *= 1.0f / FVector::DotProduct(InMatrixG, FVector(1.0f));
|
|
InMatrixB *= 1.0f / FVector::DotProduct(InMatrixB, FVector(1.0f));
|
|
|
|
// Conversion from linear rgb to luma (using HDTV coef).
|
|
FVector LumaWeights = FVector(0.2126f, 0.7152f, 0.0722f);
|
|
|
|
// Make sure white point has 1.0 as luma (so adjusting white point doesn't change exposure).
|
|
// Make sure {0.0,0.0,0.0} inputs do something sane (default to white).
|
|
InWhitePoint += FVector(1.0f / (256.0f*256.0f*32.0f));
|
|
InWhitePoint *= 1.0f / FVector::DotProduct(InWhitePoint, LumaWeights);
|
|
InShadowTint += FVector(1.0f / (256.0f*256.0f*32.0f));
|
|
InShadowTint *= 1.0f / FVector::DotProduct(InShadowTint, LumaWeights);
|
|
|
|
// Grey after color matrix is applied.
|
|
FVector ColorMatrixLuma = FVector(
|
|
FVector::DotProduct(InLuma.X * FVector(InMatrixR.X, InMatrixG.X, InMatrixB.X), FVector(1.0f)),
|
|
FVector::DotProduct(InLuma.Y * FVector(InMatrixR.Y, InMatrixG.Y, InMatrixB.Y), FVector(1.0f)),
|
|
FVector::DotProduct(InLuma.Z * FVector(InMatrixR.Z, InMatrixG.Z, InMatrixB.Z), FVector(1.0f)));
|
|
|
|
FVector OutMatrixR = FVector(0.0f);
|
|
FVector OutMatrixG = FVector(0.0f);
|
|
FVector OutMatrixB = FVector(0.0f);
|
|
FVector OutColorShadow_Luma = LumaWeights * InShadowTintBlend;
|
|
FVector OutColorShadow_Tint1 = InWhitePoint;
|
|
FVector OutColorShadow_Tint2 = InShadowTint - InWhitePoint;
|
|
|
|
if(UseColorMatrix)
|
|
{
|
|
// Final color matrix effected by saturation and exposure.
|
|
OutMatrixR = (ColorMatrixLuma + ((InMatrixR - ColorMatrixLuma) * InSaturation)) * InExposure;
|
|
OutMatrixG = (ColorMatrixLuma + ((InMatrixG - ColorMatrixLuma) * InSaturation)) * InExposure;
|
|
OutMatrixB = (ColorMatrixLuma + ((InMatrixB - ColorMatrixLuma) * InSaturation)) * InExposure;
|
|
if(UseShadowTint == 0)
|
|
{
|
|
OutMatrixR = OutMatrixR * InWhitePoint.X;
|
|
OutMatrixG = OutMatrixG * InWhitePoint.Y;
|
|
OutMatrixB = OutMatrixB * InWhitePoint.Z;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// No color matrix fast path.
|
|
if(UseShadowTint == 0)
|
|
{
|
|
OutMatrixB = InExposure * InWhitePoint;
|
|
}
|
|
else
|
|
{
|
|
// Need to drop exposure in.
|
|
OutColorShadow_Luma *= InExposure;
|
|
OutColorShadow_Tint1 *= InExposure;
|
|
OutColorShadow_Tint2 *= InExposure;
|
|
}
|
|
}
|
|
|
|
// Curve constants.
|
|
float OutColorCurveCh3;
|
|
float OutColorCurveCh0Cm1;
|
|
float OutColorCurveCd2;
|
|
float OutColorCurveCm0Cd0;
|
|
float OutColorCurveCh1;
|
|
float OutColorCurveCh2;
|
|
float OutColorCurveCd1;
|
|
float OutColorCurveCd3Cm3;
|
|
float OutColorCurveCm2;
|
|
|
|
// Line for linear section.
|
|
float FilmLineOffset = 0.18f - 0.18f*InContrast;
|
|
float FilmXAtY0 = -FilmLineOffset/InContrast;
|
|
float FilmXAtY1 = (1.0f - FilmLineOffset) / InContrast;
|
|
float FilmXS = FilmXAtY1 - FilmXAtY0;
|
|
|
|
// Coordinates of linear section.
|
|
float FilmHiX = FilmXAtY0 + InHeal*FilmXS;
|
|
float FilmHiY = FilmHiX*InContrast + FilmLineOffset;
|
|
float FilmLoX = FilmXAtY0 + InToe*FilmXS;
|
|
float FilmLoY = FilmLoX*InContrast + FilmLineOffset;
|
|
// Supported exposure range before clipping.
|
|
float FilmHeal = InDynamicRange - FilmHiX;
|
|
// Intermediates.
|
|
float FilmMidXS = FilmHiX - FilmLoX;
|
|
float FilmMidYS = FilmHiY - FilmLoY;
|
|
float FilmSlope = FilmMidYS / (FilmMidXS);
|
|
float FilmHiYS = 1.0f - FilmHiY;
|
|
float FilmLoYS = FilmLoY;
|
|
float FilmToe = FilmLoX;
|
|
float FilmHiG = (-FilmHiYS + (FilmSlope*FilmHeal)) / (FilmSlope*FilmHeal);
|
|
float FilmLoG = (-FilmLoYS + (FilmSlope*FilmToe)) / (FilmSlope*FilmToe);
|
|
|
|
if(UseContrast)
|
|
{
|
|
// Constants.
|
|
OutColorCurveCh1 = FilmHiYS/FilmHiG;
|
|
OutColorCurveCh2 = -FilmHiX*(FilmHiYS/FilmHiG);
|
|
OutColorCurveCh3 = FilmHiYS/(FilmSlope*FilmHiG) - FilmHiX;
|
|
OutColorCurveCh0Cm1 = FilmHiX;
|
|
OutColorCurveCm2 = FilmSlope;
|
|
OutColorCurveCm0Cd0 = FilmLoX;
|
|
OutColorCurveCd3Cm3 = FilmLoY - FilmLoX*FilmSlope;
|
|
// Handle these separate in case of FilmLoG being 0.
|
|
if(FilmLoG != 0.0f)
|
|
{
|
|
OutColorCurveCd1 = -FilmLoYS/FilmLoG;
|
|
OutColorCurveCd2 = FilmLoYS/(FilmSlope*FilmLoG);
|
|
}
|
|
else
|
|
{
|
|
// FilmLoG being zero means dark region is a linear segment (so just continue the middle section).
|
|
OutColorCurveCd1 = 0.0f;
|
|
OutColorCurveCd2 = 1.0f;
|
|
OutColorCurveCm0Cd0 = 0.0f;
|
|
OutColorCurveCd3Cm3 = 0.0f;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Simplified for no dark segment.
|
|
OutColorCurveCh1 = FilmHiYS/FilmHiG;
|
|
OutColorCurveCh2 = -FilmHiX*(FilmHiYS/FilmHiG);
|
|
OutColorCurveCh3 = FilmHiYS/(FilmSlope*FilmHiG) - FilmHiX;
|
|
OutColorCurveCh0Cm1 = FilmHiX;
|
|
// Not used.
|
|
OutColorCurveCm2 = 0.0f;
|
|
OutColorCurveCm0Cd0 = 0.0f;
|
|
OutColorCurveCd3Cm3 = 0.0f;
|
|
OutColorCurveCd1 = 0.0f;
|
|
OutColorCurveCd2 = 0.0f;
|
|
}
|
|
|
|
Constants[0] = FVector4(OutMatrixR, OutColorCurveCd1);
|
|
Constants[1] = FVector4(OutMatrixG, OutColorCurveCd3Cm3);
|
|
Constants[2] = FVector4(OutMatrixB, OutColorCurveCm2);
|
|
Constants[3] = FVector4(OutColorCurveCm0Cd0, OutColorCurveCd2, OutColorCurveCh0Cm1, OutColorCurveCh3);
|
|
Constants[4] = FVector4(OutColorCurveCh1, OutColorCurveCh2, 0.0f, 0.0f);
|
|
Constants[5] = FVector4(OutColorShadow_Luma, 0.0f);
|
|
Constants[6] = FVector4(OutColorShadow_Tint1, 0.0f);
|
|
Constants[7] = FVector4(OutColorShadow_Tint2, 0.0f);
|
|
}
|
|
|
|
|
|
BEGIN_UNIFORM_BUFFER_STRUCT(FBloomDirtMaskParameters,)
|
|
DECLARE_UNIFORM_BUFFER_STRUCT_MEMBER(FVector4,Tint)
|
|
DECLARE_UNIFORM_BUFFER_STRUCT_MEMBER_TEXTURE(Texture2D,Mask)
|
|
DECLARE_UNIFORM_BUFFER_STRUCT_MEMBER_SAMPLER(SamplerState,MaskSampler)
|
|
END_UNIFORM_BUFFER_STRUCT(FBloomDirtMaskParameters)
|
|
IMPLEMENT_UNIFORM_BUFFER_STRUCT(FBloomDirtMaskParameters,TEXT("BloomDirtMask"));
|
|
|
|
|
|
static TAutoConsoleVariable<float> CVarGamma(
|
|
TEXT("r.Gamma"),
|
|
1.0f,
|
|
TEXT("Gamma on output"),
|
|
ECVF_RenderThreadSafe);
|
|
|
|
/**
|
|
* Encapsulates the post processing tonemapper pixel shader.
|
|
*/
|
|
template<uint32 ConfigIndex>
|
|
class FPostProcessTonemapPS : public FGlobalShader
|
|
{
|
|
DECLARE_SHADER_TYPE(FPostProcessTonemapPS, Global);
|
|
|
|
static bool ShouldCache(EShaderPlatform Platform)
|
|
{
|
|
return IsFeatureLevelSupported(Platform, ERHIFeatureLevel::ES2);
|
|
}
|
|
|
|
static void ModifyCompilationEnvironment(EShaderPlatform Platform, FShaderCompilerEnvironment& OutEnvironment)
|
|
{
|
|
FGlobalShader::ModifyCompilationEnvironment(Platform, OutEnvironment);
|
|
|
|
uint32 ConfigBitmask = TonemapperConfBitmaskPC[ConfigIndex];
|
|
|
|
OutEnvironment.SetDefine(TEXT("USE_GAMMA_ONLY"), TonemapperIsDefined(ConfigBitmask, TonemapperGammaOnly));
|
|
OutEnvironment.SetDefine(TEXT("USE_COLOR_MATRIX"), TonemapperIsDefined(ConfigBitmask, TonemapperColorMatrix));
|
|
OutEnvironment.SetDefine(TEXT("USE_SHADOW_TINT"), TonemapperIsDefined(ConfigBitmask, TonemapperShadowTint));
|
|
OutEnvironment.SetDefine(TEXT("USE_CONTRAST"), TonemapperIsDefined(ConfigBitmask, TonemapperContrast));
|
|
OutEnvironment.SetDefine(TEXT("USE_BLOOM"), TonemapperIsDefined(ConfigBitmask, TonemapperBloom));
|
|
OutEnvironment.SetDefine(TEXT("USE_GRAIN_JITTER"), TonemapperIsDefined(ConfigBitmask, TonemapperGrainJitter));
|
|
OutEnvironment.SetDefine(TEXT("USE_GRAIN_INTENSITY"), TonemapperIsDefined(ConfigBitmask, TonemapperGrainIntensity));
|
|
OutEnvironment.SetDefine(TEXT("USE_GRAIN_QUANTIZATION"), TonemapperIsDefined(ConfigBitmask, TonemapperGrainQuantization));
|
|
OutEnvironment.SetDefine(TEXT("USE_VIGNETTE"), TonemapperIsDefined(ConfigBitmask, TonemapperVignette));
|
|
OutEnvironment.SetDefine(TEXT("USE_COLOR_FRINGE"), TonemapperIsDefined(ConfigBitmask, TonemapperColorFringe));
|
|
OutEnvironment.SetDefine(TEXT("USE_SHARPEN"), TonemapperIsDefined(ConfigBitmask, TonemapperSharpen));
|
|
OutEnvironment.SetDefine(TEXT("USE_INVERSE_TONEMAPPING"), TonemapperIsDefined(ConfigBitmask, TonemapperInverseTonemapping));
|
|
OutEnvironment.SetDefine(TEXT("USE_VOLUME_LUT"), UseVolumeTextureLUT(Platform));
|
|
}
|
|
|
|
/** Default constructor. */
|
|
FPostProcessTonemapPS() {}
|
|
|
|
public:
|
|
FPostProcessPassParameters PostprocessParameter;
|
|
FShaderParameter ColorScale0;
|
|
FShaderParameter ColorScale1;
|
|
FShaderResourceParameter NoiseTexture;
|
|
FShaderResourceParameter NoiseTextureSampler;
|
|
FShaderParameter TexScale;
|
|
FShaderParameter TonemapperParams;
|
|
FShaderParameter GrainScaleBiasJitter;
|
|
FShaderResourceParameter ColorGradingLUT;
|
|
FShaderResourceParameter ColorGradingLUTSampler;
|
|
FShaderParameter InverseGamma;
|
|
|
|
FShaderParameter ColorMatrixR_ColorCurveCd1;
|
|
FShaderParameter ColorMatrixG_ColorCurveCd3Cm3;
|
|
FShaderParameter ColorMatrixB_ColorCurveCm2;
|
|
FShaderParameter ColorCurve_Cm0Cd0_Cd2_Ch0Cm1_Ch3;
|
|
FShaderParameter ColorCurve_Ch1_Ch2;
|
|
FShaderParameter ColorShadow_Luma;
|
|
FShaderParameter ColorShadow_Tint1;
|
|
FShaderParameter ColorShadow_Tint2;
|
|
|
|
//@HACK
|
|
FShaderParameter OverlayColor;
|
|
|
|
FShaderParameter OutputDevice;
|
|
FShaderParameter OutputGamut;
|
|
FShaderParameter EncodeHDROutput;
|
|
|
|
/** Initialization constructor. */
|
|
FPostProcessTonemapPS(const ShaderMetaType::CompiledShaderInitializerType& Initializer)
|
|
: FGlobalShader(Initializer)
|
|
{
|
|
PostprocessParameter.Bind(Initializer.ParameterMap);
|
|
ColorScale0.Bind(Initializer.ParameterMap, TEXT("ColorScale0"));
|
|
ColorScale1.Bind(Initializer.ParameterMap, TEXT("ColorScale1"));
|
|
NoiseTexture.Bind(Initializer.ParameterMap,TEXT("NoiseTexture"));
|
|
NoiseTextureSampler.Bind(Initializer.ParameterMap,TEXT("NoiseTextureSampler"));
|
|
TexScale.Bind(Initializer.ParameterMap, TEXT("TexScale"));
|
|
TonemapperParams.Bind(Initializer.ParameterMap, TEXT("TonemapperParams"));
|
|
GrainScaleBiasJitter.Bind(Initializer.ParameterMap, TEXT("GrainScaleBiasJitter"));
|
|
ColorGradingLUT.Bind(Initializer.ParameterMap, TEXT("ColorGradingLUT"));
|
|
ColorGradingLUTSampler.Bind(Initializer.ParameterMap, TEXT("ColorGradingLUTSampler"));
|
|
InverseGamma.Bind(Initializer.ParameterMap,TEXT("InverseGamma"));
|
|
|
|
ColorMatrixR_ColorCurveCd1.Bind(Initializer.ParameterMap, TEXT("ColorMatrixR_ColorCurveCd1"));
|
|
ColorMatrixG_ColorCurveCd3Cm3.Bind(Initializer.ParameterMap, TEXT("ColorMatrixG_ColorCurveCd3Cm3"));
|
|
ColorMatrixB_ColorCurveCm2.Bind(Initializer.ParameterMap, TEXT("ColorMatrixB_ColorCurveCm2"));
|
|
ColorCurve_Cm0Cd0_Cd2_Ch0Cm1_Ch3.Bind(Initializer.ParameterMap, TEXT("ColorCurve_Cm0Cd0_Cd2_Ch0Cm1_Ch3"));
|
|
ColorCurve_Ch1_Ch2.Bind(Initializer.ParameterMap, TEXT("ColorCurve_Ch1_Ch2"));
|
|
ColorShadow_Luma.Bind(Initializer.ParameterMap, TEXT("ColorShadow_Luma"));
|
|
ColorShadow_Tint1.Bind(Initializer.ParameterMap, TEXT("ColorShadow_Tint1"));
|
|
ColorShadow_Tint2.Bind(Initializer.ParameterMap, TEXT("ColorShadow_Tint2"));
|
|
|
|
OverlayColor.Bind(Initializer.ParameterMap, TEXT("OverlayColor"));
|
|
|
|
OutputDevice.Bind(Initializer.ParameterMap, TEXT("OutputDevice"));
|
|
OutputGamut.Bind(Initializer.ParameterMap, TEXT("OutputGamut"));
|
|
EncodeHDROutput.Bind(Initializer.ParameterMap, TEXT("EncodeHDROutput"));
|
|
}
|
|
|
|
// FShader interface.
|
|
virtual bool Serialize(FArchive& Ar) override
|
|
{
|
|
bool bShaderHasOutdatedParameters = FGlobalShader::Serialize(Ar);
|
|
Ar << PostprocessParameter << ColorScale0 << ColorScale1 << InverseGamma << NoiseTexture << NoiseTextureSampler
|
|
<< TexScale << TonemapperParams << GrainScaleBiasJitter
|
|
<< ColorGradingLUT << ColorGradingLUTSampler
|
|
<< ColorMatrixR_ColorCurveCd1 << ColorMatrixG_ColorCurveCd3Cm3 << ColorMatrixB_ColorCurveCm2 << ColorCurve_Cm0Cd0_Cd2_Ch0Cm1_Ch3 << ColorCurve_Ch1_Ch2 << ColorShadow_Luma << ColorShadow_Tint1 << ColorShadow_Tint2
|
|
<< OverlayColor
|
|
<< OutputDevice << OutputGamut << EncodeHDROutput;
|
|
|
|
return bShaderHasOutdatedParameters;
|
|
}
|
|
|
|
void SetPS(const FRenderingCompositePassContext& Context)
|
|
{
|
|
const FPostProcessSettings& Settings = Context.View.FinalPostProcessSettings;
|
|
const FSceneViewFamily& ViewFamily = *(Context.View.Family);
|
|
|
|
const FPixelShaderRHIParamRef ShaderRHI = GetPixelShader();
|
|
|
|
FGlobalShader::SetParameters(Context.RHICmdList, ShaderRHI, Context.View);
|
|
|
|
{
|
|
// filtering can cost performance so we use point where possible, we don't want anisotropic sampling
|
|
FSamplerStateRHIParamRef Filters[] =
|
|
{
|
|
TStaticSamplerState<SF_Bilinear, AM_Clamp, AM_Clamp, AM_Clamp, 0, 1>::GetRHI(), // todo: could be SF_Point if fringe is disabled
|
|
TStaticSamplerState<SF_Bilinear, AM_Clamp, AM_Clamp, AM_Clamp, 0, 1>::GetRHI(),
|
|
TStaticSamplerState<SF_Point, AM_Clamp, AM_Clamp, AM_Clamp, 0, 1>::GetRHI(),
|
|
TStaticSamplerState<SF_Bilinear, AM_Clamp, AM_Clamp, AM_Clamp, 0, 1>::GetRHI(),
|
|
};
|
|
|
|
PostprocessParameter.SetPS(ShaderRHI, Context, 0, eFC_0000, Filters);
|
|
}
|
|
|
|
// Display format
|
|
int32 OutputGamutValue = CVarDisplayColorGamut.GetValueOnRenderThread();
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, OutputGamut, OutputGamutValue);
|
|
|
|
int32 HDROutputEncodingValue = (CVarHDROutputEnabled.GetValueOnRenderThread() != 0 && IsRHIDeviceNVIDIA()) ? 1 : 0; // Nvidia-specific scRGB encoding
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, EncodeHDROutput, HDROutputEncodingValue);
|
|
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, OverlayColor, Context.View.OverlayColor);
|
|
|
|
{
|
|
FLinearColor Col = Settings.SceneColorTint;
|
|
FVector4 ColorScale(Col.R, Col.G, Col.B, 0);
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorScale0, ColorScale);
|
|
}
|
|
|
|
{
|
|
FLinearColor Col = FLinearColor::White * Settings.BloomIntensity;
|
|
FVector4 ColorScale(Col.R, Col.G, Col.B, 0);
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorScale1, ColorScale);
|
|
}
|
|
|
|
{
|
|
UTexture2D* NoiseTextureValue = GEngine->HighFrequencyNoiseTexture;
|
|
|
|
SetTextureParameter(Context.RHICmdList, ShaderRHI, NoiseTexture, NoiseTextureSampler, TStaticSamplerState<SF_Point, AM_Wrap, AM_Wrap, AM_Wrap>::GetRHI(), NoiseTextureValue->Resource->TextureRHI);
|
|
}
|
|
|
|
{
|
|
const FPooledRenderTargetDesc* InputDesc = Context.Pass->GetInputDesc(ePId_Input0);
|
|
|
|
// we assume the this pass runs in 1:1 pixel
|
|
FVector2D TexScaleValue = FVector2D(InputDesc->Extent) / FVector2D(Context.View.ViewRect.Size());
|
|
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, TexScale, TexScaleValue);
|
|
}
|
|
|
|
{
|
|
float Sharpen = FMath::Clamp(CVarTonemapperSharpen.GetValueOnRenderThread(), 0.0f, 10.0f);
|
|
|
|
// /6.0 is to save one shader instruction
|
|
FVector2D Value(Settings.VignetteIntensity, Sharpen / 6.0f);
|
|
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, TonemapperParams, Value);
|
|
}
|
|
|
|
{
|
|
static TConsoleVariableData<int32>* CVarOutputDevice = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.HDR.Display.OutputDevice"));
|
|
static TConsoleVariableData<float>* CVarOutputGamma = IConsoleManager::Get().FindTConsoleVariableDataFloat(TEXT("r.TonemapperGamma"));
|
|
|
|
int32 OutputDeviceValue = CVarOutputDevice->GetValueOnRenderThread();
|
|
float Gamma = CVarOutputGamma->GetValueOnRenderThread();
|
|
|
|
if (PLATFORM_APPLE && Gamma == 0.0f)
|
|
{
|
|
Gamma = 2.2f;
|
|
}
|
|
|
|
if (Gamma > 0.0f)
|
|
{
|
|
// Enforce user-controlled ramp over sRGB or Rec709
|
|
OutputDeviceValue = FMath::Max(OutputDeviceValue, 2);
|
|
}
|
|
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, OutputDevice, OutputDeviceValue);
|
|
}
|
|
|
|
FVector GrainValue;
|
|
GrainPostSettings(&GrainValue, &Settings);
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, GrainScaleBiasJitter, GrainValue);
|
|
|
|
const TShaderUniformBufferParameter<FBloomDirtMaskParameters>& BloomDirtMaskParam = GetUniformBufferParameter<FBloomDirtMaskParameters>();
|
|
if (BloomDirtMaskParam.IsBound())
|
|
{
|
|
FBloomDirtMaskParameters BloomDirtMaskParams;
|
|
|
|
FLinearColor Col = Settings.BloomDirtMaskTint * Settings.BloomDirtMaskIntensity;
|
|
BloomDirtMaskParams.Tint = FVector4(Col.R, Col.G, Col.B, 0.f /*unused*/);
|
|
|
|
BloomDirtMaskParams.Mask = GSystemTextures.BlackDummy->GetRenderTargetItem().TargetableTexture;
|
|
if(Settings.BloomDirtMask && Settings.BloomDirtMask->Resource)
|
|
{
|
|
BloomDirtMaskParams.Mask = Settings.BloomDirtMask->Resource->TextureRHI;
|
|
}
|
|
BloomDirtMaskParams.MaskSampler = TStaticSamplerState<SF_Bilinear,AM_Wrap,AM_Wrap,AM_Wrap>::GetRHI();
|
|
|
|
FUniformBufferRHIRef BloomDirtMaskUB = TUniformBufferRef<FBloomDirtMaskParameters>::CreateUniformBufferImmediate(BloomDirtMaskParams, UniformBuffer_SingleDraw);
|
|
SetUniformBufferParameter(Context.RHICmdList, ShaderRHI, BloomDirtMaskParam, BloomDirtMaskUB);
|
|
}
|
|
|
|
// volume texture LUT
|
|
{
|
|
FRenderingCompositeOutputRef* OutputRef = Context.Pass->GetInput(ePId_Input3);
|
|
|
|
if(OutputRef)
|
|
{
|
|
FRenderingCompositeOutput* Input = OutputRef->GetOutput();
|
|
|
|
if(Input)
|
|
{
|
|
TRefCountPtr<IPooledRenderTarget> InputPooledElement = Input->RequestInput();
|
|
|
|
if(InputPooledElement)
|
|
{
|
|
check(!InputPooledElement->IsFree());
|
|
|
|
const FTextureRHIRef& SrcTexture = InputPooledElement->GetRenderTargetItem().ShaderResourceTexture;
|
|
|
|
SetTextureParameter(Context.RHICmdList, ShaderRHI, ColorGradingLUT, ColorGradingLUTSampler, TStaticSamplerState<SF_Bilinear, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI(), SrcTexture);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
{
|
|
FVector InvDisplayGammaValue;
|
|
InvDisplayGammaValue.X = 1.0f / ViewFamily.RenderTarget->GetDisplayGamma();
|
|
InvDisplayGammaValue.Y = 2.2f / ViewFamily.RenderTarget->GetDisplayGamma();
|
|
{
|
|
static TConsoleVariableData<float>* CVar = IConsoleManager::Get().FindTConsoleVariableDataFloat(TEXT("r.TonemapperGamma"));
|
|
float Value = CVar->GetValueOnRenderThread();
|
|
if(Value < 1.0f)
|
|
{
|
|
Value = 1.0f;
|
|
}
|
|
InvDisplayGammaValue.Z = 1.0f / Value;
|
|
}
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, InverseGamma, InvDisplayGammaValue);
|
|
}
|
|
|
|
{
|
|
FVector4 Constants[8];
|
|
FilmPostSetConstants(Constants, TonemapperConfBitmaskPC[ConfigIndex], &Context.View.FinalPostProcessSettings, false);
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorMatrixR_ColorCurveCd1, Constants[0]);
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorMatrixG_ColorCurveCd3Cm3, Constants[1]);
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorMatrixB_ColorCurveCm2, Constants[2]);
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorCurve_Cm0Cd0_Cd2_Ch0Cm1_Ch3, Constants[3]);
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorCurve_Ch1_Ch2, Constants[4]);
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorShadow_Luma, Constants[5]);
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorShadow_Tint1, Constants[6]);
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorShadow_Tint2, Constants[7]);
|
|
}
|
|
}
|
|
|
|
static const TCHAR* GetSourceFilename()
|
|
{
|
|
return TEXT("PostProcessTonemap");
|
|
}
|
|
|
|
static const TCHAR* GetFunctionName()
|
|
{
|
|
return TEXT("MainPS");
|
|
}
|
|
};
|
|
|
|
// #define avoids a lot of code duplication
|
|
#define VARIATION1(A) typedef FPostProcessTonemapPS<A> FPostProcessTonemapPS##A; \
|
|
IMPLEMENT_SHADER_TYPE2(FPostProcessTonemapPS##A, SF_Pixel);
|
|
|
|
VARIATION1(0) VARIATION1(1) VARIATION1(2) VARIATION1(3) VARIATION1(4) VARIATION1(5) VARIATION1(6) VARIATION1(7) VARIATION1(8)
|
|
VARIATION1(9) VARIATION1(10) VARIATION1(11) VARIATION1(12) VARIATION1(13) VARIATION1(14)
|
|
|
|
#undef VARIATION1
|
|
|
|
|
|
// Vertex Shader permutations based on bool AutoExposure.
|
|
IMPLEMENT_SHADER_TYPE(template<>, TPostProcessTonemapVS<true>, TEXT("PostProcessTonemap"), TEXT("MainVS"), SF_Vertex);
|
|
IMPLEMENT_SHADER_TYPE(template<>, TPostProcessTonemapVS<false>, TEXT("PostProcessTonemap"), TEXT("MainVS"), SF_Vertex);
|
|
|
|
|
|
FRCPassPostProcessTonemap::FRCPassPostProcessTonemap(const FViewInfo& InView, bool bInDoGammaOnly, bool bInDoEyeAdaptation, bool bInHDROutput)
|
|
: bDoGammaOnly(bInDoGammaOnly)
|
|
, bDoScreenPercentageInTonemapper(false)
|
|
, bDoEyeAdaptation(bInDoEyeAdaptation)
|
|
, bHDROutput(bInHDROutput)
|
|
, View(InView)
|
|
{
|
|
uint32 ConfigBitmask = TonemapperGenerateBitmaskPC(&InView, bDoGammaOnly);
|
|
ConfigIndexPC = TonemapperFindLeastExpensive(TonemapperConfBitmaskPC, sizeof(TonemapperConfBitmaskPC)/4, TonemapperCostTab, ConfigBitmask);;
|
|
}
|
|
|
|
namespace PostProcessTonemapUtil
|
|
{
|
|
// Template implementation supports unique static BoundShaderState for each permutation of Vertex/Pixel Shaders
|
|
template <uint32 ConfigIndex, bool bDoEyeAdaptation>
|
|
static inline void SetShaderTempl(const FRenderingCompositePassContext& Context)
|
|
{
|
|
typedef TPostProcessTonemapVS<bDoEyeAdaptation> VertexShaderType;
|
|
typedef FPostProcessTonemapPS<ConfigIndex> PixelShaderType;
|
|
|
|
TShaderMapRef<PixelShaderType> PixelShader(Context.GetShaderMap());
|
|
TShaderMapRef<VertexShaderType> VertexShader(Context.GetShaderMap());
|
|
|
|
static FGlobalBoundShaderState BoundShaderState;
|
|
|
|
SetGlobalBoundShaderState(Context.RHICmdList, Context.GetFeatureLevel(), BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);
|
|
|
|
VertexShader->SetVS(Context);
|
|
PixelShader->SetPS(Context);
|
|
}
|
|
|
|
template <uint32 ConfigIndex>
|
|
static inline void SetShaderTempl(const FRenderingCompositePassContext& Context, bool bDoEyeAdaptation)
|
|
{
|
|
if (bDoEyeAdaptation)
|
|
{
|
|
SetShaderTempl<ConfigIndex, true>(Context);
|
|
}
|
|
else
|
|
{
|
|
SetShaderTempl<ConfigIndex, false>(Context);
|
|
}
|
|
}
|
|
}
|
|
|
|
static TAutoConsoleVariable<int32> CVarTonemapperOverride(
|
|
TEXT("r.Tonemapper.ConfigIndexOverride"),
|
|
-1,
|
|
TEXT("direct configindex override. Ignores all other tonemapper configuration cvars"),
|
|
ECVF_RenderThreadSafe);
|
|
|
|
void FRCPassPostProcessTonemap::Process(FRenderingCompositePassContext& Context)
|
|
{
|
|
const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0);
|
|
|
|
if(!InputDesc)
|
|
{
|
|
// input is not hooked up correctly
|
|
return;
|
|
}
|
|
|
|
const FSceneViewFamily& ViewFamily = *(View.Family);
|
|
FIntRect SrcRect = View.ViewRect;
|
|
FIntRect DestRect = bDoScreenPercentageInTonemapper ? View.UnscaledViewRect : View.ViewRect;
|
|
FIntPoint SrcSize = InputDesc->Extent;
|
|
|
|
SCOPED_DRAW_EVENTF(Context.RHICmdList, PostProcessTonemap, TEXT("Tonemapper#%d GammaOnly=%d HandleScreenPercentage=%d %dx%d"),
|
|
ConfigIndexPC, bDoGammaOnly, bDoScreenPercentageInTonemapper, DestRect.Width(), DestRect.Height());
|
|
|
|
const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context);
|
|
|
|
const EShaderPlatform ShaderPlatform = GShaderPlatformForFeatureLevel[Context.GetFeatureLevel()];
|
|
|
|
if (IsVulkanPlatform(ShaderPlatform))
|
|
{
|
|
//@HACK: needs to set the framebuffer to clear/ignore in vulkan (doesn't support RHIClear)
|
|
// Clearing for letterbox mode. We could ENoAction if View.ViewRect == RT dims.
|
|
FRHIRenderTargetView ColorView(DestRenderTarget.TargetableTexture, 0, -1, ERenderTargetLoadAction::EClear, ERenderTargetStoreAction::EStore);
|
|
FRHISetRenderTargetsInfo Info(1, &ColorView, FRHIDepthRenderTargetView());
|
|
Context.RHICmdList.SetRenderTargetsAndClear(Info);
|
|
}
|
|
else
|
|
{
|
|
// Set the view family's render target/viewport.
|
|
SetRenderTarget(Context.RHICmdList, DestRenderTarget.TargetableTexture, FTextureRHIParamRef(), ESimpleRenderTargetMode::EUninitializedColorAndDepth);
|
|
|
|
if (Context.HasHmdMesh() && View.StereoPass == eSSP_LEFT_EYE)
|
|
{
|
|
// needed when using an hmd mesh instead of a full screen quad because we don't touch all of the pixels in the render target
|
|
Context.RHICmdList.ClearColorTexture(DestRenderTarget.TargetableTexture, FLinearColor::Black, FIntRect());
|
|
}
|
|
else if (ViewFamily.RenderTarget->GetRenderTargetTexture() != DestRenderTarget.TargetableTexture)
|
|
{
|
|
// needed to not have PostProcessAA leaking in content (e.g. Matinee black borders), is optimized away if possible (RT size=view size, )
|
|
Context.RHICmdList.ClearColorTexture(DestRenderTarget.TargetableTexture, FLinearColor::Black, DestRect);
|
|
}
|
|
}
|
|
|
|
Context.SetViewportAndCallRHI(DestRect, 0.0f, 1.0f );
|
|
|
|
// set the state
|
|
Context.RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI());
|
|
Context.RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI());
|
|
Context.RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI());
|
|
|
|
const int32 ConfigOverride = CVarTonemapperOverride->GetInt();
|
|
const uint32 FinalConfigIndex = ConfigOverride == -1 ? ConfigIndexPC : (int32)ConfigOverride;
|
|
switch (FinalConfigIndex)
|
|
{
|
|
using namespace PostProcessTonemapUtil;
|
|
case 0: SetShaderTempl<0>(Context, bDoEyeAdaptation); break;
|
|
case 1: SetShaderTempl<1>(Context, bDoEyeAdaptation); break;
|
|
case 2: SetShaderTempl<2>(Context, bDoEyeAdaptation); break;
|
|
case 3: SetShaderTempl<3>(Context, bDoEyeAdaptation); break;
|
|
case 4: SetShaderTempl<4>(Context, bDoEyeAdaptation); break;
|
|
case 5: SetShaderTempl<5>(Context, bDoEyeAdaptation); break;
|
|
case 6: SetShaderTempl<6>(Context, bDoEyeAdaptation); break;
|
|
case 7: SetShaderTempl<7>(Context, bDoEyeAdaptation); break;
|
|
case 8: SetShaderTempl<8>(Context, bDoEyeAdaptation); break;
|
|
case 9: SetShaderTempl<9>(Context, bDoEyeAdaptation); break;
|
|
case 10: SetShaderTempl<10>(Context, bDoEyeAdaptation); break;
|
|
case 11: SetShaderTempl<11>(Context, bDoEyeAdaptation); break;
|
|
case 12: SetShaderTempl<12>(Context, bDoEyeAdaptation); break;
|
|
case 13: SetShaderTempl<13>(Context, bDoEyeAdaptation); break;
|
|
case 14: SetShaderTempl<14>(Context, bDoEyeAdaptation); break;
|
|
default:
|
|
check(0);
|
|
}
|
|
|
|
|
|
FSceneRenderTargets& SceneContext = FSceneRenderTargets::Get(Context.RHICmdList);
|
|
|
|
FShader* VertexShader;
|
|
if (bDoEyeAdaptation)
|
|
{
|
|
// Use the vertex shader that passes on eye-adaptation values to the pixel shader
|
|
TShaderMapRef<TPostProcessTonemapVS<true>> VertexShaderMapRef(Context.GetShaderMap());
|
|
VertexShader = *VertexShaderMapRef;
|
|
}
|
|
else
|
|
{
|
|
TShaderMapRef<TPostProcessTonemapVS<false>> VertexShaderMapRef(Context.GetShaderMap());
|
|
VertexShader = *VertexShaderMapRef;
|
|
}
|
|
|
|
DrawPostProcessPass(
|
|
Context.RHICmdList,
|
|
0, 0,
|
|
DestRect.Width(), DestRect.Height(),
|
|
View.ViewRect.Min.X, View.ViewRect.Min.Y,
|
|
View.ViewRect.Width(), View.ViewRect.Height(),
|
|
DestRect.Size(),
|
|
SceneContext.GetBufferSizeXY(),
|
|
VertexShader,
|
|
View.StereoPass,
|
|
Context.HasHmdMesh(),
|
|
EDRF_UseTriangleOptimization);
|
|
|
|
Context.RHICmdList.CopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams());
|
|
|
|
// We only release the SceneColor after the last view was processed (SplitScreen)
|
|
if(Context.View.Family->Views[Context.View.Family->Views.Num() - 1] == &Context.View && !GIsEditor)
|
|
{
|
|
// The RT should be released as early as possible to allow sharing of that memory for other purposes.
|
|
// This becomes even more important with some limited VRam (XBoxOne).
|
|
SceneContext.SetSceneColor(0);
|
|
}
|
|
|
|
if (ViewFamily.Scene && ViewFamily.Scene->GetShadingPath() == EShadingPath::Mobile)
|
|
{
|
|
// Double buffer tonemapper output for temporal AA.
|
|
if(View.AntiAliasingMethod == AAM_TemporalAA)
|
|
{
|
|
FSceneViewState* ViewState = (FSceneViewState*)View.State;
|
|
if(ViewState)
|
|
{
|
|
ViewState->MobileAaColor0 = PassOutputs[0].PooledRenderTarget;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
FPooledRenderTargetDesc FRCPassPostProcessTonemap::ComputeOutputDesc(EPassOutputId InPassOutputId) const
|
|
{
|
|
FPooledRenderTargetDesc Ret = GetInput(ePId_Input0)->GetOutput()->RenderTargetDesc;
|
|
|
|
Ret.Reset();
|
|
// RGB is the color in LDR, A is the luminance for PostprocessAA
|
|
Ret.Format = bHDROutput ? GRHIHDRDisplayOutputFormat : PF_B8G8R8A8;
|
|
Ret.DebugName = TEXT("Tonemap");
|
|
Ret.ClearValue = FClearValueBinding(FLinearColor(0, 0, 0, 0));
|
|
|
|
return Ret;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ES2 version
|
|
|
|
/**
|
|
* Encapsulates the post processing tonemapper pixel shader.
|
|
*/
|
|
template<uint32 ConfigIndex>
|
|
class FPostProcessTonemapPS_ES2 : public FGlobalShader
|
|
{
|
|
DECLARE_SHADER_TYPE(FPostProcessTonemapPS_ES2, Global);
|
|
|
|
static bool ShouldCache(EShaderPlatform Platform)
|
|
{
|
|
const uint32 ConfigBitmask = TonemapperConfBitmaskMobile[ConfigIndex];
|
|
|
|
// Only cache for ES2/3.1 shader platforms, and only compile 32bpp shaders for Android or PC emulation
|
|
return IsMobilePlatform(Platform) &&
|
|
(!TonemapperIsDefined(ConfigBitmask, Tonemapper32BPPHDR) || Platform == SP_OPENGL_ES2_ANDROID || (IsES2Platform(Platform) && IsPCPlatform(Platform)));
|
|
}
|
|
|
|
static void ModifyCompilationEnvironment(EShaderPlatform Platform, FShaderCompilerEnvironment& OutEnvironment)
|
|
{
|
|
FGlobalShader::ModifyCompilationEnvironment(Platform, OutEnvironment);
|
|
|
|
const uint32 ConfigBitmask = TonemapperConfBitmaskMobile[ConfigIndex];
|
|
|
|
OutEnvironment.SetDefine(TEXT("USE_GAMMA_ONLY"), TonemapperIsDefined(ConfigBitmask, TonemapperGammaOnly));
|
|
OutEnvironment.SetDefine(TEXT("USE_COLOR_MATRIX"), TonemapperIsDefined(ConfigBitmask, TonemapperColorMatrix));
|
|
OutEnvironment.SetDefine(TEXT("USE_SHADOW_TINT"), TonemapperIsDefined(ConfigBitmask, TonemapperShadowTint));
|
|
OutEnvironment.SetDefine(TEXT("USE_CONTRAST"), TonemapperIsDefined(ConfigBitmask, TonemapperContrast));
|
|
OutEnvironment.SetDefine(TEXT("USE_32BPP_HDR"), TonemapperIsDefined(ConfigBitmask, Tonemapper32BPPHDR));
|
|
OutEnvironment.SetDefine(TEXT("USE_BLOOM"), TonemapperIsDefined(ConfigBitmask, TonemapperBloom));
|
|
OutEnvironment.SetDefine(TEXT("USE_GRAIN_JITTER"), TonemapperIsDefined(ConfigBitmask, TonemapperGrainJitter));
|
|
OutEnvironment.SetDefine(TEXT("USE_GRAIN_INTENSITY"), TonemapperIsDefined(ConfigBitmask, TonemapperGrainIntensity));
|
|
OutEnvironment.SetDefine(TEXT("USE_GRAIN_QUANTIZATION"), TonemapperIsDefined(ConfigBitmask, TonemapperGrainQuantization));
|
|
OutEnvironment.SetDefine(TEXT("USE_VIGNETTE"), TonemapperIsDefined(ConfigBitmask, TonemapperVignette));
|
|
OutEnvironment.SetDefine(TEXT("USE_LIGHT_SHAFTS"), TonemapperIsDefined(ConfigBitmask, TonemapperLightShafts));
|
|
OutEnvironment.SetDefine(TEXT("USE_DOF"), TonemapperIsDefined(ConfigBitmask, TonemapperDOF));
|
|
OutEnvironment.SetDefine(TEXT("USE_MSAA"), TonemapperIsDefined(ConfigBitmask, TonemapperMsaa));
|
|
|
|
//Need to hack in exposure scale for < SM5
|
|
OutEnvironment.SetDefine(TEXT("NO_EYEADAPTATION_EXPOSURE_FIX"), 1);
|
|
}
|
|
|
|
/** Default constructor. */
|
|
FPostProcessTonemapPS_ES2() {}
|
|
|
|
public:
|
|
FPostProcessPassParameters PostprocessParameter;
|
|
FShaderParameter ColorScale0;
|
|
FShaderParameter ColorScale1;
|
|
FShaderParameter TexScale;
|
|
FShaderParameter GrainScaleBiasJitter;
|
|
FShaderParameter InverseGamma;
|
|
FShaderParameter TonemapperParams;
|
|
|
|
FShaderParameter ColorMatrixR_ColorCurveCd1;
|
|
FShaderParameter ColorMatrixG_ColorCurveCd3Cm3;
|
|
FShaderParameter ColorMatrixB_ColorCurveCm2;
|
|
FShaderParameter ColorCurve_Cm0Cd0_Cd2_Ch0Cm1_Ch3;
|
|
FShaderParameter ColorCurve_Ch1_Ch2;
|
|
FShaderParameter ColorShadow_Luma;
|
|
FShaderParameter ColorShadow_Tint1;
|
|
FShaderParameter ColorShadow_Tint2;
|
|
|
|
FShaderParameter OverlayColor;
|
|
FShaderParameter FringeIntensity;
|
|
|
|
/** Initialization constructor. */
|
|
FPostProcessTonemapPS_ES2(const ShaderMetaType::CompiledShaderInitializerType& Initializer)
|
|
: FGlobalShader(Initializer)
|
|
{
|
|
PostprocessParameter.Bind(Initializer.ParameterMap);
|
|
ColorScale0.Bind(Initializer.ParameterMap, TEXT("ColorScale0"));
|
|
ColorScale1.Bind(Initializer.ParameterMap, TEXT("ColorScale1"));
|
|
TexScale.Bind(Initializer.ParameterMap, TEXT("TexScale"));
|
|
TonemapperParams.Bind(Initializer.ParameterMap, TEXT("TonemapperParams"));
|
|
GrainScaleBiasJitter.Bind(Initializer.ParameterMap, TEXT("GrainScaleBiasJitter"));
|
|
InverseGamma.Bind(Initializer.ParameterMap,TEXT("InverseGamma"));
|
|
|
|
ColorMatrixR_ColorCurveCd1.Bind(Initializer.ParameterMap, TEXT("ColorMatrixR_ColorCurveCd1"));
|
|
ColorMatrixG_ColorCurveCd3Cm3.Bind(Initializer.ParameterMap, TEXT("ColorMatrixG_ColorCurveCd3Cm3"));
|
|
ColorMatrixB_ColorCurveCm2.Bind(Initializer.ParameterMap, TEXT("ColorMatrixB_ColorCurveCm2"));
|
|
ColorCurve_Cm0Cd0_Cd2_Ch0Cm1_Ch3.Bind(Initializer.ParameterMap, TEXT("ColorCurve_Cm0Cd0_Cd2_Ch0Cm1_Ch3"));
|
|
ColorCurve_Ch1_Ch2.Bind(Initializer.ParameterMap, TEXT("ColorCurve_Ch1_Ch2"));
|
|
ColorShadow_Luma.Bind(Initializer.ParameterMap, TEXT("ColorShadow_Luma"));
|
|
ColorShadow_Tint1.Bind(Initializer.ParameterMap, TEXT("ColorShadow_Tint1"));
|
|
ColorShadow_Tint2.Bind(Initializer.ParameterMap, TEXT("ColorShadow_Tint2"));
|
|
|
|
OverlayColor.Bind(Initializer.ParameterMap, TEXT("OverlayColor"));
|
|
FringeIntensity.Bind(Initializer.ParameterMap, TEXT("FringeIntensity"));
|
|
}
|
|
|
|
// FShader interface.
|
|
virtual bool Serialize(FArchive& Ar) override
|
|
{
|
|
bool bShaderHasOutdatedParameters = FGlobalShader::Serialize(Ar);
|
|
Ar << PostprocessParameter << ColorScale0 << ColorScale1 << InverseGamma
|
|
<< TexScale << GrainScaleBiasJitter << TonemapperParams
|
|
<< ColorMatrixR_ColorCurveCd1 << ColorMatrixG_ColorCurveCd3Cm3 << ColorMatrixB_ColorCurveCm2 << ColorCurve_Cm0Cd0_Cd2_Ch0Cm1_Ch3 << ColorCurve_Ch1_Ch2 << ColorShadow_Luma << ColorShadow_Tint1 << ColorShadow_Tint2
|
|
<< OverlayColor
|
|
<< FringeIntensity;
|
|
|
|
return bShaderHasOutdatedParameters;
|
|
}
|
|
|
|
void SetPS(const FRenderingCompositePassContext& Context)
|
|
{
|
|
const FPostProcessSettings& Settings = Context.View.FinalPostProcessSettings;
|
|
const FSceneViewFamily& ViewFamily = *(Context.View.Family);
|
|
|
|
const FPixelShaderRHIParamRef ShaderRHI = GetPixelShader();
|
|
|
|
FGlobalShader::SetParameters(Context.RHICmdList, ShaderRHI, Context.View);
|
|
|
|
const uint32 ConfigBitmask = TonemapperConfBitmaskMobile[ConfigIndex];
|
|
|
|
if (TonemapperIsDefined(ConfigBitmask, Tonemapper32BPPHDR) && IsMobileHDRMosaic())
|
|
{
|
|
PostprocessParameter.SetPS(ShaderRHI, Context, TStaticSamplerState<SF_Point, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI());
|
|
}
|
|
else
|
|
{
|
|
PostprocessParameter.SetPS(ShaderRHI, Context, TStaticSamplerState<SF_Bilinear, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI());
|
|
}
|
|
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, OverlayColor, Context.View.OverlayColor);
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, FringeIntensity, fabsf(Settings.SceneFringeIntensity) * 0.01f); // Interpreted as [0-1] percentage
|
|
|
|
{
|
|
FLinearColor Col = Settings.SceneColorTint;
|
|
FVector4 ColorScale(Col.R, Col.G, Col.B, 0);
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorScale0, ColorScale);
|
|
}
|
|
|
|
{
|
|
FLinearColor Col = FLinearColor::White * Settings.BloomIntensity;
|
|
FVector4 ColorScale(Col.R, Col.G, Col.B, 0);
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorScale1, ColorScale);
|
|
}
|
|
|
|
{
|
|
const FPooledRenderTargetDesc* InputDesc = Context.Pass->GetInputDesc(ePId_Input0);
|
|
|
|
// we assume the this pass runs in 1:1 pixel
|
|
FVector2D TexScaleValue = FVector2D(InputDesc->Extent) / FVector2D(Context.View.ViewRect.Size());
|
|
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, TexScale, TexScaleValue);
|
|
}
|
|
|
|
{
|
|
float Sharpen = FMath::Clamp(CVarTonemapperSharpen.GetValueOnRenderThread(), 0.0f, 10.0f);
|
|
|
|
FVector2D Value(Settings.VignetteIntensity, Sharpen);
|
|
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, TonemapperParams, Value);
|
|
}
|
|
|
|
FVector GrainValue;
|
|
GrainPostSettings(&GrainValue, &Settings);
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, GrainScaleBiasJitter, GrainValue);
|
|
|
|
{
|
|
FVector InvDisplayGammaValue;
|
|
InvDisplayGammaValue.X = 1.0f / ViewFamily.RenderTarget->GetDisplayGamma();
|
|
InvDisplayGammaValue.Y = 2.2f / ViewFamily.RenderTarget->GetDisplayGamma();
|
|
InvDisplayGammaValue.Z = 1.0; // Unused on mobile.
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, InverseGamma, InvDisplayGammaValue);
|
|
}
|
|
|
|
{
|
|
FVector4 Constants[8];
|
|
FilmPostSetConstants(Constants, TonemapperConfBitmaskMobile[ConfigIndex], &Context.View.FinalPostProcessSettings, true);
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorMatrixR_ColorCurveCd1, Constants[0]);
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorMatrixG_ColorCurveCd3Cm3, Constants[1]);
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorMatrixB_ColorCurveCm2, Constants[2]);
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorCurve_Cm0Cd0_Cd2_Ch0Cm1_Ch3, Constants[3]);
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorCurve_Ch1_Ch2, Constants[4]);
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorShadow_Luma, Constants[5]);
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorShadow_Tint1, Constants[6]);
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, ColorShadow_Tint2, Constants[7]);
|
|
}
|
|
}
|
|
|
|
static const TCHAR* GetSourceFilename()
|
|
{
|
|
return TEXT("PostProcessTonemap");
|
|
}
|
|
|
|
static const TCHAR* GetFunctionName()
|
|
{
|
|
return TEXT("MainPS_ES2");
|
|
}
|
|
};
|
|
|
|
// #define avoids a lot of code duplication
|
|
#define VARIATION2(A) typedef FPostProcessTonemapPS_ES2<A> FPostProcessTonemapPS_ES2##A; \
|
|
IMPLEMENT_SHADER_TYPE2(FPostProcessTonemapPS_ES2##A, SF_Pixel);
|
|
|
|
VARIATION2(0) VARIATION2(1) VARIATION2(2) VARIATION2(3) VARIATION2(4) VARIATION2(5) VARIATION2(6) VARIATION2(7) VARIATION2(8) VARIATION2(9)
|
|
VARIATION2(10) VARIATION2(11) VARIATION2(12) VARIATION2(13) VARIATION2(14) VARIATION2(15) VARIATION2(16) VARIATION2(17) VARIATION2(18) VARIATION2(19)
|
|
VARIATION2(20) VARIATION2(21) VARIATION2(22) VARIATION2(23) VARIATION2(24) VARIATION2(25) VARIATION2(26) VARIATION2(27) VARIATION2(28) VARIATION2(29)
|
|
VARIATION2(30) VARIATION2(31) VARIATION2(32) VARIATION2(33) VARIATION2(34) VARIATION2(35) VARIATION2(36) VARIATION2(37) VARIATION2(38)
|
|
|
|
|
|
#undef VARIATION2
|
|
|
|
|
|
class FPostProcessTonemapVS_ES2 : public FGlobalShader
|
|
{
|
|
DECLARE_SHADER_TYPE(FPostProcessTonemapVS_ES2,Global);
|
|
|
|
static bool ShouldCache(EShaderPlatform Platform)
|
|
{
|
|
return !IsConsolePlatform(Platform);
|
|
}
|
|
|
|
FPostProcessTonemapVS_ES2() { }
|
|
|
|
public:
|
|
FPostProcessPassParameters PostprocessParameter;
|
|
FShaderResourceParameter EyeAdaptation;
|
|
FShaderParameter GrainRandomFull;
|
|
FShaderParameter FringeIntensity;
|
|
bool bUsedFramebufferFetch;
|
|
|
|
FPostProcessTonemapVS_ES2(const ShaderMetaType::CompiledShaderInitializerType& Initializer)
|
|
: FGlobalShader(Initializer)
|
|
{
|
|
PostprocessParameter.Bind(Initializer.ParameterMap);
|
|
GrainRandomFull.Bind(Initializer.ParameterMap, TEXT("GrainRandomFull"));
|
|
FringeIntensity.Bind(Initializer.ParameterMap, TEXT("FringeIntensity"));
|
|
}
|
|
|
|
void SetVS(const FRenderingCompositePassContext& Context)
|
|
{
|
|
const FVertexShaderRHIParamRef ShaderRHI = GetVertexShader();
|
|
FGlobalShader::SetParameters(Context.RHICmdList, ShaderRHI, Context.View);
|
|
|
|
PostprocessParameter.SetVS(ShaderRHI, Context, TStaticSamplerState<SF_Bilinear,AM_Clamp,AM_Clamp,AM_Clamp>::GetRHI());
|
|
|
|
FVector GrainRandomFullValue;
|
|
{
|
|
uint8 FrameIndexMod8 = 0;
|
|
if (Context.View.State)
|
|
{
|
|
FrameIndexMod8 = Context.View.State->GetFrameIndexMod8();
|
|
}
|
|
GrainRandomFromFrame(&GrainRandomFullValue, FrameIndexMod8);
|
|
}
|
|
|
|
// TODO: Don't use full on mobile with framebuffer fetch.
|
|
GrainRandomFullValue.Z = bUsedFramebufferFetch ? 0.0f : 1.0f;
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, GrainRandomFull, GrainRandomFullValue);
|
|
|
|
const FPostProcessSettings& Settings = Context.View.FinalPostProcessSettings;
|
|
SetShaderValue(Context.RHICmdList, ShaderRHI, FringeIntensity, fabsf(Settings.SceneFringeIntensity) * 0.01f); // Interpreted as [0-1] percentage
|
|
}
|
|
|
|
virtual bool Serialize(FArchive& Ar) override
|
|
{
|
|
bool bShaderHasOutdatedParameters = FGlobalShader::Serialize(Ar);
|
|
Ar << PostprocessParameter << GrainRandomFull << FringeIntensity;
|
|
return bShaderHasOutdatedParameters;
|
|
}
|
|
};
|
|
|
|
IMPLEMENT_SHADER_TYPE(,FPostProcessTonemapVS_ES2,TEXT("PostProcessTonemap"),TEXT("MainVS_ES2"),SF_Vertex);
|
|
|
|
namespace PostProcessTonemap_ES2Util
|
|
{
|
|
// Template implementation supports unique static BoundShaderState for each permutation of Pixel Shaders
|
|
template <uint32 ConfigIndex>
|
|
static inline void SetShaderTemplES2(const FRenderingCompositePassContext& Context, bool bUsedFramebufferFetch)
|
|
{
|
|
TShaderMapRef<FPostProcessTonemapVS_ES2> VertexShader(Context.GetShaderMap());
|
|
TShaderMapRef<FPostProcessTonemapPS_ES2<ConfigIndex> > PixelShader(Context.GetShaderMap());
|
|
|
|
VertexShader->bUsedFramebufferFetch = bUsedFramebufferFetch;
|
|
|
|
static FGlobalBoundShaderState BoundShaderState;
|
|
|
|
|
|
SetGlobalBoundShaderState(Context.RHICmdList, Context.GetFeatureLevel(), BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);
|
|
|
|
VertexShader->SetVS(Context);
|
|
PixelShader->SetPS(Context);
|
|
}
|
|
}
|
|
|
|
|
|
FRCPassPostProcessTonemapES2::FRCPassPostProcessTonemapES2(const FViewInfo& View, FIntRect InViewRect, FIntPoint InDestSize, bool bInUsedFramebufferFetch)
|
|
:
|
|
ViewRect(InViewRect),
|
|
DestSize(InDestSize),
|
|
bUsedFramebufferFetch(bInUsedFramebufferFetch)
|
|
{
|
|
uint32 ConfigBitmask = TonemapperGenerateBitmaskMobile(&View, false);
|
|
ConfigIndexMobile = TonemapperFindLeastExpensive(TonemapperConfBitmaskMobile, sizeof(TonemapperConfBitmaskMobile)/4, TonemapperCostTab, ConfigBitmask);
|
|
}
|
|
|
|
void FRCPassPostProcessTonemapES2::Process(FRenderingCompositePassContext& Context)
|
|
{
|
|
SCOPED_DRAW_EVENTF(Context.RHICmdList, PostProcessTonemap, TEXT("Tonemapper#%d%s"), ConfigIndexMobile, bUsedFramebufferFetch ? TEXT(" FramebufferFetch=0") : TEXT("FramebufferFetch=1"));
|
|
|
|
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);
|
|
const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context);
|
|
const FPooledRenderTargetDesc& OutputDesc = PassOutputs[0].RenderTargetDesc;
|
|
|
|
FIntRect SrcRect = ViewRect;
|
|
// no upscale if separate ren target is used.
|
|
FIntRect DestRect = (ViewFamily.bUseSeparateRenderTarget) ? ViewRect : View.UnscaledViewRect; // Simple upscaling, ES2 post process does not currently have a specific upscaling pass.
|
|
FIntPoint SrcSize = InputDesc->Extent;
|
|
FIntPoint DstSize = OutputDesc.Extent;
|
|
|
|
// Set the view family's render target/viewport.
|
|
//@todo Ronin find a way to use the same codepath for all platforms.
|
|
const EShaderPlatform ShaderPlatform = GShaderPlatformForFeatureLevel[Context.GetFeatureLevel()];
|
|
if (IsVulkanMobilePlatform(ShaderPlatform))
|
|
{
|
|
//@HACK: gets around an uneccessary load in Vulkan. NOT FOR MAIN as it'll probably kill GearVR
|
|
//@HACK: needs to set the framebuffer to clear/ignore in vulkan (doesn't support RHIClear)
|
|
FRHIRenderTargetView ColorView(DestRenderTarget.TargetableTexture, 0, -1, ERenderTargetLoadAction::EClear, ERenderTargetStoreAction::EStore);
|
|
FRHISetRenderTargetsInfo Info(1, &ColorView, FRHIDepthRenderTargetView());
|
|
Context.RHICmdList.SetRenderTargetsAndClear(Info);
|
|
}
|
|
else
|
|
{
|
|
SetRenderTarget(Context.RHICmdList, DestRenderTarget.TargetableTexture, FTextureRHIParamRef());
|
|
|
|
// Full clear to avoid restore
|
|
if (View.StereoPass == eSSP_FULL || View.StereoPass == eSSP_LEFT_EYE)
|
|
{
|
|
Context.RHICmdList.ClearColorTexture(DestRenderTarget.TargetableTexture, FLinearColor::Black, FIntRect());
|
|
}
|
|
}
|
|
|
|
Context.SetViewportAndCallRHI(DestRect);
|
|
|
|
// set the state
|
|
Context.RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI());
|
|
Context.RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI());
|
|
Context.RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI());
|
|
|
|
switch(ConfigIndexMobile)
|
|
{
|
|
using namespace PostProcessTonemap_ES2Util;
|
|
case 0: SetShaderTemplES2<0>(Context, bUsedFramebufferFetch); break;
|
|
case 1: SetShaderTemplES2<1>(Context, bUsedFramebufferFetch); break;
|
|
case 2: SetShaderTemplES2<2>(Context, bUsedFramebufferFetch); break;
|
|
case 3: SetShaderTemplES2<3>(Context, bUsedFramebufferFetch); break;
|
|
case 4: SetShaderTemplES2<4>(Context, bUsedFramebufferFetch); break;
|
|
case 5: SetShaderTemplES2<5>(Context, bUsedFramebufferFetch); break;
|
|
case 6: SetShaderTemplES2<6>(Context, bUsedFramebufferFetch); break;
|
|
case 7: SetShaderTemplES2<7>(Context, bUsedFramebufferFetch); break;
|
|
case 8: SetShaderTemplES2<8>(Context, bUsedFramebufferFetch); break;
|
|
case 9: SetShaderTemplES2<9>(Context, bUsedFramebufferFetch); break;
|
|
case 10: SetShaderTemplES2<10>(Context, bUsedFramebufferFetch); break;
|
|
case 11: SetShaderTemplES2<11>(Context, bUsedFramebufferFetch); break;
|
|
case 12: SetShaderTemplES2<12>(Context, bUsedFramebufferFetch); break;
|
|
case 13: SetShaderTemplES2<13>(Context, bUsedFramebufferFetch); break;
|
|
case 14: SetShaderTemplES2<14>(Context, bUsedFramebufferFetch); break;
|
|
case 15: SetShaderTemplES2<15>(Context, bUsedFramebufferFetch); break;
|
|
case 16: SetShaderTemplES2<16>(Context, bUsedFramebufferFetch); break;
|
|
case 17: SetShaderTemplES2<17>(Context, bUsedFramebufferFetch); break;
|
|
case 18: SetShaderTemplES2<18>(Context, bUsedFramebufferFetch); break;
|
|
case 19: SetShaderTemplES2<19>(Context, bUsedFramebufferFetch); break;
|
|
case 20: SetShaderTemplES2<20>(Context, bUsedFramebufferFetch); break;
|
|
case 21: SetShaderTemplES2<21>(Context, bUsedFramebufferFetch); break;
|
|
case 22: SetShaderTemplES2<22>(Context, bUsedFramebufferFetch); break;
|
|
case 23: SetShaderTemplES2<23>(Context, bUsedFramebufferFetch); break;
|
|
case 24: SetShaderTemplES2<24>(Context, bUsedFramebufferFetch); break;
|
|
case 25: SetShaderTemplES2<25>(Context, bUsedFramebufferFetch); break;
|
|
case 26: SetShaderTemplES2<26>(Context, bUsedFramebufferFetch); break;
|
|
case 27: SetShaderTemplES2<27>(Context, bUsedFramebufferFetch); break;
|
|
case 28: SetShaderTemplES2<28>(Context, bUsedFramebufferFetch); break;
|
|
case 29: SetShaderTemplES2<29>(Context, bUsedFramebufferFetch); break;
|
|
case 30: SetShaderTemplES2<30>(Context, bUsedFramebufferFetch); break;
|
|
case 31: SetShaderTemplES2<31>(Context, bUsedFramebufferFetch); break;
|
|
case 32: SetShaderTemplES2<32>(Context, bUsedFramebufferFetch); break;
|
|
case 33: SetShaderTemplES2<33>(Context, bUsedFramebufferFetch); break;
|
|
case 34: SetShaderTemplES2<34>(Context, bUsedFramebufferFetch); break;
|
|
case 35: SetShaderTemplES2<35>(Context, bUsedFramebufferFetch); break;
|
|
case 36: SetShaderTemplES2<36>(Context, bUsedFramebufferFetch); break;
|
|
case 37: SetShaderTemplES2<37>(Context, bUsedFramebufferFetch); break;
|
|
case 38: SetShaderTemplES2<38>(Context, bUsedFramebufferFetch); break;
|
|
default:
|
|
check(0);
|
|
}
|
|
|
|
// Draw a quad mapping scene color to the view's render target
|
|
TShaderMapRef<FPostProcessTonemapVS_ES2> VertexShader(Context.GetShaderMap());
|
|
|
|
DrawRectangle(
|
|
Context.RHICmdList,
|
|
0, 0,
|
|
DstSize.X, DstSize.Y,
|
|
SrcRect.Min.X, SrcRect.Min.Y,
|
|
SrcRect.Width(), SrcRect.Height(),
|
|
DstSize,
|
|
SrcSize,
|
|
*VertexShader,
|
|
EDRF_UseTriangleOptimization);
|
|
|
|
Context.RHICmdList.CopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams());
|
|
|
|
// Double buffer tonemapper output for temporal AA.
|
|
if(Context.View.AntiAliasingMethod == AAM_TemporalAA)
|
|
{
|
|
FSceneViewState* ViewState = (FSceneViewState*)Context.View.State;
|
|
if(ViewState)
|
|
{
|
|
ViewState->MobileAaColor0 = PassOutputs[0].PooledRenderTarget;
|
|
}
|
|
}
|
|
}
|
|
|
|
FPooledRenderTargetDesc FRCPassPostProcessTonemapES2::ComputeOutputDesc(EPassOutputId InPassOutputId) const
|
|
{
|
|
FPooledRenderTargetDesc Ret = GetInput(ePId_Input0)->GetOutput()->RenderTargetDesc;
|
|
|
|
Ret.Reset();
|
|
Ret.Format = PF_B8G8R8A8;
|
|
Ret.DebugName = TEXT("Tonemap");
|
|
Ret.Extent = DestSize;
|
|
Ret.ClearValue = FClearValueBinding(FLinearColor(0, 0, 0, 0));
|
|
|
|
return Ret;
|
|
}
|