You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
68 lines
1.9 KiB
68 lines
1.9 KiB
// Calculates adaptation to minimum/maximum luminance values, |
|
// based on "currently adapted" and "new values to adapt to" |
|
// textures (both 1x1). |
|
|
|
Shader "Hidden/Contrast Stretch Adaptation" { |
|
Properties { |
|
_MainTex ("Base (RGB)", 2D) = "white" {} |
|
_CurTex ("Base (RGB)", 2D) = "white" {} |
|
} |
|
|
|
Category { |
|
SubShader { |
|
Pass { |
|
ZTest Always Cull Off ZWrite Off |
|
|
|
CGPROGRAM |
|
#pragma vertex vert_img |
|
#pragma fragment frag |
|
#include "UnityCG.cginc" |
|
|
|
uniform sampler2D _MainTex; // currently adapted to |
|
uniform sampler2D _CurTex; // new value to adapt to |
|
uniform float4 _AdaptParams; // x=adaptLerp, y=limitMinimum, z=limitMaximum |
|
|
|
float4 frag (v2f_img i) : SV_Target { |
|
// value is: max, min |
|
float2 valAdapted = tex2D(_MainTex, i.uv).xy; |
|
float2 valCur = tex2D(_CurTex, i.uv).xy; |
|
|
|
// Calculate new adapted values: interpolate |
|
// from valAdapted to valCur by script-supplied amount. |
|
// |
|
// Because we store adaptation levels in a simple 8 bit/channel |
|
// texture, we might not have enough precision - the interpolation |
|
// amount might be too small to change anything, and we'll never |
|
// arrive at the needed values. |
|
// |
|
// So we make sure the change we do is at least 1/255th of the |
|
// color range - this way we'll always change the value. |
|
const float kMinChange = 1.0/255.0; |
|
float2 delta = (valCur-valAdapted) * _AdaptParams.x; |
|
delta.x = sign(delta.x) * max( kMinChange, abs(delta.x) ); |
|
delta.y = sign(delta.y) * max( kMinChange, abs(delta.y) ); |
|
|
|
float4 valNew; |
|
valNew.xy = valAdapted + delta; |
|
|
|
// Impose user limits on maximum/minimum values |
|
valNew.x = max( valNew.x, _AdaptParams.z ); |
|
valNew.y = min( valNew.y, _AdaptParams.y ); |
|
|
|
// Optimization so that our final apply pass is faster: |
|
// z = max-min (plus a small amount to prevent division by zero) |
|
valNew.z = valNew.x - valNew.y + 0.01; |
|
// w = min/(max-min) |
|
valNew.w = valNew.y / valNew.z; |
|
|
|
return valNew; |
|
} |
|
ENDCG |
|
|
|
} |
|
} |
|
} |
|
|
|
Fallback off |
|
|
|
}
|
|
|