/* * 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. */ /* Simple Ambient Occlusion * Version 1.2 : added self occlusion only * * 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 general purpose Ambient Occlusion You can use it for color or for closure, or for both at same time. if you connect use just the ' ColorIn ' or just the ' closureIn ' inputs and connect nothing to 'ColorHit' or 'closureHit'. then Occlusion will be black. AO Angle is in RADIANS, 1.0 = 180° AO search Maxdistance limit distance of occluding objects. Oversampling : finer AO, but render time increment linearly. SelfOcclusionOnly : if 1, AO is per object, ignoring other objects. AOgamma give a linear effect (1.0) or a more 'lighting' effect (2.2, for example) * 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 */ /* #include "stdosl.h" #include "oslutil.h" */ shader GAO( color ColorIn = color(1.0,1.0,1.0), color ColorHit = color(0.0 , 0.0 , 0.0 ), closure color closureIn = ColorIn * emission() , closure color closureHit = ColorHit * emission() , float AO_Angle = 0.95 , float maxDistance = 25.0 , float OverSampling = 4.0 , float AOgamma = 2.2 , int SelfOcclusionOnly = 0 , vector Normalbump = vector (0.0 , 0.0 , 0.0), output color CoulOut = color(1.0,0.0,0.0) , output closure color closureOut = closureIn ) { // Disable diffuse emission from this material int RTdiffuse = raytype ("diffuse") ; if ( RTdiffuse ) { closure color NullClosure = 0.0 ; CoulOut = 0.0 ; closureOut = NullClosure ; } else { float MixOut = 0.0 ; float mixage = 0.0 ; float ObjectIndex = 1 ; int trcu = getattribute("object:random", ObjectIndex) ; // NEW VERSION of Loop // Loop init int Loopi = 0 ; float LoopShift = 0.0007 ; for( Loopi ; Loopi < OverSampling ; Loopi++ ) { LoopShift += 0.001 ; // compute vector to trace Ray = random * N + subtle variations... vector VectorAO = N + Normalbump + ( LoopShift * noise("perlin", P*(10000.0+Loopi) ) ) ; if ( AO_Angle != 0.0 ) { vector bruitvector = AO_Angle * noise("perlin", VectorAO*(10000.0+Loopi) ); VectorAO += bruitvector ; } // init for trace float Dist = 1.0 ; vector DirTrace = VectorAO ; float MaxDistTrace = maxDistance ; // Trace one Ray int DoTrace = trace (P, DirTrace , "maxdist" , MaxDistTrace ) ; if ( DoTrace ) { // If hit something float ObjectPercut = 0 ; int HitTrace = getmessage ("trace", "object:random" , ObjectPercut ) ; if( (SelfOcclusionOnly == 1 ) && ( ObjectPercut != ObjectIndex ) ) { MixOut += 1.0 * (1.0/OverSampling) ; } else { // Get the distance of the hit. Currently doesn't work with VRay 3.0. int HitTrace = getmessage ("trace", "hitdist" , Dist ) ; mixage = clamp ( (Dist / maxDistance) , 0.0 , 1.0 ) ; // Add 1/x of loop contribution MixOut += mixage * (1.0/OverSampling) ; } } else { // else, return white MixOut += 1.0 * (1.0/OverSampling) ; } } // Outputs MixOut = pow( MixOut , 1/AOgamma ) ; CoulOut = mix ( ColorHit , ColorIn , MixOut ) ; closureOut = (closureIn * MixOut) + closureHit * (1.0 - MixOut ) ; } // END NEW VERSION }