unity Shader 磨皮

本文介绍了一种基于Unity Shader的双边滤波算法实现的磨皮效果,通过调整模糊半径和大小参数来达到平滑皮肤的效果。适用于移动平台如安卓和苹果设备。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简单的实现了磨皮效果,使用双边滤波

安卓和苹果都进行测试过..可以使用

Shader "Custom/Bilateral"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
		_BlurRadius ("BlurRadius",Range(0,9) ) = 0
		_BSIGMA("Size",Range(0.01,0.09)) = 0.1
	}
	SubShader
	{
		Tags { "RenderType"="Opaque" }
		LOD 100

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma multi_compile_fog	
			#include "UnityCG.cginc"

			#define SIGMA 10.0
			#define BSIGMA 0.1
			#define MSIZE 20
			#define PI 3.1415927f

		    sampler2D _MainTex;
			int _BlurRadius;
			float _BSIGMA;
			struct v2f
			{
				float4 pos : SV_POSITION;
				float2 uv : TEXCOORD0;
			};
			
			v2f vert (appdata_tan v)
			{
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				o.uv = v.texcoord.xy;
				return o;
			}

			float normpdf(float x,float sigma)
			{
				return 0.39894*exp(-0.5*x*x/(sigma*sigma))/sigma;
			}

			float normpdf3(fixed3 v,float sigma)
			{
				return 0.39894*exp(-0.5*dot(v,v)/(sigma*sigma))/sigma;
			}

			fixed4 GetBilateral(float2 uv)
			{
				float3 c = tex2D(_MainTex ,uv).rgb;
				float kernel[MSIZE];
				float3 final_colour = float3(0,0,0);

				float Z = 0.0;
				for (int j = 0; j <= _BlurRadius; ++j)
				{
					kernel[_BlurRadius+j] = kernel[_BlurRadius-j] = normpdf(float(j), SIGMA);
				}
				float3 cc;
				float factor;
				float bZ = 1.0/normpdf(0.0,_BSIGMA);
				for (int i=-_BlurRadius; i <= _BlurRadius; ++i)
				{
					for (int j=-_BlurRadius; j <= _BlurRadius; ++j)
					{
						cc = tex2D(_MainTex,  uv + float2(float(i),float(j))* bZ).rgb;

						factor = normpdf3(cc-c, _BSIGMA)*bZ*kernel[_BlurRadius+j]*kernel[_BlurRadius+i];
						Z += factor;
						final_colour += factor*cc;
					}
				}
				return fixed4 (final_colour/Z,1.0);
			}

			fixed4 frag (v2f i) : SV_Target
			{
				//// sample the texture
				//fixed4 col = tex2D(_MainTex, i.uv);
				//// apply fog
				//UNITY_APPLY_FOG(i.fogCoord, col);
				//return col;
				return GetBilateral(i.uv);
			}
			ENDCG
		}
	}
    Fallback "VertexLit"
}

 

### Unity 中实现图像滤镜效果Unity 中,可以通过多种方式来实现实时的图像滤镜效果。一种常见的方式是通过编写自定义着色器 (Shader),并利用 Post-processing 技术应用这些效果。 #### 高斯模糊滤波 高斯模糊是一种常见的平滑操作,在 Unity 中可通过编写 HLSL/CG 代码创建一个简单的高斯模糊 Shader 来实现[^1]: ```csharp // GaussBlur.shader Shader "Custom/GaussBlur" { Properties { _MainTex ("Texture", 2D) = "white" {} _BlurSize ("Blur Size", Range(0, 20)) = 1.0 } SubShader { Tags {"Queue"="Transparent"} Pass { CGPROGRAM #pragma vertex vert_img #pragma fragment frag sampler2D _MainTex; float _BlurSize; struct appdata_t { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 pos : SV_POSITION; }; half4 frag(v2f i) : COLOR { // Gaussian blur implementation here... return tex2D(_MainTex, i.uv); } ENDCG } } } ``` 上述代码展示了如何构建基本框架;实际的高斯权重计算和多通道采样需进一步完善。 #### 双边滤波 双边滤波能够在保持边缘的同时减少噪声,非常适合于或其他需要保留细节的应用场景。虽然 Unity 官方并没有提供内置的双边滤波组件,但是可以根据需求自行开发或寻找第三方资源包。 对于更复杂的视觉特效如 SSAO(屏幕空间环境光遮蔽),通常会涉及到随机样本采集以及降噪处理,此时也可以考虑引入双边滤波技术以改善最终成像质量。 #### 锐化效果 为了增强图片清晰度,可以采用拉普拉斯算子来进行锐化处理。具体做法是在原像素基础上叠加其邻域内差异较大的部分,从而突出显示边界特征[^3]: ```csharp void LaplacianSharpen(Texture2D srcImage, Texture2D dstImage) { Color[,] laplaceKernel = new Color[,] { {-1,-1,-1}, {-1,9,-1}, {-1,-1,-1} }; int width = srcImage.width; int height = srcImage.height; for(int y=1;y<height-1;++y){ for(int x=1;x<width-1;++x){ float rSum=gSum=bSum=aSum=0; for(int ky=-1;ky<=1;++ky){ for(int kx=-1;kx<=1;++kx){ var pixelColor = srcImage.GetPixel(x+kx,y+ky); rSum += pixelColor.r * laplaceKernel[ky+1,kx+1]; gSum += pixelColor.g * laplaceKernel[ky+1,kx+1]; bSum += pixelColor.b * laplaceKernel[ky+1,kx+1]; aSum += pixelColor.a * laplaceKernel[ky+1,kx+1]; } } dstImage.SetPixel(x,y,new Color(rSum,gSum,bSum,aSum)); } } } ``` 这段 C# 函数实现了基于 CPU 的简单版本拉普拉斯卷积核运算逻辑。当然,在 GPU 上执行效率更高,因此建议转换为 Compute Shader 或者集成到现有图形管线中的 Fragment Shader 内部完成相同任务。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值