Circuit & ShaderNova
Hey ShaderNova, I’ve been trying to squeeze a realistic refraction effect into a 2 ms frame budget on mobile GPUs, but the traditional dielectric approximation just kills performance. Think you can help me craft a more efficient shader that still looks like true glass?
Don’t over‑engineer it, just cut the noise. Keep a single texel offset, clamp the refracted UV to the viewport, and drop the Schlick mix for a fixed IOR. Sample once, then lerp the result with a tiny blur if you need softness. Here’s a bare‑bones sketch – no fences, just the idea:
```glsl
vec3 viewDir = normalize(vWorldPos - cameraPos);
vec3 refractDir = refract(viewDir, vNormal, 1.0/IOR);
vec2 offset = refractDir.xy * maxUV; // maxUV is viewport size in texels
vec2 uv = vUV + offset / texSize; // one‑pass lookup
vec4 refraction = texture(refractionTex, uv);
fragColor = mix(color, refraction, roughness);
```
Just that. If you still hit 2 ms, drop the `roughness` modulation, or replace the texture lookup with a low‑res blurred buffer. Performance is a poem of minimalism – every sample counts.
Sounds solid, but be careful with the UV clamp—if the offset pushes past the edge, you’ll see hard edges or black bleed. You could wrap or use `clamp(uv, 0.0, 1.0)` after the addition. Also, the `mix` with roughness will add another branch; if you’re fighting 2 ms, hard‑code the blend factor or use a lookup table. Keep it tight.
Right, clamp the UV back to [0,1] so you don’t end up with a black hole at the edges. And yeah, ditch that `mix` branch – hard‑code the blend, or pull the value from a tiny 1×1 texel that stores the constant. The fewer branches, the fewer pipeline stalls. Trust me, a 2 ms window is a razor, not a playground.
Got it, clamp and hard‑code that blend. Let’s push it to 2 ms and see if the GPU still loves it. Good luck.
Good luck, and watch that frame budget. Don’t forget to profile after each tweak – the only way to win 2 ms is to keep the shader as light as a single ray of light. Happy hacking.