Introduction
Here, you will learn about the scene description language used in Photon (sometimes we call it PSDL for convenience, which stands for Photon Scene Description Language). It is a special format created for storing scene data as well as controlling the behavior of the render engine. Currently we have Python and Java APIs for users to programmatically build scene descriptions, and a documentation for engine features exposed as PSDL can be found here.
Language Basics
Let us first see how a simplge scene would be represented in PSDL. A hello-world scene that can actually be rendered by Photon looks like this
This image can be generated by feeding the following descriptions into Photon:
observer(single-lens) @observer = [real fov-degrees 30] [vector3 position "0 6 40"] [vector3 direction "0 0 -1"] [vector3 up-axis "0 1 0"];
sample-source(stratified) @sampler = [integer samples 10];
visualizer(path-tracing) @visualizer = [enum sample-filter gaussian][enum estimator bneept];
option(single-frame-render-session) @session = [vector2 frame-size "512 512"] [string visualizer @visualizer] [string observer @observer] [string sample-source @sampler];
geometry(rectangle) @plane = [real width 15] [real height 15];
geometry(sphere) @ball = [real radius 2.5];
material(matte-opaque) @white = [image albedo "0.9 0.9 0.9"];
actor(model) @ground = [geometry geometry @plane] [material material @white];
actor(model).rotate(@ground) = [vector3 axis "1 0 0"] [real degrees -90];
actor(model).scale(@ground) = [vector3 amount "10 10 10"];
actor(model) @object = [geometry geometry @ball] [material material @white];
actor(model).translate(@object) = [vector3 amount "0 2.5 0"];
actor(rectangle-light) @topLight = [spectrum color "1 1 0.8"] [real watts 400] [real width 2] [real height 2];
actor(light).translate(@topLight) = [vector3 amount "0 10 0"];
actor(light).rotate(@topLight) = [vector3 axis "1 0 0"] [real degrees 90];
The scene description can be stored into a text file (.p2 filename extension) and loaded by Photon for rendering. PSDL is a command-like system and the commands can be roughly categorized into 2 parts: header and clause. Commands are normally structured in the following way (without the angle brackets):
<type-category>
(<type-name>
) @<name>
=<clauses>
;
where =
is the token that separates header and clauses, which can be naturally interpreted as assigning the RHS clauses into the LHS resource denoted by <name>
. For example, to create a unit-sized rectangle, we write:
geometry(rectangle) @plane = [real width 1] [real height 1];
geometry(rectangle)
is the full type information for a geometry resource. By specifying the type name rectangle
in the parantheses after geometry
, we are creating a rectangle geometry named plane
. Its dimension properties are specified via the two angle-bracket enclosed clauses that follows the assignment token. In most cases, a clause contains three space-separated parts: a type, a name and a value. A clause is the most fundamental data block in PSDL, and multiple clauses form a SDL data packet. In the example of creating a unit-sized rectangle, [real width 1] [real height 1]
is the data packet for initializing the SDL geometry resource named plane. Now, the intention of the following line should be quite obvious:
geometry(sphere) @ball = [real radius 2.5];
It creates a geometry resource named ball
which is a sphere with radius=2.5
. We will dive further into the topics of type and clause later.
As you may have noticed, all commands are ended with a trailing semi-colon. To disable a command or write some comment, simply put two slashes before the line:
// These commands are being disabled
//sample-source(stratified) @sampler = [integer samples 10];
//actor(model).scale(@ground) = [vector3 amount "10 10 10"];
In the next sections, we will formally introduce the syntactic structures of PSDL commands.
Type Category
<type-category>
(<type-name>
) @<name>
= <clauses>
;
Describes the category to which current command belongs, e.g., the command that creates a geometry states that its category is geometry in its type category section. There are many categories in PSDL. In addition to the ones seen in the above hello-world scene description, we also have image
, object
and much more.
Type Name
<type-category>
(<type-name>
) @<name>
= <clauses>
;
Type names generally add details to the type category. Again, in the command that creates a geometry, we know that we are now creating a rectangle geometry from the command fragment geometry(
rectangle
)
. Type category and type name are often combined and are called “full type name” together. Full type name is only needed if the underlying engine operation requires it (such as creating a resource). For executor calls (see later section), type name can be omitted (will be automatically deduced from the referenced resource) sometimes.
Data Name
<type-category>
(<type-name>
) @<name>
= <clauses>
;
Data name is the name given to the command (e.g., as a resource name, or a reference name) and is always prefixed by @. Note that @ is part of the syntax rather than part of the name. Also, names with whitespace characters should be enclosed by double quotes, see the following example to understand more clearly:
// @ is part of the syntax and should be left out of the double quotes. In this example, we created a sphere named "ball name with spaces".
geometry(sphere) @"ball name with spaces" = [real radius 2.5];
actor(model) @balloon = [geometry geometry @"ball name with spaces"];
Clauses
<type-category>
(<type-name>
) @<name>
= <clauses>
;
Clause is a structure that stores parameters for a command. It has the following form:
[<type-category> <parameter-name>:<tag> <values>]
It is worth pointing out that a <parameter-name>
does not need to start with @
. The <values>
section can have many forms such as numerical values (you have already seen that), arrays, and even stand-alone data files (we call them PSDL Resource Identifier). Details of this section will be introduced in later part of the guide.
TODO: reference & struct types
// By writing these, we now added a ball, a ground and a material to the scene!
geometry(sphere) @ball = [real radius 0.5];
geometry(rectangle) @ground = [real width 100] [real height 100];
material(matte-opaque) @white = [image albedo "0.9 0.9 0.9"];
With PSDL, you can create almost all kinds of objects the rendering system has to offer. In later sections, we will see that it is also possible to perform operations on these objects via PSDL.
Operations
TODO: introduce PSDL executors