<?xml version="1.0" encoding="utf-8"?>
<scenedata>
	<material>
		<name>base-ceramic</name>
		<phong>
			<diffuse_albedo>
				<constant>
					<rgb>
						<rgb>
							0.9062 0.9453 0.9141
						</rgb>
						<gamma>2.2</gamma>
					</rgb>
				</constant>
			</diffuse_albedo>
			<exponent>
				<constant>
					300000
				</constant>
			</exponent>
			<bump>
				<shader>
					<shader><![CDATA[# function used to get textures coordinates. mostly for testing purposes,
# for scaling down the tiles easily (by multiplying the coordinates in the whole material)
def coords ( ) vec2 :
	getTexCoords ( 0 )

#this function returns the integer texture coordinates
#this allows generating random numbers constant within the tile,
#but different between tiles. Used for tile tilt/shift
def get_tilevec( vec2 pos ) vec2 :
	vec2 ( floor ( doti ( pos ) ) , floor ( dotj ( pos ) ) )


#this function generates the tile random shift and tilt
# RANDOM_SHIFT_X : amount of misplacement along x axis. Typical value 0.01
# RANDOM_SHIFT_Y : amount of misplacement along y axis. Typical value 0.01
# RANDOM_TILT : amount of misplacement tilt. Typical value 0.015
def random_place(vec2 tilevec) vec3 :
	vec3	(
		noise ( tilevec  * 1.414213562373095 ) * RANDOM_SHIFT_X ,
		noise ( tilevec  * 3.141592653589793 ) * RANDOM_SHIFT_Y,
		noise ( tilevec * 2.64575131106 )  * RANDOM_TILT
		) 

#This function return shifted and tilted internal tile coordinates.
def placement ( vec3 place )  vec2 : 
	mat2x2 ( 	cos( dotk ( place) ) , 0. - sin( dotk ( place ) )  ,
			sin ( dotk ( place) ) , cos ( dotk ( place ) ) )
		* vec2 (	fract( doti (coords ( ) ) ) - 0.5 , 
				fract( dotj (coords ( ) ) ) - 0.5		) 
		+ vec2 ( 0.5 , 0.5 ) 
		+ vec2 ( doti(place), dotj(place) )

#This function is used to round the corners.
#ROUNDNESS : as name says. Typical value : 0.0001
#Values such as 0.01 are already quite round
def crn ( real a, real b ) real :
	0.5 * ( a + b - sqrt ( (a - b) * (a - b) + ROUNDNESS ) )

#core function used to define the tile's shape
def pyra ( vec2 xy ) real :
	crn	( 
		crn	(
			fract( doti( xy )  ) , 
			1. - fract(doti ( xy ) )
			) ,   	
		crn	(
			fract(dotj ( xy ) ) ,
			1. - fract(dotj ( xy ) )
			) 
		)

#function defining the profile of the tile's edge.
# shape(0.) must be equal to 0.
# shape(1.) must be equal to 1.
# this function corresponds to quarter-elliptical edge
def shape( real x ) real :
	sqrt( x* ( 2. - x ) )

#function generating the full z-map of the ceramic, from the previous functions
# JOINT_WIDTH : space between tiles, in fraction of the tile width. Typical value : 0.014
#			a bigger value increases the plaster width between tiles
# EDGE_SHARPNESS : slope of tile's edge. Typical value : 20.
# 			Decrease it for a smoother edge profile
# 			(this may also increase the joint plaster width due to floodfill effects)
# CERAMIC_THICKNESS : height of the ceramic tiles in meters. Typical : 0.002.
# 			Increase this causes deeper grooves in the plaster joints.

def profile () real :
	shape(
		clamp ( (
			
			pyra ( placement (
			random_place(get_tilevec( coords () ) ) 
			) )
				- ( JOINT_WIDTH * 0.5 )
			) * EDGE_SHARPNESS , 0. , 1.
			 )
		) * CERAMIC_THICKNESS


# This function defines the surface roughness of the ceramic.
# Change it to whatever you want. Here, it just adds some light waviness
def surface() real :
	noise ( getTexCoords(0) * 10. ) * 0.00001


def eval() real :
	profile () + surface()
	]]></shader>
				</shader>
			</bump>
			<layer>0</layer>
			<fresnel_scale>1</fresnel_scale>
			<ior>1.35</ior>
			<nk_data></nk_data>
		</phong>
	</material>

	<material>
		<name>base-joint-clean</name>
		<diffuse>
			<albedo>
				<constant>
					<rgb>
						<rgb>
							0.668 0.668 0.668
						</rgb>
						<gamma>2.2</gamma>
					</rgb>
				</constant>
			</albedo>
			<bump>
				<shader>
					<shader><![CDATA[# function generating the full z-map of the plaster joint
# JOINT_AVERAGE_LEVEL : average level of plaster in m. Typical : 0.0006
#	should be > 0. If too high, may cause the plaster to cover the tiles entirely...
# JOINT_RANDOM_LEVEL : amount of plaster level waviness.
#	This makes nice irregularities in the tiles edges.
#	Values greater than AVERAGE_LEVEL will cause plaster to be non continuous
def joint_height() real :
	noise( getTexCoords(0) *9. )* JOINT_RANDOM_LEVEL + JOINT_AVERAGE_LEVEL

def eval() real :
	joint_height() ]]></shader>
				</shader>
			</bump>
			<random_triangle_colours>false</random_triangle_colours>
			<layer>0</layer>
		</diffuse>
	</material>

	<material>
		<name>base-joint-dirty</name>
		<diffuse>
			<albedo>
				<constant>
					<rgb>
						<rgb>
							0.4766 0.4648 0.4531
						</rgb>
						<gamma>2.2</gamma>
					</rgb>
				</constant>
			</albedo>
			<bump>
				<shader>
					<shader><![CDATA[# function generating the full z-map of the plaster joint
# JOINT_AVERAGE_LEVEL : average level of plaster in m. Typical : 0.0006
#	should be > 0. If too high, may cause the plaster to cover the tiles entirely...
# JOINT_RANDOM_LEVEL : amount of plaster level waviness.
#	This makes nice irregularities in the tiles edges.
#	Values greater than AVERAGE_LEVEL will cause plaster to be non continuous
def joint_height() real :
	noise( getTexCoords(0) *9. )* JOINT_RANDOM_LEVEL + JOINT_AVERAGE_LEVEL

def eval() real :
	joint_height() ]]></shader>
				</shader>
			</bump>
			<random_triangle_colours>false</random_triangle_colours>
			<layer>0</layer>
		</diffuse>
	</material>

	<material>
		<name>base-joint</name>
		<blend>
			<a_name>base-joint-clean</a_name>
			<b_name>base-joint-dirty</b_name>
			<blend>
				<shader>
					<shader><![CDATA[def eval() real :
	noise(getTexCoords(0)*0.5)]]></shader>
				</shader>
			</blend>
			<step_blend>false</step_blend>
		</blend>
	</material>

	<material>
		<name>ceramic-procedural-bump</name>
		<blend>
			<a_name>base-ceramic</a_name>
			<b_name>base-joint</b_name>
			<blend>
				<shader>
					<shader><![CDATA[# function used to get textures coordinates. mostly for testing purposes,
# for scaling down the tiles easily (by multiplying the coordinates in the whole material)
def coords ( ) vec2 :
	getTexCoords ( 0 )

#this function returns the integer texture coordinates
#this allows generating random numbers constant within the tile,
#but different between tiles. Used for tile tilt/shift
def get_tilevec( vec2 pos ) vec2 :
	vec2 ( floor ( doti ( pos ) ) , floor ( dotj ( pos ) ) )


#this function generates the tile random shift and tilt
# RANDOM_SHIFT_X : amount of misplacement along x axis. Typical value 0.01
# RANDOM_SHIFT_Y : amount of misplacement along y axis. Typical value 0.01
# RANDOM_TILT : amount of misplacement tilt. Typical value 0.015
def random_place(vec2 tilevec) vec3 :
	vec3	(
		noise ( tilevec  * 1.414213562373095 ) * RANDOM_SHIFT_X ,
		noise ( tilevec  * 3.141592653589793 ) * RANDOM_SHIFT_Y,
		noise ( tilevec * 2.64575131106 )  * RANDOM_TILT
		) 

#This function return shifted and tilted internal tile coordinates.
def placement ( vec3 place )  vec2 : 
	mat2x2 ( 	cos( dotk ( place) ) , 0. - sin( dotk ( place ) )  ,
			sin ( dotk ( place) ) , cos ( dotk ( place ) ) )
		* vec2 (	fract( doti (coords ( ) ) ) - 0.5 , 
				fract( dotj (coords ( ) ) ) - 0.5		) 
		+ vec2 ( 0.5 , 0.5 ) 
		+ vec2 ( doti(place), dotj(place) )

#This function is used to round the corners.
#ROUNDNESS : as name says. Typical value : 0.0001
#Values such as 0.01 are already quite round
def crn ( real a, real b ) real :
	0.5 * ( a + b - sqrt ( (a - b) * (a - b) + ROUNDNESS ) )

#core function used to define the tile's shape
def pyra ( vec2 xy ) real :
	crn	( 
		crn	(
			fract( doti( xy )  ) , 
			1. - fract(doti ( xy ) )
			) ,   	
		crn	(
			fract(dotj ( xy ) ) ,
			1. - fract(dotj ( xy ) )
			) 
		)

#function defining the profile of the tile's edge.
# shape(0.) must be equal to 0.
# shape(1.) must be equal to 1.
# this function corresponds to quarter-elliptical edge
def shape( real x ) real :
	sqrt( x* ( 2. - x ) )

#function generating the full z-map of the ceramic, from the previous functions
# JOINT_WIDTH : space between tiles, in fraction of the tile width. Typical value : 0.014
#			a bigger value increases the plaster width between tiles
# EDGE_SHARPNESS : slope of tile's edge. Typical value : 20.
# 			Decrease it for a smoother edge profile
# 			(this may also increase the joint plaster width due to floodfill effects)
# CERAMIC_THICKNESS : height of the ceramic tiles in meters. Typical : 0.002.
# 			Increase this causes deeper grooves in the plaster joints.

def profile () real :
	shape(
		clamp ( (
			
			pyra ( placement (
			random_place(get_tilevec( coords () ) ) 
			) )
				- ( JOINT_WIDTH * 0.5 )
			) * EDGE_SHARPNESS , 0. , 1.
			 )
		) * CERAMIC_THICKNESS


# function generating the full z-map of the plaster joint
# JOINT_AVERAGE_LEVEL : average level of plaster in m. Typical : 0.0006
#	should be > 0. If too high, may cause the plaster to cover the tiles entirely...
# JOINT_RANDOM_LEVEL : amount of plaster level waviness.
#	This makes nice irregularities in the tiles edges.
#	Values greater than AVERAGE_LEVEL will cause plaster to be non continuous
def joint_height() real :
	noise( getTexCoords(0) *9. )* JOINT_RANDOM_LEVEL + JOINT_AVERAGE_LEVEL

def eval() real :
	if( gt( joint_height() , profile() ) , 1.0 , 0.0 )
]]></shader>
				</shader>
			</blend>
			<step_blend>true</step_blend>
		</blend>
	</material>

</scenedata>
