Unity Shader, Post Processing, Blur, Bloom, Depth of Field

挂在摄像机上的脚本,把source抄到中间临时纹理,然后再到destination
由于用到HDR,camera打开Allow HDR

 			void OnRenderImage (RenderTexture source, RenderTexture destination) {
	    		RenderTexture r = RenderTexture.GetTemporary(
					source.width, source.height, 0, source.format
				);
	    		
	    		Graphics.Blit(source, r);
				Graphics.Blit(r, destination);
				
				RenderTexture.ReleaseTemporary(r);
	    	}

Blur:利用GPU内置的双线性过滤,最为简单并且运行效率最高。通过改变临时纹理分辨率为一半(除以2)downsampling,在回到destination,upsampling即可。
这样可以除以2、4、8、16、32……用更小分辨率的中间纹理得到更模糊的图像,但是效果不佳。
为提高效果,要渐进处理不要直接使用source直接blit到小分辨率中间纹理上。

	[Range(1, 16)]
	public int iterations = 4;

	RenderTexture[] textures = new RenderTexture[16];

	void OnRenderImage (RenderTexture source, RenderTexture destination) {
		int width = source.width / 2;
		int height = source.height / 2;
		RenderTextureFormat format = source.format;

		RenderTexture currentDestination = textures[0] = 
			RenderTexture.GetTemporary(width, height, 0, format);
		Graphics.Blit(source, currentDestination);
		RenderTexture currentSource = currentDestination;

		int i = 1;
		for (; i < iterations; i++) {
			width /= 2;
			height /= 2;
			if (height < 2) {
				break;
			}
			currentDestination = textures[i] =
				RenderTexture.GetTemporary(width, height, 0, format);
			Graphics.Blit(currentSource, currentDestination);
			currentSource = currentDestination;
		}	

		for (i -= 2; i >= 0; i--) {
			currentDestination = textures[i];
			textures[i] = null;
			Graphics.Blit(currentSource, currentDestination);
			RenderTexture.ReleaseTemporary(currentSource);
			currentSource = currentDestination;
		}

		Graphics.Blit(currentSource, destination);
		RenderTexture.ReleaseTemporary(currentSource);
	}

改善GPU双线性的效果
要用自己box filter kernel代替GPU的采样,要使用自己的shader

Shader "Custom/Bloom" {
	Properties {
		_MainTex ("Texture", 2D) = "white" {}
	}

	CGINCLUDE
		#include "UnityCG.cginc"

		sampler2D _MainTex;
		float4 _MainTex_TexelSize;

		struct VertexData {
			float4 vertex : POSITION;
			float2 uv : TEXCOORD0;
		};

		struct Interpolators {
			float4 pos : SV_POSITION;
			float2 uv : TEXCOORD0;
		};

		// vs没有特别用处,ps定义在不同的pass里
		Interpolators VertexProgram (VertexData v) {
			Interpolators i;
			i.pos = UnityObjectToClipPos(v.vertex);
			i.uv = v.uv;
			return i;
		}

		// 采样,只是rgb
		half3 Sample (float2 uv) {
			return tex2D(_MainTex, uv).rgb;
		}

		// box 采样,通过delta来决定是up还是down
		half3 SampleBox (float2 uv, float delta) {
			float4 o = _MainTex_TexelSize.xyxy * fl

你可能感兴趣的:(unity,unity,shader,后期特效,post,processing,bloom)