/* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* QUIPCam : Quick in Panorama, Spherical Camera Mapping. Put your object inside an Environment Map ! * * by François GASTALDO * * contact me at : pressf9@free.fr * * blog (3D, shaders, photos and more) : http://vadrouillegraphique.blogspot.fr/ * * Small Documentation : This shader is a Quick Environment Integration solution. It's made to make a quick integration of 3D object inside a full spherical panorama, or environment mapping. It's a kind of Spherical camera mapping to have a very fast result. It's a first step to more advanced 3D integration or FX. Just create a ground, plane or grid, and apply this shader to it. Then, create objects to mimic the real scene (box for building). You can do very precise work for real FX, or just lowpoly object if you have fast or far camera moves. documentation : environment_file = the ful spherical panorama, HDRI is better. It has to be the same as the one in world environment. gammaEnv = gamma correction of environment image. Use 1.0 or 2.2 to correct the gamma. WhiteBalance = White balance correction. Often, the environment lighting (IBL) give a colder look. Use this value, from 3000 to 15000, to correct the warmness or coldness of ground. Luminance = correct the darkness or brightness of ground. ZFade = distance to make a smooth transition to the real environment. Your ground plane should be bigger than this value. Use it a close as you can to have very smooth (invisible) transition. AODensity = 0.0 means No Ambient Occlusion, 1.0 = completely dark (black) Ambient Occlusion. * This shader is made for educationnal purpose only. Use it in production at your own risk. * * Closures are for Blender/Cycles. They could need adaptation for your renderer. * * If you use this shader, please credit it and me. Thank you. * * Enjoy ! * * François Gastaldo */ vector sphericalmap( point Pos , vector OriginMap , output float Usph , output float Vsph ) { vector LocalP = normalize ( Pos - OriginMap ) ; Usph = 0.75 + ( atan2( LocalP[0] , LocalP[1] ) + M_PI ) / M_2PI ; Vsph = 1.0 - ( atan2( LocalP[2] , sqrt( LocalP[0] * LocalP[0] + LocalP[1] * LocalP[1] ) ) + M_PI_2 ) / M_PI ; return LocalP ; } shader QUIPCam( string environment_file = "D:\HDRI-Enviro\DordogneHDRI\LabourChamps_4k.exr" , vector Origin = vector( 0.0 , 0.0 , 1.0 ) , float Pan_Rotation = 0.0 , float gammaEnv = 1.0 , float WhiteBalance = 6200.0 , float Luminance = 1.5 , float ZFade = 100 , float AODensity = 0.25 , // vector Normalbump = vector (0.0 , 0.0 , 0.0) , output closure color closureOut = 0.0 ) { // reserved : vector Normalbump = vector (0.0 , 0.0 , 0.0) ; // distance Fade float distcam = clamp ( length ( transform ( "camera" , P ) ) / ZFade , 0.5 , 1.0 ) ; int TooFar = ( distcam >= 1.0) ; if ( TooFar ) { closureOut = transparent() ; } else { // spherical map : float Usph ; float Vsph ; sphericalmap( P , Origin , Usph , Vsph) ; color enviro = texture( environment_file , Usph + ( Pan_Rotation / 360.0 ) , Vsph ,"wrap" , "periodic" ) ; enviro = pow ( enviro , gammaEnv ) ; // Closures : float MixTransp = ( distcam * 2.0 ) - 1.0 ; closure color transp = transparent() ; closure color emiss = enviro * emission() ; // correction enviro color colorWB = blackbody ( WhiteBalance ) ; vector corrcolo = normalize ( vector ( colorWB[0] , colorWB[1] , colorWB[2] ) ) ; colorWB = color ( corrcolo[0] , corrcolo[1] , corrcolo[2] ) ; float CorrLum = Luminance ; int RTdiffuse = raytype ("diffuse") ; if ( RTdiffuse ) { closureOut = emiss ; } else { // compute vector to trace Ray = random * N vector VectorAO = N + Normalbump + ( 0.001 * noise("perlin", P * 10000.0) ) ; vector bruitvector = 2.0 * noise("perlin", VectorAO*10000.0 ); VectorAO += bruitvector ; // Trace Ray for AO color AOcol = 1.0 ; float Dist = 1.0 ; float mixage = 1.0 ; vector DirTrace = VectorAO ; int DoTrace = trace (P, DirTrace ) ; //, "maxdist" , maxDistance ) ; if ( DoTrace) { // If hit something int HitTrace = getmessage ("trace", "hitdist" , Dist ) ; // mixage = pow( clamp ( (Dist / maxDistance) , 0.0 , 1.0 ) , 10 ) ; // make a gradient between the 2 colors to have smoother (and better quality) AO. AOcol = 1.0 - AODensity ; } closureOut = (1.0 - MixTransp ) * AOcol * CorrLum * colorWB * enviro * diffuse( N + Normalbump ) + MixTransp * transp ; } } }