Unity3d Shader Beginner's Tutorial (3/6)--More real snow

Source: Internet
Author: User

If you meet the following conditions, I suggest you read this tutorial:

    • You want to know how to process color in a surface shader (blend colour)
    • You want to achieve a more realistic snow effect.

Introduction

I think there's a little abrupt transition from snow to snow-free areas, and it feels more like white paint on rocks than snow! In order to make our snow shader more perfect, the next step is to allow the snow and rock textures to be rendered at the same time, thus achieving a process color effect.

As long as we make some modifications to the pixel processing of the surface shader, we can achieve a good snow effect, and this will prove that the saturate function is very useful.

Preparatory work

The _snowlevel in the second part of the tutorial (a variable that represents the degree of snow) determines whether the pixel should be given the color of snow, and here we also use _snowlevel to make the edge color of the Snow White translucent. Instead of being completely white before. When the normal direction of the pixel is the same as that of the snow (i.e. the smaller the angle of the two), the higher the opacity of the pixel, in other words, the more snow is here, until it is completely opaque, where the pixel color value becomes white (in fact it becomes the color of snow).

Implement the shader

And the shader of the second part of the tutorial the biggest difference is that in the second part of the shader, the color value of each pixel is not the snow color, or the texture color, and this part shader the non-black or white judgment to improve the color value of the change process. This leads us to rewrite the logical part of the shader and use the mathematical calculation method instead of the if conditional judgment.

First we need a property value to indicate the degree to which we blend the snow color. We named the attribute value _wetness (wetting degree, if the value is larger, then the proportion of snow color in the process of color is lower, which indicates that the more moist snow, the less the color of snow, is turned into water):

_wetness ("wetness", Range (00.50.3

Then we need a variable to represent the property value in shader.

float _wetness;

We use the following formula to calculate the difference variable.

float difference = dot (Worldnormalvector (in, O.normal), _snowdirection.xyz)-Lerp (1,-1, _ Snow);

In fact, the second part of the code can also use the difference variable (for example, when the difference is greater than 0 to the area of snow color, less than 0 to use the original texture color), the key is to difference processing and application of different.

 void   Surf (Input in, InOut surfaceoutput o) {            Half4 c  = tex2d (_maintex, In.uv_maintex);            O.normal  = Unpacknormal (tex2d (_bump, in.uv_bump));  float  difference = dot (Worldnormalvector (in, O.normal), _ SNOWDIRECTION.XYZ)-Lerp (1 ,-1  ,_snow);;            Difference  = saturate (difference/ _wetness); O.albedo  = Difference*_snowcolor.rgb + (1 -difference) *C;        O.alpha  = C.A; }

We can see that after calculating difference, we first divide difference by _wetness (here we can get a glimpse of the specific uses of _wetness) and then use difference functions for saturate. The specific use of the saturate function is as follows:

    • The saturate function regulates the given value between 0~1 (more than 1 is set to 1, less than 0 is set to 0, and the other is unchanged)
    • So when difference is less than 0 o'clock, that is, there is no snow here, we use the saturate function to place difference to 0.
    • If the default value of _wetness is 0.3, and the angle between normal and snowy direction is between 73 degrees ~90 degrees, then the value of difference is alive 0~1, greater than 90 degrees, 0, less than 73 degrees is 1.

The range of a cosine is 1 to-1, the gap is 2, represents a change of 0 degrees to 180 degrees (from the same direction to the reverse), so if difference between 0~1, then the result of the point multiplication (that is, the Cos value) must be between 0~0.3, so the corresponding angle is 73 degrees ~90 degrees (cos73 =0.3,cos90=1).

Then we multiply the difference by the snow color, difference represents the proportion of the snow color in the final color. We then set the color of the texture itself to 1-difference, add to get the final color. The area where the angle is less than 73 degrees will be filled with the snow color, between 73 degrees ~90 degrees (that is, the edge of snow) has a snow transition effect, greater than 90 degrees will use the original color of the texture.

O.albedo = Difference*_snowcolor.rgb + (1-difference) *c;

Correcting vertex data

If our snow is very moist (wet), then only using the original shader, we will find that the area of less snow, the model will be thickened, the fundamental reason is that our vertex change mode does not vary with the snow color process (mainly added _wetness parameters) change, the effect will not be true. So we should apply the parameter _wetness to the calculation, so that the thickening effect of the model changes with _wetness.

void Vert (inout appdata_full v) {      if(dot (v.normal, _snowdirection.xyz) >= lerp (1,1 , ((1-_wetness) * _snow*2)/3))      {            + = (_snowdirection.xyz + V.normal) * _snowdepth * _snow;      }}

As you can see, we decide whether the thickening model is judged to be greater than

Lerp (1,-1, ((1-_wetness) * _snow*2)/3))

If _wetness is 0, then nothing has changed, and if _wetness has changed to its maximum range of 0.5, then _snow's proportion is no longer 2/3, but 1/3-increasing the model thickening range by 50%.

Here's the final:

Source

Shader"custom/realistic Snow"{Properties {_maintex ("Base (RGB)", 2D) =" White"{} _bump ("Bump", 2D) ="Bump"{} _snow ("Snow Level", Range (0,1) ) =0_snowcolor ("Snow Color", Color) = (1.0,1.0,1.0,1.0) _snowdirection ("Snow Direction", Vector) = (0,1,0) _snowdepth ("Snow Depth", Range (0,0.2)) =0.1_wetness ("wetness", Range (0,0.5)) =0.3} subshader {Tags {"Rendertype"="Opaque"} LOD $Cgprogram#pragmaSurface Surf Lambert Vertex:vertsampler2d _maintex;        Sampler2d _bump; float_snow;        FLOAT4 _snowcolor;        FLOAT4 _snowdirection; float_snowdepth; float_wetness; structInput {float2 Uv_maintex;            FLOAT2 Uv_bump;            FLOAT3 Worldnormal;          Internal_data}; voidVert (inout appdata_full v) {//convert _snowdirection to model local coordinate systemFLOAT4 sn =Mul (UNITY_MATRIX_IT_MV, _snowdirection); if(Dot (v.normal, sn.xyz) >= Lerp (1,-1, (_snow*2)/3) ) {v.vertex.xyz+ = (sn.xyz + v.normal) * _snowdepth *_snow; }                }         voidSurf (Input in, InOut surfaceoutput o) {half4 c=tex2d (_maintex, In.uv_maintex); O.normal=Unpacknormal (tex2d (_bump, in.uv_bump)); Half difference= Dot (Worldnormalvector (in, O.normal), _snowdirection.xyz)-Lerp (1,-1, _snow); Difference= Saturate (Difference/_wetness); O.albedo= Difference*_snowcolor.rgb + (1-difference) *C; O.alpha=C.A; } ENDCG} FallBack"Diffuse"}

Unity3d Shader Beginner's Tutorial (3/6)--More real snow

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.