[UnityShader3]彩光效果

参考链接:http://blog.csdn.net/stalendp/article/details/40690185

效果图:

这里我把它分三部分实现:1.彩色 2.光圈 3.动画

1.先实现彩色效果。分析一下那张彩色图,它是以中心为原点的,然后颜色分为三部分,如下图。当角度为90度时,蓝色最多;当角度为-150度时,红色最多;当角度为-30度时,绿色最多。然后其他地方就是三色混合。

Shader "Custom/Colors"
{
	Properties
	{
		_AngleRange ("AngleRange", Range(60, 120)) = 60
	}
	SubShader
	{
		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"

			#define PI 3.142

			struct appdata
			{
				float4 vertex : POSITION;
			};

			struct v2f
			{
				float4 vertex : SV_POSITION;
				float4 scrPos : TEXCOORD0;
			};

			half _AngleRange;

			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
				o.scrPos = ComputeScreenPos(o.vertex);

				return o;
			}

			fixed4 frag (v2f i) : SV_Target
			{
				//范围在(0, 1)
                float2 wcoord = i.scrPos.xy / i.scrPos.w;
                //映射到(-1, 1),即屏幕中心为(0, 0)
                wcoord = wcoord * 2 - 1;
                //atan2(y, x):反正切,y/x的反正切范围在[-π, π]内
                float radian = atan2(wcoord.y, wcoord.x);
				//1度(°)=0.017弧度(rad)
				//1弧度(rad)=57.29578度(°)
				float angle = radian * 57.3;
				//映射到(0, 360)
				if(angle < 0) angle = 360 + angle;

				fixed b = 1 - saturate(abs(angle - 90) / _AngleRange);
				fixed g;
				if(angle > 180) g = 1 - saturate(abs(angle - 330) / _AngleRange);
				else g = 1 - saturate((angle + 30) / _AngleRange);
				fixed r = 1 - saturate(abs(angle - 210) / _AngleRange);

				return fixed4(r, g, b, 1);
			}
			ENDCG
		}
	}
}

2.先说一下1 / (xxx)这个式子的强大,它实现的效果,往往会带有光晕效果。其中第六个就是我们想要实现的光圈效果。

Shader "Custom/Test"
{
	Properties
	{
		_Value ("Value", Range(1, 50)) = 1
	}
	SubShader
	{
		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

			struct v2f
			{
				float4 vertex : SV_POSITION;
				float2 uv : TEXCOORD0;
			};

			half _Value;

			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
				o.uv = v.uv;
				return o;
			}

			fixed4 frag (v2f i) : SV_Target
			{
				//映射到(-1, 1),使其中心点为原点
				float2 uv = i.uv * 2 - float2(1, 1);
				float v;

				//v = 1 / abs(_Value * uv.y);//1
				//v = 1 / abs(_Value * (uv.y + uv.x));//2
				//v = 1 / abs(_Value * (uv.y + 2 * uv.x));//3
				//v = 1 / abs(_Value * (abs(uv.y) + abs(uv.x)));//4
				//v = 1 / abs(_Value * length(uv));//5
				//v = 1 / abs(_Value * abs(length(uv) - 0.5));//6
				v = 1 / abs(_Value * abs(uv.x / uv.y));//7 x越小y越大,则越亮

				return fixed4(v, v, v, 1);
			}
			ENDCG
		}
	}
}

3.动画。这里我做的效果是基于角度的光线间隔效果,首先当然就是计算角度了,间隔的实现就是fmod和step的使用。

Shader "Custom/Test"
{
	Properties
	{
		_Width ("Width", Range(30, 90)) = 45
	}
	SubShader
	{
		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

			struct v2f
			{
				float4 vertex : SV_POSITION;
				float2 uv : TEXCOORD0;
			};

			half _Width;

			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
				o.uv = v.uv;
				return o;
			}

			fixed4 frag (v2f i) : SV_Target
			{
				//映射到(-1, 1),使其中心点为原点
				float2 uv = i.uv * 2 - float2(1, 1);

				float a = atan2(uv.y, uv.x);
				a *= 57.3;
				if(a < 0) a += 360;

				float b = fmod(a + _Time.y * 20, _Width);
				b = step(0.5 * _Width, b);

				return fixed4(b, b, b, 1);
			}
			ENDCG
		}
	}
}

4.最后当然就是将它们揉在一起了。

Shader "Custom/Colors"
{
	Properties
	{
		_AngleRange ("AngleRange", Range(60, 120)) = 60
		_Width ("Width", Range(30, 90)) = 45
	}
	SubShader
	{
		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"

			#define PI 3.142

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

			struct v2f
			{
				float4 vertex : SV_POSITION;
				float4 scrPos : TEXCOORD0;
				float2 uv : TEXCOORD1;
			};

			half _AngleRange;
			half _Width; 

			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
				o.scrPos = ComputeScreenPos(o.vertex);
				o.uv = v.uv; 

				return o;
			}

			fixed4 frag (v2f i) : SV_Target
			{
				//1.彩色

				//范围在(0, 1)
                float2 wcoord = i.scrPos.xy / i.scrPos.w;
                //映射到(-1, 1),即屏幕中心为(0, 0)
                wcoord = wcoord * 2 - 1;
                //atan2(y, x):反正切,y/x的反正切范围在[-π, π]内
                float radian = atan2(wcoord.y, wcoord.x);
				//1度(°)=0.017弧度(rad)
				//1弧度(rad)=57.29578度(°)
				float angle = radian * 57.3;
				//映射到(0, 360)
				if(angle < 0) angle = 360 + angle;

				fixed b = 1 - saturate(abs(angle - 90) / _AngleRange);
				fixed g;
				if(angle > 180) g = 1 - saturate(abs(angle - 330) / _AngleRange);
				else g = 1 - saturate((angle + 30) / _AngleRange);
				fixed r = 1 - saturate(abs(angle - 210) / _AngleRange);

				//2.光圈

				//映射到(-1, 1),使其中心点为原点
                float2 uv = i.uv * 2 - float2(1, 1);
                float v = 1 / abs(30 * abs(length(uv) - 0.3));

				//3.转动

				float a = atan2(uv.y, uv.x);
                a *= 57.3;
                if(a < 0) a += 360;  

                float aa = fmod(a + _Time.y * 20, _Width);
                aa = step(0.5 * _Width, aa);  

				//////////////////////
				//////////////////////
				if(length(uv) < 0.3) return fixed4(0, 0, 0, 1);
				return fixed4(r, g, b, 1) * aa + fixed4(v, v, v, 1);
			}
			ENDCG
		}
	}
}
时间: 2024-12-31 03:47:53

[UnityShader3]彩光效果的相关文章

CSS3实现文字扫光效果

本篇文章由:http://xinpure.com/css3-text-light-sweep-effect/ CSS3 实现的文字扫光效果,几乎可以和 Flash 相媲美了 效果解析 我们分析一下实现这个效果需要实现的功能: 实现一个扫光背景块,因为光是移动的,所以要加入渐变效果 (例如: 手电筒照射的一小块区域) 将扫光背景块控制到文本上 (即实现文本背景) 实现扫光动画 (扫光块从左往右循环移动) 思路理清了,接下来就是一步一步实现了 背景渐变 -webkit-linear-gradient

CSS3动画:流彩文字效果+图片模糊效果+边框伸展效果实现

前言 首先第一步,先布局html代码如下: <div class="wrap"> <img src="images/1.jpg" class="blur"/> <div class="text-gradient ">天赐神功</div> <div class="border"></div> </div> 上面一看第一个图片i

Unity3d之遛光效果

所谓遛光效果,如一个图片上一条刀光从左闪到右边,以下为实现代码: c#代码: using System; using UnityEngine; public class WalkLightEffect : MonoBehaviour { public Texture MainTex; public Texture LightTex; public float Duration; public float LightULen; public Vector2 Size; bool m_play; f

Android彩蛋效果,微信彩蛋效果

根据Android源码修改,具有微信彩蛋效果 主要代码 public static class Board extends FrameLayout { public static final boolean FIXED_STARS = true; // 控制数量 public static final int NUM_CATS = 30; static Random sRNG = new Random(); static float lerp(float a, float b, float f)

使用CALayer制作View的辉光效果

使用CALayer制作View的辉光效果 实现以下的辉光效果: 思路是这样子的: 1. 创建好需要实现辉光效果的View 2. 对这个View进行截图 3. 将这个截图重新添加进View中 4. 对这个截图实现改变透明度的动画 ViewController.m // // ViewController.m // // Copyright (c) 2013 Nick Jensen. All rights reserved. // #import "ViewController.h" #i

刀光效果

今天的成果,模型来自DMC鬼泣,没有用unity的拖尾 球形插值的刀光mesh,效果不会太硬 非球形插值的刀光mesh 没有附加材质,纯扭曲的刀光shader 有时间还需要修改..

iOS 开发 - 绘制辉光效果

如何使曲线有辉光(荧光?)效果(glow)? 试了各种方法,最终有一点效果,觉得值得记录一下,如下. 1.最开始,我想是不是用shadow可以实现,事实证明,shadow 太淡,不醒目,如果多次shadow叠加,可加重一点,但性能不好,放弃: 2.然后想是不是可以用图片沿着path绘制,结果效果也不理想(也许是图片做的不好),性能也不好 3.Spritekit 中 skshapenode 可以设置辉光,而且可以设置用texture绘制,貌似可以解决问题,但是当线段之间夹角太小时,结合部位的辉光可

支持辉光效果的Label

效果 源码 https://github.com/YouXianMing/UI-Component-Collection 中的 FBGlowLabel // // FBGlowLabel.h // // Created by YouXianMing on 16/8/3. // Copyright © 2016年 YouXianMing. All rights reserved. // // https://github.com/lyokato/fbglowlabel // #import <UI

【转】实现Fruit Ninja 的刀光效果

实现思路:√ 从多点触摸得到划过的轨迹,控制点数量,一般使用队列,新的点挤出队尾的点. 这里表示为point[16]; √ 循环;  point和point[i+1]构成直线l, 计算直线的斜率, 从斜率得到夹角θ(可以温习极坐标),从而得到l的法线方程(Xcosθ+ysinθ-p=0);以宽度W(-W),沿着法线方向平移point, 得到2条平移的轨迹.这里的W的绝对值,头部应该宽些,尾部收缩到0. 关键算法,高手就看个笑话. 1 CGPoint pt = ccpSub(p1, p2); 2