开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

开发者专栏

关注:1963

当前位置:游戏蛮牛 技术专区 开发者专栏

__________________________________________________________________________________
开发者干货区版块规则:

  1、文章必须是图文形式。(至少2幅图)
      2、文章字数必须保持在1500字节以上。(编辑器右下角有字数检查)
      3、本版块只支持在游戏蛮牛原创首发,不支持转载。
      4、本版块回复不得无意义,如:顶、呵呵、不错......【真的会扣分的哦】
      5、......
__________________________________________________________________________________
查看: 3087|回复: 62

[zhang273162308] Unity&Shader案例篇—膨胀效果

[复制链接]  [移动端链接]
排名
111
昨日变化

108

主题

526

帖子

6227

积分

Rank: 9Rank: 9Rank: 9

UID
3579
好友
87
蛮牛币
2864
威望
0
注册时间
2013-9-10
在线时间
1286 小时
最后登录
2017-10-18

专栏作家社区QQ达人活力之星游戏蛮牛QQ群会员蛮牛哥

发表于 2017-1-8 17:22:13 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x
本帖最后由 zhang273162308 于 2017-8-13 19:27 编辑

一、前言
       使用的是.3.3的版本,首先,来看一下效果图,如图所示:

GlowEffect.gif

这个效果要使得摄像机的Clear Flags为Solid Color模式,如果为其他模式可能会看不到外部那一圈光环。

二、实现原理

1、Shader部分:将需要使用两个Pass块,两个Pass块里输出的颜色不同,并最终使用透明度混合得到最后输出的像素颜色。

●第一个Pass块:这个Pass块顶点和片段程序都比较简单,代码如下

[C#] 纯文本查看 复制代码
Pass{
                Tags{ "LightMode" = "ForwardBase" }

                CGPROGRAM

#pragma vertex vert 
#pragma fragment frag


                 float4 _Color;

        float4 vert(float4 vertexPos : POSITION) : SV_POSITION{
                return mul(UNITY_MATRIX_MVP, vertexPos);
        }

                float4 frag(void) : COLOR{
                return _Color;
        }

        ENDCG
        }

只需将模型的顶点和预设的颜色输出就可以了。

●第二个Pass块:这个pass块相对复杂一点,顶点程序主要的计算内容就是顶点的法线方向和相机观察方向的向量,这两个的点积就是膨胀的强度Strength。通过指数

函数缩放对Strength和透明度opacity进行计算就会得到膨胀的效果。计算的代码部分为:
[C#] 纯文本查看 复制代码
  float3 normalDirectionT = normalize(normalDirection);
                   float3 viewDirectionT = normalize(viewDirection);
                   float strength = abs(dot(viewDirectionT, normalDirectionT));
                   float opacity = pow(strength, _Strength);


而片段程序也是简单的输出最终的颜色就可以,完整的代码如下:


[C#] 纯文本查看 复制代码
Pass{
                Tags{"LightMode" = "ForwardBase"        "Queue" = "Transparent"        "RenderType" = "Transparent"}
        //        Cull Front
                ZWrite Off
        
                Blend SrcAlpha OneMinusSrcAlpha

                CGPROGRAM

#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"

                 float4 _GlowColor;
                 float  _Strength;;
                 float _GlowRange;
        struct vInput {
                float4 vertex : POSITION;
                float4 normal : NORMAL;
        };

        struct v2f {
                float4 position : SV_POSITION;
                float4 col:COLOR;
        };

        v2f vert(vInput i) {
                v2f o;

                float4x4 modelMatrix = _Object2World;
                float4x4 modelMatrixInverse = _World2Object;

                float3 normalDirection = normalize(mul(i.normal, modelMatrixInverse)).xyz;
                float3 viewDirection = normalize(_WorldSpaceCameraPos - mul(modelMatrix, i.vertex).xyz);

                float4 pos = i.vertex + (i.normal * _GlowRange);

                o.position = mul(UNITY_MATRIX_MVP, pos);
                
                float3 normalDirectionT = normalize(normalDirection);
                float3 viewDirectionT = normalize(viewDirection);
                float strength = abs(dot(viewDirectionT, normalDirectionT));
                float opacity = pow(strength, _Strength);

                float4 col = float4(_GlowColor.xyz, opacity);

                o.col = col;

                return o;
        }

        float4 frag(v2f i) : COLOR{
                
                return i.col;
        }

                ENDCG
        }



在第二个Pass块中使用到了ZWrite Off命令,也即关闭遮挡,模型所有的面和通道都会被渲染,如果使用了ZWrite On命令,你会发现好像并没有什么变化,还是可以正

常运行得到前面的效果。这是因为,Cull命令,默认的是Cull Back,即提出背面,不渲染模型的背面。如果使用Cull Front命令,即不渲染模型的前面,渲染的是模型的

背面,得到的效果图如图所示,当然最终的选择就看你想要实现什么样的效果吧。

GlowEffect2.gif.gif

完整的Shader代码:

[C#] 纯文本查看 复制代码
Shader "CgInUnity/Glow"
{
        Properties{
                _Color("Object's Color", Color) = (0, 1, 0, 1)
                _GlowColor("Glow's Color", Color) = (1, 0, 0, 0)
                _Strength("Glow Strength", Range(5.0, 1.0)) = 2.0
                _GlowRange("GlowRange",Range(0.1,1))=0.3
        }
                SubShader{
                Pass{
                Tags{ "LightMode" = "ForwardBase" }

                CGPROGRAM

#pragma vertex vert 
#pragma fragment frag


                 float4 _Color;

        float4 vert(float4 vertexPos : POSITION) : SV_POSITION{
                return mul(UNITY_MATRIX_MVP, vertexPos);
        }

                float4 frag(void) : COLOR{
                return _Color;
        }

        ENDCG
        }

                Pass{
                Tags{"LightMode" = "ForwardBase"        "Queue" = "Transparent"        "RenderType" = "Transparent"}
        //        Cull Front
                ZWrite Off
        
                Blend SrcAlpha OneMinusSrcAlpha

                CGPROGRAM

#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"

                 float4 _GlowColor;
                 float  _Strength;;
                 float _GlowRange;
        struct vInput {
                float4 vertex : POSITION;
                float4 normal : NORMAL;
        };

        struct v2f {
                float4 position : SV_POSITION;
                float4 col:COLOR;
        };

        v2f vert(vInput i) {
                v2f o;

                float4x4 modelMatrix = _Object2World;
                float4x4 modelMatrixInverse = _World2Object;

                float3 normalDirection = normalize(mul(i.normal, modelMatrixInverse)).xyz;
                float3 viewDirection = normalize(_WorldSpaceCameraPos - mul(modelMatrix, i.vertex).xyz);

                float4 pos = i.vertex + (i.normal * _GlowRange);

                o.position = mul(UNITY_MATRIX_MVP, pos);
                
                float3 normalDirectionT = normalize(normalDirection);
                float3 viewDirectionT = normalize(viewDirection);
                float strength = abs(dot(viewDirectionT, normalDirectionT));
                float opacity = pow(strength, _Strength);

                float4 col = float4(_GlowColor.xyz, opacity);

                o.col = col;

                return o;
        }

        float4 frag(v2f i) : COLOR{
                
                return i.col;
        }

                ENDCG
        }
        }
}


2、控制脚本部分C#代码
[C#] 纯文本查看 复制代码
using UnityEngine;
using System.Collections;

public class GlowControl : MonoBehaviour {
    private Material mat;
    private float value;
    [SerializeField]
    float speed=1;

        // Use this for initialization
        void Start () {
        mat = GetComponent<MeshRenderer>().sharedMaterial;
        
        }
        
        // Update is called once per frame
        void Update () {

        value = Mathf.PingPong(Time.time * speed, 5);
      ///  Debug.Log(value);
        mat.SetFloat("_Strength", value);

        
        }
}


就是一个简单控制强度随着时间变换的代码。

三、总结
       这个小小的案例我们学习到了怎么使用多个Pass块来渲染同一个物体,以及在多个Pass块中使用透明度混合。我个人认为是一个非常不错的学习案例,不只是因为

它的代码部分非常简洁明了,更重要的是这个案例在很多应用中也是非常有用的。祝好好学习,慢慢变牛。

最后附上工程下载地址

游客,如果您要查看本帖隐藏内容请回复


Glow.txt (48 Bytes, 下载次数: 34, 售价: 2 蛮牛币)

回复

使用道具 举报

8常驻蛮牛
5966/10000
排名
245
昨日变化

0

主题

3018

帖子

5966

积分

Rank: 8Rank: 8

UID
3215
好友
0
蛮牛币
247
威望
0
注册时间
2013-9-4
在线时间
1326 小时
最后登录
2017-11-17
发表于 2017-1-8 19:05:12 | 显示全部楼层
银行股黄金管灌灌灌灌灌灌灌灌灌灌灌灌灌灌灌

回复 支持 反对

使用道具 举报

3偶尔光临
270/300
排名
6760
昨日变化
6

0

主题

24

帖子

270

积分

Rank: 3Rank: 3Rank: 3

UID
173251
好友
0
蛮牛币
92
威望
0
注册时间
2016-10-2
在线时间
100 小时
最后登录
2017-10-23
发表于 2017-1-8 21:22:45 | 显示全部楼层
很好,谢谢分享

回复

使用道具 举报

6蛮牛粉丝
1244/1500
排名
5280
昨日变化
4

2

主题

775

帖子

1244

积分

Rank: 6Rank: 6Rank: 6

UID
92518
好友
1
蛮牛币
2464
威望
0
注册时间
2015-4-15
在线时间
277 小时
最后登录
2017-4-6
发表于 2017-1-8 23:50:29 | 显示全部楼层
666666666666

回复

使用道具 举报

7日久生情
3052/5000
排名
1444
昨日变化
2

4

主题

1817

帖子

3052

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
182740
好友
0
蛮牛币
4723
威望
0
注册时间
2016-11-10
在线时间
533 小时
最后登录
2017-11-17
发表于 2017-1-9 07:44:20 | 显示全部楼层
谢谢分享!!!!!!

回复

使用道具 举报

3偶尔光临
242/300
排名
12687
昨日变化
6

0

主题

64

帖子

242

积分

Rank: 3Rank: 3Rank: 3

UID
129445
好友
0
蛮牛币
125
威望
0
注册时间
2015-11-20
在线时间
128 小时
最后登录
2017-11-2
发表于 2017-1-9 08:48:38 | 显示全部楼层
好好很好非常好

回复

使用道具 举报

3偶尔光临
242/300
排名
12687
昨日变化
6

0

主题

64

帖子

242

积分

Rank: 3Rank: 3Rank: 3

UID
129445
好友
0
蛮牛币
125
威望
0
注册时间
2015-11-20
在线时间
128 小时
最后登录
2017-11-2
发表于 2017-1-9 08:50:53 | 显示全部楼层
网盘地址有问题  尼玛的

回复 支持 反对

使用道具 举报

5熟悉之中
640/1000
排名
4734
昨日变化
5

0

主题

190

帖子

640

积分

Rank: 5Rank: 5

UID
160770
好友
6
蛮牛币
443
威望
0
注册时间
2016-8-5
在线时间
216 小时
最后登录
2017-11-16
发表于 2017-1-9 09:05:05 | 显示全部楼层
很好,谢谢分享

回复

使用道具 举报

6蛮牛粉丝
1386/1500
排名
1378
昨日变化
1

7

主题

326

帖子

1386

积分

Rank: 6Rank: 6Rank: 6

UID
104110
好友
0
蛮牛币
306
威望
0
注册时间
2015-5-29
在线时间
337 小时
最后登录
2017-11-10
发表于 2017-1-9 09:21:11 | 显示全部楼层
学习一下,谢谢。

回复

使用道具 举报

排名
28834
昨日变化
51

0

主题

20

帖子

52

积分

Rank: 2Rank: 2

UID
181576
好友
0
蛮牛币
80
威望
0
注册时间
2016-11-6
在线时间
24 小时
最后登录
2017-11-15
发表于 2017-1-9 09:35:49 | 显示全部楼层
看到好东西就要学习

回复 支持 反对

使用道具 举报

7日久生情
3151/5000
排名
92
昨日变化
1

0

主题

392

帖子

3151

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
239
好友
4
蛮牛币
5673
威望
0
注册时间
2013-6-6
在线时间
657 小时
最后登录
2017-11-17
发表于 2017-1-9 10:29:13 | 显示全部楼层
good!!!!!!!!!!!

回复

使用道具 举报

6蛮牛粉丝
1007/1500
排名
3246
昨日变化
17

3

主题

114

帖子

1007

积分

Rank: 6Rank: 6Rank: 6

UID
167937
好友
0
蛮牛币
531
威望
0
注册时间
2016-9-10
在线时间
536 小时
最后登录
2017-11-17
发表于 2017-1-9 10:37:00 | 显示全部楼层
感谢分享

回复

使用道具 举报

4四处流浪
429/500
排名
7015
昨日变化
4

0

主题

74

帖子

429

积分

Rank: 4

UID
115241
好友
2
蛮牛币
140
威望
0
注册时间
2015-7-26
在线时间
215 小时
最后登录
2017-11-15
发表于 2017-1-9 11:21:13 | 显示全部楼层
好东西,谢谢分享

回复

使用道具 举报

排名
53009
昨日变化
39

0

主题

13

帖子

15

积分

Rank: 1

UID
200169
好友
0
蛮牛币
32
威望
0
注册时间
2017-1-9
在线时间
0 小时
最后登录
2017-1-9
发表于 2017-1-9 11:22:29 | 显示全部楼层
谢谢分享!

回复

使用道具 举报

6蛮牛粉丝
1229/1500
排名
22304
昨日变化
21

10

主题

674

帖子

1229

积分

Rank: 6Rank: 6Rank: 6

UID
158776
好友
1
蛮牛币
53
威望
0
注册时间
2016-7-26
在线时间
531 小时
最后登录
2017-11-17
发表于 2017-1-9 11:33:13 | 显示全部楼层
谢谢分享
[发帖际遇]: Hao521314 被钱袋砸中进医院,看病花了 2 蛮牛币. 幸运榜 / 衰神榜

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则

快速回复 返回顶部 返回列表