Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to realize simple diurnal variation based on Illumination Map by Unity Shader

2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly introduces how to realize the simple diurnal variation based on the light map by Unity Shader. The article is very detailed and has certain reference value. Interested friends must read it!

OK, let's start with a dynamic chart of the final effect. The change process is a bit stuttered, which is caused by GIF compression and frame extraction, but there is no such problem. But it should be able to show a change in the time of day.

Some friends may have found the problem, alas, how the shadow has not changed. Yes, it can't, because we make changes based on baked lighting images, so the shadows are fixed. If we had real time, it would not be covered in this tutorial, just adjust the directional light directly.

This project was originally based on a MMO project I worked on. A few years ago, real-time light was not realistic (and now it is not realistic for many projects), and light is almost always determined by baked lighting. But when we do some plot animation, we need some diurnal changes, which are usually very fast. For example, the plot says, "just like that, the night has passed." if you can add a fast-changing lighting system at this time, it's still very picturesque, right? Then came this violent and crude version of the day and night system.

Why is it a violent and crude version? Because it is really violent, we finally think of the best way to modify the color of all materials directly, of course, if we achieve a good effect, we still need to consider many aspects. Here is only a simple way to solve the problem.

To change the color of the material, we can't write code to change the color by traversing all the materials in the scene one by one. I'm exhausted, and I know the performance is worrying when I think about it. Fortunately, Unity provides us with a convenient way to modify the shader property globally. Let's take a look at the official API, which modifies the global shader color (Shader.SetGlobalColor).

It's easy to use, this API can directly modify all attributes with that name in the scene, as long as the attribute is not exposed in the editor, that is, you can only declare it in the Pass channel, if you declare it in the attribute block, sorry, this API is invalid, it will give priority to the parameters defined in the attribute block.

Once you are familiar with this API, it will be simple. We just need to add a skylight color attribute to each shader that needs to be changed, multiply it directly, and then modify the color globally. Take a look at the following shader key code, the extra code can be counted with your fingers.

/ / here is the global color to be modified-Sky fixed4 _ SkyColor

Void surf (Input IN, inout SurfaceOutputStandard o) {/ / just multiply it directly fixed4 c = tex2D (_ MainTex, IN.uv_MainTex) * _ Color*_SkyColor

Okay, it's not over yet. the point is that we need to use a script to control and change the color.

Here I wrote down the colors of four periods, namely, morning, noon, afternoon and evening (in fact, if you don't care about the details, morning and noon can be merged). And expose these four colors for the scene staff to modify. There is also the time, in seconds, that it takes to cycle through the whole day.

Next is to promote the time in the code, the following is the code, or relatively simple, each line I wrote a detailed comment, but my code is not good, please understand.

Public class DayAndNightManager: MonoBehaviour {public float oneDayTime = 10; / / cycle time throughout the day, where the default 10-second public Color morningColor = Color.white; / / morning color public Color noonColor = Color.white; / / noon color public Color afterNoonColor = Color.white; / / evening color public Color nightColor = Color.white; / / night color

Color private Color currentColor;// for all time periods used by private Color [] colors;// current color private float dayTimer / / time / / Use this for initialization void Start () {/ / collect the colors of all the time periods. There is an extra one here, because the whole cycle ends and returns to the early morning period, so the last color is the morning color colors = new Color [5]; colors [0] = morningColor; colors [1] = noonColor; colors [2] = afterNoonColor Colors [3] = nightColor; colors [4] = morningColor; / / initialize Shader.SetGlobalColor ("_ SkyColor", Color.white); currentColor = morningColor; dayTimer = 0;}

/ / Update is called once per frame void Update () {/ / the time starts to advance, multiplied by 4 because we have four periods, so multiplying it by the rest of the day is accurate. DayTimer + = Time.deltaTime*4/oneDayTime; / / A cycle ends, restart if (dayTimer > = (float) colors.Length-1) {dayTimer = 0;} / / sample two colors, the first is the time color that is about to pass, and the second is the time color that is coming. We round down and up through two mathematical methods. Color color01 = colors [Mathf.FloorToInt (dayTimer)]; Color color02 = colors [Mathf.CeilToInt (dayTimer)]; / / the proportion of two colors, we can do it by taking the fractional part of time. Float weight = dayTimer-Mathf.FloorToInt (dayTimer); / / use weights to fuse colors currentColor = Color.Lerp (color01, color02, weight); / / modify global colors. _ SkyColor has been written to all shader Shader.SetGlobalColor ("_ SkyColor", currentColor); / / modify global time, which is mainly used to control the map fusion Shader.SetGlobalFloat ("_ DayAndNightChange", dayTimer) of the sky box.

}

The last line of the code is to modify the map fusion of the sky box, yes, the light has changed, how can the sky box remain the same, so I used four sky box maps to do too much, listening to the memory is a little tight, right? If you want to save, you can use a map to change the color, but the effect may not be so good. Art students can draw all four pictures for you.

As for the shader of Sky Box, it is also very simple. I used a float attribute to blend the four maps. The key code is as follows.

/ / the focus is on this variable. The mapping of the four periods is sampled and fused by modifying the parameters of this variable globally. / / the range of this variable is consistent with the time of the script, which is a cycle of 0-4. The last period is the same as the first one, which is float _ DayAndNightChange in the early morning.

Half4 frag (v2f I): SV_Target {/ / is basically some fusion algorithm, which first uses time to calculate the color proportion of each map, and then adds it together. / / this is only one side of the sky box is calculated, and the following Pass algorithm is the same half4 col01 = skybox_frag (iGrainTex01, _ Tex01_HDR) * (saturate (1-_ DayAndNightChange)); half4 col02 = (skybox_frag (idhowTex02, _ Tex02_HDR) * (saturate (2-_ DayAndNightChange)-(skybox_frag (iRegent Tex02, _ Tex02_HDR) * (saturate (1-_ DayAndNightChange) Half4 col03 = (skybox_frag (iGrainTex03, _ Tex03_HDR) * (saturate (3-_ DayAndNightChange)-(skybox_frag (iGrainTex03, _ Tex03_HDR) * (saturate (2-_ DayAndNightChange); half4 col04 = (skybox_frag (iGrainTex04, _ Tex04_HDR) * (saturate (4-_ DayAndNightChange)-(skybox_frag (iGrainTex04, _ Tex04_HDR) * (saturate (3-_ DayAndNightChange) Half4 col05 = skybox_frag (I DayAndNightChange Tex01, _ Tex01_HDR) * (saturate (_ DayAndNightChange-3)); half4 c = col01 + col02+col03+col04+col05; return c;}

The code is redundant and there is a lot of room for modification. But if you look at it this way, it is clearer that you use the attribute _ DayAndNightChange to sample each map and then fuse it.

Okay, here I just achieve a simple version of the effect, if you want to use in the project, and achieve good results, there are many things to consider, for example, to change the color of the fog globally, and to turn on some lighting effects and torch effects at night. You can also write a method to jump to a certain time. And if there are too many of these attributes, it is best to modify the editing window, otherwise the art students will look very messy.

As for performance, this system is still very easy to control, personal recommended time change is not as I wrote once per frame, can be controlled, such as 0.1s once.

I am also attached to the above simple project. If there is anything wrong, please correct it.

By the way, the scene may be black when the project is opened, just run it once. The reason is that the globally modified variable, that is, the _ SkyColor, is black when there is no assignment. This thing may need to be changed in the later stage.

The above is all the contents of the article "how to achieve simple diurnal changes based on Unity Shader Lighting Map". Thank you for reading! Hope to share the content to help you, more related knowledge, welcome to follow the industry information channel!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report