float4x4 brightnessMatrix( float brightness ) { return float4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, brightness, brightness, brightness, 1 ); } float4x4 contrastMatrix( float contrast ) { float t = ( 1.0 - contrast ) / 2.0; return float4x4(contrast, 0, 0, 0, 0, contrast, 0, 0, 0, 0, contrast, 0, t, t, t, 1 ); } float4x4 saturationMatrix( float saturation ) { float3 luminance = float3( 0.3086, 0.6094, 0.0820 ); float oneMinusSat = 1.0 - saturation; float3 red = float3( luminance.x * oneMinusSat, luminance.x * oneMinusSat, luminance.x * oneMinusSat ); red+= float3( saturation, 0, 0 ); float3 green = float3( luminance.y * oneMinusSat, luminance.y * oneMinusSat, luminance.y * oneMinusSat ); green += float3( 0, saturation, 0 ); float3 blue = float3( luminance.z * oneMinusSat, luminance.z * oneMinusSat, luminance.z * oneMinusSat ); blue += float3( 0, 0, saturation ); return float4x4(red, 0, green, 0, blue, 0, 0, 0, 0, 1 ); } float3 Brightness(float3 color, float brightness, float contrast) { const float saturation = 1.0; float4 res; res = mul( float4(color, 1.0), mul( mul( brightnessMatrix( brightness ), contrastMatrix( contrast ) ), saturationMatrix( saturation ) ) ); return res.rgb; } ///////////////////////////////////////////////////////////////////////////////////// float3 RGBToHCV( in float3 RGB ) { float4 P = ( RGB.g < RGB.b ) ? float4( RGB.bg, -1.0f, 2.0f/3.0f ) : float4( RGB.gb, 0.0f, -1.0f/3.0f ); float4 Q1 = ( RGB.r < P.x ) ? float4( P.xyw, RGB.r ) : float4( RGB.r, P.yzx ); float C = Q1.x - min( Q1.w, Q1.y ); float H = abs(( Q1.w - Q1.y ) / ( 6.0f * C + 0.000001f ) + Q1.z ); return float3( H, C, Q1.x ); } float3 RGBToHSL( in float3 RGB ) { RGB.xyz = max( RGB.xyz, 0.000001f ); float3 HCV = RGBToHCV(RGB); float L = HCV.z - HCV.y * 0.5f; float S = HCV.y / ( 1.0f - abs( L * 2.0f - 1.0f ) + 0.000001f); return float3( HCV.x, S, L ); } float curve( float x, float k ) { float s = sign( x - 0.5f ); float o = ( 1.0f + s ) / 2.0f; return o - 0.5f * s * pow( 2.0f * ( o - s * x ), k ); } float3 ProcessBW( float3 col, float r, float y, float g, float c, float b, float m ) { float3 hsl = RGBToHSL( col.xyz ); float lum = 1.0f - hsl.z; float curve_str=4.000000; float weight_r = curve( max( 1.0f - abs( hsl.x * 6.0f ), 0.0f ), curve_str ) + curve( max( 1.0f - abs(( hsl.x - 1.0f ) * 6.0f ), 0.0f ), curve_str ); float weight_y = curve( max( 1.0f - abs(( hsl.x - 0.166667f ) * 6.0f ), 0.0f ), curve_str ); float weight_g = curve( max( 1.0f - abs(( hsl.x - 0.333333f ) * 6.0f ), 0.0f ), curve_str ); float weight_c = curve( max( 1.0f - abs(( hsl.x - 0.5f ) * 6.0f ), 0.0f ), curve_str ); float weight_b = curve( max( 1.0f - abs(( hsl.x - 0.666667f ) * 6.0f ), 0.0f ), curve_str ); float weight_m = curve( max( 1.0f - abs(( hsl.x - 0.833333f ) * 6.0f ), 0.0f ), curve_str ); float sat = hsl.y * ( 1.0f - hsl.y ) + hsl.y; float ret = hsl.z; ret += ( hsl.z * ( weight_r * r ) * sat * lum ); ret += ( hsl.z * ( weight_y * y ) * sat * lum ); ret += ( hsl.z * ( weight_g * g ) * sat * lum ); ret += ( hsl.z * ( weight_c * c ) * sat * lum ); ret += ( hsl.z * ( weight_b * b ) * sat * lum ); ret += ( hsl.z * ( weight_m * m ) * sat * lum ); return saturate( ret ); } float3 BlackandWhite(float3 color) { color.xyz = saturate( color.xyz ); float red; float yellow; float green; float cyan; float blue; float magenta; red = -0.400000; yellow = 2.000001; green = 3.000000; cyan = 0.000000; blue = -0.600000; magenta = -0.200000; color.xyz = ProcessBW( color.xyz, red, yellow, green, cyan, blue, magenta ); return color; } ///////////////////////////////////////////////////////////////////////////////////// float3 LevelsPass(float3 color) { const float3 InputColor = color; float3 OutputColor = InputColor; float3 InputBlackPoint=float3(0.000000,0.000000,0.000000); float3 InputWhitePoint=float3(1.000000,1.000000,1.000000); float3 OutputBlackPoint=float3(0.000000,0.000000,0.000000); float3 OutputWhitePoint=float3(1.000000,1.000000,1.000000); float3 InputGamma=float3(3.920000,1.000000,7.467000); OutputColor = pow(abs(((InputColor) - InputBlackPoint)/(InputWhitePoint - InputBlackPoint)), InputGamma) * (OutputWhitePoint - OutputBlackPoint) + OutputBlackPoint; return OutputColor; } ////////////////////////////////////////////////////////////////////////////////////// #define permONE 1.0f / 256.0f #define permHALF 0.5f * permONE #define permTexSize 256 float discreteNoise(float rand) { return float(int(rand * 3.0) * 64) / 256.0; } float4 rnm( float2 tc, float t ) { float grainAdjust=1.000000; float noise = sin( dot( tc, float2( 12.9898, 78.233 ))) * ( 43758.5453 + t ); float noiseR = frac( noise * grainAdjust ) * 2.0 - 1.0; float noiseG = frac( noise * 1.2154 * grainAdjust ) * 2.0 - 1.0; float noiseB = frac( noise * 1.3453 * grainAdjust ) * 2.0 - 1.0; float noiseA = frac( noise * 1.3647 * grainAdjust ) * 2.0 - 1.0; return float4( noiseR, noiseG, noiseB, noiseA ); } float4 samplerPermTex(float2 uv) { float4 gen = rnm(uv, 13.14381); gen.x = discreteNoise(gen.x); gen.y = discreteNoise(gen.y); gen.z = discreteNoise(gen.z); return gen; } float fade( float t ) { return t * t * t * ( t * ( t * 6.0 - 15.0 ) + 10.0 ); } float pnoise3D( float3 p, float t, float grainSize ) { float3 pi = permONE * floor( p ) + permHALF; pi.xy *= permTexSize; pi.xy = round(( pi.xy - permHALF ) / grainSize ) * grainSize; pi.xy /= permTexSize; float3 pf = frac( p ); // Noise contributions from (x=0, y=0), z=0 and z=1 float perm00 = rnm( pi.xy, t ).x; float3 grad000 = samplerPermTex(float2( perm00, pi.z )).xyz * 4.0 - 1.0; float n000 = dot( grad000, pf ); float3 grad001 = samplerPermTex(float2( perm00, pi.z + permONE )).xyz * 4.0 - 1.0; float n001 = dot( grad001, pf - float3( 0.0, 0.0, 1.0 )); // Noise contributions from (x=0, y=1), z=0 and z=1 float perm01 = rnm( pi.xy + float2( 0.0, permONE ), t ).y ; float3 grad010 = samplerPermTex(float2( perm01, pi.z )).xyz * 4.0 - 1.0; float n010 = dot( grad010, pf - float3( 0.0, 1.0, 0.0 )); float3 grad011 = samplerPermTex(float2( perm01, pi.z + permONE )).xyz * 4.0 - 1.0; float n011 = dot( grad011, pf - float3( 0.0, 1.0, 1.0 )); // Noise contributions from (x=1, y=0), z=0 and z=1 float perm10 = rnm( pi.xy + float2( permONE, 0.0 ), t ).z ; float3 grad100 = samplerPermTex(float2( perm10, pi.z )).xyz * 4.0 - 1.0; float n100 = dot( grad100, pf - float3( 1.0, 0.0, 0.0 )); float3 grad101 = samplerPermTex(float2( perm10, pi.z + permONE )).xyz * 4.0 - 1.0; float n101 = dot( grad101, pf - float3( 1.0, 0.0, 1.0 )); // Noise contributions from (x=1, y=1), z=0 and z=1 float perm11 = rnm( pi.xy + float2( permONE, permONE ), t ).w ; float3 grad110 = samplerPermTex(float2( perm11, pi.z )).xyz * 4.0 - 1.0; float n110 = dot( grad110, pf - float3( 1.0, 1.0, 0.0 )); float3 grad111 = samplerPermTex(float2( perm11, pi.z + permONE )).xyz * 4.0 - 1.0; float n111 = dot( grad111, pf - float3( 1.0, 1.0, 1.0 )); // Blend contributions along x float4 n_x = lerp( float4( n000, n001, n010, n011 ), float4( n100, n101, n110, n111 ), fade( pf.x )); // Blend contributions along y float2 n_xy = lerp( n_x.xy, n_x.zw, fade( pf.y )); // Blend contributions along z float n_xyz = lerp( n_xy.x, n_xy.y, fade( pf.z )); // We're done, return the final noise value return n_xyz; } float3 doGrain(float3 color, float2 texcoord, float grainSize, float grainAmount, float grainIntensity, float grainColor, float grainIntHigh, float grainIntLow, float grainDensity) { float timer = timers.x % 1000.0f; float2 uv = texcoord.xy * float2( screen_res.x, screen_res.y ); float3 noise = pnoise3D( float3( uv.xy, 1 ), timer, grainSize ); noise.y = pnoise3D( float3( uv.xy, 2 ), timer, grainSize ); noise.z = pnoise3D( float3( uv.xy, 3 ), timer, grainSize ); // Old, practically does the same as grainAmount below // Added back on request noise.xyz *= grainIntensity; // Noise saturation noise.xyz = lerp( dot( noise.xyz, 1.0f ), noise.xyz, grainColor ); // Control noise density noise.xyz = pow( abs( noise.xyz ), max( 11.0f - grainDensity, 0.1f )) * sign( noise.xyz ); // Mixing options float lum = dot( color.xyz, 0.333333f ); // Just using average here noise.xyz = lerp( noise.xyz * grainIntLow, noise.xyz * grainIntHigh, fade( lum )); // Noise adjustments based on average intensity color.xyz = lerp( color.xyz, color.xyz + ( noise.xyz ), grainAmount ); return float3( color.xyz ); } float3 Grain2(float3 color, float2 texcoord) { float grainSize = 2.0; float grainAmount=0.023000 * 0.00004; float grainIntensity=1.000000; float grainColor=0.000000; float grainIntHigh=0.000000; float grainIntLow=1.000000; float grainDensity=0.000000; return doGrain(color, texcoord, grainSize, grainAmount, grainIntensity, grainColor, grainIntHigh, grainIntLow, grainDensity); } ////////////////////////////////////////////////////////////////////////////////////// float3 Grain1(float3 color, float2 texcoord) { float grainSize=1.0; float grainAmount=0.500000; float grainIntensity=0.300000; float grainColor=0.000000; float grainIntHigh=0.000000; float grainIntLow=0.500000; float grainDensity=10.000000; return doGrain(color, texcoord, grainSize, grainAmount, grainIntensity, grainColor, grainIntHigh, grainIntLow, grainDensity); }