(This article is purely self-created, it is inevitable that there are omissions, but also hope that you do not hesitate to correct. )
Looked at a variety of volume light tutorials, tried to do a bit, found a lot of bugs, which have a textbook is added vertex displacement function to save the GPU. But after the move the whole model fell apart, and the square operation was executed 4 times, and the principle of the author is also very reluctant to speak. After reading the mood is very bad. Make a self-adjusting mood.
********************
First look at the volume of light in reality:
1. Fixed shape;
2. Translucent
3. There is a gradient feature,
4. The observation distance is close enough to be completely transparent;
**************
Two paths:
1 is a geometric shader; 2 is a polygon plus color.
The geometry shader is not supported inside unity, so this path is not available; only polygon + color is used.
You can use 3dmax to build several common models: cube, cylinder, and so on. You can also use the mesh class to build the model in your script. Save the method must still use 3dmax, haha ^_^
**************
First, to achieve these characteristics, consider the data structure :
float_fadeoutdistnear;//The closest distance to fade out, less than the value, and the minimum transparency, no longer changes float_fadeoutdistfar;//fade out the maximum distance, greater than this value, the transparency is maximum and no longer changes float_maxalpha;//Maximum Transparency float_minalpha;//Minimum Transparency float_DAMPX;//x-axis attenuation factor float_dampy;//y-axis attenuation factor float_dampz;//z-axis attenuation factor
I have added comments that are not difficult to understand.
Second, the core functional part
First realize the effect of transparency gradient, this is generally "manual" control, so there are data structures in the _DAMPX, Dampy, Dampz. (The data structure part should be placed in the process of algorithmic design, so it seems reasonable.) )
This part of my operation is in the object's local coordinate system. Before the vertex transitions to the world coordinate system, the center of the object is the origin point. This greatly reduces the resistance, as long as the model shape roughly rules, it does not need to go back and forth in the world coordinate system. (So be careful when modeling , Center as far as possible at one end )
The mathematical formula is also very simple, I only use the one-time operation, if you want to achieve a more smooth effect, can square several times. The code is as follows:
1 floatDampparam (float3 pos, Float3 Len,floatMinA,floatMaxA)2 {3 //Basic attenuation function of light4 floatatt;5ATT =1-Pos.z*len.z;//attenuation by square meter6 7Att *= (1-ABS (pos.x * len.x *len.x));8Att *= (1-ABS (POS.Y * LEN.Y *len.y));9 Ten returnlerp (MinA, MaxA, ATT); One}
The vertex transparency is then adjusted according to the observer position, which is less difficult and is directly on the code:
1 float Dampviewparam float float float float float maxA2 {3 // attenuation 4return due to observer position (lerp (Nfade, Ffade, Dist)-nfade) * (Maxa-mina)/(Ffade- nfade); 5 }
The final running result of the program:
Forgive me only to cut such a small figure, haha, the final works come out before the other details can not be too revealing. ^_^
Full version of the code:
1Shader"Custom/godray" {2 3 Properties {4_maintex ("Base Texture", 2D) =" White" {}5_maincolor ("Color", color) = (1,1,1,1)6_fadeoutdistnear ("Near fadeout Dist",float) =3 7_fadeoutdistfar ("Far fadeout Dist",float) =100008_maxalpha ("Maxalpha", Range (0,1)) =19_minalpha ("Minalpha", Range (0.001,1)) =0.01Ten One A_DAMPX ("dampx", Range (0,6) ) =0.3 //attenuation coefficient of volumetric light -_dampy ("Dampy", Range (0,6) ) =0.3 // -_dampz ("Dampz",float) =0.3 // the - } - - + Subshader { -Tags {"Queue"="Transparent" "Ignoreprojector"="True" "Rendertype"="Opaque" } + A Blend One Oneminussrccolor atCull off Lighting off Zwrite off Fog {Color (0,0,0,0) } - -Lod - - - - Cginclude in#include"Unitycg.cginc" - sampler2d _maintex; to fixed4 _maincolor; + float_fadeoutdistnear;//The closest distance to fade out, less than the value, and the minimum transparency, no longer changes - float_fadeoutdistfar;//fade out the maximum distance, greater than this value, the transparency is maximum and no longer changes the float_maxalpha;//Maximum Transparency * float_minalpha;//Minimum Transparency $ Panax Notoginseng float_DAMPX;//x-axis attenuation factor - float_dampy;//y-axis attenuation factor the float_dampz;//z-axis attenuation factor + A structv2f { the float4 pos:sv_position; + float2 uv:texcoord0; - fixed4 color:texcoord1; $ }; $ - - floatDampparam (float3 pos, Float3 Len,floatMinA,floatMaxA) the { - //Basic attenuation function of lightWuyi floatatt; theATT =1-Pos.z*len.z;//attenuation by square meter - WuAtt *= (1-ABS (pos.x * len.x *len.x)); -Att *= (1-ABS (POS.Y * LEN.Y *len.y)); About $ returnlerp (MinA, MaxA, ATT); - } - - floatDampviewparam (floatDistfloatNfade,floatFfade,floatMinA,floatMaxA) A { + //attenuation due to observer point position the return(Lerp (Nfade, Ffade, Dist)-nfade) * (Maxa-mina)/(Ffade-nfade); - } $ the the v2f Vert (appdata_full v) the { the v2f o; - in //local space of the model theFLOAT3 MPos =v.vertex.xyz; the About //in GL coordinates, the camera coordinates are always (0,0,0) the //so the length of the vertex world coordinates is the distance from the camera. theFLOAT3 Viewpos =Mul (Unity_matrix_mv,v.vertex). xyz; the floatDist =length (viewpos); + -FLOAT3 len =float3 (_dampx, _dampy, _dampz); the floatATT =Dampparam (MPos, Len, _minalpha, _maxalpha);Bayi theAtt *=Dampviewparam (Dist, _fadeoutdistnear, _fadeoutdistfar, _minalpha, _maxalpha); theO.COLOR.A =att; - -O.UV =V.texcoord.xy; theO.pos =Mul (UNITY_MATRIX_MVP, V.vertex); the the //O.color.rgb = _maincolor; the - returno; the the } the ENDCG94 the the Pass { the Cgprogram98 #pragmaVertex vert About #pragmaFragment Frag - #pragmaFragmentoption Arb_precision_hint_fastest101 fixed4 Frag (v2f i): COLOR102 {103 fixed4 Finalcolor;104Finalcolor = tex2d (_maintex, I.UV) *(I.COLOR.A); the 106 returnFinalcolor;107 }108 ENDCG109 } the }111}
In the end, a few more words:
Sleepy, sleep.
Unity shader--Volumetric Light