This namespace provides templates & utility functions to simplify the process of producing render scenes.
The following function creates a basic render scene setup with the following entities:
- Low-discrepancy sampler/renderer
- Bi-directional light integrator
- Perspective camera w/ DOF
- Film w/ linear tonemap config (ISO 100, f2.8 @ 0.95s exposure)
- Two independent light groups: top area light, left/right fillers (also area lights)
- Infinity curve backdrop
- Grey matte material
- Grey glossy material
The following parameters can be configured:
- Camera position, target, up vector, FOV, lens radius
- Image width/height
- Infinity curve width
This table gives an overview of the different light groups (the code to create this scene is further below). Each light group can also be manually adjusted during rendering using the Luxrender UI:
top light only | fill lights only (left/right) | combined |
(defn base-scene
[{:keys [eye target up fov width height bg-width]
:or {eye [0 1.25 0]
target [0 0.4 -2]
up V3Y
fov 70
bg-width 6.0
width 1280
height 720}}]
(-> (lux/lux-scene)
(lux/configure-meshes-as-byte-arrays)
(lux/renderer-sampler)
(lux/sampler-ld {})
(lux/integrator-bidir {})
(lux/camera
{:eye eye :target target :up up :fov fov
:focal-dist (* (g/dist (vec3 eye) target) 0.8)
:lens-radius 0.03})
(lux/film
{:width width :height height
:response :agfacolor-optima2-200cd
:display-interval 10 :halt-spp 1000})
(lux/tonemap-linear
{:iso 100 :exposure 0.95 :f-stop 2.8 :gamma 2.2})
(lux/material-matte
:bg-matte {:diffuse [0.5 0.5 0.5]})
(lux/material-matte
:basic {:diffuse [0.64 0.622 0.615]})
(lux/material-glossy-coating
:gloss {:ior :plastic :specular [1 1 1] :base :basic})
(lux/light-groups {:top {:gain 0.15} :fill {:gain 0.1}})
(lux/area-light
:top {:n [0 -1 0] :size [6 2] :group :top :tx {:translate [0 2 -2] :rx 30}})
(lux/area-light
:left {:n [1 0 0] :size 0.5 :group :fill :tx {:translate [-1 1.25 0] :ry 45 :rz -20}})
(lux/area-light
:right {:n [-1 0 0] :size 0.5 :group :fill :tx {:translate [1 1.25 0] :ry -45 :rz 20}})
(lux/ply-mesh
:bg {:material :bg-matte
:mesh (prims/infinity-curve bg-width 2.0 4.0 0.5 0.75 0.05 4)})))
The scene-add-mesh
and scene-add-main-mesh
functions are used to
add a mesh to a given scene with some optional defaults. The latter
function is the more useful for the above base-scene
, since it first
scales a mesh to fit within a given bounding box and then
automatically repositions it. The following options are supported:
Key | Default |
---|---|
:bounds | (aabb 1) |
:target | scene target XZ position, Y defaults to 1/2 of given bounding box |
:material | :gloss (defined in base-scene ) |
:rx :ry :rz | XYZ rotation angles (in radians) |
(defn add-mesh
[scene mesh & [opts]]
(let [opts (if (:material opts) opts (assoc opts :material :gloss))]
(lux/stl-mesh scene (or (:id opts) (keyword (gensym))) (assoc opts :mesh mesh))))
(defn add-main-mesh
[scene mesh &
[{:keys [id bounds target material rx ry rz]
:or {id (keyword (gensym)) bounds (a/aabb 1) rx 0 ry 0 rz 0}}]]
(let [target-s (-> scene :camera first val :__lookat :target)
target (or target (assoc target-s 1 (:y (g/centroid bounds))))
mat (-> M44
(g/translate target)
(g/rotate-x rx)
(g/rotate-y ry)
(g/rotate-z rz))
mesh (first (tu/fit-all-into-bounds (g/center bounds) [mesh]))]
(add-mesh scene mesh {:id id :material material :tx {:matrix mat}})))
This example creates the scene shown in the images above and can be
run from a REPL in the /luxor/babel
dir using (load-file
"examples/base-scene.clj")
. It creates a subdivided cube mesh and
adds it to the base-scene
as main mesh. The exported scene file will
be written in the same directory, called base.lxs
.
(require
'[thi.ng.geom.core :as g]
'[thi.ng.geom.aabb :as a]
'[thi.ng.geom.gmesh :as gm]
'[thi.ng.geom.mesh.subdivision :as sd]
'[thi.ng.luxor.scenes :as scenes]
'[thi.ng.luxor.io :as lio])
(let [mesh (->> (g/as-mesh (a/aabb 1) {:mesh (gm/gmesh)})
(iterate sd/catmull-clark)
(take 4)
(last))]
(-> (scenes/base-scene {:width 640 :height 360})
(scenes/add-main-mesh mesh)
(lio/serialize-scene "base" false)
(lio/export-scene)
(dorun)))
(ns thi.ng.luxor.scenes
(:require
[thi.ng.geom.core :as g]
[thi.ng.geom.core.vector :refer [vec3 V3Y]]
[thi.ng.geom.core.matrix :refer [M44]]
[thi.ng.geom.types.utils :as tu]
[thi.ng.geom.aabb :as a]
[thi.ng.luxor.core :as lux]
[thi.ng.luxor.io :as lio]
[thi.ng.luxor.primitives :as prims]))
<<lxs>>
<<generator>>