How to make a cartoon water effects

How to make a cartoon water effects

Since herein by reference tutorials , with their little feelings and experiences.

First, the difference between the surface and the depth of the scene is divided into two extreme values ​​from each shallow and deep water, shallow and deep water, and then interpolated in accordance with the depth. So-called shallow, and the distance of the object is below the surface of the water is smaller, lighter color; so-called deep water, is the distance below the surface of the object and the surface is large, darker.

So, how to get the depth of the scene it? Unity engine comes with ** _ CameraDepthTexture **, but this is based on the screen coordinates of the texture, how to sample it at the correct value to frag shader to go? Vertex \ (V \) , we first UnityObjectToClipPos by converting it to homogeneous coordinates, this time \ (VX \) and \ (Vy \) ranges are \ ([- vw, vw] \) , then the viewport transformation according to:
\ [screen.x = (VX + VW * 0.5 * 0.5) * screen.width / VW \]

\[ screen.y = (v.y * 0.5 + v.w * 0.5) * screen.height / v.w \]

We found that the actual sample coordinates is the \ ((screen.x / screen.width, screen.y / screen.height) \) . Unity provides two built-in functions to help us to sample: ComputeScreenPos and tex2Dproj . ComputeScreenPos result of this function is obtained \ (((VX + 0.5 * 0.5 * VW), (Vy * 0.5 + 0.5 * VW), VZ, VW) \) , tex2Dproj function will be passed perspective division re-sample coordinates sampling.

However, out of the depth value of the sample through depth after perspective projection conversion, is no longer linear, we need to restore it to the original depth value be used. In fact, this is the inverse transform projection transformation of nature. Unity also provides a built-in function: LinearEyeDepth . This function is obtained by the original depth, the depth of the water to make the original difference by the color difference value can be a linear interpolation. Two points need to be aware:

  1. Depth information of the scene depth texture in the surface of the water saved before rendering, that does not contain the water depth information, in addition, in the case of open early-z, the condition code execution frag water is the water depth value than scene depth value is smaller
  2. The water depth value is the original ComputeScreenPos returned by this function \ (W \) . Before performing perspective division, the original depth value has been stored in the vertex \ (W \) component

In summary, shader code for the above to achieve the following:

float existDepth01 = tex2Dproj(_CameraDepthTexture, i.screenPos).r;
float existDepth = LinearEyeDepth(existDepth01);
float difference = existDepth - i.screenPos.w;
float difference01 = saturate(difference / _MaxDistanceCutOff);

float4 waterColor = lerp(_ShallowWaterColor, _DeepWaterColor, difference01);

FIG effect.

The second step, we need to add some water disturbance information to achieve ripple effect. Using a noise map, the direct sampling conventional color overlay color:

Can be found, due to the direct overlay color, the color of most of the region's brush too bright, and we want, in fact, bright colors remain the same place, a dark place painted the color of a ripple, so add a cutoff filter :

Next, we want an edge portion near the shore also have ripple. Difference in depth of the water near the shore and the scene is small, you can take advantage of this lower cutoff values ​​for noise, so noise can also add an edge portion to the surface:

Further, a disturbance can add texture, two channels of sampled noise texture uv offset to achieve the effect of the flow.

Now, the general feeling has been. Careful observation can be found, where the object is in contact with the surface of the water, ripples should be more obvious point, which is the local contact with the object to reduce the need for additional cutoff value of noise. In this case, the normal line data required by the scene to process. The method of differentially line contact with the object surface is relatively large, a method other line difference is relatively small. Easy to think of using dot product of two vectors method to measure the degree of difference vectors.

Because Unity comes with the normal texture precise limited here to consider their own normals texture map rendering a scene. Additional a new Camera, by setting its depth, using SetReplacementShader method, replace all other scene Shader, are allowed to render written line manner, to give RT. This method can replace all for the same shader Tag, so that they are rendered with the specified shader, for Tag different, then skip rendering, Unity here can refer to the official documentation.

Next, we can modify the shader's tag and blend mode to allow the water to become transparent. At the same time, we also hope to be able to adjust the color ripple. In order to be able ripple own color and the color of the water itself, rather than adding the fusion, we use alpha-blend model, so ripples own color blend to the surface, then, the results obtained previously used cutoff can be used in alpha disposed on corrugated.

Finally, the corrugations at the edges, can be smoothed with a cutoff smoothstep.

In summary, to achieve a simple cartoon water effects, divided into the following steps:

  1. The difference between the water depth of the scene, divided into shallow and deeper zones;
  2. Using the noise map blend to the water, to the effect of ripples of water, attention edge surface, a large difference in the depth of the water where little ripple effect; an object in the center of the local surface normals differences, a large ripple effect;
  3. By adjusting the blend mode, corrugations can be provided so that the water color blend itself to the surface;
  4. Water ripple effect edge smoothing can be smoothstep.

Guess you like

Origin www.cnblogs.com/back-to-the-past/p/12483905.html