Unity Shader总结(十三)——深度和法线纹理、改进的运动模糊和边缘检测及高度雾的生成


深度纹理实际就是一张渲染纹理,它里面存储的像素值是一个高精度的深度值,范围是[0,1],非线性分布;

如何获取

脚本中:
深度:camera.depthTextureMode = DepthTextureMode.Depth
深度+法线:camera.depthTextureMode = DepthTextureMode.DepthNormals

深度和深度+法线:camera.depthTextureMode | = DepthTextureMode.Depth
                               camera.depthTextureMode | = DepthTextureMode.DepthNormals
采样:SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv)——绝大多数情况tex2D也可以,这里防止某些平台特殊处理;

查看

在片元着色器中用代码输出深度和法线值后如果画面全黑或全白,将摄像机的远剪裁平面调小;

运动模糊

运动模糊的另一种方法是速度映射图:利用深度纹理在片元着色器中为每个像素计算其在世界空间下的位置,计算前一帧和当前帧的位置差,生成该像素的速度。

脚本

using UnityEngine;
using System.Collections;

public class MotionBlurWithDepthTexture : PostEffectsBase {
   

	public Shader motionBlurShader;
	private Material motionBlurMaterial = null;

	public Material material {
     
		get {
   
			motionBlurMaterial = CheckShaderAndCreateMaterial(motionBlurShader, motionBlurMaterial);
			return motionBlurMaterial;
		}  
	}

	private Camera myCamera;
	public Camera camera {
   
		get {
   
			if (myCamera == null) {
   
				myCamera = GetComponent<Camera>();
			}
			return myCamera;
		}
	}

	[Range(0.0f, 1.0f)]
	public float blurSize = 0.5f;
	//保存上一帧的视角*投影矩阵
	private Matrix4x4 previousViewProjectionMatrix;
	
	void OnEnable() {
   
		camera.depthTextureMode |= DepthTextureMode.Depth;

		previousViewProjectionMatrix = camera.projectionMatrix * camera.worldToCameraMatrix;
	}
	
	void OnRenderImage (RenderTexture src, RenderTexture dest) {
   
		if (material != null) {
   
			material.SetFloat("_BlurSize", blurSize);

			material.SetMatrix("_PreviousViewProjectionMatrix", previousViewProjectionMatrix);
			Matrix4x4 currentViewProjectionMatrix = camera.projectionMatrix * camera.worldToCameraMatrix;
			//当前帧的视角*投影
			Matrix4x4 currentViewProjectionInverseMatrix = currentViewProjectionMatrix.inverse;
			material.SetMatrix("_CurrentViewProjectionInverseMatrix", currentViewProjectionInverseMatrix);
			previousViewProjectionMatrix = currentViewProjectionMatrix;

			Graphics.Blit (src, dest, material);
		} else {
   
			Graphics.Blit(src, dest);
		}
	}
}

shader

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Unity Shaders Book/Chapter 13/Motion Blur With Depth Texture" {
   
	Properties {
   
		_MainTex ("Base (RGB)", 2D) = "white" {
   }
		_BlurSize ("Blur Size", Float) = 1.0
	}
	SubShader {
   
		CGINCLUDE
		
		#include "UnityCG.cginc"
		
		sampler2D _MainTex;
		half4 _MainTex_TexelSize;
		//unity传递的深度纹理
		sampler2D _CameraDepthTexture;
		//脚本传递的矩阵
		float4x4 _CurrentViewProjectionInverseMatrix;
		float4x4 _PreviousViewProjectionMatrix;
		half _BlurSize;
		
		struct v2f {
   
			float4 pos : SV_POSITION;
			half2 uv : TEXCOORD0;
			half2 uv_depth : TEXCOORD1;
		};
		
		v2f vert(appdata_img v) {
   
			v2f o;
			o.pos = UnityObjectToClipPos(v.vertex);
			
			o.uv = v.texcoord;
			o.uv_depth = v.texcoord;
			//平台差异化处理
			#if UNITY_UV_STARTS_AT_TOP
			if (_MainTex_TexelSize.y < 0)
				o.uv_depth.y = 1 - o.uv_depth.y;
			#endif
					 
			return o;
		}
		
		fixed4 frag(v2f i) : SV_Target {
   
			// 对深度纹理采样得到深度值
			float d = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv_depth);
			//将深度值重新映射回NDC
			float4 H = float4(i.uv.x * 2 - 1, i.uv.y * 2 - 1, d * 2 - 1, 1);
			// 视角*投影逆矩阵变换
			float4 D = mul(_CurrentViewProjectionInverseMatrix, H);
			
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值