How do I specify what is the interior vs the exterior of an object? My assumption it is done by the order of the vertices for each face. Looking from inside ordering them clockwise, or is it the other way around?
Here the code for a simple model: a prism between a spot and a plane. There is no visible effect of refraction. The comments show some stuff I tried.
Any other remarks on the code appreciated.
Code: Select all
import sys
sys.path.append('/home/mick/dev/DLO/lib')
import pyluxcore
from time import sleep
import array
import imageio
import numpy as np
from scipy import stats, signal
from common import SP
from prism import make_prism_mesh
from luxcore import add_object
def main():
pyluxcore.Init()
scene = pyluxcore.Scene()
props = pyluxcore.Properties()
if False:
props.SetFromString("""
scene.volumes.vol_air.type = clear
scene.volumes.vol_air.absorption = 0.0 0.0 0.0
scene.volumes.vol_air.asymmetry = 0.0 0.0 0.0
scene.world.volume.default = vol_air
""")
else:
props.SetFromString("""
scene.volumes.vol_air.type = homogeneous
scene.volumes.vol_air.multiscattering = 0
scene.volumes.vol_air.scattering = 0. 0. 0.01
scene.volumes.vol_air.absorption = 0.01 0.01 0.01
scene.volumes.vol_air.asymmetry = 0.0 0.0 0.0
scene.world.volume.default = vol_air
""")
scene.Parse(props)
prism_vol = "lens_vol"
props = pyluxcore.Properties()
# props.Set(pyluxcore.Property("scene.volumes."+prism_vol+".type", "homogeneous"))
# props.Set(pyluxcore.Property("scene.volumes."+prism_vol+".scattering", [0.01, 0, 0]))
# props.Set(pyluxcore.Property("scene.volumes."+prism_vol+".multiscattering", 0))
props.Set(pyluxcore.Property("scene.volumes."+prism_vol+".type", "clear"))
props.Set(pyluxcore.Property("scene.volumes."+prism_vol+".absorption", [0,0,0]))
props.Set(pyluxcore.Property("scene.volumes."+prism_vol+".ior", SP["prism_ior"]))
#props.Set(pyluxcore.Property("scene.volumes."+prism_vol+".priority", 255))
scene.Parse(props)
prism_mat = "lens"
props = pyluxcore.Properties()
props.Set(pyluxcore.Property("scene.materials."+prism_mat+".type", "glass"))
props.Set(pyluxcore.Property("scene.materials."+prism_mat+".transparency", 0.8))
props.Set(pyluxcore.Property("scene.materials."+prism_mat+".interiorior", 1.5))
props.Set(pyluxcore.Property("scene.materials."+prism_mat+".exteriorior", 1.0))
props.Set(pyluxcore.Property("scene.materials."+prism_mat+".kt", [0.5, 0.5, 0.5]))
props.Set(pyluxcore.Property("scene.materials."+prism_mat+".kr", [0.5, 0.5, 0.5]))
# props.Set(pyluxcore.Property("scene.materials."+prism_mat+".cauchyc", 0.1))
# props.Set(pyluxcore.Property("scene.materials."+prism_mat+".volume.interior", prism_vol))
scene.Parse(props)
# prism = make_prism_mesh(1, 2, 0, -0.1, 0, 2)
vertices = [
(-0.7, -0.7, 0),
(1, -1, 0),
(0.1, 1, 0),
(-0.7, -0.7, 2),
(1, -1, 2),
(0.1, 1, 2),
]
if True:
# clockwise
faces = [
(0, 2, 1),
(0, 1, 3),
(1, 4, 3),
(1, 2, 4),
(2, 5, 4),
(2, 0, 5),
(0, 3, 5),
(3, 5, 4),
]
else:
faces = [
(0, 1, 2),
(0, 3, 1),
(1, 3, 4),
(1, 4, 2),
(2, 4, 5),
(2, 5, 0),
(0, 5, 3),
(3, 4, 5),
]
prism = (vertices, faces)
name = "lens0"
scene.DefineMesh(name, prism[0], prism[1], None, None, None, None, None)
add_object(scene, name, name, prism_mat, visible=True)
name = "background"
obj_props = pyluxcore.Properties()
obj_props.SetFromString("""
scene.materials.{name}.type = matte
scene.materials.{name}.kd = 0.5 0.5 0.5
""".format(name=name))
scene.Parse(obj_props)
vertices = [
(-10, 4, -10),
(10, 4, -10),
(10, 4, 10),
(-10, 4, 10)
]
faces = [
(0, 1, 2),
(2, 3, 0)
]
scene.DefineMesh(name, vertices, faces, None, None, None, None, None)
add_object(scene, name, name, name, True)
props = pyluxcore.Properties()
props.SetFromString("""
scene.camera.lookat.orig = 0.5 -9 9.2
scene.camera.lookat.target = 0 2 1
scene.camera.up = 0 0 1
""")
scene.Parse(props)
# props = pyluxcore.Properties()
# props.SetFromString("""
# scene.lights.s.type = sky2
# """)
# scene.Parse(props)
props = pyluxcore.Properties()
props.SetFromString("""
scene.lights.l.type = spot
scene.lights.l.position = 0 -5 1
scene.lights.l.target = 0 0 1
#scene.lights.l.radius = 0.04
scene.lights.l.coneangle = 15
scene.lights.l.conedeltaangle = 1
scene.lights.l.gain = 2000.0 2000.0 2000.0
""")
scene.Parse(props)
session = render(scene, 800)
save_rendering(session)
def build_session(scene, pixels):
config_props = pyluxcore.Properties()
config_props.SetFromString("""
#renderengine.type = TILEPATHCPU
## This sampler must be used with this engine, no other samplers work
#sampler.type = TILEPATHSAMPLER
## This controls the amount of samples per pixel
#tilepath.sampling.aa.size = 3
## Stop once all pixels were sampled, do not start another pass
#tile.multipass.enable = 0
renderengine.type = PATHCPU
sampler.type = SOBOL
path.pathdepth.total = 20
path.pathdepth.diffuse = 20
path.pathdepth.glossy = 20
path.pathdepth.specular = 20
path.russianroulette.depth = 99
path.russianroulette.cap = 0.
#lightstrategy.type = POWER
renderengine.seed = 11
film.width = """ + str(pixels) + """
film.height = """ + str(pixels) + """
# The first plugin: the linear tonemapper multiplies the pixel colors with the scale
film.imagepipelines.0.0.type = TONEMAP_AUTOLINEAR
# The second plugin: gamma correction
film.imagepipelines.0.1.type = GAMMA_CORRECTION
film.imagepipelines.0.1.value = 2.2
# Pipeline 1, plugin 0
#film.imagepipelines.1.0.type = TONEMAP_LINEAR
#film.imagepipelines.1.0.scale = 5e-5
# Pipeline 1, plugin 1
film.imagepipelines.1.1.type = CONTOUR_LINES
#film.imagepipelines.1.1.scale = 3e-1
film.imagepipelines.1.1.range = """ + str(179*715) + """
film.imagepipelines.1.1.steps = 10
film.imagepipelines.1.1.zerogridsize = 8
# Pipeline 1, plugin 2
film.imagepipelines.1.2.type = GAMMA_CORRECTION
film.imagepipelines.1.2.value = 2.2
# This is the pipeline with the tonemapped image as usual
film.outputs.0.type = RGB_IMAGEPIPELINE
film.outputs.0.filename = image0.png
# You have to specify which imagepipeline you want as output
film.outputs.0.index = 0
# This is the pipeline with the visible contour lines
film.outputs.1.type = RGB_IMAGEPIPELINE
film.outputs.1.filename = image1.png
# You have to specify which imagepipeline you want as output
film.outputs.1.index = 1
film.outputs.2.type = IRRADIANCE
film.outputs.2.filename = image2.hdr
""")
renderconfig = pyluxcore.RenderConfig(config_props, scene)
session = pyluxcore.RenderSession(renderconfig)
return session
def render(scene, pixels):
session = build_session(scene, pixels)
session.Start()
for i in range(3):
sleep(1)
#session.WaitForDone()
# session.UpdateStats()
# stats = session.GetStats()
# print("[Elapsed time: %3dsec][Samples %4d][Avg. samples/sec % 3.2fM on %.1fK tris]" % (
# stats.Get("stats.renderengine.time").GetFloat(),
# stats.Get("stats.renderengine.pass").GetInt(),
# (stats.Get("stats.renderengine.total.samplesec").GetFloat() / 1000000.0),
# (stats.Get("stats.dataset.trianglecount").GetFloat())))# / 1000.0)))
#print(stats)
session.UpdateStats()
session.Stop()
return session
def save_rendering(session):
session.GetFilm().Save()
pixels = session.GetFilm().GetWidth()
buffer = array.array("f", [0.0]) * (pixels * pixels * 3)
session.GetFilm().GetOutputFloat(pyluxcore.FilmOutputType.IRRADIANCE, buffer, 1)
npa = np.array(buffer).reshape(pixels, pixels, 3)[::-1]
print(stats.describe(signal.medfilt(npa.reshape(pixels * pixels, 3))))
print("MEAN:{} MAX:{}".format(npa.mean(), npa.max()))
imageio.imwrite("image5.png", npa)
if __name__ == "__main__":
main()