[Unity]用shader实现画面呈圆形缩放的效果。
2017-12-21 19:26
841 查看
话不多说,先上效果图:
![](https://img-blog.csdn.net/20171221192627457?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXEzMDI3NTYxMTM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
没做动图,大致效果也就是从一个完整的画面逐渐呈圆形缩放至指定大小,最后再放大为一个完整画面的效果。
大概的思路就是,在shader中设置一个固定的uv坐标为圆心,设置一个可变的半径_Radius。然后在C#中动态为_Radius赋值。
![](https://img-blog.csdn.net/20171221193120413?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXEzMDI3NTYxMTM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
然后在shader内通过判断当前传入的uv坐标和圆心坐标的关系,距离大于半径_Radius,则设置目标颜色为纯黑(第一次写shader,不晓得这么说对不对。。。):
![](https://img-blog.csdn.net/20171221193421750?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXEzMDI3NTYxMTM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
至于上图的_ScreenParams.x /和_ScreenParams.y,暂时没搞清楚什么意思,但是不这么写。圆就会被拉伸为椭圆
= =。
最后呢,unity会调用自带的API:OnRenderImage(RenderTexture source, RenderTexture destination),将源贴图向目标贴图进行融合,这个过程是unity自己去调用的。我们不需要手动调用。
具体的使用方法就是,讲下面的脚本挂载到主相机就ok。
刚开始写博客,难免吧啦吧啦说一堆废话,多担待,多担待。。
C#脚本:
Shader:
代码是有参考他人的,一时半会找不到链接了,尴尬。
总之感谢他们。。。
最后,动态设置上述的圆心坐标,可以实现追光灯的效果,具体实现,待我去研究一下。。
--------------------------------------------------分割线-----------------------------------------------------
其实frag函数内没必要用if判断的,而且改成下面的实现方法,会有边缘平滑渐变的一个效果,看起来更舒服些:
float dis = sqrt((x - _Center_X)*(x - _Center_X) + (y - _Center_Y)*(y - _Center_Y));
float t = _Radius - dis;
float rt = 0.5f + _tanh(t * _Sharp) * 0.5f;
float col = float4(rt, rt, rt, rt);
return tex2D(_MainTex, i.uv) * col;
没做动图,大致效果也就是从一个完整的画面逐渐呈圆形缩放至指定大小,最后再放大为一个完整画面的效果。
大概的思路就是,在shader中设置一个固定的uv坐标为圆心,设置一个可变的半径_Radius。然后在C#中动态为_Radius赋值。
然后在shader内通过判断当前传入的uv坐标和圆心坐标的关系,距离大于半径_Radius,则设置目标颜色为纯黑(第一次写shader,不晓得这么说对不对。。。):
至于上图的_ScreenParams.x /和_ScreenParams.y,暂时没搞清楚什么意思,但是不这么写。圆就会被拉伸为椭圆
= =。
最后呢,unity会调用自带的API:OnRenderImage(RenderTexture source, RenderTexture destination),将源贴图向目标贴图进行融合,这个过程是unity自己去调用的。我们不需要手动调用。
具体的使用方法就是,讲下面的脚本挂载到主相机就ok。
刚开始写博客,难免吧啦吧啦说一堆废话,多担待,多担待。。
C#脚本:
using UnityEngine; using System.Collections; public class SceneFadeInOut : MonoBehaviour { public static SceneFadeInOut Instance; public Material ma; public float ChangeSpeed = 1.0f; public float waitTime = 0.8f; private float count; private void Awake() { Instance = this; } // Use this for initialization void Start() { if (ma == null) { ma = new Material(Shader.Find("MyShader/BlackScreen")); } } //测试效果的代码,可以忽略 private void Update() { //if (Input.GetKeyDown(KeyCode.Space)) //{ // StartCoroutine(ChangeEffect()); //} } void OnRenderImage(RenderTexture source, RenderTexture destination) { Graphics.Blit(source, destination, ma); } IEnumerator ChangeEffect() { while (ma.GetFloat("_Radius") >= 0) { count = ma.GetFloat("_Radius") - ChangeSpeed * Time.deltaTime; //count = count <= 0 ? 0 : count; ma.SetFloat("_Radius", count); yield return 0; } yield return new WaitForSeconds(waitTime); while (ma.GetFloat("_Radius") <= 1.5) { count = ma.GetFloat("_Radius") + ChangeSpeed * Time.deltaTime; //count = count >= 1 ? 1 : count; ma.SetFloat("_Radius", count); yield return 0; } yield return 0; } }
Shader:
Shader "MyShader/BlackScreen" { Properties { _Color("Main Color", Color) = (1,1,1,1) _ChangeFloat("改变颜色",Range(0,1)) = 1.0 _MainTex("Base (RGB)", 2D) = "white" {} _Radius("Radius",float)=1.5 _Center_X("Center_X", float) =0.95 _Center_Y("Center_Y", float) = 0.5 } SubShader { Pass { CGPROGRAM #pragma vertex vert_img #pragma fragment frag #include "UnityCG.cginc" fixed4 _Color; sampler2D _MainTex; float1 _ChangeFloat; float _Radius; float _Center_X; float _Center_Y; float4 frag(v2f_img i) : COLOR { float x = i.uv.x*(_ScreenParams.x / _ScreenParams.y); float y = i.uv.y; float dis = sqrt((x - _Center_X)*(x - _Center_X) + (y - _Center_Y)*(y - _Center_Y)); if (dis>_Radius) { float4 col = (0, 0, 0, 0); return col; } return tex2D(_MainTex, i.uv); } ENDCG } } Fallback off }
代码是有参考他人的,一时半会找不到链接了,尴尬。
总之感谢他们。。。
最后,动态设置上述的圆心坐标,可以实现追光灯的效果,具体实现,待我去研究一下。。
--------------------------------------------------分割线-----------------------------------------------------
其实frag函数内没必要用if判断的,而且改成下面的实现方法,会有边缘平滑渐变的一个效果,看起来更舒服些:
float dis = sqrt((x - _Center_X)*(x - _Center_X) + (y - _Center_Y)*(y - _Center_Y));
float t = _Radius - dis;
float rt = 0.5f + _tanh(t * _Sharp) * 0.5f;
float col = float4(rt, rt, rt, rt);
return tex2D(_MainTex, i.uv) * col;
相关文章推荐
- unity shader 实现常见的混合效果
- unity如何实现画面左右反转(镜像)效果
- android 使用BitmapShader实现圆形以及放大镜效果
- Android自定义ImageView实现图片缩放滑动,双击放大缩小,多点触控旋转,圆角矩形,圆形和仿刮刮卡效果
- Unity Shader:实现菲涅尔+色散效果以及相关原理解析
- Unity喷墨效果Shader实现
- UnityShader顶点动画实现Mage-Fiers漂移效果
- Unity Shader——Shader实现大海的波涛效果
- unity shader 实现自由放大缩小效果
- unity 使用shader加rendertexture实现刮刮乐效果
- Unity中使用Shader实现3D打印机效果
- iOS开发中Quartz2D控制圆形缩放和实现刷帧效果
- Unity光晕剑效果的Shader简单实现
- 【Unity Shader】手游中高光效果的几种实现方法
- Unity用Shader实现波浪效果
- unity用shader实现物体的忽隐忽现效果
- 01-实现图片按钮的缩放、动画效果(block的初步应用)
- Unity Shader:用几何着色器实现图元转换,细分,以及粒子系统
- Unity游戏画面品质增强,shader和贴图
- AE二次开发中,过滤后的图层,实现缩放至图层效果