Skip to content

Commit

Permalink
feat(shaders): add colored film grain
Browse files Browse the repository at this point in the history
  • Loading branch information
clshortfuse committed Dec 19, 2024
1 parent 6408b30 commit 2163b4a
Showing 1 changed file with 57 additions and 0 deletions.
57 changes: 57 additions & 0 deletions src/shaders/effects.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ float ComputeFilmGraininess(float density) {
float bof_d_over_c = 0.880f - (0.736f * density) - (0.003f * pow(density, 7.6f));
return pow(10.f, bof_d_over_c);
}

// Bartleson
// https://www.imaging.org/common/uploaded%20files/pdfs/Papers/2003/PICS-0-287/8583.pdf
float3 ComputeFilmGraininess(float3 density) {
density = max(0, density);
float3 bof_d_over_c = 0.880f - (0.736f * density) - (0.003f * pow(density, 7.6f));
return pow(10.f, bof_d_over_c);
}

} // namespace internal

float3 ApplyFilmGrain(float3 color, float2 xy, float seed, float strength, float reference_white = 1.f, bool debug = false) {
Expand Down Expand Up @@ -71,6 +80,54 @@ float3 ApplyFilmGrain(float3 color, float2 xy, float seed, float strength, float

return output_color;
}

float3 ApplyFilmGrainColored(float3 color, float2 xy, float3 seed, float strength, float reference_white = 1.f, bool debug = false) {
const float3 random_numbers = float3(
renodx::random::Generate(xy + seed.r),
renodx::random::Generate(xy + seed.g),
renodx::random::Generate(xy + seed.b)
);

// Film grain is based on film density
// Film works in negative, meaning black has no density
// The greater the film density (lighter), more perceived grain
// Simplified, grain scales with Y

// Scaling is not not linear

float3 ap1_color = renodx::color::ap1::from::BT709(color);
ap1_color = max(0, ap1_color);

// float color_y = renodx::color::y::from::AP1(color);

const float3 adjusted_color = ap1_color * (1.f / reference_white);

// Emulate density from a chosen film stock (Removed)
// float density = computeFilmDensity(adjustedColorY);

// Ideal film density matches 0-3. Skip emulating film stock
// https://www.mr-alvandi.com/technique/measuring-film-speed.html
const float3 density = adjusted_color * 3.f;


float3 graininess = internal::ComputeFilmGraininess(density);
// Graininess of all 3 layers (CMY)

float3 random_factor = (random_numbers * 2.f) - 1.f;
float boost = 1.667f; // Boost max to 0.05

float3 change = random_factor * graininess * strength * boost;
float3 output_color = ap1_color * (1.f + change);

if (debug) {
// Output Visualization
output_color = abs(change);
}

output_color = renodx::color::bt709::from::AP1(output_color);

return output_color;
}
} // namespace effects
} // namespace renodx

Expand Down

0 comments on commit 2163b4a

Please sign in to comment.