一、实现思路

在正常的漫反射Shader的基础之上,在最终的漫反射颜色值出来之后,再准备一个自发光颜色值,附加上去,即得到了最终的带自发光的颜色值。

公式表达:

最终颜色 = (漫反射系数 x 纹理颜色 x RGB颜色)+自发光颜色

英文公式:

FinalColor=(Diffuse x Texture x RGBColor)+Emissive

二、Surface Shader版边缘发光Shader

源码如下:

Shader "Shader/Surface Rim Shader"

{

//-----------------------------------【属性 || Properties】------------------------------------------

Properties

{

//主颜色 || Main Color

_MainColor("【主颜色】Main Color", Color) = (0.5,0.5,0.5,1)

//漫反射纹理 || Diffuse Texture

_MainTex("【纹理】Texture", 2D) = "white" {}

//凹凸纹理 || Bump Texture

_BumpMap("【凹凸纹理】Bumpmap", 2D) = "bump" {}

//边缘发光颜色 || Rim Color

_RimColor("【边缘发光颜色】Rim Color", Color) = (0.17,0.36,0.81,0.0)

//边缘发光强度 ||Rim Power

_RimPower("【边缘颜色强度】Rim Power", Range(0.6,36.0)) = 8.0

//边缘发光强度系数 || Rim Intensity Factor

_RimIntensity("【边缘颜色强度系数】Rim Intensity", Range(0.0,100.0)) = 1.0

}

//----------------------------------【子着色器 || SubShader】---------------------------------------

SubShader

{

//渲染类型为Opaque,不透明 || RenderType Opaque

Tags

{

"RenderType" = "Opaque"

}

//-------------------------开启CG着色器编程语言段 || Begin CG Programming Part----------------------

CGPROGRAM

//【1】声明使用兰伯特光照模式 ||Using the Lambert light mode

#pragma surface surf Lambert

//【2】定义输入结构 || Input Struct

struct Input

{

//纹理贴图 || Texture

float2 uv_MainTex;

//法线贴图 || Bump Texture

float2 uv_BumpMap;

//观察方向 || Observation direction

float3 viewDir;

};

//【3】变量声明 || Variable Declaration

//边缘颜色

float4 _MainColor;

//主纹理

sampler2D _MainTex;

//凹凸纹理

sampler2D _BumpMap;

//边缘颜色

float4 _RimColor;

//边缘颜色强度

float _RimPower;

//边缘颜色强度

float _RimIntensity;

//【4】表面着色函数的编写 || Writing the surface shader function

void surf(Input IN, inout SurfaceOutput o)

{

//表面反射颜色为纹理颜色

o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb*_MainColor.rgb;

//表面法线为凹凸纹理的颜色

o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));

//边缘颜色

half rim = 1.0 - saturate(dot(normalize(IN.viewDir), o.Normal));

//计算出边缘颜色强度系数

o.Emission = _RimColor.rgb * pow(rim, _RimPower)*_RimIntensity;

}

//-------------------结束CG着色器编程语言段 || End CG Programming Part------------------

ENDCG

}

//后备着色器为普通漫反射 || Fallback use Diffuse

Fallback "Diffuse"

}

稍微琢磨一下就明白,此Shader其实就是用利用了Unity5中封装好的Standard Surface Output结构体中的Emission(自发光)属性,来达到这样的边缘光效果,技术含量很有限。这边附一下Unity5中的SurfaceOutputStandard原型:

// Unity5 SurfaceOutputStandard原型:

struct SurfaceOutputStandard

{

fixed3 Albedo; // 漫反射颜色

fixed3 Normal; // 切线空间法线

half3 Emission; //自发光

half Metallic; // 金属度;取0为非金属, 取1为金属

half Smoothness; // 光泽度;取0为非常粗糙, 取1为非常光滑

half Occlusion; // 遮挡(默认值为1)

fixed Alpha; // 透明度

};

三、可编程Shader版边缘发光Shader

源码如下:

Shader "Shader/Basic Rim Shader"

{

//-----------------------------------【属性 || Properties】------------------------------------------

Properties

{

//主颜色 || Main Color

_MainColor("【主颜色】Main Color", Color) = (0.5,0.5,0.5,1)

//漫反射纹理 || Diffuse Texture

_TextureDiffuse("【漫反射纹理】Texture Diffuse", 2D) = "white" {}

//边缘发光颜色 || Rim Color

_RimColor("【边缘发光颜色】Rim Color", Color) = (0.5,0.5,0.5,1)

//边缘发光强度 ||Rim Power

_RimPower("【边缘发光强度】Rim Power", Range(0.0, 36)) = 0.1

//边缘发光强度系数 || Rim Intensity Factor

_RimIntensity("【边缘发光强度系数】Rim Intensity", Range(0.0, 100)) = 3

}

//----------------------------------【子着色器 || SubShader】---------------------------------------

SubShader

{

//渲染类型为Opaque,不透明 || RenderType Opaque

Tags

{

"RenderType" = "Opaque"

}

//---------------------------------------【唯一的通道 || Pass】------------------------------------

Pass

{

//设定通道名称 || Set Pass Name

Name "ForwardBase"

//设置光照模式 || LightMode ForwardBase

Tags

{

"LightMode" = "ForwardBase"

}

//-------------------------开启CG着色器编程语言段 || Begin CG Programming Part----------------------

CGPROGRAM

//【1】指定顶点和片段着色函数名称 || Set the name of vertex and fragment shader function

#pragma vertex vert

#pragma fragment frag

//【2】头文件包含 || include

#include "UnityCG.cginc"

#include "AutoLight.cginc"

//【3】指定Shader Model 3.0 || Set Shader Model 3.0

#pragma target 3.0

//【4】变量声明 || Variable Declaration

//系统光照颜色

uniform float4 _LightColor0;

//主颜色

uniform float4 _MainColor;

//漫反射纹理

uniform sampler2D _TextureDiffuse;

//漫反射纹理_ST后缀版

uniform float4 _TextureDiffuse_ST;

//边缘光颜色

uniform float4 _RimColor;

//边缘光强度

uniform float _RimPower;

//边缘光强度系数

uniform float _RimIntensity;

//【5】顶点输入结构体 || Vertex Input Struct

struct VertexInput

{

//顶点位置 || Vertex position

float4 vertex : POSITION;

//法线向量坐标 || Normal vector coordinates

float3 normal : NORMAL;

//一级纹理坐标 || Primary texture coordinates

float4 texcoord : TEXCOORD0;

};

//【6】顶点输出结构体 || Vertex Output Struct

struct VertexOutput

{

//像素位置 || Pixel position

float4 pos : SV_POSITION;

//一级纹理坐标 || Primary texture coordinates

float4 texcoord : TEXCOORD0;

//法线向量坐标 || Normal vector coordinates

float3 normal : NORMAL;

//世界空间中的坐标位置 || Coordinate position in world space

float4 posWorld : TEXCOORD1;

//创建光源坐标,用于内置的光照 || Function in AutoLight.cginc to create light coordinates

LIGHTING_COORDS(3,4)

};

//【7】顶点着色函数 || Vertex Shader Function

VertexOutput vert(VertexInput v)

{

//【1】声明一个顶点输出结构对象 || Declares a vertex output structure object

VertexOutput o;

//【2】填充此输出结构 || Fill the output structure

//将输入纹理坐标赋值给输出纹理坐标

o.texcoord = v.texcoord;

//获取顶点在世界空间中的法线向量坐标

o.normal = mul(float4(v.normal,0), _World2Object).xyz;

//获得顶点在世界空间中的位置坐标

o.posWorld = mul(_Object2World, v.vertex);

//获取像素位置

o.pos = mul(UNITY_MATRIX_MVP, v.vertex);

//【3】返回此输出结构对象 || Returns the output structure

return o;

}

//【8】片段着色函数 || Fragment Shader Function

fixed4 frag(VertexOutput i) : COLOR

{

//【8.1】方向参数准备 || Direction

//视角方向

float3 ViewDirection = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz);

//法线方向

float3 Normalection = normalize(i.normal);

//光照方向

float3 LightDirection = normalize(_WorldSpaceLightPos0.xyz);

//【8.2】计算光照的衰减 || Lighting attenuation

//衰减值

float Attenuation = LIGHT_ATTENUATION(i);

//衰减后颜色值

float3 AttenColor = Attenuation * _LightColor0.xyz;

//【8.3】计算漫反射 || Diffuse

float NdotL = dot(Normalection, LightDirection);

float3 Diffuse = max(0.0, NdotL) * AttenColor + UNITY_LIGHTMODEL_AMBIENT.xyz;

//【8.4】准备自发光参数 || Emissive

//计算边缘强度

half Rim = 1.0 - max(0, dot(i.normal, ViewDirection));

//计算出边缘自发光强度

float3 Emissive = _RimColor.rgb * pow(Rim,_RimPower) *_RimIntensity;

//【8.5】计在最终颜色中加入自发光颜色 || Calculate the final color

//最终颜色 = (漫反射系数 x 纹理颜色 x rgb颜色)+自发光颜色 || Final Color=(Diffuse x Texture x rgbColor)+Emissive

float3 finalColor = Diffuse * (tex2D(_TextureDiffuse,TRANSFORM_TEX(i.texcoord.rg, _TextureDiffuse)).rgb*_MainColor.rgb) + Emissive;

//【8.6】返回最终颜色 || Return final color

return fixed4(finalColor,1);

}

//-------------------结束CG着色器编程语言段 || End CG Programming Part------------------

ENDCG

}

}

//后备着色器为普通漫反射 || Fallback use Diffuse

FallBack "Diffuse"

}

unity物体边缘发光shader_Shaderlab Notizen 15 Rim Shader(边缘发光)的两种实现形态相关推荐

  1. 【Unity Shader编程】之十四 边缘发光Shader(Rim Shader)的两种实现形态

    本系列文章由@浅墨_毛星云 出品,转载请注明出处.   文章链接: http://blog.csdn.net/poem_qianmo/article/details/51764028 作者:毛星云(浅 ...

  2. 【Unity Shader编程】之十四 边缘发光Shader Rim Shader 的两种实现形态

    分享一下我老师大神的人工智能教程.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow 本系列文章由@浅墨 ...

  3. Shader编程】之十四 边缘发光Shader(Rim Shader)的两种实现形态

    本系列文章由@浅墨_毛星云 出品,转载请注明出处.   文章链接: http://blog.csdn.net/poem_qianmo/article/details/51764028 作者:毛星云(浅 ...

  4. Unity中传入任意数,转换成分,秒,并进行倒计时换算..(两种方式)

    第一种方式是利用Unity中的协程,代码如下: using System.Collections; using System.Collections.Generic; using UnityEngin ...

  5. Qt学习15:打包可执行文件.exe的两种方式

    参考:Qt打包可执行文件.exe的两种方式_qt打包成可执行程序_阿衰0110的博客-CSDN博客

  6. Unity Shader人物发光特效

    Unity Shader人物发光特效 写在前面 效果 实现方法 项目地址 写在后面 写在前面 当人物被击中或则有任务引导提升时,人物身上将会有发光特效,这里我自己实现一下. 效果 实现方法 核心思想就 ...

  7. Unity物体围绕中中心旋转加角度

    Unity物体围绕中中心旋转加角度 ```csharp using System.Collections; using System.Collections.Generic; using UnityE ...

  8. 云计算通俗讲义(Yanlz+Unity+XR+5G+云计算+IoT+TaaS+IaaS+PaaS+SaaS+边缘计算+泛在物联网+立钻哥哥+==)

    <云计算通俗讲义> <云计算通俗讲义> 版本 作者 参与者 完成日期 备注 YanlzXR_CloudNormal_V01_1.0 严立钻 2019.03.18 ++++5G接 ...

  9. unity Canvas,Rect Transform,自动烘焙和手动烘焙,四种光源和两种发光系统

    UGUI Canvas 画布,是用来把UI元素组合在一起的组件,所有UI元素必须是Canvas的子节点:场景中可以有多个Canvas,若没有则会在创建UI元素的时候自动创建Canvas: Sortin ...

最新文章

  1. 【美团】招聘计算机视觉研究岗实习生
  2. php fread读行,如何使fread阻塞和读取直到结束?
  3. Virtual Lab. For Probability and Statistics
  4. innodb一页为什么要存储两行记录_InnoDB中的页合并与分裂
  5. 30年货币翻了300倍!如何能跑赢印钞机?
  6. openssl下开发sm4-gcm-ciphers
  7. Java监听器Listener入门示例
  8. 【Linux】一步一步学Linux——uptime命令(76)
  9. mysql yum 升级_CentOS 7中升级MySQL 5.7.23的坑与解决方法
  10. 表关联关系,表的复制
  11. 3.从尾到头打印链表
  12. extjs 兼容性问题解决方案
  13. 使用VMware创建DOS虚拟机
  14. Iphone手机,调用微信支付JSAPI缺少参数 timeStamp
  15. Metasploit利用vnc图形化远程控制工具获得靶机远程控制桌面
  16. vscode英文界面转换为中文界面
  17. java重构工具_Piranha(陈旧代码自动重构工具)
  18. 嵌入式Linux:移植USB接口的RTL8188EUS、RTL8188ETV WIFI模块
  19. HyperLynx(八)带状线串扰的仿真
  20. 启动计算机时听到嘀嘀声,为何电脑开机时会有滴滴的声音?

热门文章

  1. python图片处理(PIL)
  2. ajax.updater 返回值,使用 Ajax.Updater() 类
  3. 打包后自定义attr找不到_80后长沙文物修复师刘胄造“精绝古城”,修复实力连X光都找不到破绽...
  4. Android手机之 App2SD 和 App2SD+ 教程
  5. 订餐系统之同步美团商家订单
  6. ZUK 22(Z2131) 免解锁BL 免rec 保留数据 Magisk Xposed 救砖 ROOT ZUI 4.0.199
  7. 抗阿达木单抗的抗体可能与阿达木单抗治疗过程中静脉和动脉血栓事件相关
  8. Python随机生成电话号码号码段分析
  9. 虚拟现实中漫游方式的分类
  10. 云和恩墨2022届春季校招正式启动!