当前位置:   article > 正文

【Unity Shader实例】 水体WaterEffect(三) 环境映射_unity池塘水面

unity池塘水面

Unity Shader实现水体的环境映射

平静的水面会像镜子一样映射出周围的景致(光的反射)。此外,水这种透明材质,应该可以透视,我们的眼睛可以透过水面看到水下的环境(光的折射)。

效果展示

这里写图片描述

实现

在图形学中,立方体纹理(CubeMap)是环境映射(Environment Mapping)的一种实现方法。环境映射可以模拟物体周围IDE环境,而使用了环境映射的物体可以看起来像镀了层膜一样反射出周围的环境。

我们接下来要解决的是,如何让水面反射周围环境?如何让水面折射水下环境?能量是守恒的,如何计算多少光发生了反射,多少光发生了折射?

1. 水面的环境反射

原理

环境反射的原理很简单,一个光滑的物体表面可以根据我们观察的不同角度反射出不同位置的环境。即物体表面一点反射的颜色和该点的法线,观察视线和反射视线有关系。
image

如果我们使用texCube函数对立方体纹理进行采样时,使用视线关于物体顶点法线的反射向量作为采样的方向向量就可以得到反射的效果。

具体实现
步骤:
  • 创建用于环境映射的立方体纹理(反射源)
  • 用该立方体纹理作为天空盒子
  • 使用worldRef(视线关于物体顶点法线的反射向量)作为采样的方向向量,对CubeMap采样作为物体的表面纹理

如果物体的纹理采集自与天空盒子同一个CubeMap,就会有一种环境映射的感觉。

shader代码:
Shader "Hidden/CMReflect"
{
    Properties
    {
        _CubeMap("CubeMap", CUBE) = ""{}
    }
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;           
                float3 normal : NORMAL;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float3 worldNormal : TEXCOORD0;
                float3 worldRef : TEXCOORD1;
                float3 worldPos : TEXCOORD2;
                float3 worldViewDir : TEXCOORD3;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.worldPos = mul(unity_ObjectToWorld, v.vertex);
                o.worldNormal 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/108475
推荐阅读
相关标签
  

闽ICP备14008679号