write in front
I have been thinking about how to do the following study, of course, I have to do on the side of the project while learning OpenGL, and occasionally turn over papers and so on. However, writing shader is a process that requires actual combat and hands-on experience, and imitation is the only way to learn early. Many people will ask, how to learn shader, read what books. Of course, my experience is not enough, the current route is: Master a coloring language + read a few classic books + Learn excellent shader instances + hands-on Practice + hands-on Practice + hands-on practice. Every one is not easy, so learning shader is a long and arduous process.
When it's time to be ~ So, after the surface shader series, I'm going to learn about the various case shader that are now available. These shader may come from some websites, perhaps from open source projects, or from a summary of my own reading. And Shadowgun is one of the open source projects.
Shadowgun
Shadowgun actually started out as a third-person shooter in the 2011 mobile platform. Of course, it was also developed with unity. That year, because of the excellent performance on the screen to win a lot of eyeballs ~ more commendable is, in 2012, its developers released a sample scenario, to let more developers learn how to optimize the mobile platform shader. Please poke the official blog. If you can't read English, you can read this article (well written). Nearly 20 optimized shader are included in the project. With regard to licensing issues, shader in the project are free to use, and stickers and models are not available for commercial use.
Although Shadowgun's play time is a bit long, but a lot of technology can learn from the drop ~ and it is still updated, and the price is high ¥30, it is visible to the degree of confidence.
Shadowgun contains several more important shader, such as the very famous banner fluttering shader, the dynamic effect of the sky box shader, ambient specular texture mapping and so on. and the smoke effect of this plane crash should be a very good understanding of shader. We also start from here to learn.
Smoke Effect
The smoke effects of the plane crash can be seen from:
The traditional implementation of this effect is usually the use of particle systems, and it is well known that the performance of the particle system consumes too much, not to mention the resource-constrained mobile platform. So Shadowgun uses a mesh + texture + move UV method to simulate this effect. At the same time, vertex color and transparency are cleverly used to simulate flame color and to smooth the edges of the mesh. The results appear to be acceptable from the screen .
See below for specific analysis.
Shader Source
Shader "Madfinger/environment/scroll 2 Layers Sine alphablended" {Properties {_maintex ("Base layer (RGB)", 2D) = "White" {}_detailtex ("2nd Layer (RGB)", 2D) = "White" {}_scrollx ("base layer Scroll speed X", Float) = 1.0_scrolly ("Base layer Scroll speed y ", float) = 0.0_scroll2x (' 2nd layer Scroll speed X ', Float) = 1.0_scroll2y (" 2nd Layer Scroll Speed Y ", Flo at) = 0.0_SINEAMPLX ("Base layer sine amplitude X", float) = 0.5 _sineamply ("Base layer sine amplitude Y", float) = 0.5_sin EFREQX ("Base layer sine freq X", float) = Ten _sinefreqy ("Base layer sine freq Y", float) = 10_sineamplx2 ("2nd layer sine Amplitude X ", float) = 0.5 _sineamply2 (" 2nd layer sine amplitude Y ", float) = 0.5_sinefreqx2 (" 2nd layer sine freq X ", float ) = Ten _sinefreqy2 ("2nd layer sine freq Y", Float) = 10_color ("Color", color) = (1,1,1,1) _mmultiplier ("Layer Multiplier", Float) = 2.0}subshader {Tags {"Queue" = "Transparent" "ignoreprojector" = "True" "rendertype" = "Transparent"}blend Srcalpha Oneminussrcalphacull Off Lighting off Zwrite off Fog {Color (0,0,0,0)}lod 100cginclude#pragma multi_compile lightmap_off lightmap_on#pragma excl Ude_renderers molehill #include "unitycg.cginc" sampler2d _maintex;sampler2d _detailtex;float4 _maintex_st;float4 _ Detailtex_st;float _scrollx;float _scrolly;float _scroll2x;float _scroll2y;float _MMultiplier;float _SineAmplX;float _sineamply;float _sinefreqx;float _sinefreqy;float _sineamplx2;float _sineamply2;float _SineFreqX2;float _SineFreqY2 ; Float4 _color;struct v2f {float4 pos:sv_position;float4 uv:texcoord0;fixed4 color:texcoord1;}; v2f Vert (Appdata_full v) {v2f O;o.pos = Mul (UNITY_MATRIX_MVP, V.vertex); o.uv.xy = Transform_tex (V.texcoord.xy,_maintex) + Frac (FLOAT2 (_SCROLLX, _scrolly) * _time) O.UV.ZW = Transform_tex (V.texcoord.xy,_detailtex) + frac (Float2 (_scroll2x, _ SCROLL2Y) * _time); o.uv.x + sin (_time * _sinefreqx) * _sineamplx;o.uv.y + sin (_time * _sinefreqy) * _sineamply;o.uv.z + = Sin (_time * _sinefreqx2) * _sineamplx2;o.uv.w + = sin (_time * _sinEFREQY2) * _sineamply2;o.color = _mmultiplier * _color * v.color;return o;} Endcgpass {cgprogram#pragma vertex vert#pragma fragment Frag#pragma fragmentoption arb_precision_hint_fastestfixed4 Frag (v2f i): color{fixed4 o;fixed4 tex = tex2d (_maintex, i.uv.xy); Fixed4 tex2 = tex2d (_detailtex, i.uv.zw); o = Tex * t EX2 * I.color;return o; ENDCG}}}
In factShadowgun in the shader are not long, but some shader to fully understand or need some time. Of course, this is still very simple ~
Subshader Tags
Tags {"Queue" = "Transparent" "ignoreprojector" = "True" "rendertype" = "Transparent"}
The tags used in this shader are standard for the rendering of translucent objects in unity. "Queue" = "Transparent" Indicates the render queue for the shader, "ignoreprojector"="True" Indicates that the shader is not affected by projector (translucent objects are generally set to true), "rendertype"="Transparent" indicated its rendering category, the document said can be used for shader replacement, but I do not understand now, some people know please leave a message to tell me ~ Thank you.
For instructions on Subshader tags, please see the official website.
Render Settings
Blend Srcalpha oneminussrcalphacull off Lighting off Zwrite off Fog {Color (0,0,0,0)}
This shader is characterized by the full use of alpha blending techniques, so the first line is to refer to its mixing coefficients. Alpha Blending is the focus of this article. After all the shader in the scene have been rendered, the pixels produced by each shader are written to the frame cache because their rendering is in a certain order, so how to control the blending order of these pixels is controlled by the blend directive. It specifies the blend coefficients of the source and target pixels, which are processed by this factor as output pixels. Specifically, this article and the official website. and Blend srcalpha oneminussrcalpha Is the factor used for alpha blending, which means that the alpha channel controls the pixel color.
Cull Off indicates that the shader does not reject the face, i.e. the back is also rendered.
Zwrite OFF indicates that the depth cache is not written, but that the display is determined based on the rendering order. In fact , "Queue"="Transparent" is automatically generated Of the zwrite Off statement.
Other commands can be found on the official website.
Algorithm Analysis
The key to this shader is the vert function:
v2f Vert (Appdata_full v) {v2f O;o.pos = Mul (UNITY_MATRIX_MVP, V.vertex); o.uv.xy = Transform_tex (V.texcoord.xy,_maintex) + Frac (FLOAT2 (_SCROLLX, _scrolly) * _time) O.UV.ZW = Transform_tex (V.texcoord.xy,_detailtex) + frac (Float2 (_scroll2x, _ SCROLL2Y) * _time); o.uv.x + sin (_time * _sinefreqx) * _sineamplx;o.uv.y + sin (_time * _sinefreqy) * _sineamply;o.uv.z + = Sin (_time * _sinefreqx2) * _sineamplx2;o.uv.w + = sin (_time * _sinefreqy2) * _sineamply2;o.color = _mmultiplier * _Color * V.color;return o;}
The main use of the following
function Formulas:
u = sin (freq * x) * Ampl + scroll * x;
The above formula represents the output in the U direction. This function is actually the sine wave function + once function, thus obtains the fluctuation effect in the particular direction. The function image of this function (where scroll = -2,ampl = 0.005,freq = 250) resembles the following:
It can be seen as a tilting wave that simulates the slow movement of the flame and the way it moves up.
Shader uses two textures to simulate the stereoscopic effect, each of which corresponds to 6 parameters, representing the function parameters in the U direction and v direction, respectively.
In addition to the use of functions, this shader also has a very clever place, that is, the use of vertex color . From the beginning of the dynamic graph can be seen that there is a red flame, but in fact this is not the color of the texture, but the vertex color. If we remove the textures, we can see that the real model is actually long:
In other words, its vertex color simulates the flame color. They skillfully use the vertex color itself and the value of its alpha channel to simulate transitions from flames to smoke. The following code, though with only one line, plays a key role:
O.color = _mmultiplier * _color * V.COLOR;
Shader allows us to be in the panel (via_mmultiplierAnd_colorAdjusts the overall color based on the vertex color and stores the result inv2fIn Note that the vertex color here, that is, v. Color , contains important transparency information, the transparent transition effect of smoke is actually its credit.
written in the last
Standing on the shoulders of the predecessors can always see farther. This shader is small, but it embodies a lot of common tricks: alpha blending, UV animation, using model vertex information to reduce texture input, and more. Thank the former people for their contributions and share, I hope you can have some gains ~ next time See!
One of the "Unity Shaders" Shadowgun Series--smoke effects from aircraft crashes