再续PS

最近几天断了更,毕竟是周末,还是很不要脸地休息了,出去跟同学骑行,骑了七十多公里,还是很佩服自己的耐力(更甚的是同行的还有两个女生坚持了下来),也算干了件牛逼的事。今天回看上面几篇博客发现格式出了些问题,发表前和发表后明显不一样,不知道是审核时出了什么问题,我尽量写的格式规范一点,以免出现问题。
今天继续上面几篇的内容,前面我们学到了静态图片怎么通过高斯模糊来达到一定的效果,那么今天我们就学学运动模糊。运动模糊可以让物体运动起来更加真实、平滑。游戏中实现高速运动的物体时就用到了运动模糊。实现运动的方法有很多,一种就是利用一块累积缓存来混合多张图像,当物体快速移动产生多张图像后,我们取它们之间的平均值作为最后的运动模糊图像,但是这种方法对性能消耗很大;另一种是创建和使用速度缓存,速度映射图存储了每一个像素的速度,然后使用这个速度来决定模糊的大小和方向。
好,现在我们讲第二种方法:
首先,我们需要创建一个C#脚本继承上一篇讲到的PostEffectBase脚本,代码如下:
“`
public class MotionBlurWithDepthTexture:PostEffectBase{
public Shader motionBlurShader;
private Material motionBlurMaterial=null;
public Material material{
get{
motionBlurMaterial=CheckShaderAndCreateMaterial(motionBlurShader,motionBlurMaterial);
return motionBlurMaterial;
}

}


这里我们还是和上一篇类似定义一个纹理和一个shader。

[Range(0.0f,1.0f)]
public float blurSize=0.5f;

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


这里我们首先定义了一个模糊图像大小的变量,然后下面定义一个Camera的变量,然后获取其组建。

private Matrix4*4 previousViewProjectionMatrix;  
void OnEnable(){  
        camera.depthTextureMode|=DepthTextureMode.depth;  
 }
定义了一个4*4的矩阵,这些矩阵知识我建议去看看《Unity shader入门精要》里面的有关的数学基础,这里我就不赘述,这里定义的是上一帧摄像机视角*投影矩阵。然后定义了一个函数设置摄像机模式。

void OnRenderImage(RenderTexture src ,RenderTexture dest){
if(material!=null){
material.SetFloat(“_BlurSize”,blurSize);
material.SetMatrix(_PreviousViewProjectionMatrix”,previousViewProjectionMatrix);
Matrix4*4 currentViewProjectionMatrix=camera.projectionMatrix*camera.worldToCameraMatrix;
Matrix 4*4 currentViewProjectionInverseMatrix=currentViewProjectionMatrix.inverse;
material.SetMaterix(“_CurrentViewProjectionInverseMatrix”,currentViewProjectionInverseMatrix);
proviousViewProjectionMatrix=currentViewProjectionMatrix;
Graphics.Blit(src,dest,material);}else{
Graphics.Blit(src,dest);
}


}
首先传递运动模糊的属性,然后使用了两个变换矩阵,前一帧的视角*投影矩阵和当前帧的视角投影矩阵。然后camera.worldToCamera和camera.projectionMatrix分别求视角矩阵和投影矩阵相乘后再取逆矩阵。
接下来就是最重要的shader实现了。

Properties{
_MainTex(“Base(RGB)”,2D)=”white”{}
_BlurSize(“Blur Size”,Float)=1.0
}
SubShader{
CGINCLUDE
#include”UnityCG.cginc”
sampler2D _MainTex;
half4 _MainTex_TexelSize;
sampler2D _CameraDepthTexture;
float4x4 _CurrentViewProjectionInverseMatrix;
float4x4 _PreviousViewProjectionMatrix;
half _BlurSize;


这里就相比之前多了三个属性_CameraDepthTexture是Unity传给我们的深度纹理,另外两个由脚本传递

struct v2f {
float4 pos:SV_POSITION;
half2 uv:TEXCOORD0;
half2 uv_depth:TEXCOORD1;
};
v2f vert(appdata_img v) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, 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);//获取像素深度值
float4 H = float4(i.uv.x * 2 - 1, i.uv.y * 2 - 1, d * 2 - 1, 1);//使用原函数的反函数
float4 D = mul(_CurrentViewProjectionInverseMatrix, H);
float4 worldPos = D / D.w;
float4 currentPos = H;
float4 previousPos = mul(_PreviousViewProjectionMatrix, worldPos);
previousPos /= previousPos.w;
float2 velocity = (currentPos.xy - previousPos.xy) / 2.0f;//求得两个帧之间的速度
float2 uv = i.uv;
float4 c = tex2D(_MainTex, uv);
uv += velocity*_BlurSize;
for (int it = 1; it < 3; it++, uv += velocity*_BlurSize) {
float4 currentColor = tex2D(_MainTex, uv);
c += currentColor;
}
c /= 3;
return fixed4(c.rgb, 1.0);
}
ENDCG
片元着色器是重点,我们首先利用深度纹理和当前帧视角*投影矩阵的逆矩阵来求世界空间下坐标,然后根据两帧之间世界坐标距离求得速度,最后利用该速度值与领域像素进行采样,相加后去取平均值得到一个模糊的效果。
Pass{
ZTest Always Cull Off ZWrite Off
CGPROGRAM

pragma vertex vert

pragma fragment frag

ENDCG
}
}
FallBack Off
}运行结果如下:
这里写图片描述

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 、 1资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READmE.文件(md如有),本项目仅用作交流学习参考,请切勿用于商业用途。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值