文/日音

游戏中海水实现后,在商店反响还不错,有人评论说需要增加一个烘焙深度图的工具,想想也有道理,于是就做了一个。原理其实非常简单,就是放一个摄像机照射岛屿,然后用shader将z的值归一化存在贴图中, 然后再将贴图转成png保存。

最重要的部分如下:
 

  1. Shader depthShader {
  2. Properties {

  3. SubShader {
  4. Pass {
  5. CGPROGRAM
  6. // Upgrade NOTE: excluded shader from DX11 and Xbox360; has structs without semantics (struct v2f members pos1)
  7. #pragma exclude_renderers xbox360
  8. #pragma vertex vert
  9. #pragma fragment frag
  10. #include UnityCG.cginc
  11. struct appdata {
  12. float4 vertex : POSITION;
  13. };
  14. struct v2f {
  15. half4 pos : SV_POSITION;
  16. float4 depth : TEXCOORD0;
  17. };
  18. v2f vert (appdata v) {
  19. v2f o;
  20. o.pos = UnityObjectToClipPos (v.vertex);
  21. o.depth.x = mul(unity_ObjectToWorld,(v.vertex)).y;
  22. return o;

  23. float4 frag(v2f i) : COLOR

  24. float d = i.depth.x;
  25. float high = 0;
  26. float low = -2;
  27. float a = (high - d) / (high - low);
  28. return float4(1, 0, 0, a);

  29. ENDCG



092056rkcwxw0xahqbqeqq.jpg
接下来我会写一个运行时烘焙深度图的水,适用任何场景。

先上最终效果:


我开始思考,有没有可能在牺牲部分性能的情况下实现更加贴近pc端表现的海水。

首先,我们要知道目光射入海水的方向:

 

 

  1. float3 worldView = (IN.worldPos - _WorldSpaceCameraPos);

然后就是海面的高光,我们打算模拟下光照,如下:

 

 

  1. half reflectiveFactor = max(0.0, dot(viewdir, reflect(lightDir, worldNormal)));
    • half shininess = _Strength * 100;
      • half specularFactor = pow(reflectiveFactor, shininess);
        •  
        • half diffuseFactor = max(0.0, dot(worldNormal, lightDir));
          • color = tex2D(_MainTex, i.texcoord);
            • color.rgb *= diffuseFactor;
              • color.rgb = _Specular.rgb * specularFactor;

接下来处理海岸的部分,先使用自带的深度图试试:

 

 

  1. o.args = ComputeScreenPos(o.pos);
    • COMPUTE_EYEDEPTH(o.args.z);
      • half4 foam = (tex2D(_FoamTex, uv1) + tex2D(_FoamTex, uv2)) * 0.5;
        •  
        • half3 worldNormal = (normal.xyz * 2 - 1).xzy;
          • color = tex2D(_MainTex, i.texcoord);
            • float depth = tex2Dproj(_CameraDepthTexture, i.args).r;
              • depth = LinearEyeDepth(depth);
                • depth = depth - i.args.z;
                  • float depth1 = saturate(depth * _Range.x);
                    • float depth2 = saturate(depth * _Range.x * 0.9);

接下来就是增加光照和深浅变化的控制,这部分就很简单了:

 

 

  1. half3 lightDir = _WorldSpaceLightPos0.xyz;
    • // Phong shading model
      • half reflectiveFactor = max(0.0, dot(viewdir, normalize(reflect(-lightDir, worldNormal)))) * 0.995;
        • half shininess = _Strength * 200.0;
          • half specularFactor = pow(reflectiveFactor, shininess);
            • float deep = 1 - saturate(depth1 * _Range.y);
              • float4 deepColor = lerp(_Bright, _Dark, deep * 2)* _Range.y;
                • color.rgb = color.rgb * _Range.z + deepColor * (1 - _Range.z);

via:游戏扶持by腾讯游戏学院

锐亚教育

锐亚教育,游戏开发论坛|游戏制作人|游戏策划|游戏开发|独立游戏|游戏产业|游戏研发|游戏运营| unity|unity3d|unity3d官网|unity3d 教程|金融帝国3|8k8k8k|mcafee8.5i|游戏蛮牛|蛮牛 unity|蛮牛