unity3d Crease效果分析

unity3d的Crease描边效果非常不错,所以分析了一下这个效果。

用到3个shader:

ConvertDepth //渲染depthmap

CreaseApply //描边

SeparableBlur//模糊

这个效果的重点是 1.怎么查找边缘 2.怎么模糊边缘

unity3d的方法是:

采用2张depthmap,一张清晰,一张模糊,模糊的depthmap上可以看到边缘都模糊了,两种图做差,就知道边缘在哪里了。

看代码:return color * (1.0-abs(hrDepth.a-lrDepth.a)*intensity);

假如abs(hrDepth.a-lrDepth.a)即深度差越大,值越大,不是边缘的部分模糊之后值是不会有变化的,原理很简单。而且模糊之后这个差也能有渐变的效果,所以最后的描边可以比较虚幻。但是消耗是很大的,会增加drawcall,overdraw比较高,模糊的shader用到了很多次的图片采样,而且是在frag shader里面采样的,手机上的显卡填充率本来就不高,根本就用不了。

下面是深度渲染的shader:

Shader "Hidden/ConvertDepth" {
	Properties {
		_MainTex ("Base (RGB)", 2D) = "" {}
	}
	CGINCLUDE
		#include "UnityCG.cginc"
		struct v2f {
			float4 pos : POSITION;
			float2 uv : TEXCOORD0;
		};
		sampler2D _MainTex;
		sampler2D _CameraDepthTexture;
		v2f vert( appdata_img v ) 
		{
			v2f o;
			o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
			o.uv =  v.texcoord.xy;
			return o;
		}
		half4 frag(v2f i) : COLOR 
		{
			float d = UNITY_SAMPLE_DEPTH( tex2D(_CameraDepthTexture, i.uv.xy) );
			d = Linear01Depth(d);
				 
			if(d>0.99999)
				return half4(1,1,1,1);
			else
			return half4(d,d,d,1);//灰度显示的深度图
			//return EncodeFloatRGBA(d); 
		}
	ENDCG
	Subshader {
	 Pass {
		  ZTest Always Cull Off ZWrite Off
		  Fog { Mode off }      

		  CGPROGRAM
		  #pragma fragmentoption ARB_precision_hint_fastest
		  #pragma vertex vert
		  #pragma fragment frag
		  ENDCG
	  }
	}
	Fallback off
} 
其中的EncodeFloatRGBA函数是为了能够更精确的存储深度值,具体算法如下:

// Encoding/decoding [0..1) floats into 8 bit/channel RGBA. Note that 1.0 will not be encoded properly.
inline float4 EncodeFloatRGBA( float v )
{
	float4 kEncodeMul = float4(1.0, 255.0, 65025.0, 160581375.0);
	float kEncodeBit = 1.0/255.0;
	float4 enc = kEncodeMul * v;
	enc = frac (enc);
	enc -= enc.yzww * kEncodeBit;
	return enc;
}
inline float DecodeFloatRGBA( float4 enc )
{
	float4 kDecodeDot = float4(1.0, 1/255.0, 1/65025.0, 1/160581375.0);
	return dot( enc, kDecodeDot );
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值