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 'PositionFog()' with multiply of UNITY_MATRIX_MVP by position 

// 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 着色器]冰霜效果的思考和实现的更多相关文章

  1. Unity Shader着色器优化

    https://mp.weixin.qq.com/s?__biz=MzU5MjQ1NTEwOA==&mid=2247493518&idx=1&sn=c51b92e9300bcf ...

  2. Unity3D学习笔记(三十四):Shader着色器(1)

    一.GPU:图形处理器,Graphics Processing Unit 显卡的处理器就是图形处理器.与CPU类似.   GPU和CPU的区别? 1.CPU主要是为了串行指令设计,GPU则是为了大规模 ...

  3. [Unity] Shader(着色器)输入输出和语义

    在Unity5.x后, 已经支持了基于物理的光照模型,也就是常说的次时代引擎所必须具备的功能. 如果在Properties使用2D,CG里要用sampler2D,代表使用的是2维纹理 如果在Prope ...

  4. [Unity] Shader(着色器)之纹理贴图

    在Shader中,我们除了可以设定各种光线处理外,还可以增加纹理贴图. 使用 settexture 命令可以为着色器指定纹理. 示例代码: Shader "Sbin/ff2" { ...

  5. OpenGL之shader着色器的应用,三色渐变的三角形

    学习自: https://learnopengl-cn.github.io/01%20Getting%20started/05%20Shaders/#_7 首先放一张效果图: 本次教程,将着色器单独定 ...

  6. Unity3D学习笔记(三十五):Shader着色器(2)- 顶点片元着色器

    Alpha测试 AlphaTest Great:大于 AlphaTest Less:小于 AlphaTest Equal:等于 AlphaTest GEqual:大于等于 AlphaTest LEqu ...

  7. osg Shader 着色器

    #ifdef _WIN32 #include <Windows.h> #endif // _WIN32 #include <osg/Group> #include <os ...

  8. [Unity] Shader(着色器)之固定管线

    在Unity中,固定管线Shader的性能是最好的. 什么是固定管线呢? 固定渲染管线 —— 这是标准的几何&光照(T&L)管线,功能是固定的,它控制着世界.视.投影变换及固定光照控制 ...

  9. Unity3D学习笔记(三十六):Shader着色器(3)- 光照

    光照模型:用数学的方法模拟现实世界中的光照效果.   场景中模型身上的光反射到相机中的光线: 1.漫反射:产生明暗效果 2.高光反射:产生镜面反射,物体中有最亮且比较耀眼的一部分 3.自发光: 4.环 ...

随机推荐

  1. three.js 源代码凝视(九)Math/Matrix4.js

    商域无疆 (http://blog.csdn.net/omni360/) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:商域无疆 -  本博客专注于 敏捷开发 ...

  2. JAVA_MyEclipse常见配置NETGEAR路由器如何设置

    1 把宽带网线接到路由器的Internet口,然后用一个网线连接PC和路由器的任意端口(1,2,3,4一般四个),如下图所示 2 在浏览器地址栏中输入下面的网址,中途会弹出对话框询问账号密码,默认的账 ...

  3. minimum-depth-of-binary-tree——二叉树遍历、链表、广度优先

    Given a binary tree, find its minimum depth.The minimum depth is the number of nodes along the short ...

  4. vimrc 避免中文乱码配置

    et smsyntax onset ts=4set sts=4set sw=4set hlsearchset rulerset backspace=indent,eol,startset encodi ...

  5. stream_context_create()模拟POST/GET

    有时候,我们需要在服务器端模拟 POST/GET 等请求,也就是在 PHP 程序中去实现模拟,该怎么做到呢?或者说,在 PHP 程序里,给你一个数组,如何将这个数组 POST/GET 到另外一个地址呢 ...

  6. oracle 11G direct path read 非常美也非常伤人

    direct path read 在11g中,全表扫描可能使用direct path read方式,绕过buffer cache,这种全表扫描就是物理读了. 在10g中,都是通过gc buffer来读 ...

  7. AIX下RAC搭建 Oracle10G(二)主机配置

    AIX下RAC搭建系列 AIX下RAC搭建 Oracle10G(二)主机配置 环境 节点 节点1 节点2 小机型号 IBM P-series 630 IBM P-series 630 主机名 AIX2 ...

  8. Nova虚拟机启动提示libvirtError

    OpenStack自动化安装基本折腾完毕,装一次大概也就10分钟,但是装完后今天我的虚拟机起不来,经过查找log发 现如下图提示: 已经到这里,说明已经过了nova-sheduler那一关,跟踪一下代 ...

  9. coco2d-x 3.0游戏实例学习笔记 《跑酷》 第二步---游戏界面&amp;全新的3.0物理世界

    说明:这里是借鉴:晓风残月前辈的博客,他是将泰然网的跑酷教程.用cocos2d-x 2.X 版本号重写的,眼下我正在学习cocos2d-X3.0 于是就用cocos2d-X 3.0重写.并做相关笔记 ...

  10. 使用Javamelody验证struts-spring框架与springMVC框架下action的訪问效率

    在前文中我提到了关于为何要使用springMVC的问题,当中一点是使用springMVC比起原先的struts+spring框架在效率上是有优势的.为了验证这个问题,我做了两个Demo来验证究竟是不是 ...