Shader Forge Academy

Master the art of real-time shader development. Advanced Shader Graph courses taught by a professional Gameplay Engineer — from procedural t...
2 joined
Profile picture
@karenaoldingProfile pictureMay 31
Pinned post

Welcome to Shader Forge Academy — Start Here

Welcome, Shader Engineer 🔥


You've just joined the most focused community on the internet for production-grade shader development. Here's how to get the most out of your membership.


📚 Course Structure

The Advanced Shader Graph Masterclass is organized into 6 modules, 15 lessons, progressing from foundational GPU pipeline knowledge through to shipping optimized shaders in production. Lessons unlock sequentially — each one builds directly on the last.


Module 1 — Shader Foundations & Environment Setup

Module 2 — Procedural Texturing (Noise, UVs, Material Systems)

Module 3 — Custom Lighting Models (PBR, BRDF, SSS)

Module 4 — Post-Processing & Screen-Space Effects

Module 5 — VFX & Particle Shaders

Module 6 — Optimization & Shipping to Production


🛠 How to Use This Space

  • Course — Work through lessons at your own pace. Complete all 15 to earn your certificate.

  • Community Chat — Ask questions, share your shader breakdowns, get feedback from me and other members.

  • Updates & Resources — Supplementary resources, node graph templates, and announcements.


⚡ First Steps

  1. Open Module 1, Lesson 1 and read the full roadmap

  2. Introduce yourself in the Community Chat — tell us what engine you're working in

  3. Bookmark this post for reference


Let's build some shaders.


— Your Instructor

Profile picture
@karenaoldingProfile pictureMay 31

5 Shader Graph Mistakes That Tank Your Frame Rate (And How to Fix Them)

I've shipped shaders on 4 production titles. These are the performance killers I see constantly — even from experienced devs.


1. Sampling Textures Inside Branches


// ❌ GPU still samples BOTH textures
if (mask > 0.5)
    color = tex2D(_DetailTex, uv);
else
    color = tex2D(_BaseTex, uv);


GPUs execute both branches in a warp/wavefront. Use lerp with the mask instead:


// ✅ Both sample, but no branch divergence
color = lerp(tex2D(_BaseTex, uv), tex2D(_DetailTex, uv), step(0.5, mask));


2. Regenerating Noise Every Frame


If your noise doesn't animate, bake it to a texture. A single Perlin noise node costs ~0.3ms on mobile. A 256×256 LUT costs almost nothing to sample.


Rule: If the input doesn't change per-frame, it shouldn't be calculated per-frame.


3. Fullscreen Effects Without Resolution Scaling


Your custom post-process runs at native res by default. On a 4K display, that's 8.3 million fragment invocations. Add a _DownsampleFactor property and render to a half-res RT for effects like blur, fog, or AO where pixel-perfect accuracy isn't needed.


4. Using normalize() Everywhere


normalize() involves a square root. If your vector is already unit-length (like a pre-baked normal from a texture), normalizing it again is pure waste. Audit every normalize call — remove the ones operating on data you know is already normalized.


5. Ignoring Shader Variants


Unity compiles a variant for every keyword combination. 10 toggles = 1,024 variants. Use #pragma shader_feature (strips unused variants from builds) instead of #pragma multi_compile (includes all). Check your variant count in the shader inspector — if it's over 100, you have a problem.


---


These five fixes alone have saved me 2-4ms per frame on real projects. If you want the full deep dive — profiling workflows, GPU timers, LOD strategies, and the complete production pipeline — that's exactly what I teach in the Advanced Shader Graph Masterclass.