Skip to content

feat: dual Color LUT crossfade and lut-grading example#8749

Merged
mvaligursky merged 2 commits into
mainfrom
mv-dual-color-lut
May 19, 2026
Merged

feat: dual Color LUT crossfade and lut-grading example#8749
mvaligursky merged 2 commits into
mainfrom
mv-dual-color-lut

Conversation

@mvaligursky

Copy link
Copy Markdown
Contributor

Summary

Adds a second optional Color LUT slot on CameraFrame for crossfading between two graded looks, fixes compose LUT sampling to the standard 256×16 Unreal strip only, and ships a Gaussian splatting example to exercise the feature.

Changes

  • Dual LUT: When colorLUT.texture2 is set, the compose pass enables COLOR_LUT2, samples both LUTs with shared 16³ lookup math, and blends results using intensity, intensity2, and blend.
  • Fixed LUT size: Shader uses compile-time 16×16×16 constants; debug validation warns if a texture is not 256×16 (plus existing srgb/mipmap/filter checks).
  • Editor script: CameraFrame script exposes texture2, intensity2, and blend on the Color LUT group.
  • Example: New gaussian-splatting/lut-grading with two LUT dropdowns, blend/intensity controls, and optional animate cycle; example LUT assets and thumbnails included.
  • Utility: examples/scripts/convert-lut-32-to-16.mjs subsamples 1024×32 strips to 256×16 (even indices on R/G/B); lut-blue.png regenerated for 16³.

Public API

CameraFrame.colorLUT (and matching camera-frame.mjs script attributes):

cameraFrame.colorLUT.texture = lutA;      // required for LUT path
cameraFrame.colorLUT.intensity = 1;
cameraFrame.colorLUT.texture2 = lutB;     // optional; enables dual-LUT shader variant
cameraFrame.colorLUT.intensity2 = 1;
cameraFrame.colorLUT.blend = 0;           // 0 = LUT1 only, 1 = LUT2 only

RenderPassCompose (internal but set via CameraFrame): colorLUT2, colorLUT2Intensity, colorLUTBlend. colorLUTParams uniform is now vec3 (was vec4 with width/height/maxColor/intensity).

Test plan

  • Open Gaussian Splatting → LUT grading; verify single-LUT and dual-LUT crossfade (Blend slider).
  • Enable Animate; confirm 3s cycle (1.5s hold + 1.5s blend).
  • HDR example still loads lut-blue.png without size warnings.
  • WebGL2 and WebGPU compose passes.

Support a second LUT texture with per-LUT intensities and a blend factor
for crossfading graded looks. Fix compose LUT sampling to 256x16 Unreal
strips only and add a Gaussian splatting example with animate mode.
@mvaligursky mvaligursky merged commit e740809 into main May 19, 2026
8 checks passed
@mvaligursky mvaligursky deleted the mv-dual-color-lut branch May 19, 2026 10:23
mvaligursky added a commit that referenced this pull request Jun 5, 2026
…escription (#8849)

The CameraFrame script fails to parse in the Editor after the dual-LUT
change (#8749). The texture2 attribute description contained an inline
JSDoc {@link ColorLUT#blend} tag.

When a JSDoc summary contains {@link}, TypeScript represents the comment
as a NodeArray of comment nodes rather than a plain string. The attribute
parser stores this verbatim as the attribute description, and because
those nodes carry circular parent references, serializing the parsed
schema throws 'Converting circular structure to JSON' - surfacing as an
Editor parse error even though the program itself parses without error.

Replace the inline link with plain prose so the description stays a
string and the schema serializes cleanly.

Co-authored-by: Martin Valigursky <mvaligursky@snapchat.com>
mvaligursky added a commit that referenced this pull request Jun 5, 2026
…escription (#8849)

The CameraFrame script fails to parse in the Editor after the dual-LUT
change (#8749). The texture2 attribute description contained an inline
JSDoc {@link ColorLUT#blend} tag.

When a JSDoc summary contains {@link}, TypeScript represents the comment
as a NodeArray of comment nodes rather than a plain string. The attribute
parser stores this verbatim as the attribute description, and because
those nodes carry circular parent references, serializing the parsed
schema throws 'Converting circular structure to JSON' - surfacing as an
Editor parse error even though the program itself parses without error.

Replace the inline link with plain prose so the description stays a
string and the schema serializes cleanly.

Co-authored-by: Martin Valigursky <mvaligursky@snapchat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant