1. 程式人生 > >unityShader物體表面流光效果

unityShader物體表面流光效果

本文轉載自http://blog.csdn.net/lyh916/article/details/51831720

參考連結:http://liweizhaolili.blog.163.com/blog/static/162307442012726111843408/

效果圖:


1.首先,匯入unity自帶的模型,如下圖,它使用的是StandardSpecular這個shader,具體的實現可以從unity官網中下載看看。它的實現比較複雜,這裡我們把它替換為我們自己寫的shader,方便我們去控制。對於法線貼圖,注意要設定Texture Type為Normal map。


下面這個shader是漫反射+高光+法線貼圖:

Shader "Custom/Light"
{
    Properties
    {
        _MainColor ("主顏色", Color) = (0.5, 0.5, 0.5, 1)
        _NormalTex ("法線貼圖", 2D) = "white" {}

        _Specular ("高光顏色", Color) = (1, 1, 1, 1)
        _Gloss ("高光係數", Range(8, 256)) = 20
    }
    SubShader
    {
        Tags { "LightMode" = "ForwardBase" }

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "Lighting.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float3 normal : NORMAL;
                float4 tangent : TANGENT;
            };

            struct v2f
            {           
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
                float3 lightDir : TEXCOORD1;
                float3 viewDir : TEXCOORD2;
            };

            fixed4 _MainColor;
            sampler2D _NormalTex;
            fixed4 _Specular;
            float _Gloss;

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

                TANGENT_SPACE_ROTATION;

                //rotation是使模型空間轉為切線空間的矩陣
                o.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex)).xyz;
                o.viewDir = mul(rotation, ObjSpaceViewDir(v.vertex)).xyz;

                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed3 tangentLightDir = normalize(i.lightDir);
                fixed3 tangentViewDir = normalize(i.viewDir);

                fixed4 packedNormal = tex2D(_NormalTex, i.uv);
                fixed3 tangentNormal = UnpackNormal(packedNormal);

                //漫反射
                fixed3 diffuse = _LightColor0.rgb * _MainColor.rgb * saturate(dot(tangentNormal, tangentViewDir));
                //Blinn-Phong高光光照模型,相對於普通的Phong高光模型,會更加光
                fixed3 halfDir = normalize(tangentLightDir + tangentViewDir);
                fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(tangentNormal, halfDir)), _Gloss);

                return fixed4(diffuse + specular, 1);
            }
            ENDCG
        }
    }
}

兩個shader的對比,左邊是模型原本的shader,右邊是上面的shader。左邊的有一種泥瓦的質感,而右邊的有一種金屬的質感。



2.從效果圖中,我們可以發現有邊緣光的效果,因此先加上。

Shader "Custom/Light"
{
    Properties
    {
        _MainColor ("主顏色", Color) = (0.5, 0.5, 0.5, 1)
        _NormalTex ("法線貼圖", 2D) = "white" {}

        _Specular ("高光顏色", Color) = (1, 1, 1, 1)
        _Gloss ("高光係數", Range(8, 256)) = 20

        _RimColor ("邊緣顏色", Color) = (1, 0, 0, 1)
        _RimPower ("邊緣顏色強度", Range(0.1, 1)) = 1
    }
    SubShader
    {
        Tags { "LightMode" = "ForwardBase" }

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "Lighting.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float3 normal : NORMAL;
                float4 tangent : TANGENT;
            };

            struct v2f
            {           
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
                float3 lightDir : TEXCOORD1;
                float3 viewDir : TEXCOORD2;
            };

            fixed4 _MainColor;
            sampler2D _NormalTex;
            fixed4 _Specular;
            float _Gloss;
            fixed4 _RimColor;
            half _RimPower;

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

                TANGENT_SPACE_ROTATION;

                //rotation是使模型空間轉為切線空間的矩陣
                o.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex)).xyz;
                o.viewDir = mul(rotation, ObjSpaceViewDir(v.vertex)).xyz;

                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed3 tangentLightDir = normalize(i.lightDir);
                fixed3 tangentViewDir = normalize(i.viewDir);

                fixed4 packedNormal = tex2D(_NormalTex, i.uv);
                fixed3 tangentNormal = UnpackNormal(packedNormal);

                //漫反射
                fixed3 diffuse = _LightColor0.rgb * _MainColor.rgb * saturate(dot(tangentNormal, tangentViewDir));
                //Blinn-Phong高光光照模型,相對於普通的Phong高光模型,會更加光
                fixed3 halfDir = normalize(tangentLightDir + tangentViewDir);
                fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(tangentNormal, halfDir)), _Gloss);

                //邊緣顏色,對於法線和觀察方向,只要在同一座標系下即可
                fixed dotProduct = 1 - saturate(dot(tangentNormal, tangentViewDir));
                fixed3 rim = _RimColor.rgb * pow(dotProduct, 1 / _RimPower);

                return fixed4(diffuse + specular + rim, 1);
            }
            ENDCG
        }
    }
}


3.接著就需要用到遮罩效果,這裡我用到了下面這張遮罩圖。分析一下我們的效果圖,它的邊緣光是流動的,對於某一個位置的邊緣光,隨著時間的變化,它是在有光與無光這兩個狀態不斷變化的,而看一下我們的遮罩圖,以y軸方向來說,它也是黑白兩種狀態的切換,通過對遮罩圖的取樣,就能對邊緣光進行控制了。再說一點,如果我們把遮罩圖改為全白的,那麼就是我們上方那種效果了,不會發生流動。


Shader "Custom/Light"
{
    Properties
    {
        _MainColor ("主顏色", Color) = (0.5, 0.5, 0.5, 1)
        _NormalTex ("法線貼圖", 2D) = "white" {}

        _Specular ("高光顏色", Color) = (1, 1, 1, 1)
        _Gloss ("高光係數", Range(8, 256)) = 20

        _RimColor ("邊緣顏色", Color) = (1, 0, 0, 1)
        _RimPower ("邊緣顏色強度", Range(0.1, 1)) = 1

        _MaskTex ("光遮罩圖", 2D) = "white" {}
        _MoveDir ("邊緣光移動方向", Range(-1, 1)) = 1
    }
    SubShader
    {
        Tags { "LightMode" = "ForwardBase" }

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "Lighting.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float3 normal : NORMAL;
                float4 tangent : TANGENT;
            };

            struct v2f
            {           
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
                float3 lightDir : TEXCOORD1;
                float3 viewDir : TEXCOORD2;
            };

            fixed4 _MainColor;
            sampler2D _NormalTex;

            fixed4 _Specular;
            float _Gloss;

            fixed4 _RimColor;
            half _RimPower;

            sampler2D _MaskTex;
            fixed _MoveDir;

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

                TANGENT_SPACE_ROTATION;

                //rotation是使模型空間轉為切線空間的矩陣
                o.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex)).xyz;
                o.viewDir = mul(rotation, ObjSpaceViewDir(v.vertex)).xyz;

                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed3 tangentLightDir = normalize(i.lightDir);
                fixed3 tangentViewDir = normalize(i.viewDir);

                fixed4 packedNormal = tex2D(_NormalTex, i.uv);
                fixed3 tangentNormal = UnpackNormal(packedNormal);

                //漫反射
                fixed3 diffuse = _LightColor0.rgb * _MainColor.rgb * saturate(dot(tangentNormal, tangentViewDir));
                //Blinn-Phong高光光照模型,相對於普通的Phong高光模型,會更加光
                fixed3 halfDir = normalize(tangentLightDir + tangentViewDir);
                fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(tangentNormal, halfDir)), _Gloss);

                //邊緣顏色,對於法線和觀察方向,只要在同一座標系下即可
                fixed dotProduct = 1 - saturate(dot(tangentNormal, tangentViewDir));
                fixed3 rim = _RimColor.rgb * pow(dotProduct, 1 / _RimPower);

                fixed4 maskCol = tex2D(_MaskTex, i.uv + float2(0, _Time.y * _MoveDir));

                return fixed4(diffuse + specular + rim * maskCol.rgb, 1);
            }
            ENDCG
        }
    }
}

這是unitypackage:

http://pan.baidu.com/s/1mh9T1l2

相關推薦

unityShader物體表面效果

本文轉載自http://blog.csdn.net/lyh916/article/details/51831720 參考連結:http://liweizhaolili.blog.163.com/blog/static/162307442012726111843408/ 效果圖: 1.首先,匯入un

Unity Shader 模型效果

gin coord 技術 mali pass pda class hit geo Shader "Custom/FlowColor" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _Flow

文字效果

<!doctype html> <html> <head> <meta charset="utf-8"> <title>文字流光效果</title> <script src="http://libs.baidu.com/j

Unity Shader-邊緣檢測效果(基於顏色,基於深度法線,邊緣效果,轉場效果

前言 週末通關了一個小遊戲,流程很短,6個小時左右就通關,但是遊戲的畫風,視角,玩法都比較新奇,對了,遊戲的名字也很奇特《12 Is Better Than 6》(12比6好是有什麼梗嗎?)。 遊戲採用的是俯視角,人物在活著的時候基本只能看到個帽子,玩法類似很早玩的《

【複習筆記】 cocos2d-x 2.x 渲染特效實現 八 效果

簡單來說,流光效果就是在貼圖上利用glowmap在原貼圖上的移動做動態的發亮效果,來讓貼圖看起來有光亮在移動。為了讓貼圖上的亮斑的排布看起來更加貼近自然,我們利用柏林噪聲來生成glowmap。事實上,二維或者三維的柏林噪聲在圖形學上有很多的應用,它可以用來描述很多自然的數學

shader 效果

Shader "Custom/FlashUV" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _Layer1Tex("Layer1",2D) = "white"{} _Color("Color"

NGUI相關----UITexture圖片邊緣效果

寫在前面     文章來源為http://blog.csdn.net/blinkseed        大概已經有兩個星期沒寫文章了,中間又搞了幾個效果,但完全沒時間總結         本人入行時間比較奇葩,本來新人都是一開始搞NGUI的,但我一開始就是搞實景,導致幾乎對

Unity3D開發(九):Unity3d效果

遊戲開發群:201276069 之前曾經注意過Material中紋理的屬性都有Tiling和Offset,但沒有深究過其用途,今天才知道竟然可以利用Offset做uv動畫,從而完成各種有趣的動畫,比如流光效果! 流過效果即通常一條高光光在物體上劃過,模擬高光移動照射物體

2D效果

Shader例項:2D流光 準備: 1.一張背景圖 2.一張流光圖 3.一張過濾圖 like this: 效果: 程式碼: 複製程式碼 Shader “Custom/2d_flow” { Properties {

Unity LOGO效果

之前寫過一篇LOGO流光的shader,原理幾乎是一樣的,今天我又翻出來優化了一下,為了讓效果看起來更有質感,不那麼突兀,或者說是不那麼直接的讓人看出來原理就是將一張斜著的作為流光的圖片放在上面移動,為此我做了一點改動。 我們讓流光劃過的位置呈現出一種凸起的樣

unity--滑鼠放上顯示物體資訊和物體效果

滑鼠放在物體上顯示資訊程式碼 using UnityEngine; using System.Collections; public class info : MonoBehaviour { bool isShowInfo; public GUISty

使用法實現物體跟蹤

簡介   本篇講解使用opencv提供的流光法演算法介面,實現物體跟蹤。範例程式碼為參考修改tvl1_optical_flow.cpp實現。 具體實現 實現程式碼 #include <iostream> #include <fstream>

css實現滑鼠懸浮字型背景模糊效果

原文地址:→看過來 寫在前面 有的時候感覺寫點小玩意兒挺開心的,還能實踐很多的小知識點,所以這次學著寫了個有趣的滑鼠懸浮模糊效果,只使用了css額。 效果圖 原始碼地址→傳送門 預覽地址→傳送門 小知識點 filter: blur(

shader 和 +扭曲shader

針對 targe for 分享 posit stream ans dir sky 我認為這種shader能通過簡單的方式呈現出不錯的效果。 1.流光shader: Shader "Unlit/StreamShader" { //流光shader Prope

讓文字發出炫酷的效果

round 分享 bgp 發出 .com gre bsp mask ini .colorful { /* -webkit-mask-image: linear-gradient(to right, red, orange, yellow, green, cyan, b

【unity實用技能】unity在遊戲中更換角色的shader,比如加個

無原本想著這個功能怎麽實現,剛好在項目裏看到這裏記錄一下。 首先項目的模型裏會有一個基本的Material,這個就是美術出給你的模型的材質。 可能有的需求是在遊戲中觸發一個事件,你身上加個流光或者描邊等效果。 我們知道這些效果如果要表現在身上,用特效是不好看的,要用Shader去表現。 這時候就需要你換一個S

text-stroke實現文字描邊(鏤空)、text-fill-color實現文字填充&漸變(+animation實現字體)

stroke 顏色 width mas key ani kit mat idt text-stroke:<‘ text-stroke-width ‘> || <‘ text-stroke-color ‘>(text-stroke-width:設置或檢

Shader_ShaderForge_NGUI_&波紋&消融

lamp bool ase NPU oid a* pri star ora Shader篇   總結:總算解決了NGUI中Shader不能實時更改的問題,原來NGUI中的Texture組件提供了OnRender代碼示例如下 /*******************

android 自定義TextView 字,彩色text

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="ht

| 參考文獻

[1]Bruhn A, Weickert J, Kohlberger T, et al. A Multigrid Platform for Real-Time Motion Computation with Discontinuity-Preserving Variational Methods