/*================================================================================================== This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA. Persistence of Vision Ray Tracer Scene Description File File: Granite_21.mcr [beta #1.5] Vers: 3.7+ Desc: Granite macro, based on the original code by Daniel Mecklenburg Jr. from 1996. -> Change to Master Macro reading a suite of different granite include files (to be developed). Usage of the macro can be found at end of this file! Date: 29 May 2021 Auth: Thomas de Groot ====================================================================================================*/ // These are the parameters controlling the macro. Copy and use in your own scene /* Required parameters: ------------------- #declare Granite_file = "DakotaRedGranite.inc" //[default: "DakotaRedGranite.inc"] the granite file to be included into the macro #declare CSC = 2; //[default: 2] 1 = 'raw' sRGB; 2 = sRGB conversion; every other value is rgb #declare Pol = off; //[default: off] on = polished; off = frosted #declare Typ = 1; //[default: 1] 1 = no veins; 2 = veins [2 = still EXPERIMENTAL] #declare Pat1 = 2; //[default: 2] stone pattern: 1 = cells; 2 = step noise; 3 = crackle solid #declare Pat2 = 3; //[default: 3] pigment_pattern: 1 = cells mask; 2 = step noise mask; 3 = crackle solid mask #declare Blend = off; //[default: off] on = the granite pattern is blended/blurred (weathering); off = the pattern is 'fresh' Optional parameters: ------------------- #declare SN_Start = 0.2; //[default: 0.2] Step Noise range 0.0 to 1.0, =< SN_End! #declare SN_End = 0.8; //[default: 0.8] Step Noise range 0.0 to 1.0, >= SN_Start! #declare SN_Turb = 0.325; //[default: 0.325] Step Noise turbulence #declare BC_Blur = 2; //[default: 2] Blended Cells blurriness Optional transforms for the material: ------------------------------------ #declare M_scale = <1.0, 1.0, 1.0>; //[default: <1.0, 1.0, 1.0>] be careful with the scaling of the material! #declare M_rotat = <0.0, 0.0, 0.0>; //[default: <0.0, 0.0, 0.0>] #declare M_trans = <0.0, 0.0, 0.0>; //[default: <0.0, 0.0, 0.0>] Experimental parameters: ----------------------- #declare SS = off; //[default: off] subsurface translucency #declare Translucency = <0.669, 0.229, 0.198>*1; //[default: <0.669, 0.229, 0.198>*1] this is an experimental choice based o the Dakota Red Granite. example code to be copied and changed, to the global_settings of your scene file: -------------------------------------------------------------------------------- #if (SS) mm_per_unit 10 subsurface { radiosity off //samples 100, 40 } #end */ /*====================================================================================================*/ /*== (0) =============================================================================================*/ // Start of the Granite macro declaration and additional necessary presets #macro Granite_21 () /*---------------------------------------- Presets -------------------------------------------------*/ #ifndef (_FUNCTIONS_INC) #include "functions.inc" #end #ifndef (_GRANITE_FILE_INC_) #include "DakotaRedGranite.inc" #end #include Granite_file #ifndef (CSC) #local CSC = 2; #end #ifndef (Pol) #local Pol = off; #end #ifndef (Typ) #local Typ = 1; #end #ifndef (Pat1) #local Pat1 = 2; #end #ifndef (Pat2) #local Pat2 = 3; #end #ifndef (Blend) #local Blend = off; #end #ifndef (SS) #local SS = off; #end #ifndef (Translucency) #local Translucency = <0.669, 0.229, 0.198>*1; #end /*---------------------------------------------------------------------------------------------------- By Bald Eagle: No values in the (s)rgb triplets should ever be zero. First, because there are almost never absolutely black objects in real life ("vanta black"); Second, because there is no way to modify it with a multiplier. If you had a red value of one millionth, you could multiply that by a million to get 1. But anything multiplied by zero is always zero. ----------------------------------------------------------------------------------------------------*/ #local not_0 = 1/265; /*---------------------------------------------------------------------------------------------------- By Bald Eagle: Step Noise pattern; with SN_Start and SN_End of the Smoothstep function set both to the same value (0-1) corresponds to the cells pattern; with SN_Start = 0, SN_End = 1 comes as close as this can get to f_noise3d() ----------------------------------------------------------------------------------------------------*/ #ifndef (SN_Start) #local SN_Start = 0.2; #end #ifndef (SN_End) #local SN_End = 0.8; #end #ifndef (SN_Turb) #local SN_Turb = 0.325; #end // smoothstep function #local SN_K = function (t1, t2, T) {max (0, min(1, (T-t1)/(t2-t1) ) )} #local SN_Smoothstep = function (t1, t2, T) {pow (SN_K(t1, t2, T), 2) * (3-2*SN_K(t1, t2, T))} // mod function that plays nice when crossing 0 #local SN_Mod = function (T) {select (T, 1-mod (abs(T), 1), mod (abs(T), 1) )} // smoothstep function //#local SN_N = function (NN) {floor (NN-0.5) + Smoothstep (SN_Start, SN_End, abs(SN_Mod(NN-0.5)-0.5) )} #local SN_N = function (NN) {floor (NN) + SN_Smoothstep (SN_Start, SN_End, SN_Mod(NN) )} /* usage: #declare StepNoise = pigment { function {f_noise3d (SN_N(x), SN_N(y), SN_N(z))} turbulence SN_Turb } */ /*---------------------------------------------------------------------------------------------------- Color Space conversion - A combination of two macros: 1. Transformation functions from scRGB (linear color space) -> sRGB; 2. Colour saturation/brightness variation code by Clipka. [povray.advanced-users 15-07-2016: Reverse engineering pigments and textures by BaldEagle] ----------------------------------------------------------------------------------------------------*/ //Default Saturation and Brightness values for Clipka's saturation macro: #ifndef (SatBoost) #declare SatBoost = 0.01; #end #ifndef (BrightBoost) #declare BrightBoost = -0.1; #end //0 = no brightness change; >0 = brighter; <0 = darker #macro Convert(CSC, SatBoost, BrightBoost, Color) #switch (CSC) #case (1) #local MyColour = srgb Color; #break #case (2) #local sRGB_Gamma = function(C) {select(C-0.0031308, C*12.92, 1.055*pow(C, 1/2.4)-0.055)} #local SB = SatBoost; // Saturation boost #local VB = BrightBoost; // Brightness ("volume") boost #local RawColour = srgb ; #local SatColour = RawColour-SB; #local MyColour = SatColour*(1+VB)*RawColour.gray/SatColour.gray; #break #else #local MyColour = rgb Color; #end MyColour #end /*---------------------------------------------------------------------------------------------------- By Ive: the 0.5 value for Granite_Specular_strength is just my personal preference and taste because people in the old times did have a tendency to overuse these faked specular highlights way too much making everything look like plastic. ----------------------------------------------------------------------------------------------------*/ #declare Granite_Specular_strength = 0.5; #declare Granite_Reflection_strength = 0.15; //Two little macros to be applied to the frosted version of the granite: //A small amount of highlights for realism #macro Dull_Highlights() specular 0.05 roughness 0.1 #end //A replacement for the crand in the finish block of the original texture #macro Crand(Intensity) texture { pigment { granite color_map { [1/3 rgb 0.001 transmit 1] [2/3 rgb 0.001 transmit max(0,1-Intensity) ] } scale 0.05 } } #end /*---------------------------------------------------------------------------------------------------- By Tekno Frannansa (23-2-2007): Blended Cells. Offset the unit squares pattern (done in a macro in case I want cells picking patterns). Somehow, cells don't quite line up with the blend gradient, but an addition of .001 completely fixes it!!! ----------------------------------------------------------------------------------------------------*/ #macro mycells(Pat1, Offset) #if (Pat1 = 1) P_Granite #elseif (Pat1 = 2) P_Granite_SN #elseif (Pat1 = 3) P_Granite_crackle #else #debug "\nAttention! Pat1 should be 1, 2 or 3! 3 is used instead.\n" P_Granite_crackle #end translate Offset + .001 #end //blur the pattern #ifndef (BC_Blur) #local BC_Blur = 2; #end #macro blend(V) pigment_pattern { //gradient controlling the blend gradient V //phase .001 //mess with this colour map to reduce blend region colour_map { [0.5-BC_Blur/2 rgb 0] [0.5+BC_Blur/2 rgb 1] } } cubic_wave #end /*== (1) =============================================================================================*/ // The colour_maps of the Granite #local C_Granite_map1 = //the granite colour_map proper color_map { #if (version >= 3.8) blend_mode 2 #end #for (J, 0, Map1_entries-1, 1) #local Entry = Convert (CSC, SatBoost, BrightBoost, ); [A_Granite_map1[J][0] Entry] #end } #local C_Granite_map2 = //quartz vein colour_map color_map { #if (version >= 3.8) blend_mode 2 #end #for (J, 0, Map2_entries-1, 1) #local Entry = Convert (CSC, SatBoost, BrightBoost, ); [A_Granite_map2[J][0] Entry transmit A_Granite_map2[J][4]] #end } /*== (2) =============================================================================================*/ // The different masks used as pigment_pattern for the Dakota Red Granite #local C_Granite_mask_map = //the mask based on the granite colour_map proper color_map { #if (version >= 3.8) blend_mode 2 #end #for (J, 0, Mask_entries-1, 1) #local Entry = rgb ; [A_Granite_mask_map[J][0] Entry] #end } #local P_Granite_mask = //mask to distribute large and small minerals using cells pigment { cells warp {turbulence 0.425} //(0.325 is too low) color_map {C_Granite_mask_map} warp {turbulence 0.1} //some extra turbulence for the mask scale 0.075 } #local P_Granite_mask_SN = //mask to distribute large and small minerals using step noise pigment { function {f_noise3d (SN_N(x), SN_N(y), SN_N(z))} warp {turbulence SN_Turb octaves 2 lambda 1 omega 2} color_map {C_Granite_mask_map} //warp {turbulence 0.1} //some extra turbulence for the mask scale 0.075 } #local CrackleMask = pigment { crackle solid turbulence 0.1 lambda 2.5 omega 0.75 octaves 5 scale 0.75 frequency 1 phase 0.25 rotate <0, 45, 60> color_map { [0.00 rgb <1.00, 1.00, 1.00> ] [0.05 rgb <0.10, 0.10, 0.10> ] [0.10 rgb <0.90, 0.90, 0.90> ] [0.15 rgb <0.20, 0.20, 0.20> ] [0.20 rgb <0.80, 0.80, 0.80> ] [0.25 rgb <0.30, 0.30, 0.30> ] [0.30 rgb <0.70, 0.70, 0.70> ] [0.35 rgb <0.40, 0.40, 0.40> ] [0.40 rgb <0.60, 0.60, 0.60> ] [0.45 rgb <0.50, 0.50, 0.50> ] [0.50 rgb <0.50, 0.50, 0.50> ] [0.55 rgb <0.60, 0.60, 0.60> ] [0.60 rgb <0.40, 0.40, 0.40> ] [0.65 rgb <0.70, 0.70, 0.70> ] [0.70 rgb <0.30, 0.30, 0.30> ] [0.75 rgb <0.80, 0.80, 0.80> ] [0.80 rgb <0.20, 0.20, 0.20> ] [0.85 rgb <0.90, 0.90, 0.90> ] [0.90 rgb <0.10, 0.10, 0.10> ] [0.95 rgb <1.00, 1.00, 1.00> ] [1.00 rgb <1.00, 1.00, 1.00> ] } } /*== (3) =============================================================================================*/ // The pigments for the Dakota Red Granite #local P_Granite = //basic granite pigment using the cells pattern pigment { cells warp {turbulence 0.425} //(0.325 is too low) color_map {C_Granite_map1} scale 0.1 } #local P_Granite_SN = //basic granite pigment using the step noise pattern pigment { function {f_noise3d (SN_N(x), SN_N(y), SN_N(z))} warp {turbulence SN_Turb octaves 2 lambda 1 omega 2} color_map {C_Granite_map1} scale 0.1 } #local P_Granite_crackle = //basic granite pigment using the crackle solid pattern pigment { pigment_pattern {CrackleMask scale 0.75} color_map {C_Granite_map1} scale 0.1 } #local P_Granite_blend = //basic granite pigment using blended cells pattern pigment { blend(x) pigment_map { [0 blend(y) pigment_map { [0 blend(z) pigment_map { [0 mycells(Pat1,<1,1,1>)] [1 mycells(Pat1,<1,1,0>)] } ] [1 blend(z) pigment_map { [0 mycells(Pat1,<1,0,1>)] [1 mycells(Pat1,<1,0,0>)] } ] } ] [1 blend(y) pigment_map { [0 blend(z) pigment_map { [0 mycells(Pat1,<0,1,1>)] [1 mycells(Pat1,<0,1,0>)] } ] [1 blend(z) pigment_map { [0 mycells(Pat1,<0,0,1>)] [1 mycells(Pat1,<0,0,0>)] } ] } ] } } /*== (4) =============================================================================================*/ // The pigment for the veins crossing the Dakota Red Granite [EXPERIMENTAL!] #local P_Granite_veins = //quartz veins through the granite pigment { marble frequency 0.25 color_map {C_Granite_map2} scale <0.15, 1.0, 1.0> warp {turbulence <0.35, 0.05, 0.30>} translate <20.0, 20.0, 33.0> rotate <0.3, 0.2, -25.0> } /*== (5) =============================================================================================*/ // Texture code - Polished or Frosted Dakota Red Granite #local A_Granite_pigmap = array [8][2] { {0.20, 0.15}, {0.25, 0.18}, {0.35, 0.18}, {0.40, 0.15}, {0.60, 0.15}, {0.65, 0.18}, {0.75, 0.18}, {0.80, 0.15} } #if (Pol) #local T1_GranitePol = texture { #else #local T1_GraniteFro = texture { #end pigment { #if (Pat2=1) pigment_pattern {P_Granite_mask scale 0.3} #elseif (Pat2=2) pigment_pattern {P_Granite_mask_SN scale 0.3} #elseif (Pat2=3) pigment_pattern {CrackleMask scale 0.3} #else #debug "\nAttention! Pat2 should be 1, 2 or 3! 3 is used instead.\n" pigment_pattern {CrackleMask scale 0.3} #end pigment_map { #for (J, 0, Pigmap_entries-1, 1) #if (Blend) [A_Granite_pigmap[J][0] P_Granite_blend scale A_Granite_pigmap[J][1]] #else #if (Pat1=1) [A_Granite_pigmap[J][0] P_Granite scale A_Granite_pigmap[J][1]] #elseif (Pat1=2) [A_Granite_pigmap[J][0] P_Granite_SN scale A_Granite_pigmap[J][1]] #elseif (Pat1=3) [A_Granite_pigmap[J][0] P_Granite_crackle scale A_Granite_pigmap[J][1]] #else #debug "\nAttention! Pat1 should be 1, 2 or 3! 3 is used instead.\n" [A_Granite_pigmap[J][0] P_Granite_crackle scale A_Granite_pigmap[J][1]] #end #end #end //for loop } } //pigment #if (Pol) //polished #if (Typ=1) finish { diffuse albedo 0.6 brilliance 1.5 specular albedo 0.9*Granite_Specular_strength roughness 0.0025 //roughness 0.005 = less proeminent fresnel on #if (SS) subsurface {translucency Translucency} #end reflection {0 Granite_Reflection_strength fresnel on} conserve_energy } #else finish { diffuse albedo 0.6 brilliance 1.5 } #end #else //frosted normal { #if (Pat2=1) pigment_pattern {P_Granite_mask scale 0.3} #elseif (Pat2=2) pigment_pattern {P_Granite_mask_SN scale 0.3} #elseif (Pat2=3) pigment_pattern {CrackleMask scale 0.3} #else #debug "\nAttention! Pat2 should be 1, 2 or 3! 3 is used instead.\n" pigment_pattern {CrackleMask scale 0.3} #end normal_map { [0.20 granite 0.50 scale 0.15] [0.25 granite 1.00 scale 0.18] [0.35 granite 1.00 scale 0.18] [0.40 granite 0.50 scale 0.15] [0.50 granite 1.00 scale 0.15] [0.60 granite 0.50 scale 0.15] [0.65 granite 1.00 scale 0.18] [0.75 granite 1.00 scale 0.18] [0.80 granite 0.50 scale 0.15] } } //normal #if (Typ=1) finish { diffuse albedo 0.6 brilliance 1.5 Dull_Highlights() #if (SS) subsurface {translucency Translucency} #end } #else finish { diffuse albedo 0.6 brilliance 1.5 #if (SS) subsurface {translucency Translucency} #end } #end #end //Pol } //texture T1 #if (Typ=2) #if (Pol) //polished #local T2_GranitePol = texture { pigment {P_Granite_veins} finish { diffuse albedo 0.6 brilliance 1.5 specular albedo 0.9*Granite_Specular_strength roughness 0.0025 //roughness 0.005 = less proeminent fresnel on //IMPORTANT! SS does not work well in a top layered texture! Avoid and only use SS in the lower layer! //#if (SS) // subsurface {translucency Translucency} //#end reflection {0 Granite_Reflection_strength fresnel on} conserve_energy } } //texture T2 polished #else //frosted #local T2_GraniteFro = texture { pigment {P_Granite_veins} finish { diffuse albedo 0.6 brilliance 1.5 Dull_Highlights() //IMPORTANT! SS does not work well in a top layered texture! Avoid and only use SS in the lower layer! //#if (SS) // subsurface {translucency Translucency} //#end } normal { pigment_pattern {P_Granite_veins} normal_map { [0.50 granite 0.25 scale 0.4] [0.50 granite 0.00 scale 0.4] } } } //texture T2 frosted #end //Pol #end //Typ /*== (6) =============================================================================================*/ // material code - Polished or Frosted Dakota Red Granite #ifndef (M_scale) #local M_scale = <1.0, 1.0, 1.0>; #end #ifndef (M_rotat) #local M_rotat = <0.0, 0.0, 0.0>; #end #ifndef (M_trans) #local M_trans = <0.0, 0.0, 0.0>; #end #declare M_Granite = material { interior {ior 1.6} #if (Pol) //polished #if (Typ=1) texture {T1_GranitePol} #else texture {T1_GranitePol} texture {T2_GranitePol} #end //Typ #else //frosted #if (Typ=1) texture {T1_GraniteFro} Crand(0.25) #else texture {T1_GraniteFro} texture {T2_GraniteFro} Crand(0.25) #end //Typ #end //Pol scale M_scale rotate M_rotat translate M_trans } //material M_Granite /*== (7) =============================================================================================*/ // undefining parameters and closing the macro #undef CSC #undef Pol #undef Typ #undef Pat1 #undef Pat2 #undef Blend //#undef SS #undef Translucency #undef SN_Start #undef SN_End #undef SN_Turb #undef BC_Blur #undef M_scale #undef M_rotat #undef M_trans #end //Granite_21 macro /*== (8) =============================================================================================*/ // Application to an object /* union { ovus {1.00, 0.65 scale 0.5 translate <0, 0.45, 0> } superellipsoid { <0.1, 0.1> scale 0.5 translate -0.5*y } material { Granite_21 () } //transforms for the object here } */ /*====================================================================================================*/