Here is the overall structure
Code: Select all
#ifdef APPLYGAMECOLORCORRECTION
//fallout4 vanilla post process. Just an example for modders, better not enable without know how to edit and what you need
// combines bloom, adaptation
float4 r0, r1, r2, r3;
r0.xyz = color.xyz;
r1.xy = Params01[4].zw * IN.txcoord0.xy;
r1.xyz = TextureBloom.Sample(Sampler1, r1.xy).xyz;
r0.w = TextureAdaptation.Sample(Sampler0, IN.txcoord0.xy).x;
r1.w = Params01[1].z / (0.001 + r0.w);
r2.x = r1.w < Params01[1].y;
r1.w = r2.x ? Params01[1].y : r1.w;
r2.x = Params01[1].x < r1.w;
r1.w = r2.x ? Params01[1].x : r1.w;
r0.xyz = r1.xyz + r0.xyz;
r0.xyz = r0.xyz * r1.w;
// returns color_adapt
// filmic tonemapper
r1.xyz = r0.xyz + r0.xyz;
r2.xyz = r0.xyz * 0.3 + 0.05;
r3.xy = float2(0.2, 3.333333) * Params01[1].w;
r2.xyz = r1.xyz * r2.xyz + r3.x;
r0.xyz = r0.xyz * 0.3 + 0.5;
r0.xyz = r1.xyz * r0.xyz + 0.06;
r0.xyz = r2.xyz / r0.xyz;
r0.xyz = -Params01[1].w * 3.333333 + r0.xyz;
r1.x = Params01[1].w * 0.2 + 19.376;
r1.x = r1.x * 0.0408564 - r3.y;
r1.xyz = r0.xyz / r1.x;
// returns filmic result
// post process
r0.x = dot(r1.xyz, float3(0.2125, 0.7154, 0.0721));
r1.xyz = r1.xyz - r0.x;
r1.xyz = Params01[2].x * r1.xyz + r0.x;
r2.xyz = r0.x * Params01[3].xyz - r1.xyz;
r1.xyz = Params01[3].w * r2.xyz + r1.xyz;
r1.xyz = Params01[2].w * r1.xyz - r0.w;
r0.xyz = Params01[2].z * r1.xyz + r0.w;
//last color filter used only for certain conditions, like rifle night scope
color.xyz = lerp(r0.xyz, Params01[5].xyz, Params01[5].w);
color.xyz=saturate(color);
color.xyz = pow(color.xyz, 1.0/2.2);
#endif //APPLYGAMECOLORCORRECTION
And in detail:
the first part is to combine bloom and scale the result with adaption to get Color_adpt for tonemapper.
Code: Select all
#ifdef APPLYGAMECOLORCORRECTION
//fallout4 vanilla post process. Just an example for modders, better not enable without know how to edit and what you need
float2 bloom_offset = Params01[4].zw; //bloom coord scaling
float3 adaptation = Params01[1].xyz; //.x = adaption max, .y = min, .z = scale/sensitivity
float4 color = TextureColor.Sample(Sampler0, IN.txcoord0.xy);
float3 bloom = TextureBloom.Sample(Sampler1, bloom_offset * IN.txcoord0.xy).rgb;
float middlegray = TextureAdaptation.Sample(Sampler0, IN.txcoord0.xy).x;
float adapt = clamp(adaptation.z / (0.001 + middlegray), adaptation.y, adaptation.x); //auto exposure
color.rgb = (color.rgb + bloom.rgb) * adapt; //bloom in add mode
Code: Select all
// Filmic operator
float A = 0.3; // Shoulder Strength
float B = 0.5; // Linear Strength
float C = 0.1; // Linear Angle
float D = 0.1; // Toe Strength
float E = Params01[1].w; // Toe Numerator
float F = 0.3; // Toe Denominator
float W = 5.6; // LinearWhite, white level
color.rgb = Tonemap_Filmic(color.rgb, W, A, B, C, D, E, F);
Code: Select all
float3 Tonemap_Filmic(float3 color, float W, float A, float B, float C, float D, float E, float F)
{
float4 res = float4(color.rgb, W);
res = (res * ( A * res + C * B) + D * E) / (res * ( A * res + B) + D * F);
res -= E / F;
return res.rgb / res.a;
}
The final part is post color correction where the Params can be modded in the future through Creation Kit.
Code: Select all
#define LUM_709 float3(0.2125, 0.7154, 0.0721)
//color corrections
float saturation = Params01[2].x; // 0 == gray scale
float3 tint_color = Params01[3].rgb; // tint color
float tint_weight = Params01[3].w; // 0 == no tint
float contrast = Params01[2].z; // 0 == no contrast
float brightness = Params01[2].w; // intensity
float3 fade = Params01[5].xyz; // fade current scene to specified color, mostly used in special effects
float fade_weight = Params01[5].w; // 0 == no fade
color.a = dot(color.rgb, LUM_709); //get luminance
color.rgb = lerp(color.a, color.rgb, saturation); //saturation
color.rgb = lerp(color.rgb, color.a * tint.rgb, tint.a); //tint
color.rgb = lerp(middlegray, brightness * color.rgb, contrast); //contrast & intensity
color.rgb = lerp(color.rgb, fade, fade_weight); //fade current scene to specified color
color.rgb = saturate(color.rgb);
color.rgb = pow(color.rgb, 1.0/2.2);
#endif //APPLYGAMECOLORCORRECTION
Haven't tested ingame though, might have missing something.
⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄
thanks to roxahris for testing, fix typo in filmic function & constant.
update Oct/30/16 fix a error on float adapt.