Implement screen-space framebuffer copy for refraction and other effects #48

Closed
opened 2026-03-20 06:17:09 +00:00 by kit · 0 comments
Owner

Problem

Refract materials and other Source shaders sample a _rt_PowerOfTwoFB render target — a copy of the current framebuffer used for screen-space effects like refraction, distortion, and glass. We currently have no framebuffer copy mechanism, so refract materials fall back to a semi-transparent tinted overlay with no actual distortion.

Visible in

shader_test_01 — refract cubes should distort the caution tape and scene behind them, but instead appear as flat colored blocks.

What's needed

  1. Framebuffer copy pass: Before rendering transparent/refract materials, copy the current framebuffer to a separate render target texture.
  2. Screen-space UV sampling: Refract materials need to sample the copied framebuffer at distorted UV coordinates (based on normal map perturbation and $refractamount).
  3. Shader support: Update the refract shader path to sample from the framebuffer copy instead of using a simple alpha blend.

Source engine approach

Source copies the framebuffer to _rt_PowerOfTwoFB once per frame, then refract/distortion shaders sample it with UV offsets derived from the normal map. The copy happens after opaque rendering but before translucent rendering.

Other shaders that use this

  • Refract / PortalRefract — primary consumers
  • Any material using $BASETEXTURE set to _rt_PowerOfTwoFB
  • Potentially custom Lua render targets in GMod
  • #8 — VMT shader types (Refract)
## Problem Refract materials and other Source shaders sample a `_rt_PowerOfTwoFB` render target — a copy of the current framebuffer used for screen-space effects like refraction, distortion, and glass. We currently have no framebuffer copy mechanism, so refract materials fall back to a semi-transparent tinted overlay with no actual distortion. ## Visible in `shader_test_01` — refract cubes should distort the caution tape and scene behind them, but instead appear as flat colored blocks. ## What's needed 1. **Framebuffer copy pass**: Before rendering transparent/refract materials, copy the current framebuffer to a separate render target texture. 2. **Screen-space UV sampling**: Refract materials need to sample the copied framebuffer at distorted UV coordinates (based on normal map perturbation and `$refractamount`). 3. **Shader support**: Update the refract shader path to sample from the framebuffer copy instead of using a simple alpha blend. ## Source engine approach Source copies the framebuffer to `_rt_PowerOfTwoFB` once per frame, then refract/distortion shaders sample it with UV offsets derived from the normal map. The copy happens after opaque rendering but before translucent rendering. ## Other shaders that use this - `Refract` / `PortalRefract` — primary consumers - Any material using `$BASETEXTURE` set to `_rt_PowerOfTwoFB` - Potentially custom Lua render targets in GMod ## Related - #8 — VMT shader types (Refract)
kit closed this issue 2026-03-20 10:31:06 +00:00
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
kit/gmod-web-stream#48
No description provided.