2015-07-21 17:48:37 lj820348789 阅读数 3469

这是本人在学习unity的shader的一些理解,效果图如下


核心代码为

void surf (Input IN, inout SurfaceOutput o) {
fixed4 t = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = t.rgb;
o.Alpha = t.a;  
half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal));
o.Emission= _RimColor.rgb * pow (rim, _RimWidth); 
}

我们便来理解一下这些代码的意思

dot (normalize(IN.viewDir), o.Normal))这是将视口向量与模型的法线做一个点积分,点积的结果是两个向量夹角的余弦值,

由上图,可知道,越是与视口方向偏离角度大的,点积之后结果越小,所以1.0 - saturate(dot (normalize(IN.viewDir), o.Normal));这是一个递增函数,越往边缘越大。最后o.Emission= _RimColor.rgb * pow (rim, _RimWidth); 可以得到漫反射

2016-06-05 16:19:35 datealive 阅读数 4953

Unity3D实现粒子光环效果


参考效果: http://i-remember.fr/en
基本思路如下
1. 使用unity3d自带的粒子系统
2. 为圆环设置最大半径maxR和最小半径minR
3. 使用x=R*sin(angle), y=R*cos(angle)来计算每个粒子的坐标
4. 将粒子数组设置到选定的粒子系统中

下面说说具体步骤

一.
设置Main Camera的投影方式为正交投影,将背景设置为黑色,方便观察粒子效果
摄像机设置

接着新建一个Empty GameObject,用来挂载粒子系统,注意这个空物体要放在摄像机的投影范围内,为这个物体添加粒子系统,并且按图中方式设置粒子系统
粒子系统设置
主要是要将Looping选项和Play OnAwake选项去掉,同时把Emission Rate设为0

二.
新建C#脚本,用来控制粒子系统
定义点结构,用来表示粒子的坐标信息

public class Point {
    public float angle;
    public float radius;

    private float x = 0.0f;
    private float y = 0.0f;


    public void Cal() {
        float temp = angle / 180.0f * Mathf.PI;
        y = radius * Mathf.Sin(temp);
        x = radius * Mathf.Cos(temp);
    }
    public Point(float angle, float radius) {
        this.angle = angle;
        this.radius = radius;
    }

    public float getX() {
        return x;
    }

    public float getY() {
        return y;
    }
}

三.
声明粒子系统和粒子系统的相关参数

    private ParticleSystem particleSystem;
    //粒子数组
    private ParticleSystem.Particle[] particleArray;
    //粒子坐标集合
    private Point[] points;

    //颜色梯度
    public Gradient grad;
    //控制透明度的变化
    private GradientAlphaKey[] gradAplp;
    //控制颜色的变化
    private GradientColorKey[] gradCol;

    //粒子参数
    public int count = 1000;
    public float size = 0.5f;
    public float minRadius = 5.0f;
    public float maxRadius = 12.0f;
    //控制主方向是顺时针还是逆时针
    public bool clockwise = true;
    public float speed = 0.5f;

四:
初始化粒子坐标,在一开始就生成一个圆环

private void Init() {
        int i;
        for (i = 0; i < count; i++) {
            float midRadius = (minRadius + maxRadius) / 2.0f;
            float minRate = Random.Range(1.0f, midRadius / minRadius);
            float maxRate = Random.Range(midRadius / maxRadius, 1.0f);
            float radius = Random.Range(minRadius * minRate, maxRadius * maxRate);
            float angle = Random.Range(0.0f, 360.0f);
            points[i] = new Point(angle, radius);
            points[i].Cal();
            particleArray[i].position = new Vector3(points[i].getX(), points[i].getY(), 0f);
        }

        particleSystem.SetParticles(particleArray, particleArray.Length);
}

这里为了让粒子尽量集中在圆环的中间,首先计算出最大半径和最小半径之间的平均值,这个值就是圆环的中间,分别求出一个在最小半径和中间之间的一个随机比率以及中间值和最大半径之间的一个随机比率,再在这两个随机比率对应的半径值之间求出一个随机值就可以让粒子的坐标集中在中间值附近,根据概率的知识可知,求出的两个随机比率是符合正太分布的,所以这两个比率的中间值也是接近于圆环的中间,由于这两个比率对应的半径值中选取随机数也是符合正太分布的,所以会让大部分粒子集中在圆环中间的位置

四:
设置颜色梯度,我希望圆环在运动的时候能够根据当前的位置对颜色和透明度做出相应的变化

// Update is called once per frame
    void Update () {
        int i;
        int level = 7; //将整个粒子系统分成七层,每一层的旋转方向和速度都有差异
        for (i = 0; i < count; i++) {

            if (i % level > 3)
            {
                //外层顺时针旋转
                points[i].angle -= (i % level + 1) * speed;
            } else {
                //内层逆时针旋转
                points[i].angle += (i % level + 1) * speed;
            }

            points[i].angle = (points[i].angle + 360.0f) % 360.0f;
            //粒子旋转半径的微小变化,能够让粒子运动体现出随机性
            points[i].radius += 0.04f * (Mathf.PerlinNoise(points[i].angle/360.0f, 0.0f))-0.02f;
            //Debug.Log(points[i].radius);
            points[i].Cal();
            particleArray[i].color = grad.Evaluate(Time.time*0.1f);
            particleArray[i].position = new Vector3(points[i].getX(), points[i].getY(), 0.0f);
        }
        particleSystem.SetParticles(particleArray, particleArray.Length);
}

这里面为了实现样例中的效果,需要让不同层次的粒子旋转方向不同,所以我将粒子分成了7层,每一层都有自己的旋转方向,当然这里还可调整旋转增量的参数,让旋转增量和运动半径产生关联,实现外围的粒子半径增量更大的效果,同时我使用Perlin噪声让粒子的运动半径发生随机的改变,然粒子的运动看起来更加无序,当然每次Update也需要重新计算梯度的变化

最终效果(不同时期的运行效果,可以看到粒子的运行半径和圆环形状,透明度等都有变化):
这里写图片描述

这里写图片描述

这里写图片描述

完整代码

using UnityEngine;
using System.Collections;


public class Point {
    public float angle;
    public float radius;

    private float x = 0.0f;
    private float y = 0.0f;


    public void Cal() {
        float temp = angle / 180.0f * Mathf.PI;
        y = radius * Mathf.Sin(temp);
        x = radius * Mathf.Cos(temp);
    }
    public Point(float angle, float radius) {
        this.angle = angle;
        this.radius = radius;
    }

    public float getX() {
        return x;
    }

    public float getY() {
        return y;
    }
}
public class PCircle : MonoBehaviour {

    private ParticleSystem particleSystem;
    //粒子数组
    private ParticleSystem.Particle[] particleArray;
    //粒子坐标集合
    private Point[] points;

    //颜色梯度
    public Gradient grad;
    //控制透明度的变化
    private GradientAlphaKey[] gradAplp;
    //控制颜色的变化
    private GradientColorKey[] gradCol;

    //粒子参数
    public int count = 1000;
    public float size = 0.5f;
    public float minRadius = 5.0f;
    public float maxRadius = 12.0f;
    //控制主方向是顺时针还是逆时针
    public bool clockwise = true;
    public float speed = 0.5f;

    private void Init() {
        int i;
        for (i = 0; i < count; i++) {
            float midRadius = (minRadius + maxRadius) / 2.0f;
            float minRate = Random.Range(1.0f, midRadius / minRadius);
            float maxRate = Random.Range(midRadius / maxRadius, 1.0f);
            float radius = Random.Range(minRadius * minRate, maxRadius * maxRate);
            float angle = Random.Range(0.0f, 360.0f);
            points[i] = new Point(angle, radius);
            points[i].Cal();
            particleArray[i].position = new Vector3(points[i].getX(), points[i].getY(), 0f);
        }

        particleSystem.SetParticles(particleArray, particleArray.Length);
    }
    // Use this for initialization
    void Start () {
        particleSystem = this.GetComponent<ParticleSystem>();
        particleArray = new ParticleSystem.Particle[count];
        points = new Point[count];
        particleSystem.startSpeed = 0;
        particleSystem.startSize = size;
        particleSystem.maxParticles = count;
        particleSystem.Emit(count);
        particleSystem.GetParticles(particleArray);

        grad = new Gradient();
        gradAplp = new GradientAlphaKey[5];
        gradCol = new GradientColorKey[5];
        float delt = 0f;
        //设置梯度变化有五个程度,且是均匀变化
        for (int i = 0; i < 5; i++) {
            gradAplp[i].time = delt;
            gradAplp[i].alpha = delt;
            delt += 0.2f;
        }

        gradCol[0].time = 0.0f;
        gradCol[0].color = Color.black;
        gradCol[1].time = 1.0f;
        gradCol[1].color = Color.white;
        grad.SetKeys(gradCol, gradAplp);
        Init();
    }

    // Update is called once per frame
    void Update () {
        int i;
        int level = 7; //将整个粒子系统分成七层,每一层的旋转方向和速度都有差异
        for (i = 0; i < count; i++) {

            if (i % level > 3)
            {
                //外层顺时针旋转
                points[i].angle -= (i % level + 1) * speed;
            } else {
                //内层逆时针旋转
                points[i].angle += (i % level + 1) * speed;
            }

            points[i].angle = (points[i].angle + 360.0f) % 360.0f;
            //粒子旋转半径的微小变化,能够让粒子运动体现出随机性
            points[i].radius += 0.04f * (Mathf.PerlinNoise(points[i].angle/360.0f, 0.0f))-0.02f;
            //Debug.Log(points[i].radius);
            points[i].Cal();
            particleArray[i].color = grad.Evaluate(Time.time*0.1f);
            particleArray[i].position = new Vector3(points[i].getX(), points[i].getY(), 0.0f);
        }
        particleSystem.SetParticles(particleArray, particleArray.Length);
    }
}

当然也可以自己写shader,毕竟unity3d自带的光效还是不太灵活,鉴于水平问题(本人太渣),这里就不做了

2014-11-06 14:04:28 wjb0108 阅读数 1470

Unity3D制作闪关灯效果

                                      

 

代码段:

public GameObject goFlash;//使用的是SpotLight,也可使用其他的效果灯

public float flashDeltaTime = 0.01f; //闪光时间间隔

 

 

   public void AutoFlash() //自动闪光调用方法

   {

      StartCoroutine(Flash());

   }

 

   IEnumerator Flash() //自动闪光实现

   {

       if(goFlash != null)

       {

           for (int i=0; i < 4; i++)

           {

                goFlash.SetActive(i%2 == 0);// 开关控制

               

                yield return newWaitForSeconds(flashDeltaTime);

           }

       }

   }

2018-10-09 15:37:47 zouxin_88 阅读数 5523

1.新建工程,在Asset Store下载Legacy Image Effects,导入工程。
2.在Camera上加上Bloom脚本。调节Bloom参数就可以看到自发光(荧光效果)了。

3.通过步骤2发现,只要高亮度的物体都有自发光效果,包括天空盒子。有一种初略的过略方式:新建Shader,新建Material,将Shader附在材质上,通过调节Material的Intensity和Bloom上的Threshold实现过滤,这种过滤方式比较粗,要更细致的过滤方式需要自己进一步开发。

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Glow" {
    Properties {
        _MainTex ("Texture", 2D) = "white" {}
        _Color ("Color", Color) = (1,1,1,1)
        _Glow ("Intensity", Range(0, 3)) = 1
    }
    SubShader {
        Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" }
        LOD 100
        Cull Off
        ZWrite On
        Blend SrcAlpha OneMinusSrcAlpha

        Pass {
            CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag

                sampler2D _MainTex;
                half4 _MainTex_ST;
                fixed4 _Color;
                half _Glow;

                struct vertIn {
                    float4 pos : POSITION;
                    half2 tex : TEXCOORD0;
                };

                struct v2f {
                    float4 pos : SV_POSITION;
                    half2 tex : TEXCOORD0;
                };

                v2f vert (vertIn v) {
                    v2f o;
                    o.pos = UnityObjectToClipPos(v.pos);
                    o.tex = v.tex * _MainTex_ST.xy + _MainTex_ST.zw;
                    return o;
                }

                fixed4 frag (v2f f) : SV_Target {
                    fixed4 col = tex2D(_MainTex, f.tex);
                    col *= _Color;
                    col *= _Glow;
                    return col;
                }
            ENDCG
        }
    }
}

 

2019-03-01 16:29:42 q764424567 阅读数 1014

一、前言

本篇文章讲的是如何让3D物体放光的方法

二、效果

在这里插入图片描述
在这里插入图片描述

三、实现

这个是一个插件,但是主要就是这几个脚本加Shader
在这里插入图片描述
资源包下载:
链接:https://pan.baidu.com/s/1mfZWPsUsbgvH2ACUTBW7Hg
提取码:5207
或者
https://download.csdn.net/download/q764424567/11188790

操作步骤

1.主摄像机上面添加HighlightingEffect脚本
在这里插入图片描述
2.要发光的物体上面添加这两个脚本
在这里插入图片描述

OK,搞定了

没有更多推荐了,返回首页