Unity3D surf 函数,简单折射

Refration - 折射

struct Input {
            float2 uv_MainTex;
            float2 uv_BumpMap;
            float3 viewDir;
            //因为这里使用了Normal map,所以要使用INTERNAL_DATA
            float3 worldRefl ; 
            float3 worldNormal; INTERNAL_DATA 
        };
        samplerCUBE _Cubemap;
        float _ReflAmount;

        fixed4 _Color;

        void surf (Input IN, inout SurfaceOutput   o) {
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            //如果不使用Normal map的话,是可以直接操作Normal和viewDir的,但是一旦改变了Normal
            //就必须用WorldNormalVector 和 WorldReflectionVector 来做法线和反射向量。
            //o.Normal = -o.Normal;
            //IN.viewDir = -IN.viewDir;

            //因为使用了Normal map,所以下面的操作就必须基于WorldNormalVector和WorldReflectionVector
            //特别要注意的是,此时除了o.Normal之外,是万万不能使用了IN.viewDir的,因为IN.viewDir的参考系也变了
            o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap)).rgb;

            /*
            这个是求折射的
            其中需要注意的是折射光线的求法。 此处是用 ref向量 减去 1.3倍的Normal来做的。
            这个系数1.2很关键,说的理论一点是用来控制折射率的。 从肉眼看就是物体是水、玻璃、钻石的区别
            实际上这个系数不同取值范围有不同的物理含义:
            当其大于1的时候,表示obj介质密度大于camera介质密度。
            当其在0.5到1之间,表示obj介质密度小于camera介质密度。(譬如水中看气泡)
            当其小于0.5的时候,就不是折射而是反射了。
            */
            float3 back = 0.9*texCUBE(_Cubemap, normalize( -1.2* WorldNormalVector( IN, o.Normal) + 1* WorldReflectionVector (IN, o.Normal)) ).rgb*_ReflAmount;

            //很简单的改动Normal后的求反射光线的做法
            float3 front = 0.3 * texCUBE(_Cubemap, WorldReflectionVector ( IN, o.Normal)).rgb*_ReflAmount;
            o.Emission = back + front ;
            o.Alpha = c.a;
        }

猜你喜欢

转载自blog.csdn.net/mconreally/article/details/50759800
今日推荐