You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用2D纹理读取GLSL色彩校正所需的8*64规格Hald CLUT图像?

Reading an 8x64 Hald CLUT as a 2D Texture in GLSL

Hey there! Let's walk through how to read an 8x64 Hald CLUT as a 2D texture in GLSL, building on the 8x8 method you already understand.

First, let's clarify the layout of an 8x64 Hald CLUT:

  • An 8-level CLUT (8 samples per R/G/B channel) has a total of 8^3 = 512 color entries, which fits perfectly into an 8x64 texture (8 rows × 64 columns).
  • Each row in the texture corresponds to a single B-channel intensity (from 0 to 7, 8 total rows).
  • Each row's 64 columns cover all combinations of R and G intensities: R ranges from 0-7 within 8-pixel blocks, and each block corresponds to a G intensity (0-7, 8 blocks total).

Step 1: Map Input Color to CLUT Indices

First, take your normalized input color (0-1 range for R/G/B) and map it to the 0-7 index range used by the 8-level CLUT:

vec3 rgb = texture2D(inputTexture, vTextureCoord).rgb;
// Scale 0-1 color to 0-7 index range (since 8 levels = 0 to 7)
float rIndex = rgb.r * 7.0;
float gIndex = rgb.g * 7.0;
float bIndex = rgb.b * 7.0;

Step 2: Calculate 2D Texture UV Coordinates

Convert the 3D R/G/B indices into 2D UV coordinates that match the CLUT's layout:

  • The x-coordinate (U) combines R and G: rIndex + gIndex * 8.0 (each G level takes 8 columns for all R values).
  • The y-coordinate (V) is just the B index, since each row maps to one B level.
  • Add 0.5 to both coordinates to sample the center of each texture pixel (avoids edge sampling artifacts), then normalize to the 0-1 UV range:
// 64 columns wide, 8 rows tall
float u = (rIndex + gIndex * 8.0 + 0.5) / 64.0;
float v = (bIndex + 0.5) / 8.0;
vec2 clutUV = vec2(u, v);

Step 3: Sample the CLUT and Apply Correction

Sample the CLUT texture with the calculated UV. Make sure your texture is set to LINEAR filtering—this lets the GPU handle smooth bilinear interpolation between adjacent CLUT entries, just like a 3D texture would:

vec3 correctedColor = texture2D(clutTexture, clutUV).rgb;
// Preserve the original alpha channel from your input
gl_FragColor = vec4(correctedColor, texture2D(inputTexture, vTextureCoord).a);

Critical Texture Settings

Don't forget to configure your CLUT texture correctly when loading it:

  • Set filtering to GL_LINEAR (enables smooth interpolation between CLUT entries).
  • Set wrap mode to GL_CLAMP_TO_EDGE (prevents unwanted color wrapping at the edges of the CLUT).

How This Compares to the 8x8 CLUT Method

The 8x8 CLUT likely maps R/G/B indices to 2D coordinates in a more compact grid (e.g., x = R * 8 + G, y = B), but the core logic is the same: translating 3D color indices into 2D texture positions. The 8x64 layout simply spreads the R/G combinations into a single row per B value, which is a standard way to unpack 3D LUTs into 2D textures.

内容的提问来源于stack exchange,提问作者Manish Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:24:41