Newer
Older
# For BI > POV shaders emulation
import bpy
def writeMaterial(using_uberpov, DEF_MAT_NAME, scene, tabWrite, safety, comments, uniqueName, materialNames, material):
# Assumes only called once on each material
if material:
name_orig = material.name
name = materialNames[name_orig] = uniqueName(bpy.path.clean_name(name_orig), materialNames)
else:
name = name_orig = DEF_MAT_NAME
if material:
# If saturation(.s) is not zero, then color is not grey, and has a tint
colored_specular_found = ((material.pov.specular_color.s > 0.0) and (material.pov.diffuse_shader != 'MINNAERT'))
##################
# Several versions of the finish: Level conditions are variations for specular/Mirror
# texture channel map with alternative finish of 0 specular and no mirror reflection.
# Level=1 Means No specular nor Mirror reflection
# Level=2 Means translation of spec and mir levels for when no map influences them
# Level=3 Means Maximum Spec and Mirror
def povHasnoSpecularMaps(Level):
if Level == 1:
if comments:
else:
tabWrite("\n")
elif Level == 2:
if comments:
tabWrite("//--translation of spec and mir levels for when no map " \
"influences them--\n")
else:
tabWrite("\n")
elif Level == 3:
if comments:
else:
tabWrite("\n")
if material:
# POV-Ray 3.7 now uses two diffuse values respectively for front and back shading
# (the back diffuse is like blender translucency)
frontDiffuse = material.pov.diffuse_intensity
backDiffuse = material.pov.translucency
if material.pov.conserve_energy:
#Total should not go above one
if (frontDiffuse + backDiffuse) <= 1.0:
pass
elif frontDiffuse == backDiffuse:
# Try to respect the user's 'intention' by comparing the two values but
# bringing the total back to one.
frontDiffuse = backDiffuse = 0.5
# Let the highest value stay the highest value.
elif frontDiffuse > backDiffuse:
# clamps the sum below 1
backDiffuse = min(backDiffuse, (1.0 - frontDiffuse))
else:
frontDiffuse = min(frontDiffuse, (1.0 - backDiffuse))
# map hardness between 0.0 and 1.0
roughness = ((1.0 - ((material.pov.specular_hardness - 1.0) / 510.0)))
## scale from 0.0 to 0.1
roughness *= 0.1
# add a small value because 0.0 is invalid.
roughness += (1.0 / 511.0)
################################Diffuse Shader######################################
# Not used for Full spec (Level=3) of the shader.
if material.pov.diffuse_shader == 'OREN_NAYAR' and Level != 3:
# Blender roughness is what is generally called oren nayar Sigma,
# and brilliance in POV-Ray.
tabWrite("brilliance %.3g\n" % (0.9 + material.roughness))
if material.pov.diffuse_shader == 'TOON' and Level != 3:
tabWrite("brilliance %.3g\n" % (0.01 + material.diffuse_toon_smooth * 0.25))
# Lower diffuse and increase specular for toon effect seems to look better
# in POV-Ray.
frontDiffuse *= 0.5
if material.pov.diffuse_shader == 'MINNAERT' and Level != 3:
#tabWrite("aoi %.3g\n" % material.darkness)
pass # let's keep things simple for now
if material.pov.diffuse_shader == 'FRESNEL' and Level != 3:
#tabWrite("aoi %.3g\n" % material.diffuse_fresnel_factor)
pass # let's keep things simple for now
if material.pov.diffuse_shader == 'LAMBERT' and Level != 3:
# trying to best match lambert attenuation by that constant brilliance value
if Level == 2:
###########################Specular Shader######################################
# No difference between phong and cook torrence in blender HaHa!
if (material.pov.specular_shader == 'COOKTORR' or
material.pov.specular_shader == 'PHONG'):
tabWrite("phong %.3g\n" % (material.pov.specular_intensity))
tabWrite("phong_size %.3g\n" % (material.pov.specular_hardness /3.14))
# POV-Ray 'specular' keyword corresponds to a Blinn model, without the ior.
elif material.pov.specular_shader == 'BLINN':
# Use blender Blinn's IOR just as some factor for spec intensity
tabWrite("specular %.3g\n" % (material.pov.specular_intensity *
(material.pov.specular_ior / 4.0)))
tabWrite("roughness %.3g\n" % roughness)
#Could use brilliance 2(or varying around 2 depending on ior or factor) too.
elif material.pov.specular_shader == 'TOON':
tabWrite("phong %.3g\n" % (material.pov.specular_intensity * 2.0))
# use extreme phong_size
tabWrite("phong_size %.3g\n" % (0.1 + material.pov.specular_toon_smooth / 2.0))
elif material.pov.specular_shader == 'WARDISO':
# find best suited default constant for brilliance Use both phong and
# specular for some values.
tabWrite("specular %.3g\n" % (material.pov.specular_intensity /
(material.pov.specular_slope + 0.0005)))
# find best suited default constant for brilliance Use both phong and
# specular for some values.
tabWrite("roughness %.4g\n" % (0.0005 + material.pov.specular_slope / 10.0))
# find best suited default constant for brilliance Use both phong and
# specular for some values.
tabWrite("brilliance %.4g\n" % (1.8 - material.pov.specular_slope * 1.8))
####################################################################################
elif Level == 1:
if (material.pov.specular_shader == 'COOKTORR' or
material.pov.specular_shader == 'PHONG'):
tabWrite("phong %.3g\n" % (material.pov.specular_intensity/5))
tabWrite("phong_size %.3g\n" % (material.pov.specular_hardness /3.14))
# POV-Ray 'specular' keyword corresponds to a Blinn model, without the ior.
elif material.pov.specular_shader == 'BLINN':
# Use blender Blinn's IOR just as some factor for spec intensity
tabWrite("specular %.3g\n" % (material.pov.specular_intensity *
(material.pov.specular_ior / 4.0)))
tabWrite("roughness %.3g\n" % roughness)
#Could use brilliance 2(or varying around 2 depending on ior or factor) too.
elif material.pov.specular_shader == 'TOON':
tabWrite("phong %.3g\n" % (material.pov.specular_intensity * 2.0))
tabWrite("phong_size %.3g\n" % (0.1 + material.pov.specular_toon_smooth / 2.0))
elif material.pov.specular_shader == 'WARDISO':
# find best suited default constant for brilliance Use both phong and
# specular for some values.
tabWrite("specular %.3g\n" % (material.pov.specular_intensity /
(material.pov.specular_slope + 0.0005)))
# find best suited default constant for brilliance Use both phong and
# specular for some values.
tabWrite("roughness %.4g\n" % (0.0005 + material.pov.specular_slope / 10.0))
# find best suited default constant for brilliance Use both phong and
# specular for some values.
tabWrite("brilliance %.4g\n" % (1.8 - material.pov.specular_slope * 1.8))
elif Level == 3:
tabWrite("specular %.3g\n" % ((material.pov.specular_intensity*material.pov.specular_color.v)*5))
tabWrite("roughness %.3g\n" % (1.1/material.pov.specular_hardness))
tabWrite("diffuse %.3g %.3g\n" % (frontDiffuse, backDiffuse))
tabWrite("ambient %.3g\n" % material.pov.ambient)
# POV-Ray blends the global value
#tabWrite("ambient rgb <%.3g, %.3g, %.3g>\n" % \
# tuple([c*material.pov.ambient for c in world.ambient_color]))
tabWrite("emission %.3g\n" % material.pov.emit) # New in POV-Ray 3.7
#POV-Ray just ignores roughness if there's no specular keyword
#tabWrite("roughness %.3g\n" % roughness)
if material.pov.conserve_energy:
# added for more realistic shading. Needs some checking to see if it
# really works. --Maurice.
tabWrite("conserve_energy\n")
if colored_specular_found == True:
# 'phong 70.0 '
if Level != 1:
if material.pov_raytrace_mirror.use:
raytrace_mirror = material.pov_raytrace_mirror
if raytrace_mirror.reflect_factor:
tabWrite("reflection {\n")
tabWrite("rgb <%.3g, %.3g, %.3g>\n" % material.pov.mirror_color[:])
if material.pov.mirror_metallic:
tabWrite("metallic %.3g\n" % (raytrace_mirror.reflect_factor))
# Blurry reflections for UberPOV
if using_uberpov and raytrace_mirror.gloss_factor < 1.0:
#tabWrite("#ifdef(unofficial) #if(unofficial = \"patch\") #if(patch(\"upov-reflection-roughness\") > 0)\n")
tabWrite("roughness %.6f\n" % \
(0.000001/raytrace_mirror.gloss_factor))
#tabWrite("#end #end #end\n") # This and previous comment for backward compatibility, messier pov code
if material.pov.mirror_use_IOR: # WORKING ?
# Removed from the line below: gives a more physically correct
Loading
Loading full blame...