AI-Powered Color Grading Engine for Filmmakers
Turn natural language descriptions into professional 3D LUTs. Type "Blade Runner 2049 teal and orange" and get an industry-standard .cube file ready for DaVinci Resolve, Premiere Pro, or any NLE.
- AI Vibe-to-Grade: Describe a look in plain English โ get precise color grading parameters
- Real Color Science: ASC-CDL math (Slope/Offset/Power), proper gamut conversions, broadcast-safe output
- Camera Log Support: Native IDTs for ARRI LogC3, Sony S-Log3, Canon C-Log3
- Smart Skin Protection: Automatically preserves skin tones even with aggressive grades
- Live Scopes: Real-time histogram and vectorscope monitoring
- Industry Export: Standard 33x33x33
.cubeLUT files - DaVinci Resolve Bridge: Python automation to sync grades directly to your timeline
Be aware of what this tool can't do (yet):
| Limitation | Why |
|---|---|
| AI doesn't see your image | It only reads your text prompt - it's not analyzing the actual footage |
| Single LUT output | No multi-node grading chains; one look per generation |
| No reference matching | Can't match a grade from a reference photo (feature idea for contributors!) |
| Resolve Studio required | The free version of DaVinci Resolve doesn't support external scripting |
| Limited camera profiles | Only ARRI, Sony, Canon Log supported; no RED, Blackmagic, Panasonic yet |
These are all solvable - PRs welcome!
- Node.js 18+
- A Google AI Studio API key (Gemini)
# Clone the repo
git clone https://github.com/TanaTTV/vibe-engine.git
cd vibe-engine
# Install dependencies
npm install
# Create environment file
echo "GEMINI_API_KEY=your_api_key_here" > .env
# Start development server
npm run devOpen http://localhost:3000 in your browser.
- Import an image - Upload a still frame from your footage
- Select your camera - Choose the correct IDT (Input Device Transform) if shooting Log
- Describe your vibe - Type something like "moody noir with cyan shadows" or "warm 70s Kodak film"
- Generate - Click "Generate Look" and watch the AI dial in the grade
- Export - Download the
.cubefile and import it into your NLE
Not sure what to type? Try these:
| Prompt | Result |
|---|---|
Blade Runner 2049 teal and orange |
Cool cyan shadows, warm orange highlights, high contrast |
Warm 70s Kodak film stock |
Lifted blacks, warm highlights, slight desaturation |
Matrix green sci-fi |
Green tint in midtones, crushed blacks, cool highlights |
Wes Anderson pastel hotel |
Soft contrast, muted pastels, balanced exposure |
Moody noir detective film |
Deep shadows, desaturated, cool temperature |
Golden hour magic hour warmth |
Orange/amber push, soft contrast, glowing highlights |
Cyberpunk neon city night |
High contrast, saturated, teal/magenta split |
Faded vintage Instagram |
Lifted blacks, low saturation, slight color cast |
The AI understands film references, color terms, moods, and even specific movies/shows.
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ
โ Camera โ -> โ IDT โ -> โ ASC-CDL โ -> โ Output โ
โ Log/Rec709 โ โ Transform โ โ Grading โ โ .cube LUT โ
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ
-
Input Device Transform (IDT): Converts camera-native formats to a working color space
- ARRI LogC3 / AWG โ Rec.709
- Sony S-Log3 / S-Gamut3.Cine โ Rec.709
- Canon C-Log3 / Cinema Gamut โ Rec.709
-
ASC-CDL Grading: Industry-standard color correction
- Lift (Offset): Adjusts shadow density
- Gamma (Power): Controls midtone response
- Gain (Slope): Scales highlight brightness
-
Creative Controls: Temperature, tint, saturation, contrast
-
Signal Safety: Soft-knee rolloff prevents illegal broadcast levels
The AI (Google Gemini) acts as a virtual colorist. It receives:
- Your text prompt ("Blade Runner neon noir")
- A detailed system prompt explaining color theory and ASC-CDL math
It returns structured JSON with precise values:
{
"lift": { "r": -0.02, "g": -0.01, "b": 0.03 },
"gamma": { "r": 0.95, "g": 1.0, "b": 1.1 },
"gain": { "r": 1.1, "g": 0.95, "b": 0.85 },
"saturation": 0.9,
"temperature": -0.2,
"contrast": 1.15,
"skinProtect": 0.7,
"aiThought": "Creating a cool, high-contrast look with teal shadows..."
}The engine detects skin tones using a hue-angle mask (targeting ~35-50ยฐ on the vectorscope) and blends them back toward their original state. This prevents the "alien skin" problem common with heavy color grades.
// Skin detection heuristic
const getSkinWeight = (r, g, b) => {
if (r <= g || g <= b) return 0.0; // Skin is always r > g > b
const hueNorm = (g - b) / (r - b);
// Target orange/red hue range
return smoothstep(0.5, 0.9, hueNorm);
};vibe-engine/
โโโ App.tsx # Main application component
โโโ index.tsx # React entry point
โโโ index.html # HTML template + Tailwind config
โโโ types.ts # TypeScript interfaces
โโโ vite.config.ts # Vite build configuration
โ
โโโ components/
โ โโโ Controls.tsx # Left panel with sliders and AI input
โ โโโ ImageViewer.tsx # Canvas preview + Web Worker integration
โ โโโ Scopes.tsx # Histogram and vectorscope displays
โ
โโโ services/
โ โโโ geminiService.ts # AI integration (Gemini API)
โ โโโ lutEngine.ts # LUT generation + pixel processing
โ โโโ colorTransforms.ts # Camera IDTs and matrix math
โ
โโโ automation/ # DaVinci Resolve integration
โ โโโ bridge_server.py # Flask server for live sync
โ โโโ build_grade.py # Standalone grade applier
โ โโโ requirements.txt # Python dependencies
โ
โโโ docs/ # Additional documentation
โโโ USER_GUIDE.md
โโโ RESOLVE_WORKFLOW.md
โโโ EXPORT_CST.md
Create a .env file in the project root:
GEMINI_API_KEY=your_google_ai_studio_keyThe UI uses a custom "Resolve-inspired" dark theme defined in index.html:
colors: {
resolve: {
bg: '#0F0F0F',
panel: '#272727',
input: '#151515',
border: '#3E3E3E',
accent: '#4B88FF',
text: '#CCCCCC'
}
}| Control | Range | Description |
|---|---|---|
| Lift R/G/B | -0.2 to 0.2 | Shadow color offset |
| Gamma R/G/B | 0.5 to 2.0 | Midtone power (inverse = brighter) |
| Gain R/G/B | 0.5 to 2.0 | Highlight multiplier |
| Contrast | 0.5 to 1.5 | Tonal range expansion |
| Saturation | 0.0 to 2.0 | Color intensity |
| Temperature | -1.0 to 1.0 | Cool (blue) โ Warm (orange) |
| Tint | -1.0 to 1.0 | Green โ Magenta |
| Skin Protect | 0.0 to 1.0 | Skin tone preservation strength |
- DaVinci Resolve Studio (free version doesn't support scripting)
- Python 3.6+
- Enable scripting: Resolve โ Preferences โ System โ General โ External Scripting: Local
The bridge applies LUTs to Node 2 by default, following the standard professional workflow:
โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ
โ Node 1 โ -> โ Node 2 โ -> โ Node 3 โ
โ CST โ โ VIBE โจ โ โ Secondaryโ
โ (if Log) โ โ (LUT) โ โ Grades โ
โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ
- Node 1: Color Space Transform (CST) - converts your camera's Log format to Rec.709
- Node 2: Where Vibe Engine applies your LUT โ applied here
- Node 3+: Secondary corrections, power windows, qualifiers, etc.
Note: If Node 2 fails, the bridge falls back to Node 1. Make sure you have at least 2 nodes in your tree before syncing.
cd automation
pip install -r requirements.txt
python bridge_server.pyThis starts a Flask server on localhost:8000. Click "Sync to Resolve" in the web app to instantly apply your grade to the selected clip.
- Click "Export JSON" to download the grade blueprint
- Run
python automation/build_grade.py - Select the JSON file when prompted
- The script installs the LUT and applies it to Node 2 (or Node 1 as fallback)
The American Society of Cinematographers Color Decision List:
output = (input ร slope + offset) ^ power
In Vibe Engine terms:
- Slope = Gain (highlight multiplier)
- Offset = Lift (shadow shift)
- Power = 1/Gamma (midtone curve)
ARRI LogC3:
// LogC3 โ Linear (simplified)
if (val > E * cut + F) {
return (10^((val - D) / C) - B) / A;
} else {
return (val - F) / E;
}Sony S-Log3:
// S-Log3 โ Linear
if (val >= 171.2 / 1023) {
return 10^((val * 1023 - 420) / 261.5) * 0.19 - 0.01;
}AWG to Rec.709:
[ 1.6175, -0.5373, -0.0802]
[-0.0706, 1.3346, -0.2640]
[-0.0211, -0.2270, 1.2481]
- Make sure you created a
.envfile in the project root (not in a subfolder) - The variable must be named
GEMINI_API_KEY(notAPI_KEYorGOOGLE_API_KEY) - Restart the dev server after adding the key
This usually means a color space mismatch:
- If your image is already Rec.709 (exported from Resolve/Premiere), set IDT to Rec.709
- If you're using raw Log footage, select the matching camera profile
- Don't apply a Log IDT to an already-converted image (double transform = bad)
- Is Resolve open? The bridge needs a running instance
- Is it Resolve Studio? Free version doesn't support scripting
- Is scripting enabled? Resolve โ Preferences โ System โ General โ External Scripting: Local
- Is a clip selected? Go to the Color page and click on a clip (red outline)
- Do you have 2+ nodes? The bridge targets Node 2 by default
- The web preview uses sRGB; Resolve uses your project color settings
- For best matching, set your Resolve timeline to Rec.709 Gamma 2.4
- Export a CST-converted frame from Resolve for most accurate preview
- Check your internet connection
- Google AI Studio may have rate limits on free tier
- Try a simpler prompt first to test
Contributions welcome! Some ideas:
- Add more camera profiles (RED, Blackmagic, Panasonic)
- Reference image analysis (match grade to a photo)
- Preset library system
- Multi-node grading chains
- ACES workflow support
npm run dev # Start dev server
npm run build # Production build
npm run preview # Preview production buildMIT License - feel free to use this in personal or commercial projects.
- Color science references from ARRI, Sony, and Canon white papers
- ASC-CDL specification from the American Society of Cinematographers
- UI inspired by DaVinci Resolve's color page
Made with โ and too many hours staring at waveform monitors.