/*==================================================================================== Original rain objects and macros by Jaime Vives Piqueres, 2007-2008. Changes by Thomas de Groot, 2013. Note: The macros rain_streak() and rain_spurt() have not been changed. They are available at Jaime's site: http://www.ignorancia.org/en/index.php?page=Raining ====================================================================================*/ #debug " Adding the rain...\n" // rain objects: // faked visibility loss (change to need): fog {fog_type 2 color White transmit 0.5 distance 100 fog_offset 0 fog_alt 8 turbulence <0.5, 1, 0.9> turb_depth 0.3} // rain water: #declare Rain_dist = 0.1; //determines the depth transparency of the water column #declare Rain_fd = -(Rain_dist/(6*25.4))/ln(0.58); //fade distance (formula by Trevor Quayle) #declare M_rainwater = material { texture { pigment {rgbft <0,0,0,1,1>} finish { conserve_energy diffuse 0.4 reflection {0.01, 0.2 fresnel on metallic 0} } normal {crackle 0.15 scale <0.45,0.25,0.25>*2 turbulence 0.5 } } interior { ior 1.33 media { absorption 0.3 density {rgb 1/Rain_fd} } media { samples 100 jitter 0.5 scattering {3, 0.2} density {rgb 1/Rain_fd} } } } // rain drop: #declare p_drop_base = pigment { function {abs(y)} pigment_map { [0 rgb 1] [1 rgbt 1] } } #declare t_drop = texture { pigment { cylindrical pigment_map { [0.75 p_drop_base] [1.00 rgbt 1] } } finish {emission 1} } //either use the original object (cylinder) or: #include "JVP_rain_drop_POV_geom.inc" #declare rain_drop = //cylinder {-y, y, 0.02 //original object object {JVP_rain_drop_ texture {t_drop} scale 0.5 double_illuminate } // rain drop splash: #declare p_splash_base = pigment { function {abs(y)} pigment_map { [0 rgbt 1] [1 rgb 1 transmit 0.0] } } #declare t_splash = texture { pigment { cylindrical pigment_map { [0.85 p_splash_base] [1.00 rgbt 1] } } finish {emission 1.0} } #declare splash_drop = cylinder{0, y*0.5, 0.025 texture {t_splash} scale 0.5 double_illuminate } #declare splash_ring = torus {0.5, 0.05 scale 0.75 hollow } #declare r_spld = seed(77); #declare i_spld = 0; #declare n_spld = 50; #declare splash = union { #while (i_spld < n_spld) #declare spt = pow(rand(r_spld),2); object {splash_drop rotate 180*spt*x// curvature translate spt*z*2 // distance translate spt*sin(pi*spt)*y*rand(r_spld)*1 // height rotate 360*rand(r_spld)*y // randomize } #declare i_spld = i_spld+1; #end } //==================================================================================== // rain macro 1: // place the rain drops randomly within a defined volume // with variable wind angle and drop density #macro rain_over( num_drops, // number of drops rain_on, // area over which rain falls (no rain inside this object) rain_area_min, // volume to trace (min) rain_area_max, // volume to trace (max) rain_wind_angle, // rotation vector (wind) rain_scale, // scale for the drops rain_seed, // seed for the random placement rain_write // write drop parameters to file (on/off) ) #if (rain_write) #debug " writing rain drop info...\n" #fopen DropFile "RainDrops.inc" write #write (DropFile, "//Rain drop parameters\n") #local r_rain = seed(rain_seed); #local i_drops = 0; #local RainBox = box {rain_area_min, rain_area_max} //a function to gather drops together (from Kirk Andrews) #local F_drops = function { pattern { bumps turbulence 0.1 scale 5 //change this value according to need } } #while (i_drops <= num_drops) #local rain_drop_pos = VRand_In_Obj(RainBox, r_rain); #if (F_drops(rain_drop_pos.x,rain_drop_pos.y,rain_drop_pos.z) < 0.5+rand(r_rain)*0.1 & !inside(rain_on,rain_drop_pos)) #local rain_drop_ang = rain_wind_angle+RRand(-1,1,r_rain); #local Dist = VDist(CamLoc, rain_drop_pos); #local Dist_scale = rain_scale + (/100); #write (DropFile, rain_drop_ang, ", ", rain_drop_pos, ",", Dist_scale, ",","\n") #if (mod(i_drops, num_drops/100) = 0) #debug concat(" drops: ", str(i_drops,3,0), "\n" ) #end #local i_drops = i_drops+1; #end //if #end //while #fclose DropFile #end //if #debug " reading rain drop info...\n" #fopen DropFile "RainDrops.inc" read #while (defined(DropFile)) #read (DropFile, rain_drop_ang, rain_drop_pos, Dist_scale) object {rain_drop scale Dist_scale rotate rain_drop_ang translate rain_drop_pos } #end #end //==================================================================================== // rain macro 2: // place splashes from drops falling within a defined area // using trace to detect surfaces to splash on #macro rain_splashes( object_to_trace, // object to splash on num_splash, // num of splashes rain_area_min, // area to trace (min). Defines a volume above the surface rain_area_max, // area to trace (max) splash_scale, // scale of the splashes splash_seed // random seed for placement ) #local r_splash = seed(splash_seed); #local i_splash = 0; #local RainBox = box {rain_area_min, rain_area_max} union { #while (i_splash <= num_splash) // trace vertically to find splash pos #local Norm = <0,0,0>; #local Start = VRand_In_Obj(RainBox, r_splash); #local Inter = trace(object_to_trace,Start,-y,Norm); object {splash scale <1, 1+2*rand(r_splash), 1> scale splash_scale*(0.1+0.3*rand(r_splash)) rotate 360*rand(r_splash)*y Reorient_Trans(y,Norm) translate Inter } #local i_splash = i_splash+1; #end } #end //==================================================================================== // rain macro 3: // splash variant with rings from drops falling on a defined water surface // using trace to detect surfaces to splash on #macro rain_splashes_with_rings( object_to_trace, // object to splash on num_splash, // num of splashes rain_area_min, // area to trace (min). Defines a volume above the surface rain_area_max, // area to trace (max) splash_scale, // scale of the splashes splash_seed // random seed for placement ) #local r_splash = seed(splash_seed); #local i_splash = 0; #local RainBox = box {rain_area_min, rain_area_max} union { #while (i_splash <= num_splash) #local Norm = <0,0,0>; #local Start = VRand_In_Obj(RainBox, r_splash); #local Inter = trace(object_to_trace,Start,-y,Norm); #if (vlength(Norm) != 0) #local ring_rad = rand(r_splash); object {splash scale <1, 1+2*rand(r_splash), 1> scale splash_scale*(0.1+0.3*rand(r_splash)) rotate 360*rand(r_splash)*y Reorient_Trans(y,Norm) translate Inter } object {splash_ring scale <0.5, 1, 0.5> scale <1, 0.25, 1>*ring_rad*splash_scale Reorient_Trans(y,Norm) translate Inter } object {splash_ring scale <1, 0.25, 1>*ring_rad*splash_scale Reorient_Trans(y,Norm) translate Inter } object {splash_ring scale <1.5, 1, 1.5> scale <1, 0.25, 1>*ring_rad*splash_scale Reorient_Trans(y,Norm) translate Inter } #local i_splash = i_splash+1; #end //of #if #end //of #while } #end //==================================================================================== /* Examples of macro uses: #declare r_rain=seed(2802); // random seed #declare SplashObj = object {hf} // rain in the air: #local Rain = union { rain_over( 300000, // number of drops SplashObj, // area over which rain falls (no rain inside this object) , // rain volume (min) , // rain volume (max) <-10,0,30>, // rotation vector (wind) 0.08, // scale for the drops int(1000*rand(r_rain)), // seed for the random placement off // write drop parameters to file (on/off) ) } // rain splashes on objects: rain_splashes( SplashObj, // object to splash on 6000, // num of splashes , // area to trace (min) , // area to trace (max) 0.05, // scale of the splashes int(1000*rand(r_rain)) // random seed for placement ) // rain splashes on water: union { //or merge with transparent water (note: increases render time!) rain_splashes_with_rings( SplashObj, // object to splash on 3000, // num of splashes , // area to trace (min) , // area to trace (max) 0.05, // scale of the splashes int(500*rand(r_rain)) // random seed for placement ) object {SplashObj} //material {M_rainwater} //the rings need the same texture as the water surface pigment {rgb <1, 1, 1> transmit 0.5} finish {reflection {0.01, 1} conserve_energy} } */