[Shader 着色器]冰霜效果的思考和实现
http://game.ceeger.com/forum/read.php?tid=23209&fid=2
由于最近要做一个冰系的角色,就想能不能做一些冰霜效果。那么就试试吧,先弄一张原图:
1.常规的冰霜,最简单的要数霜冻的颜色变化,只需要减少亮度,增加蓝色分量。
片段着色器:
texcol *= fixed4(0.9, 0.9, 0.9, 1f);
texcol.b += 0.2;
效果如下:
虽然简单,但效果也十分一般。
2.如果你玩过冰火围城,它里面的冰冻效果则是更加金属化,给人的感觉是一层灰色滤镜再增加一点蓝色,然后顶部会更亮。
首先,我们要计算法线夹角,方便处理顶部更亮这部分。
顶点着色器:
float3 normal = mul(SCALED_NORMAL, (float3x3)_World2Object);
fixed dotProduct = dot(normal, fixed3(0, 1, 0)) / 2;
if(dotProduct <= 0)
{
dotProduct = 0;
}
o.color = dotProduct.xxx;
然后灰化整个角色,并且增加顶部亮度。
片段着色器:
float grey = dot(texcol.rgb, float3(0.299, 0.587, 0.114)) + i.color.x;
texcol = fixed4(grey, grey, grey, texcol.a);
texcol.r -= 0.15;
texcol.b += 0.15;
效果如下:
不过由于这个模型本身比较暗,所以看上去有点像雕像。但这似乎不是我们想要的效果呢,于是我打算换一个思路,让材质先变成霜。
增加了一张贴图,看看霜的效果:
哈哈,有点像冰棍了呢。但霜应该要亮一些,我打算增加下亮度,同时增加外发光。
顶点着色器:
fixed3 viewDir = normalize(ObjSpaceViewDir(v.vertex));
fixed dotProduct = 1 - dot(v.normal, viewDir);
o.color = smoothstep(0, 1, dotProduct);
o.color *= _RimColor;
片段着色器:
texcol.rgb += i.color;
效果:
可是这样就完全是冰棍了呢,我想要混合一下原始的像素,于是增加一个变量,控制一下混合。
片段着色器:
texcol = texcol * _Frezz + alpha * (1 - _Frezz);
设置效果:
通过控制滚动条可以调整混合比例,这个大概是64开的比例,看着还行吧。
但这样就结束的话还是差强人意,因为冰霜的变化太过规则了,我们很多时候希望的是随机变化,显得更自然。
再增加一张噪点贴图,通过获得贴图的值调整混合比例。
float ClipTex = tex2D (_RandomTex, i.uv).r ;
float ClipAmount = (_Frezz - ClipTex) / 2 + 0.5;
if(ClipAmount < 0)
{
ClipAmount = 0;
}
if(ClipAmount > 1)
{
ClipAmount = 1;
}
效果如下:
这样马马虎虎吧,如果还要继续就需要法线贴图,遗憾的是这个模型没有法线贴图。
如果有法线贴图,我们可以再法线贴图层面上增加冰霜的颜色变化。
最后 的完整shader代码:
本部分设定了隐藏,您已回复过了,以下是隐藏的内容
// Upgrade NOTE: replaced 'V2F_POS_FOG' with 'float4 pos : SV_POSITION'
Shader "Custom/CharactorShaderCullOff" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_AlphaTex ("Base (RGB)", 2D) = "white" {}
_RandomTex ("Base (RGB)", 2D) = "white" {}
_RimColor ("Rim Color", Color) = (1, 0, 0, 1)
_Color("_Color", Color) = (0.5,0.5,0.5,1)
_Rampage("_Rampage", Float) = 0
_Frezz("_Frezz", Range(0, 1)) = 0
}
SubShader {
//Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
Pass {
cull off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
// Upgrade NOTE: excluded shader from DX11 and Xbox360; has structs without semantics (struct v2f members pos1)
#pragma exclude_renderers d3d11 xbox360
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata {
float4 vertex : POSITION;
float3 normal : NORMAL;
float2 texcoord : TEXCOORD0;
};
struct v2f {
half4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
fixed3 color : COLOR;
};
uniform fixed4 _RimColor;
uniform fixed _Rampage;
uniform fixed _Frezz;
v2f vert (appdata_base v) {
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
if(_Rampage == 1)
{
fixed3 viewDir = normalize(ObjSpaceViewDir(v.vertex));
fixed dotProduct = 1 - dot(v.normal, viewDir);
o.color = smoothstep(0, 1, dotProduct);
o.color *= _RimColor;
}
float3 normal = mul(SCALED_NORMAL, (float3x3)_World2Object);
fixed dotProduct = dot(normal, fixed3(0, 1, 0)) / 2;
if(dotProduct <= 0)
{
dotProduct = 0;
}
o.color += dotProduct.xxx;
o.uv = v.texcoord.xy;
return o;
}
uniform sampler2D _MainTex;
uniform sampler2D _AlphaTex;
uniform sampler2D _RandomTex;
uniform fixed4 _Color;
fixed4 frag(v2f i) : COLOR {
fixed4 texcol = tex2D(_MainTex, i.uv);
fixed4 alpha = tex2D(_AlphaTex, i.uv);
float ClipTex = tex2D (_RandomTex, i.uv).r ;
float ClipAmount = (_Frezz - ClipTex) / 2 + 0.5;
if(ClipAmount < 0)
{
ClipAmount = 0;
}
if(ClipAmount > 1)
{
ClipAmount = 1;
}
if(_Rampage == 1)
{
texcol.rgb += i.color;
}
texcol = texcol * ClipAmount + alpha * (1 - ClipAmount);
texcol.a = alpha.a;
clip(texcol.a - 0.5);
texcol *= _Color;
return texcol;
}
ENDCG
}
}
}
[Shader 着色器]冰霜效果的思考和实现的更多相关文章
- Unity Shader着色器优化
https://mp.weixin.qq.com/s?__biz=MzU5MjQ1NTEwOA==&mid=2247493518&idx=1&sn=c51b92e9300bcf ...
- Unity3D学习笔记(三十四):Shader着色器(1)
一.GPU:图形处理器,Graphics Processing Unit 显卡的处理器就是图形处理器.与CPU类似. GPU和CPU的区别? 1.CPU主要是为了串行指令设计,GPU则是为了大规模 ...
- [Unity] Shader(着色器)输入输出和语义
在Unity5.x后, 已经支持了基于物理的光照模型,也就是常说的次时代引擎所必须具备的功能. 如果在Properties使用2D,CG里要用sampler2D,代表使用的是2维纹理 如果在Prope ...
- [Unity] Shader(着色器)之纹理贴图
在Shader中,我们除了可以设定各种光线处理外,还可以增加纹理贴图. 使用 settexture 命令可以为着色器指定纹理. 示例代码: Shader "Sbin/ff2" { ...
- OpenGL之shader着色器的应用,三色渐变的三角形
学习自: https://learnopengl-cn.github.io/01%20Getting%20started/05%20Shaders/#_7 首先放一张效果图: 本次教程,将着色器单独定 ...
- Unity3D学习笔记(三十五):Shader着色器(2)- 顶点片元着色器
Alpha测试 AlphaTest Great:大于 AlphaTest Less:小于 AlphaTest Equal:等于 AlphaTest GEqual:大于等于 AlphaTest LEqu ...
- osg Shader 着色器
#ifdef _WIN32 #include <Windows.h> #endif // _WIN32 #include <osg/Group> #include <os ...
- [Unity] Shader(着色器)之固定管线
在Unity中,固定管线Shader的性能是最好的. 什么是固定管线呢? 固定渲染管线 —— 这是标准的几何&光照(T&L)管线,功能是固定的,它控制着世界.视.投影变换及固定光照控制 ...
- Unity3D学习笔记(三十六):Shader着色器(3)- 光照
光照模型:用数学的方法模拟现实世界中的光照效果. 场景中模型身上的光反射到相机中的光线: 1.漫反射:产生明暗效果 2.高光反射:产生镜面反射,物体中有最亮且比较耀眼的一部分 3.自发光: 4.环 ...
随机推荐
- HDU 2825 Wireless Password (AC自己主动机,DP)
pid=2825">http://acm.hdu.edu.cn/showproblem.php? pid=2825 Wireless Password Time Limit: 2000 ...
- font-family,font-size,color
CreateTime--2017年12月20日16:43:35 Author:Marydon css设置字体样式 1.font-family 语法:属性值可以有一个或多个,多个值之间使用逗号隔开. ...
- INAPP登陆调用的FB接口
public function login_get (){ $this->load->helper ( 'auth' ); $redirectUrl = $this->input-& ...
- Json实现异步请求(提交评论)
主要将代码粘贴,通过阅读代码理解当中的相关逻辑. html代码: <form id="form1" runat="server"> <p> ...
- zoj1232Adventure of Super Mario(图上dp)
题目连接: 啊哈哈.点我点我 思路: 这个题目是一个图上dp问题.先floyd预处理出图上全部点的最短路,可是在floyd的时候,把可以用神器的地方预处理出来,也就是转折点地方不能为城堡..预处理完成 ...
- adb的那点小事——360电视助手实现研究
欢迎转载,转载请注明:http://blog.csdn.net/zhgxhuaa 1. 前言 1.1. 行业背景简单介绍 当下,智能家居与智能穿戴设备无疑是继智能手机后两个最热门的方向.而智能家 ...
- Mysql 数据库中间件
读写分离:简单的说是把对数据库读和写的操作分开对应不同的数据库服务器,这样能有效地减轻数据库压力,也能减轻io压力.主数据库提供写操作,从数据库提供读操作,其实在很多系统中,主要是读的操作.当主数据库 ...
- 关于Text Kit 一些事
1. Text Kit 是什么? 在iOS7中,苹果引入了Text Kit--Text Kit是一个高速而又现代化的文字排版和渲染引擎.Text Kit在UIKit framework中的定义了一些类 ...
- 集群环境搭建-SSH免密码登陆(二)
1.打开sshd配置 命令: vi /etc/ssh/sshd_config 找到以下内容,并去掉注释符”#“ RSAAuthentication yes PubkeyAuthentication y ...
- 关于在PHP中当一个请求未完成时,再发起另一个请求被阻塞的问题
最近做项目的时候遇到个问题,就是做阿里云oss大文件上传进度条显示,因为要实时查询上传分片进度,所以在上传的同时必须要再发起查询的请求,但是一直都是所有分片上传完成后查询的请求才执行,刚开始以为是阿里 ...