Custom Post-Processing Shaders: Full Cycle from Development to Optimization

Our video game development company runs independent projects, jointly creates games with the client and provides additional operational services. Expertise of our team allows us to cover all gaming platforms and develop an amazing product that matches the customer’s vision and players preferences.

From immersive apps to game worlds and 3D scenes

Our dedicated team for VR/AR/MR development, Unity production and 3D modeling & animation — with its own case studies and capability decks.

Visit the dedicated studio
Showing 1 of 1All 242 services
Custom Post-Processing Shaders: Full Cycle from Development to Optimization
Complex
~5 days
Frequently Asked Questions

Our competencies

What are the stages of Game Development?

Latest works

  • image_games_mortal_motors_495_0.webp
    Game development for Mortal Motors
    1386
  • image_games_a_turnbased_strategy_game_set_in_a_fantasy_setting_with_fire_and_sword_603_0.webp
    A turn-based strategy game set in a fantasy setting, With Fire and Sword
    926
  • image_games_second_team_604_0.webp
    Game development for the company Second term
    544
  • image_games_phoenix_ii_606_0.webp
    3D animation - teaser for the game Phoenix 2.
    591

Custom Post-Processing Shaders: Full Cycle

One common challenge in game development is creating a visual style that standard Volume Framework effects cannot cover. For example, a custom bloom with controllable threshold or stylized vignetting. On one mobile project, we reduced rendering costs by 25% by optimizing a shader from 4ms to 1.1ms — saving about 30% of the budget compared to an off-the-shelf solution. We guarantee every shader is profiled on target devices and does not break existing effects like TAA. Contact us for a consultation — we will find the optimal approach.

When Standard Effects Are Not Enough?

Unity URP/HDRP and Unreal Engine provide Volume Framework for post-processing, but each has areas where standard effects do not cover the needs of a specific visual style. In URP the most common pain point is the lack of native support for custom passes in Renderer Feature without deep understanding of ScriptableRenderPass and execution order in RenderPassEvent. Developers often insert a custom Blit in AfterRenderingPostProcessing and get an effect that is layered on top of the URP stack instead of being integrated inside it — resulting in TAA and FXAA either not working with the custom material or doubling artifacts. In HDRP the situation is different: Custom Pass works through CustomPassVolume, and if the shader uses _CameraDepthTexture without explicit declaration in TEXTURE2D + SAMPLER under HDRP macros, it simply renders a black screen on some platforms — no console warnings. Unreal-specific: post-processing via Material with Post Process domain works fast until you encounter r.PostProcessAAQuality and how TAA interacts with custom SceneTexture nodes. If the shader reads PostProcessInput0 without accounting for jitter offset, moving camera produces ghosting that looks like a renderer bug, but the cause is in the shader.

How to Avoid Ghosting with Custom Effects?

Ghosting arises from not accounting for jitter offset in TAA-compatible shaders. When inserting a custom pass into the pipeline, you must explicitly pass the difference between the previous and current frame. In Unity this uses _ScreenParams and _Jitter for URP; in Unreal, parameters from PostProcessSceneView. During integration we always check whether the shader correctly handles subpixel movement, and add compensation if needed. Profiling with RenderDoc and comparison with a reference frame identifies such artifacts before production delivery.

How to Properly Develop a Post-Processing Shader?

Step-by-step guide:

  1. Analyze reference and define requirements — determine the effect and target platforms.
  2. Prototype in ShaderGraph or Material Editor — quick hypothesis validation in 1–2 days.
  3. Write HLSL/GLSL with platform constraints: for mobile use mediump float, minimal samples; for PC/console use multi-pass Blit and compute shaders.
  4. Integrate into pipeline: ScriptableRenderPass for URP, CustomPassVolume for HDRP, Post Process Material for Unreal. Always set the correct RenderPassEvent and verify TAA compatibility.
  5. Profile: RenderDoc, GPU Profiler, mobile profilers. Optimize until target FPS is achieved.

On one project — a mobile RPG in URP — the client wanted a custom "ink outline" effect over geometry. The first prototype using ScriptableRenderPass with Roberts Cross on depth took 4ms on Adreno 650 at 1080p. After rewriting to a single-pass with a simplified kernel and using _CameraDepthNormalsTexture instead of two separate textures — 1.1ms. The difference is not in the algorithm but in the number of texture fetches. Get a consultation from our engineer — we will analyze your project and propose the optimal solution.

What Is Included in the Work

Each shader comes with a complete package:

  • Shader source code (HLSL/GLSL) with comments
  • Integration script (ScriptableRenderPass / CustomPassVolume / Post Process Material)
  • Setup instructions for Volume Framework parameters
  • Performance recommendations for target platforms
  • Support during implementation (up to 2 consultations)

Work Stages for Shader Development

Stage What is done Approximate timeline
Reference and spec analysis Analyze visual style, determine algorithm 1–2 days
Prototype in ShaderGraph / Material Graph Quick hypothesis validation, approval 1–3 days
HLSL implementation Write shader for target platform 2–7 days
Integration into render pipeline ScriptableRenderPass / CustomPassVolume / PP Material 1–3 days
Profiling and optimization Frame capture, GPU timing, optimize for target 1–4 days
Documentation and handover Code comments, setup instructions 0.5–1 day

Complex effects with multiple passes (e.g., volumetric fog via ray marching in post-process or screen-space subsurface scattering) can take 3–4 weeks including iterations.

Typical Mistakes in DIY Development

Most problems are not in the algorithm but in integration.

  • Incorrect RenderPassEvent. Inserting a custom pass in BeforeRenderingPostProcessing without understanding that URP hasn't applied Color Grading yet — the LUT ends up on top of the custom effect instead of underneath.
  • Ignoring camera stacking. In URP, with Overlay Camera a custom ScriptableRenderPass attached to Base Camera does not execute for Overlay — you must register the pass in both Renderer Assets or use Universal Renderer with correct renderingLayerMask.
  • Hardcoded resolution. float2(1.0/1920.0, 1.0/1080.0) in shader instead of _ScreenParams.zw - 1 — on devices with non-standard resolution or dynamic resolution the effect breaks.
  • HDR loss. If the effect is applied after tonemap but designed for linear HDR buffer — colors will be wrong. Important to explicitly define the point of application in the pipeline.
Shader type comparison by platform
Shader type Mobile (Adreno 650) PC (RTX 3070)
Single-pass Blit <1ms <0.2ms
Multi-pass (3 Blit) 2-3ms <0.5ms
Compute shader 1.5-2ms <0.3ms

Consult with our engineer — we will analyze your project and propose the optimal solution. Order a preliminary assessment — we will calculate timelines and cost based on your requirements.