Unity Shader-非主流纹理采样研究(流光,溶解,隐身效果)
简介
流光效果
//流光效果
//by:puppet_master
//2017.7.29
Shader "ApcShader/FlashEffect"
{Properties{_MainTex("MainTex(RGB)", 2D) = "white" {}_FlashTex("FlashTex", 2D) = "black" {}_FlashColor("FlashColor",Color) = (1,1,1,1)_FlashSpeedX("FlashSpeedX", Range(-5, 5)) = 0_FlashSpeedY("FlashSpeedY", Range(-5, 5)) = 0.5_FlashFactor ("FlashFactor", Range(0, 5)) = 1}CGINCLUDE#include "Lighting.cginc"uniform sampler2D _MainTex;uniform float4 _MainTex_ST;uniform sampler2D _FlashTex;uniform fixed4 _FlashColor;uniform fixed _FlashSpeedX;uniform fixed _FlashSpeedY;uniform fixed _FlashFactor;struct v2f {float4 pos : SV_POSITION;float3 worldNormal : NORMAL;float2 uv : TEXCOORD0;float3 worldLight : TEXCOORD1;};v2f vert(appdata_base v){v2f o;o.pos = mul(UNITY_MATRIX_MVP, v.vertex);o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);o.worldNormal = UnityObjectToWorldNormal(v.normal);o.worldLight = UnityObjectToWorldDir(_WorldSpaceLightPos0.xyz);return o;}fixed4 frag(v2f i) : SV_Target{half3 normal = normalize(i.worldNormal);half3 light = normalize(i.worldLight);fixed diff = max(0, dot(normal, light));fixed4 albedo = tex2D(_MainTex, i.uv);//通过时间将采样flash的uv进行偏移half2 flashuv = i.uv + half2(_FlashSpeedX, _FlashSpeedY) * _Time.y;fixed4 flash = tex2D(_FlashTex, flashuv) * _FlashColor * _FlashFactor;fixed4 c;//将flash图与原图叠加c.rgb = diff * albedo + flash.rgb;c.a = 1;return c;}ENDCGSubShader{Pass{Tags{ "RenderType" = "Opaque" }CGPROGRAM#pragma vertex vert#pragma fragment fragENDCG }}FallBack "Diffuse"
}
shader比较简单,flashuv是随着时间逐渐增大的,这个值肯定会大于1,而正常纹理的范围是0-1,所以,要想让贴图在采样时大于0-1也有效果,我们就必须要把贴图的WrapMode设置为Repeat,否则当这个值大于1之后,边缘就被截断了,我们也就不会看到流光效果了。注意,流光的贴图是一个方向,采样uv偏移是另一个方向,比如我的流光图是水平方向的,那么流光运动的方向就是竖直方向,效果如下面动图所示:
更通用的流光效果
//流光效果
//by:puppet_master
//2017.7.30
Shader "ApcShader/FlashEffect"
{Properties{_MainTex("MainTex(RGB)", 2D) = "white" {}_FlashTex("FlashTex", 2D) = "black" {}_FlashColor("FlashColor",Color) = (1,1,1,1)_FlashFactor("FlashFactor", Vector) = (0, 1, 0.5, 0.5)_FlashStrength ("FlashStrength", Range(0, 5)) = 1}CGINCLUDE#include "Lighting.cginc"uniform sampler2D _MainTex;uniform float4 _MainTex_ST;uniform sampler2D _FlashTex;uniform fixed4 _FlashColor;//改为一个vector4,减少传参次数消耗uniform fixed4 _FlashFactor;uniform fixed _FlashStrength;struct v2f {float4 pos : SV_POSITION;float3 worldNormal : NORMAL;float2 uv : TEXCOORD0;float3 worldLight : TEXCOORD1;float4 worldPos : TEXCOORD2;};v2f vert(appdata_base v){v2f o;o.pos = mul(UNITY_MATRIX_MVP, v.vertex);o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);//顶点转化到世界空间o.worldPos = mul(unity_ObjectToWorld, v.vertex);o.worldNormal = UnityObjectToWorldNormal(v.normal);o.worldLight = UnityObjectToWorldDir(_WorldSpaceLightPos0.xyz);return o;}fixed4 frag(v2f i) : SV_Target{half3 normal = normalize(i.worldNormal);half3 light = normalize(i.worldLight);fixed diff = max(0, dot(normal, light));fixed4 albedo = tex2D(_MainTex, i.uv);//通过时间偏移世界坐标对flashTex进行采样half2 flashuv = i.worldPos.xy * _FlashFactor.zw + _FlashFactor.xy * _Time.y;fixed4 flash = tex2D(_FlashTex, flashuv) * _FlashColor * _FlashStrength;fixed4 c;//将flash图与原图叠加c.rgb = diff * albedo + flash.rgb;c.a = 1;return c;}ENDCGSubShader{Pass{Tags{ "RenderType" = "Opaque" }CGPROGRAM#pragma vertex vert#pragma fragment fragENDCG }}FallBack "Diffuse"
}
好了,下面我们找个帅帅哒模型,看一下修改之后的流光效果:
按照方向消失或重现效果
//按照方向消失的效果
//by:puppet_master
//2017.8.10
Shader "ApcShader/DissolveEffectX"
{Properties{_MainTex("MainTex(RGB)", 2D) = "white" {}_DissolveVector("DissolveVector", Vector) = (0,0,0,0)}CGINCLUDE#include "Lighting.cginc"uniform sampler2D _MainTex;uniform float4 _MainTex_ST;uniform float4 _DissolveVector;struct v2f {float4 pos : SV_POSITION;float3 worldNormal : NORMAL;float2 uv : TEXCOORD0;float3 worldLight : TEXCOORD1;float4 objPos : TEXCOORD2;};v2f vert(appdata_base v){v2f o;o.pos = mul(UNITY_MATRIX_MVP, v.vertex);o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);//顶点转化到世界空间o.objPos = v.vertex;o.worldNormal = UnityObjectToWorldNormal(v.normal);o.worldLight = UnityObjectToWorldDir(_WorldSpaceLightPos0.xyz);return o;}fixed4 frag(v2f i) : SV_Target{half3 normal = normalize(i.worldNormal);half3 light = normalize(i.worldLight);fixed diff = max(0, dot(normal, light));fixed4 albedo = tex2D(_MainTex, i.uv);//不满足条件的discardclip(i.objPos.xyz - _DissolveVector.xyz);fixed4 c;c.rgb = diff * albedo;c.a = 1;return c;}ENDCGSubShader{Pass{Tags{ "RenderType" = "Opaque" }CGPROGRAM#pragma vertex vert#pragma fragment fragENDCG }}FallBack "Diffuse"
}
还是上面的模型,我们逐渐调整X,Y,Z轴三个方向的阈值,就可以有逐渐消失或者出现的效果啦,如下面动图所示:
在这里,我们没有像流光效果那样使用世界空间坐标采样,而是使用了模型空间坐标采样,其实还可以使用屏幕空间坐标或者视口空间坐标采样等等,几种方式各有各的优点和缺点。使用世界空间采样,消失的方向是绝对的,比如是从上向下,那么这个模型如果趴在地上,消失的方向就会是从模型后背到前胸的方向,而且坐标阈值会随着模型处于世界中的位置不同而不同;使用模型空间采样,消失的方向与模型本身有关,比如站着的话消失方向是从头到脚,那么趴着也是从头到脚,而且坐标的阈值与模型的高矮胖瘦有关(也与模型的原点位置有点关系);使用屏幕空间采样的话,消失的方向就可能会与我们观察的方向有关,这种可能不太可控。
//消失效果
//by:puppet_master
//2017.8.11Shader "ApcShader/DissolveEffectX"
{Properties{_Diffuse("Diffuse", Color) = (1,1,1,1)_DissolveColor("Dissolve Color", Color) = (0,0,0,0)_MainTex("Base 2D", 2D) = "white"{}_ColorFactor("ColorFactor", Range(0,1)) = 0.7_DissolveThreshold("DissolveThreshold", Float) = 0 }CGINCLUDE#include "Lighting.cginc"uniform fixed4 _Diffuse;uniform fixed4 _DissolveColor;uniform sampler2D _MainTex;uniform float4 _MainTex_ST;uniform float _ColorFactor;uniform float _DissolveThreshold; struct v2f{float4 pos : SV_POSITION;float3 worldNormal : TEXCOORD0;float2 uv : TEXCOORD1;float4 objPos : TEXCOORD2; };v2f vert(appdata_base v){v2f o;o.pos = mul(UNITY_MATRIX_MVP, v.vertex);o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);o.objPos = v.vertex; return o;}fixed4 frag(v2f i) : SV_Target{float factor = i.objPos.x - _DissolveThreshold;clip(factor); //Diffuse + Ambient光照计算fixed3 worldNormal = normalize(i.worldNormal);fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);fixed3 lambert = saturate(dot(worldNormal, worldLightDir));fixed3 albedo = lambert * _Diffuse.xyz * _LightColor0.xyz + UNITY_LIGHTMODEL_AMBIENT.xyz;fixed3 color = tex2D(_MainTex, i.uv).rgb * albedo;//等价于下面注释代码的操作fixed lerpFactor = saturate(sign(_ColorFactor - factor));return lerpFactor * _DissolveColor + (1 - lerpFactor) * fixed4(color, 1);/*if (factor < _ColorFactor){return _DissolveColor;}return fixed4(color, 1);*/}ENDCGSubShader{Tags{ "RenderType" = "Opaque" }Pass{//不让模型穿帮,关掉了背面裁剪Cull OffCGPROGRAM#pragma vertex vert#pragma fragment frag ENDCG}}FallBack "Diffuse"
}
这一次我们只让模型在上下方向上逐渐消失,调整ColorFactor可以控制高亮区域的高度:
溶解效果进阶版
//溶解效果
//by:puppet_master
//2017.8.11Shader "ApcShader/DissolveEffectX"
{Properties{_Diffuse("Diffuse", Color) = (1,1,1,1)_DissolveColor("Dissolve Color", Color) = (1,1,1,1)_MainTex("Base 2D", 2D) = "white"{}_DissolveMap("DissolveMap", 2D) = "white"{}_DissolveThreshold("DissolveThreshold", Range(0,1)) = 0_DissolveSpeedFactor("DissolveSpeed", Range(0,5)) = 2_DissolveControl("ColorFactorB", Float) = 0}CGINCLUDE#include "Lighting.cginc"uniform fixed4 _Diffuse;uniform fixed4 _DissolveColor;uniform sampler2D _MainTex;uniform float4 _MainTex_ST;uniform sampler2D _DissolveMap;uniform float _DissolveThreshold;uniform float _DissolveSpeedFactor;uniform float _DissolveControl; struct v2f{float4 pos : SV_POSITION;float3 worldNormal : TEXCOORD0;float2 uv : TEXCOORD1;float4 objPos : TEXCOORD2; };v2f vert(appdata_base v){v2f o;o.pos = mul(UNITY_MATRIX_MVP, v.vertex);o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);o.objPos = v.vertex; return o;}fixed4 frag(v2f i) : SV_Target{fixed4 dissolve = tex2D(_DissolveMap, i.uv);//Diffuse + Ambient光照计算fixed3 worldNormal = normalize(i.worldNormal);fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);fixed3 lambert = saturate(dot(worldNormal, worldLightDir));fixed3 albedo = lambert * _Diffuse.xyz * _LightColor0.xyz + UNITY_LIGHTMODEL_AMBIENT.xyz;fixed3 color = tex2D(_MainTex, i.uv).rgb * albedo;float factor = i.objPos.x - _DissolveControl;if(factor < 0){clip(_DissolveThreshold - dissolve.r * abs(factor) * _DissolveSpeedFactor);}return fixed4(color, 1);}ENDCGSubShader{Tags{ "RenderType" = "Opaque" }Pass{Cull OffCGPROGRAM#pragma vertex vert#pragma fragment frag ENDCG}}FallBack "Diffuse"
}
效果如下:
当然,也可以参考之前溶解效果,增加溶解描边高亮的效果:
Unity Shader-非主流纹理采样研究(流光,溶解,隐身效果)相关推荐
- unity shader立方体纹理中的反射以及折射效果的实现
反射: 如果不考虑反射效果的话,在场景中的问题的镜面表面的效果应该是用表面的法线对立方体纹理进行采样得到该点的颜色. 所以我们进行反射的计算的时候,只需要求得反射方向,再用反射的方向对立方体纹理进行采 ...
- unity shader实现纹理贴图
unity实现纹理贴图很简单,首先在appdata结构体里声明uv语义TEXCOORD0,就可以获得当前顶点的uv坐标,对外部导入的模型来说.这个uv坐标是在3d模型软件例如maya中制作模型的人预先 ...
- Unity Shader学习案例一: 流光效果
Unity Shader Lab新手宝典简单Shader案例一:流光效果 + 相关基础知识说明 Shader "Samples/Light Flow"//shader名称 {Pro ...
- Unity Shader - GrabPass 实现武器热扭曲拖尾效果
文章目录 先来看看效果 实现思路 Unity带的TrailRender组件 编写脚本实现 CSharp Shader 参数 注意性能 还可以优化 总结 Project 以前龙之谷喜欢选战士,帅气. 战 ...
- Unity Shader - 入门级 - 火烧 2D 旗帜 的溶解效果
文章目录 需求 思路 效果 Ramp 纹理 Shader 集成到 UGUI Shader 中 Project 美术提的需求比较简单,但是之前没整过,当作记录一丢丢效果集中 需求 从图片的 下方往上 燃 ...
- 【Unity Shader】纹理实践4.0:简单尝试渐变纹理和遮罩纹理
写在前面 由于我还是处于刚刚入门(其实还是小菜鸡...)的阶段,关于渐变纹理目前主要是学习一下如何通过渐变纹理控制漫反射光照. 这种用渐变纹理控制颜色效果的想法,是Valve公司(提出半兰伯特光照技术 ...
- Unity shader 角色消失 溶解 隐身 效果
先上两张效果图 实现原理 一句话总结: 空间中有一个隐形的面,判断模型上和面的相对位置,根据需求隐藏上方或者下方的点. 原理就这么简单,具体怎么实现呢,首先确定数学几何中平面的性质:原点到到面上任意一 ...
- Unity Shader学习记录(18) —— Shader动画
纹理动画 纹理动画在游戏中的应用非常广泛.尤其在各种资源都比较局限的移动平台上,我们往往会使用纹理动画来代替复杂的粒子系统等模拟各种动画效果. 11.2.1序列帧动画 _Time是float4类型, ...
- Games101结合Unity Shader入门精要学习笔记(个人向)
第四章 3D旋转 绕X轴旋转: 绕Y轴旋转: 绕Z轴旋转: 旋转变换(一)旋转矩阵_csxiaoshui的博客-CSDN博客_旋转矩阵 重点:MVP变换!!! model transformation ...
最新文章
- bugzilla迁移需要修改的文件
- Java背景颜色怎么设成随机的_JS实现随机改变背景颜色
- 如何实现一套可切换的声网+阿里的直播引擎
- python人工智能_人工智能人才缺口千万!学Python抓住风口机会
- 下载旧版本jdk和tomcat
- UWP锁、解屏后无法响应操作
- mysql索引超出范围 index_输入查询条件会报参数索引超出范围的错误
- Pandas入门教程(一)
- Atitit 财政学概论 attilax学习笔记
- 演化博弈论----gyy参考总结
- Amazon IoT Core 服务成本优化
- centos yum安装tracert_centos6.3如何打开tracert
- 在华为能拿多少工资,揭秘一个真实的华为!
- ipsec-***过程
- oracle调优总结 本文转自:http://blog.csdn.net/wonth/article/details/1670366
- 【基于TCP的在线词典】
- firefly-rk3288开发板Linux驱动——LED驱动
- C++控制台实现简单的注册登录
- 苹果CMS怎么更换模板详细教程
- 2020华中科技大学计算机保研夏令营经验