š2Ĺ5.5.1f1ţ˙˙˙˙˙Č0ĹňĂôL.`?^Ů0D7€˙˙˙˙€Ś€˛€ЀŚ€Ś€Ś€#Ś€+H€3˙˙˙˙€1€1€˙˙˙˙@ހ€ Q€j€ ™€< Ś€H H€Z˙˙˙˙ €1€1€˙˙˙˙@ހ€Q€j€ЀgŚ€Ś€Ś€#Ś€+v~ € €– €Ÿ €¨ €ą €ş €Ă €Ě €Ő €Ţ  €ç! €ń" €ű# €$ €% €&Ő€#˙˙˙˙'€1€1€˙˙˙˙(€ހ€)H€j€˙˙˙˙*€1€1€˙˙˙˙+@ހ€,Q€j€-™€*.ހ8/AssetMetaDataguiddata[0]data[1]data[2]data[3]pathNametimeCreatedoriginalChangesetoriginalNameoriginalParentHash128originalDigestbytes[0]bytes[1]bytes[2]bytes[3]bytes[4]bytes[5]bytes[6]bytes[7]bytes[8]bytes[9]bytes[10]bytes[11]bytes[12]bytes[13]bytes[14]bytes[15]labelsassetStoreReflicenseType ˙˙z{ď@îČă5^(H'7€˙˙˙˙€Ś€˛€ Ő€ ހ#.€,†€Ä€ ހ#.€,H€Ť€˙˙˙˙€1€1€˙˙˙˙ @ހ€ Q€j€ Ő€5˙˙˙˙ €1€1€˙˙˙˙ €ހ€€j€˙˙˙˙€H€›€˙˙˙˙€1€1€˙˙˙˙@ހ€Q€j€y€ € ހ#.€, €I@ž€X @ހ#.€,H€]˙˙˙˙€1€1€˙˙˙˙@ހ€Q€j€H€h˙˙˙˙€1€1€˙˙˙˙ @ހ€!Q€j€"H€z˙˙˙˙#€1€1€˙˙˙˙$@ހ€%Q€j€&MonoImporterPPtrm_FileIDm_PathIDm_DefaultReferencesexecutionOrdericonm_UserDatam_AssetBundleNamem_AssetBundleVariants˙˙˙8-l'€Łć„hŒÎA,Œ€7€˙˙˙˙€Ś€˛€Ő€ ހ.€†€Ä€ ހ.€H€Ť€˙˙˙˙€1€1€˙˙˙˙ @ހ€ Q€j€ H€ę€˙˙˙˙ €1€1€˙˙˙˙ @ހ€Q€j€ń€(˙˙˙˙€1€1€˙˙˙˙€ހ€€j€˙˙˙˙€H€›€˙˙˙˙€1€1€˙˙˙˙@ހ€Q€j€y€ € ހ.€y€< ހ.€ހCH€T˙˙˙˙€1€1€˙˙˙˙ @ހ€!Q€j€"H€`˙˙˙˙#€1€1€˙˙˙˙$@ހ€%Q€j€&H€l˙˙˙˙'€1€1€˙˙˙˙(@ހ€)Q€j€*L€{+PPtrm_FileIDm_PathIDm_DefaultReferencesm_Iconm_ExecutionOrderm_ClassNamem_Namespacem_AssemblyNamem_IsEditorScript  °ŕyŻPu!ëżK›<K¨€ţ§ż9kœu;ŁAk]CÇĽX<öĆ;+RˇŒĂë[DE° ^…Şš18O ńRMER˜C¸ť˜eÓčÎ) -MBęźăd/čkGFAssets/Standard Assets/Effects/ImageEffects/Scripts/ContrastStretch.cs shaderLum>I shaderReduce>I shaderAdapt>I shaderApply>IContrastStretch_ using System; using UnityEngine; namespace UnityStandardAssets.ImageEffects { [ExecuteInEditMode] [AddComponentMenu("Image Effects/Color Adjustments/Contrast Stretch")] public class ContrastStretch : MonoBehaviour { /// Adaptation speed - percents per frame, if playing at 30FPS. /// Default is 0.02 (2% each 1/30s). [Range(0.0001f, 1.0f)] public float adaptationSpeed = 0.02f; /// If our scene is really dark (or really bright), we might not want to /// stretch its contrast to the full range. /// limitMinimum=0, limitMaximum=1 is the same as not applying the effect at all. /// limitMinimum=1, limitMaximum=0 is always stretching colors to full range. /// The limit on the minimum luminance (0...1) - we won't go above this. [Range(0.0f,1.0f)] public float limitMinimum = 0.2f; /// The limit on the maximum luminance (0...1) - we won't go below this. [Range(0.0f, 1.0f)] public float limitMaximum = 0.6f; // To maintain adaptation levels over time, we need two 1x1 render textures // and ping-pong between them. private RenderTexture[] adaptRenderTex = new RenderTexture[2]; private int curAdaptIndex = 0; // Computes scene luminance (grayscale) image public Shader shaderLum; private Material m_materialLum; protected Material materialLum { get { if ( m_materialLum == null ) { m_materialLum = new Material(shaderLum); m_materialLum.hideFlags = HideFlags.HideAndDontSave; } return m_materialLum; } } // Reduces size of the image by 2x2, while computing maximum/minimum values. // By repeatedly applying this shader, we reduce the initial luminance image // to 1x1 image with minimum/maximum luminances found. public Shader shaderReduce; private Material m_materialReduce; protected Material materialReduce { get { if ( m_materialReduce == null ) { m_materialReduce = new Material(shaderReduce); m_materialReduce.hideFlags = HideFlags.HideAndDontSave; } return m_materialReduce; } } // Adaptation shader - gradually "adapts" minimum/maximum luminances, // based on currently adapted 1x1 image and the actual 1x1 image of the current scene. public Shader shaderAdapt; private Material m_materialAdapt; protected Material materialAdapt { get { if ( m_materialAdapt == null ) { m_materialAdapt = new Material(shaderAdapt); m_materialAdapt.hideFlags = HideFlags.HideAndDontSave; } return m_materialAdapt; } } // Final pass - stretches the color values of the original scene, based on currently // adpated minimum/maximum values. public Shader shaderApply; private Material m_materialApply; protected Material materialApply { get { if ( m_materialApply == null ) { m_materialApply = new Material(shaderApply); m_materialApply.hideFlags = HideFlags.HideAndDontSave; } return m_materialApply; } } void Start() { // Disable if we don't support image effects if (!SystemInfo.supportsImageEffects) { enabled = false; return; } if (!shaderAdapt.isSupported || !shaderApply.isSupported || !shaderLum.isSupported || !shaderReduce.isSupported) { enabled = false; return; } } void OnEnable() { for( int i = 0; i < 2; ++i ) { if ( !adaptRenderTex[i] ) { adaptRenderTex[i] = new RenderTexture(1, 1, 0); adaptRenderTex[i].hideFlags = HideFlags.HideAndDontSave; } } } void OnDisable() { for( int i = 0; i < 2; ++i ) { DestroyImmediate( adaptRenderTex[i] ); adaptRenderTex[i] = null; } if ( m_materialLum ) DestroyImmediate( m_materialLum ); if ( m_materialReduce ) DestroyImmediate( m_materialReduce ); if ( m_materialAdapt ) DestroyImmediate( m_materialAdapt ); if ( m_materialApply ) DestroyImmediate( m_materialApply ); } /// Apply the filter void OnRenderImage (RenderTexture source, RenderTexture destination) { // Blit to smaller RT and convert to luminance on the way const int TEMP_RATIO = 1; // 4x4 smaller RenderTexture rtTempSrc = RenderTexture.GetTemporary(source.width/TEMP_RATIO, source.height/TEMP_RATIO); Graphics.Blit (source, rtTempSrc, materialLum); // Repeatedly reduce this image in size, computing min/max luminance values // In the end we'll have 1x1 image with min/max luminances found. const int FINAL_SIZE = 1; //const int FINAL_SIZE = 1; while( rtTempSrc.width > FINAL_SIZE || rtTempSrc.height > FINAL_SIZE ) { const int REDUCE_RATIO = 2; // our shader does 2x2 reduction int destW = rtTempSrc.width / REDUCE_RATIO; if ( destW < FINAL_SIZE ) destW = FINAL_SIZE; int destH = rtTempSrc.height / REDUCE_RATIO; if ( destH < FINAL_SIZE ) destH = FINAL_SIZE; RenderTexture rtTempDst = RenderTexture.GetTemporary(destW,destH); Graphics.Blit (rtTempSrc, rtTempDst, materialReduce); // Release old src temporary, and make new temporary the source RenderTexture.ReleaseTemporary( rtTempSrc ); rtTempSrc = rtTempDst; } // Update viewer's adaptation level CalculateAdaptation( rtTempSrc ); // Apply contrast strech to the original scene, using currently adapted parameters materialApply.SetTexture("_AdaptTex", adaptRenderTex[curAdaptIndex] ); Graphics.Blit (source, destination, materialApply); RenderTexture.ReleaseTemporary( rtTempSrc ); } /// Helper function to do gradual adaptation to min/max luminances private void CalculateAdaptation( Texture curTexture ) { int prevAdaptIndex = curAdaptIndex; curAdaptIndex = (curAdaptIndex+1) % 2; // Adaptation speed is expressed in percents/frame, based on 30FPS. // Calculate the adaptation lerp, based on current FPS. float adaptLerp = 1.0f - Mathf.Pow( 1.0f - adaptationSpeed, 30.0f * Time.deltaTime ); const float kMinAdaptLerp = 0.01f; adaptLerp = Mathf.Clamp( adaptLerp, kMinAdaptLerp, 1 ); materialAdapt.SetTexture("_CurTex", curTexture ); materialAdapt.SetVector("_AdaptParams", new Vector4( adaptLerp, limitMinimum, limitMaximum, 0.0f )); // clear destination RT so its contents don't need to be restored Graphics.SetRenderTarget(adaptRenderTex[curAdaptIndex]); GL.Clear(false, true, Color.black); Graphics.Blit ( adaptRenderTex[prevAdaptIndex], adaptRenderTex[curAdaptIndex], materialAdapt); } } }  shaderAdapt>I shaderApply>I shaderLum>I shaderReduce>IContrastStretch UnityStandardAssets.ImageEffectsAssembly-CSharp-firstpass.dll