UnityShader使用图像叠加实现运动模糊
程序员文章站
2023-12-06 13:18:04
本文实例为大家分享了unityshader实现运动模糊的具体代码,供大家参考,具体内容如下
1.此代码挂在摄像机上,使摄像机运动起来
using unityen...
本文实例为大家分享了unityshader实现运动模糊的具体代码,供大家参考,具体内容如下
1.此代码挂在摄像机上,使摄像机运动起来
using unityengine; using system.collections; public class translating : monobehaviour { public float speed = 10.0f; public vector3 startpoint = vector3.zero; public vector3 endpoint = vector3.zero; public vector3 lookat = vector3.zero; public bool pingpong = true; private vector3 curendpoint = vector3.zero; // use this for initialization void start () { transform.position = startpoint; curendpoint = endpoint; } // update is called once per frame void update () { transform.position = vector3.slerp(transform.position, curendpoint, time.deltatime * speed); transform.lookat(lookat); if (pingpong) { if (vector3.distance(transform.position, curendpoint) < 0.001f) { curendpoint = vector3.distance(curendpoint, endpoint) < vector3.distance(curendpoint, startpoint) ? startpoint : endpoint; } } } }
2.此代码挂在摄像机上
using system.collections; using system.collections.generic; using unityengine; public class motionblur : posteffectsbase { public shader motionblurshader; private material _motionblurmaterial = null; public material material { get { _motionblurmaterial = checkshaderandcreatematerial(motionblurshader, _motionblurmaterial); return _motionblurmaterial; } } //定义运动模糊在混合图像时使用的模糊参数,值越大,拖尾越明显,但过大会完全替代当前帧的渲染结果,所以最大为0.9 [range(0.0f, 0.9f)] public float bluramount = 0.5f; //定义一个rendertexture类型的变量,保存之前图像叠加的结果 private rendertexture _accumulationtexture; //当脚本不运行时,立即销毁,这样在下一次开始运行时会重新叠加图像 void ondisable() { destroyimmediate(_accumulationtexture); } void onrenderimage(rendertexture src, rendertexture dest) { if (material != null) { //判断用于混合图像的_accumulationtexture是否为空,或者是否与当前屏幕分辨率相等 //如果不满足,需要重新创建 if (_accumulationtexture == null || _accumulationtexture.width != src.width || _accumulationtexture.height != src.height) { //立即销毁当前_accumulationtexture destroyimmediate(_accumulationtexture); //创建一个与当前屏幕分辨率相等的 _accumulationtexture = new rendertexture(src.width, src.height, 0); //由于我们自己控制这个变量的销毁,所以不需要他显示在hierarchy中,也不需要保存在场景中 _accumulationtexture.hideflags = hideflags.hideanddontsave; //使用当前的帧图像初始化_accumulationtexture graphics.blit(src, _accumulationtexture); } //对渲染纹理进行恢复操作,发生在渲染的纹理而该纹理又没有被提前清空或销毁的情况下 //运动模糊每次调用onrenderimage函数,都需要把当前纹理与_accumulationtexture中的图像混合,所以_accumulationtexture不需要被提前清空 _accumulationtexture.markrestoreexpected(); //将参数传给材质 material.setfloat("_bluramount", 1.0f - bluramount); //把当前的屏幕图像叠加到_accumulationtexture graphics.blit(src, _accumulationtexture, material); //把叠加后的图像输出到屏幕 graphics.blit(_accumulationtexture, dest); } else { graphics.blit(src, dest); } } }
3.此shader赋值给代码2
shader "unity shaders book/chapter 12/motionblur" { properties { _maintex ("base (rgb)", 2d) = "white" {} //混合系数 _bluramount("blur amount", float) = 1.0 } subshader { cginclude #include "unitycg.cginc" sampler2d _maintex; fixed _bluramount; //定义顶点着色器 struct v2f { float4 pos : sv_position; half2 uv : texcoord0; }; v2f vert(appdata_img v) { v2f o; o.pos = unityobjecttoclippos(v.vertex); o.uv = v.texcoord; return o; } //定义第一个片元着色器,用于更新渲染纹理的rgb通道部分 fixed4 fragrgb(v2f i) : sv_target{ //将a通道的值设为_bluramount,这样在后面混合时可直接使用透明通道进行混合 return fixed4(tex2d(_maintex, i.uv).rgb, _bluramount); } //定义第二个片元着色器,用于更新渲染纹理的a通道部分 half4 fraga(v2f i) : sv_target{ //直接返回采样结果,为了维护渲染纹理的透明通道值,不让其受到混合时使用的透明度值的影响 return tex2d(_maintex, i.uv); } endcg ztest always cull off zwrite off //第一个pass,用于更新渲染纹理的rgb通道 pass { blend srcalpha oneminussrcalpha colormask rgb cgprogram #pragma vertex vert #pragma fragment fragrgb endcg } //第二个pass,用于更新渲染纹理的a通道 pass { blend one zero colormask a cgprogram #pragma vertex vert #pragma fragment fraga endcg } } fallback off }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。