water effect(1)

  在GPU Gems1的第一小节中,可以看到通过Gerstner wave function来模拟海洋的波浪效果,同时在Unity自带的Water(Pro)效果中,FX/Water4中的部分水波效果正是通过该公式来模拟的。

  首先来看看FX-Water4.shader的代码。

    Tags {"RenderType"="Transparent" "Queue"="Transparent"}

    Lod 500
    ColorMask RGB

    GrabPass { "_RefractionTex" }
    Pass {
            #pragma vertex vert
            #pragma fragment frag
    }
}

Subshader
{
    Tags {"RenderType"="Transparent" "Queue"="Transparent"}

    Lod 300
    ColorMask RGB

    Pass {
            #pragma vertex vert300
            #pragma fragment frag300
    }
}
Subshader
{
    Tags {"RenderType"="Transparent" "Queue"="Transparent"}

    Lod 200
    ColorMask RGB

    Pass {
            #pragma vertex vert200
            #pragma fragment frag200
    }
}

Fallback "Transparent/Diffuse"

其中包含三个subshader,具体执行哪一个Subshader,是通过waterBase.cs来设置sharedMaterial.shader.maximumLOD设置的。我们从low quality开始分析,顶点着色器的代码如下。

    v2f_simple vert200(appdata_full v)
    {
        v2f_simple o;
        //计算出顶点的世界坐标
        half3 worldSpaceVertex = mul(_Object2World, v.vertex).xyz;
        half2 tileableUv = worldSpaceVertex.xz;

        //通过设置的 _BumpDirection.xy值来模拟第一个方向,zw值模拟另一个方向, _BumpTiling.xy模拟第一个方向的速率,zw模拟第二个方向的变化速率。
        o.bumpCoords.xyzw = (tileableUv.xyxy + _Time.xxxx * _BumpDirection.xyzw) * _BumpTiling.xyzw;    

       //viewInterpolator是用来计算相机到该顶点的方向。
        o.viewInterpolator.xyz = worldSpaceVertex-_WorldSpaceCameraPos;

        //pos暂时无用。
        o.pos = mul(UNITY_MATRIX_MVP,  v.vertex);

        o.viewInterpolator.w = 1;//GetDistanceFadeout(ComputeScreenPos(o.pos).w, DISTANCE_SCALE); 

        return o;

    }                                                                                                                

在片元着色器中,我们可以看到法线的计算是通过PerPixelNormal函数实现的,在WaterInclude.cginc中可以找到该函数。

inline half3 PerPixelNormal(sampler2D bumpMap, half4 coords, half3 vertexNormal, half bumpStrength)
{
//计算normal map中两个不同方向的值。
    half4 bump = tex2D(bumpMap, coords.xy) + tex2D(bumpMap, coords.zw);

//计算出法线方向
    bump.xy = bump.wy - half2(1.0, 1.0);

//通过bumpStrength来增大x,z相对于Y的比例,即增加纹理的凹凸感,在unity 中可以看到,bumpStrength越大,水面反光效果越明显。
    half3 worldNormal = vertexNormal + bump.xxy * bumpStrength * half3(1,0,1);

//归一化计算。
    return normalize(worldNormal);
} 

得到法线方向后,具体的片元着色器代码如下。

    half4 frag200( v2f_simple i ) : SV_Target
    {
//法线计算
        half3 worldNormal = PerPixelNormal(_BumpMap, i.bumpCoords, half3(0,1,0), PER_PIXEL_DISPLACE);

//归一化视角向量
        half3 viewVector = normalize(i.viewInterpolator.xyz);

//暂时无用
        half3 reflectVector = normalize(reflect(viewVector, worldNormal));

//半角向量计算,减少计算光线与法线之间的计算量(Jim Blinn),与binnPhong高光模型计算一致
        half3 h = normalize ((_WorldLightDir.xyz) + viewVector.xyz);

        float nh = max (0, dot (worldNormal, -h));
        float spec = max(0.0,pow (nh, _Shininess));    

//通过Fresnel参数控制缩放
        worldNormal.xz *= _FresnelScale;    

//计算出fresnel反射率。
        half refl2Refr = Fresnel(viewVector, worldNormal, FRESNEL_BIAS, FRESNEL_POWER);    

        half4 baseColor = _BaseColor;

//通过fresnel反射率混合折射与反射颜色。
        baseColor = lerp(baseColor, _ReflectionColor, saturate(refl2Refr * 2.0));

//fresnel反射率越大,alpha越大,水下物品越看不清。
        baseColor.a = saturate(2.0 * refl2Refr + 0.5);

//与高光混合,最终颜色计算。
        baseColor.rgb += spec * _SpecularColor.rgb;
        return baseColor;
    }

核心是fresnel反射率的计算,fresnel的基本原理是视线与法线的角度越小,即与平面越垂直,反射越小,折射越大,水下的物品越清晰,视线与平面越平行,反射越大,水下物品越看不清。在WaterINclude.cginc中有简易的fresnel的计算公式。

inline half Fresnel(half3 viewVector, half3 worldNormal, half bias, half power)
{
//夹角的计算。
    half facing =  clamp(1.0-max(dot(-viewVector, worldNormal), 0.0), 0.0,1.0);
//反射率的计算。
    half refl2Refr = saturate(bias+(1.0-bias) * pow(facing,power));
    return refl2Refr;
}

  这一节主要是通过UV纹理的变化来模拟简易水波,但无法在相同的normal map下实现大波浪似的效果。下一节主要介绍Gerstner wave function如何更实现高级的水波效果。

时间: 2024-10-03 13:46:00

water effect(1)的相关文章

unity3d 制造自己的水体water effect(二)

前篇:unity3d 制造自己的水体water effect(一) 曲面细分:Unity3d 使用DX11的曲面细分 PBR: 讲求基本算法 Unity3d 基于物理渲染Physically-Based Rendering之specular BRDF plus篇 Unity3d 基于物理渲染Physically-Based Rendering之实现 最终篇 Unity3d 基于物理渲染Physically-Based Rendering之最终篇 之前一直在用unity4.6写shader,终于下

unity3d 制造自己的水体water effect

first,I wish you a happy new year, and study in spring festival's eve means you are hardworking,haha. I write in two languages. One passage write in Chineseone passage translate into English. My English is poor., If I write some thing wrong, welcome

unity3d 制造自己的水体water effect(一)

first,I wish you a happy new year, and study in spring festival's eve means you are hardworking,haha. I write in two languages. One passage write in Chineseone passage translate into English. My English is poor., If I write some thing wrong, welcome

water effect(2)

这节主要记录的是第二个Subshader的具体效果,相对于的vert200, vert300顶点着色器主要会对mesh中的顶点进行变换,主要函数是Gerstner,根据gpugems第一小节的描述,Gerstner wave function是对 sin() 次方运算的简化版,具体公式如下,下面的条件中默认初始值为0. 其中A是坡度,即从低谷到高峰的高度值,W为波的频率值,即两个波峰之间的距离越小,W越大,D为波的方向向量,Q为控制波的程度.在unity中,WaterInclude.cginc的

Unity3d 实现顶点动画

在今年GDC上发现一个非常有趣的演讲,叫做Animating With Math,遂实现之,是讲述顶点shader动画的,举了几个经典的例子,但是讲者并没有给代码,而是像虚幻引擎那样的节点,这样更加清楚明了之前博主通过顶点着色器实现了水的波动算法: unity3d 制造自己的水体water effect(二) 顶点着色器动画可以减少动画的开销,并减少关节joint的数量开始举的例子都很简单,可以着手一试   关于vertex color是自定义的一个贴图,会控制各种参数下面会说明接下来的例子是一

(转)水面渲染小结

转自:http://blog.csdn.net/soilwork/article/details/1548490 水面渲染小结 本文版权归我所有,仅供个人学习使用,请勿转载,勿用于任何商业用途.由于本人水平有限,难免出错,欢迎大家和我交流.作者:claymanBlog:http://blog.csdn.net/soilwork[email protected] 从几何模型上来看,水面其实和地面是一样的,可以看做普通的均匀网格,不同点在于地形中,顶点高度是固定的,而水面是动态的.此外,对于水面来说

进阶光照与材质之物体和材质

第四章主要介绍分析真实世界中某些常见材质的特性与细节,作者提醒我们应该时刻关注大自然真实世界中材质的特点,加强自己的思考与敏锐的观察力和感知力对渲染实现很有帮助.作者主要对如下材质进行了分析:塑料木头:树,木材,被油漆过的木材叶子和植物金属混凝土和石头:混凝土,砖石,自然界的石头皮肤头发和毛发大气半透明材质:玻璃,水油漆旧的磨损的材质 塑料  塑料有很多种颜色形状甚至有的上了不同的漆,但是它的材质构成是一致的.大部分塑料由白色或半透明的基质构成,这些基质充满了染色粒子,像下图这样 当 光照射到塑

随便聊聊水面效果的2D实现(一)

0. 引子 一直想随便写写自己关于水面效果2D实现的一些了解,可惜各种原因一直拖沓,幸而近来有些事情终算告一段落,自己也有了一些闲暇时间,于是便有了这篇东西 :) 1. 概述 关于水面效果的实现方法,google一下非常之多,目前的很多游戏也有非常好的呈现,其中最令我印象深刻的当数<Crysis>~ 自己由于工作原因接触过一段时间的CryEngine,对于Crysis的水面渲染有一点点的了解,当然其中细节非常复杂,但就基本原理来讲,就是将整块水面细分成适当粒度的三角面,然后通过动态改变各个三角

How to create water Ripple effect using HTML5 canvas

https://www.script-tutorials.com/how-to-create-water-drops-effect-using-html5-canvas/ https://www.script-tutorials.com/demos/97/index.html Rain & Water Effects(只在谷歌浏览器有效) http://tympanus.net/Development/RainEffect/#slide-1 示例(http://tympanus.net/Deve