Skip to content

Instantly share code, notes, and snippets.

@TheGag96
Created May 23, 2026 04:13
Show Gist options
  • Select an option

  • Save TheGag96/80ec7b6c2cb89ed35f65a6175bb07830 to your computer and use it in GitHub Desktop.

Select an option

Save TheGag96/80ec7b6c2cb89ed35f65a6175bb07830 to your computer and use it in GitHub Desktop.
Replication of the TexEnv stages the 3DS system UI separator graphic
void shaderSeparatorOfficial() {
C3D_TexBind(0, &gUiAssets.separator);
C3D_ProcTexBind(1, null);
C3D_ProcTexLutBind(GPUProcTexLutId.alphamap, null);
// Reverse-engineered from the combiner settings used for the separator on the Home Menu.
// It expects the primary colors of the left vertices to have R=1.0, G=0.0, on the right, R=0.0, G=1.0.
// Think of the sweep from left to right in G as "x", and thus the R being "1-x".
// Amazingly, this ends up calculating:
//
// f = clamp(2.0*clamp(4.0*(clamp(2.0*x)*clamp(2.0*(1-x)))));
// g = clamp(177/255 * (1.0 - (clamp(2.0*x) * clamp(2.0*(1.0-x)))));
// out.rgb = vec3(mix(constant[5].g, constant[5].r, tex0.a));
// out.a = primary.a * (f * (1.0 - g));
//
// Punch these into Desmos to get an intuitive visual about the alpha:
// f\left(x\right)=c\left(2c\left(4\left(c\left(2x\right)\cdot c\left(2\left(1-x\right)\right)\right)\right)\right)
// g\left(x\right)=c\left(\left(1-\left(c\left(2x\right)\cdot c\left(2\left(1-x\right)\right)\right)\right)\cdot\frac{177}{255}\right)
// c\left(f\left(x\right)\cdot\left(1-g\left(x\right)\right)\right)
// c\left(x\right)=\max\left(\min\left(x,\ 1\right),0\right)
C3D_TexEnv* env = C3D_GetTexEnv(0);
C3D_TexEnvInit(env);
C3D_TexEnvSrc(env, C3DTexEnvMode.both, GPUTevSrc.primary_color);
C3D_TexEnvFunc(env, C3DTexEnvMode.both, GPUCombineFunc.replace);
C3D_TexEnvOpRgb(env, GPUTevOpRGB.src_r);
C3D_TexEnvOpAlpha(env, GPUTevOpA.src_g);
C3D_TexEnvScale(env, C3DTexEnvMode.both, GPUTevScale.x2);
//C3D_TexEnvColor(env, uniform0);f
env = C3D_GetTexEnv(1);
C3D_TexEnvInit(env);
C3D_TexEnvSrc(env, C3DTexEnvMode.both, GPUTevSrc.previous, GPUTevSrc.previous);
C3D_TexEnvFunc(env, C3DTexEnvMode.both, GPUCombineFunc.modulate);
C3D_TexEnvOpRgb(env, GPUTevOpRGB.src_r, GPUTevOpRGB.src_alpha);
C3D_TexEnvOpAlpha(env, GPUTevOpA.src_r, GPUTevOpA.src_alpha);
C3D_TexEnvScale(env, C3DTexEnvMode.alpha, GPUTevScale.x4);
env = C3D_GetTexEnv(2);
C3D_TexEnvInit(env);
C3D_TexEnvSrc(env, C3DTexEnvMode.rgb, GPUTevSrc.previous, GPUTevSrc.constant);
C3D_TexEnvFunc(env, C3DTexEnvMode.rgb, GPUCombineFunc.modulate);
C3D_TexEnvOpRgb(env, GPUTevOpRGB.one_minus_src_color, GPUTevOpRGB.src_alpha);
C3D_TexEnvScale(env, C3DTexEnvMode.alpha, GPUTevScale.x2);
C3D_TexEnvColor(env, C2D_Color32(255, 160, 255, 177));
env = C3D_GetTexEnv(3);
C3D_TexEnvInit(env);
C3D_TexEnvSrc(env, C3DTexEnvMode.alpha, GPUTevSrc.previous, GPUTevSrc.previous);
C3D_TexEnvFunc(env, C3DTexEnvMode.alpha, GPUCombineFunc.modulate);
C3D_TexEnvOpAlpha(env, GPUTevOpA.one_minus_src_r, GPUTevOpA.src_alpha);
env = C3D_GetTexEnv(5);
C3D_TexEnvInit(env);
C3D_TexEnvSrc(env, C3DTexEnvMode.rgb, GPUTevSrc.constant, GPUTevSrc.constant, GPUTevSrc.texture0);
C3D_TexEnvFunc(env, C3DTexEnvMode.rgb, GPUCombineFunc.interpolate);
C3D_TexEnvOpRgb(env, GPUTevOpRGB.src_r, GPUTevOpRGB.src_g, GPUTevOpRGB.src_alpha);
C3D_TexEnvSrc(env, C3DTexEnvMode.alpha, GPUTevSrc.previous, GPUTevSrc.primary_color);
C3D_TexEnvFunc(env, C3DTexEnvMode.alpha, GPUCombineFunc.modulate);
C3D_TexEnvColor(env, C2D_Color32(255, 170, 255, 255));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment