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