AI Photo Has No Film Grain: 5 Fixes for a Real Analog Look

Your photo prompt outputs CG-clean, grain-free images. Cause is the model's smooth-render bias. Fix with a named film stock, weighted grain, and grain-safe upscaling or post.

You prompt 35mm film photograph of a coffee shop and the output is suspiciously clean: perfectly smooth gradients, zero grain, flat blocks of pure color in the shadows. It reads as a CG render of a photo, not an actual photo. This is a model-defaults problem. SDXL, Flux (including FLUX.2), and Midjourney all bias toward smooth rendering because their training data leans heavily on cleaned-up stock photos and digital images. Real grain, the random luminance noise from silver-halide crystals or a high-ISO sensor, has to be summoned explicitly.

Fastest fix: name a specific film stock (not just “film”), add weighted grain terms, and lower CFG/guidance a notch. On Midjourney add --style raw. If the render is still clean after that, the grain is being eaten downstream by an upscaler or a low-quality JPEG export, so jump to Steps 4-5.

Which bucket are you in?

SymptomMost likely causeGo to
Prompt says film but no stock nameVague film term averaged to cleanStep 1
Generated image is clean even at 1:1 zoomSmooth-render bias, no grain weightingSteps 1-3
Grain present at preview, gone after upscaleUpscaler smooths grain as “noise”Step 4
Grain present in editor, gone in exported fileLow-quality JPEG quantizes grain awayStep 5
Midjourney auto-beautifies everythingDefault stylize is too strongStep 1 (--style raw)

Common causes

Ordered by hit rate, highest first.

1. Generic “film” or “analog” word without a stock

film photo, analog, vintage photograph are too vague. The model averages across both clean digital scans of old photos and actually-grainy negatives, and the clean average usually wins.

How to spot it: prompt says film but no film-stock name (Kodak Portra, Fuji Pro, etc.) is present.

2. Guidance / CFG too high

High guidance pushes the model hard toward the “ideal clean photo” it thinks you want, sanding off micro-texture. As of June 2026 the grain-friendly ranges are roughly CFG 5-7 for SDXL and guidance 3.0-3.8 for Flux. Run higher and grain disappears first.

How to spot it: SDXL CFG above 8, or Flux guidance above 4. Drop one point and re-render.

3. Render resolution too low

At 768x768 or below, grain detail is lost in the latent compression. The model rounds away the noise pattern because it cannot represent it cleanly at that size.

How to spot it: same prompt at 1024x1024 has visible grain, but 768x768 does not.

4. Post-pipeline upscaler smooths grain

ESRGAN, 4x-UltraSharp, and especially SwinIR_4x aggressively smooth grain when upscaling. They were trained to treat grain as noise to remove. Diffusion-based restorers like SUPIR can hallucinate their own smooth texture over real grain too.

How to spot it: pre-upscale image has grain, post-upscale does not.

5. JPEG export at low quality

Saving as JPEG at quality 75 or below quantizes grain into blocky 8x8 artifacts that the eye reads as “no texture.”

How to spot it: check file size. If a 1024x1024 photo JPEG is under 200KB, quality is too aggressive.

Shortest path to fix

Step 1: Use a specific film stock name

The training data has strong associations for specific stocks. Replace film photo with one of:

Kodak Portra 400 (warm skin, soft grain, classic editorial)
Kodak Tri-X 400 (classic black-and-white, punchy grain)
Fujifilm Pro 400H (cool tones, fine grain, wedding favorite)
Fujifilm Velvia 50 (saturated, very fine grain, landscape)
Cinestill 800T (tungsten balance, dreamy halation, neon nights)
Ilford HP5 (black-and-white, gritty, photojournalism)
Kodak Gold 200 (warm, slight grain, vacation snapshot)

These each carry distinct grain characteristics in the training set. On Midjourney V7/V8.1, also append --style raw. This turns off the automatic beautify pass and is the single biggest lever for keeping texture (V8.1 has been the default model since June 10, 2026; V7 stays selectable). A working pattern: kodak portra 400, 35mm, slight film grain, natural imperfections --style raw.

Step 2: Weight grain explicitly (SDXL / SD-family)

Add to the prompt:

(film grain:0.8), (visible grain:0.7), (analog noise:0.6),
35mm film, slight noise in shadows, organic grain pattern, ISO 800

The weight values 0.6-0.8 are loud enough to be noticed without dominating composition. Above 1.0 the grain becomes a visual artifact rather than a texture.

Note on syntax: the (term:weight) attention weighting is an SDXL / Automatic1111 / ComfyUI feature. Flux ignores weighted parentheses, so for Flux just write the grain terms as plain natural language: 35mm film, heavy organic film grain, ISO 800, visible noise in shadows.

Step 3: Negative-prompt the clean look (SDXL only)

digital, clean, smooth, noise-free, CGI, 3d render, ultra clean,
no grain, perfect smooth gradient, plastic, oversharpened

This actively repels the smooth-render bias. Flux does not use negative prompts the way SDXL does (it is a flow-matching model, not classifier-free guidance), so this step applies to SDXL / SD-family only. For Flux, lower the guidance (Step 2 cause) and load a realism or film-grain LoRA instead.

Step 4: Skip aggressive upscalers

Replace ESRGAN or SwinIR with grain-friendly upscalers:

4x_NMKD-Siax (preserves grain better)
4x_RealisticRescaler (designed for photo realism, keeps texture)
4x_foolhardy_Remacri (mild, preserves micro-detail)

Browse and download these from OpenModelDB. Or upscale via img2img at low denoise (0.2-0.3) with the same prompt. This re-runs the upscale through the diffusion model, which can re-introduce grain rather than averaging it out. In ComfyUI you can also re-add grain after upscaling with the BetterFilmGrain node instead of fighting the upscaler.

Step 5: Add grain in post if still missing

When all else fails, add the grain in post:

Photoshop: Filter > Camera Raw > Effects > Grain. Amount 25, Size 25, Roughness 50
Lightroom: Develop module > Effects panel > Grain. Amount 25, Size 25, Roughness 50
Affinity Photo: Filters > Noise > Add Noise, 2.5% Gaussian, Monochromatic
DaVinci Resolve (for video): Effects > ResolveFX Texture > Film Grain

In Lightroom and Camera Raw, keep Roughness greater than or equal to Size. When Roughness is lower than Size the grain looks blocky and artificial. The free GIMP HSV Noise filter at 5% value-only noise works too. Post-grain is preferable to a fully clean render shipping as a “film photo.”

How to confirm it’s fixed

  • Zoom to 100% (1:1 pixel view) on a mid-tone area like skin or a gray wall. You should see fine random luminance speckle, not a flat smooth surface.
  • Check the shadows: real grain is visible there, not just in highlights. Dead-flat black shadow blocks mean grain was lost.
  • Export your final file, reopen the exported file (not the editor preview), and zoom in again. This catches the Step 5 / JPEG case where grain survives in the app but dies on save.

Prevention

  • Keep a list of 5 favorite film stocks and rotate through them by mood.
  • Default grain weight in your portrait preset: (film grain:0.7) (SDXL) or a film-grain LoRA at 0.4-0.6 (Flux).
  • Never upscale grainy looks with ESRGAN or SwinIR; use NMKD-Siax or Remacri instead.
  • Render at 1024x1024 minimum for any photo prompt; never lower.
  • Save final JPEGs at quality 92+, or use PNG for grainy renders to preserve texture.

FAQ

Why does my AI photo look clean even when I write “film grain” in the prompt? The word film alone gets averaged with millions of clean digital images in training. Anchor it to a named stock (Kodak Portra 400), weight the grain term on SDXL ((film grain:0.8)), and on Midjourney add --style raw. Vague terms almost always lose to the smooth-render bias.

Do negative prompts work for film grain on Flux? No. Flux is a flow-matching model and does not support classifier-free negative prompts the way SDXL does. For Flux, lower the guidance to roughly 3.0-3.8, write grain as plain language, and load a realism or film-grain LoRA. Negative prompts only help on SDXL / SD-family.

Which Midjourney version and parameter gives the most grain? Use --style raw on V7 or V8.1 to disable the automatic beautify pass, then name a film stock and ISO. V8.1 is the default model as of June 10, 2026; V7 is still selectable in settings if you prefer its texture.

My grain disappears after upscaling. Why? Most upscalers (ESRGAN, 4x-UltraSharp, SwinIR_4x) were trained to treat grain as noise and remove it. Switch to a grain-friendly model like 4x_NMKD-Siax or 4x_foolhardy_Remacri, upscale via img2img at denoise 0.2-0.3, or re-add grain after upscaling (ComfyUI BetterFilmGrain or a post step).

What grain weight is too much? On SDXL, weights above 1.0 turn grain from texture into a visible artifact (dotty, distracting). Stay in the 0.6-0.8 range. In Lightroom/Camera Raw, Amount around 25 is a natural film look; 50+ starts to look like deliberate stylization.

Tags: #ai-image #Troubleshooting #texture #postprocess