1/* Beta-0.4.7: MOSAIC default atmosphere shader for Blender integration */
2
3#define VOLUME_UTILITIES 1
4#include "MOSAICfunctions.h"
5
6volume
7MOSAICfog(
8    uniform float HazeRadius            = 0.1;
9    uniform float HazeSamples           = 2;
10    uniform float HazeEnergy            = 2;
11    uniform float HazeDist              = 1;
12    uniform float HaloVary1             = 0;
13    uniform point HaloVary1Scale        = point "world" (1, 1, 1);
14    uniform point HaloVary1Offset       = point "world" (0, 0, 0);
15    uniform float HaloVary2             = 0;
16    uniform point HaloVary2Scale        = point "world" (4, 4, 4);
17    uniform point HaloVary2Offset       = point "world" (0, 0, 0);
18    uniform float HaloAtten             = 2;
19    uniform float HaloFactor            = 1;
20    uniform float HaloJitter            = 1;
21    uniform float HaloStepSize          = 0.2;
22    uniform float HaloMaxSteps          = 10000;
23	uniform float MistUF_X0[6]			= {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
24	uniform color MistUC_X0[1]			= {color(1.0, 1.0, 1.0)};
25 output varying color _mistcolor     = 0;    //Mist color channel for AOV
26    output varying float _mistalpha     = 0;)   //Mist alpha depth channel for AOV
27{
28    //// Lets setup general purpose variables...
29    varying float                       p1, p2, p3, p4, nonfog = 0, halolights = 0, atten = 1;
30    varying float Li                    = length(I);
31    varying float atype                 = (MistUF_X0[MIST_UF_MISTTYPE] == 0 ? 3 : MistUF_X0[MIST_UF_MISTTYPE]);
32    varying color                       mist = color(0), halo = color(0);
33    uniform string rendertype           = "beauty";
34
35    //// Lets manage parameter passing...
36    surface("__nonfog", nonfog);
37    attribute("user:render_halos", halolights);
38    attribute("user:render_type", rendertype);
39
40    //// Lets do it...
41
42    // Are we using light halos?
43    if (nonfog == 0 && halolights > 0)
44    {
45        float                           samples = 0, step = 0, sta = 0, dis = 1;
46        point WO                        = P-I;
47        point O                         = transform("shader", WO);
48        vector In                       = normalize(vtransform("shader", I));
49        vector WIn                      = vtransform("shader", "current", In);
50
51        // If attenuation is off then use clipping distances instead of mist settings...
52        if (HaloAtten == 0 || (HaloAtten == 2 && MistUF_X0[MIST_UF_ISMIST] == 0))
53        {
54            float clip[2]               = {0, 0};
55            option("Clipping", clip);
56            sta                         = clip[0];
57            dis                         = clip[1]-sta;
58        }
59        // Otherwise use mist diatance settings...
60        else
61        {
62            sta                         = MistUF_X0[MIST_UF_MISTSTA];
63            dis                         = MistUF_X0[MIST_UF_MISTDI];
64        }
65
66        float start                     = sta+random()*HaloJitter*HaloStepSize;
67        float end                       = min(length(I), start+dis, start+HaloStepSize*HaloMaxSteps);
68        float steps                     = min(dis, HaloStepSize*HaloMaxSteps)/HaloStepSize;
69
70        // Step from front to back towards volume point...
71        for (step = start; step <= end; step += HaloStepSize)
72        {
73            point Ws                    = WO+step*WIn;
74            point Os                    = O+step*In;
75
76            // Step through all lights at volume point...
77            illuminance(Ws)
78            {
79                // Does current light use halo?
80                float halolight         = 0;
81                lightsource("__foglight", halolight);
82
83                // Only process halo lights for illuminated points...
84                if(halolight > 0 && Cl != color(0) && (rendertype == "beauty" || rendertype == "environment_map" || rendertype == "user_pass"))
85                {
86                    color hazecolor     = color(0);
87                    float halovary      = 1;
88                    float haloint       = 1;
89                    string shadowname   = "";
90                    string depthname    = "";
91                    string hazename     = "";
92                    string depthmap     = "";
93                    lightsource("__haloint", haloint);
94                    lightsource("__hazename", hazename);
95                    lightsource("__shadowname", shadowname);
96                    lightsource("__depthname", depthname);
97
98                    // Use special depth map if specified otherwise use standard shadow map...
99                    if (depthname != "")
100                        depthmap        = depthname;
101                    else
102                        depthmap        = shadowname;
103
104                    // Lets figure halo attenuation if used...
105                    if (HaloAtten == 1 || (HaloAtten == 2 && MistUF_X0[MIST_UF_ISMIST] > 0))
106                    {
107                        p1              = step-start;
108                        p2              = MistUF_X0[MIST_UF_MISTDI];
109                        atten           = Attenuate(atype, p1, p2, 0, 0, 1);
110                        // Lets mix in height attenuation if used...
111                        if (MistUF_X0[MIST_UF_MISTHI] > 0)
112                            atten       = mix(atten, 1, 1-clamp(zcomp(transform("world", Ws))/MistUF_X0[MIST_UF_MISTHI], 0, 1));
113                        // Lets adjust overall attenuation by mist intensity...
114                        if (MistUF_X0[MIST_UF_MISTINT] > 0)
115                            atten       *= 1-MistUF_X0[MIST_UF_MISTINT];
116                    }
117
118                    // Lets figure 3D density variance if used...
119                    if (HaloVary1 > 0)
120                    {
121                        point S1        = transform("shader", HaloVary1Scale);
122                        point O1        = transform("shader", HaloVary1Offset);
123                        halovary        *= max(0, mix(1, float noise((Os+O1)*S1), HaloVary1));
124                    }
125                    if (HaloVary2 > 0)
126                    {
127                        point S2        = transform("shader", HaloVary2Scale);
128                        point O2        = transform("shader", HaloVary2Offset);
129                        halovary        *= max(0, mix(1, float noise((Os+O2)*S2), HaloVary2));
130                    }
131
132                    // Add ray or image based haze to volume if used...
133                    if (atten > 0 && halovary > 0 && hazename != "")
134                        hazecolor       = volumehaze(hazename, depthmap, Ws, HazeSamples, HazeRadius, HazeDist)*HazeEnergy;
135
136                    // Lets put it all together...
137                    halo                += (Cl+hazecolor)*haloint*halovary*HaloFactor*atten;
138                }
139            }
140        }
141
142        halo                            /= steps;
143
144        // If attenuation is off then use halo intensity to determine mixing...
145        if (HaloAtten == 0 || (HaloAtten == 2 && MistUF_X0[MIST_UF_ISMIST] == 0))
146            atten                       = 1-clamp(comp(ctransform("hsv", halo), 2), 0, 1);
147    }
148
149    // Are we using mist?
150    if (nonfog == 0 && MistUF_X0[MIST_UF_ISMIST] > 0)
151    {
152        mist                            = MistUC_X0[MIST_UC_MISTCOL];
153
154        // Lets figure mist attenuation if used...
155        if (Li > MistUF_X0[MIST_UF_MISTSTA])
156        {
157            p1                          = Li-MistUF_X0[MIST_UF_MISTSTA];
158            p2                          = MistUF_X0[MIST_UF_MISTDI];
159            atten                       = Attenuate(atype, p1, p2, 0, 0, 1);
160            // Lets mix in height attenuation if used...
161            if (MistUF_X0[MIST_UF_MISTHI] > 0)
162                atten                   = mix(atten, 1, clamp(zcomp(transform("world", P))/MistUF_X0[MIST_UF_MISTHI], 0, 1));
163            // Lets adjust overall attenuation by mist intensity...
164            if (MistUF_X0[MIST_UF_MISTINT] > 0)
165                atten                   *= 1-MistUF_X0[MIST_UF_MISTINT];
166        }
167    }
168
169    //// Lets mix the results...
170    mist                                += halo;
171    _mistalpha                          = atten;
172    _mistcolor                          = mist;
173    Ci                                  = mix(mist, Ci, atten);
174    Oi                                  = mix(color(1), Oi, atten);
175}
176