Photon 2.0.0-beta
A physically based renderer.
|
Here, you will learn about the scene description language used in Photon, sometimes referred to as PSDL (Photon Scene Description Language). It is a special format created for storing scene data as well as controlling the behavior of the render engine. We also have API generators for different programming languages, allowing users to programmatically build scene descriptions and output customized formats for various applications. The reference for all engine features exposed as PSDL can be found here.
Let us first see how a simple scene would be represented in PSDL. The hello-world scene that will be rendered by Photon looks like this
This image can be generated by feeding the following descriptions into Photon:
Scene descriptions can be stored in a text file (.p2 filename extension) and loaded by Photon for rendering. Without getting into too much details, the scene description shown above can be summarized as:
rectangle
geometry faces +z by default, a series of transformations are required to place the ground object with the desired rotation and scale.After saving the scene description as hello_world.p2
under the build/install directory, you can run the following command in the same directory to render the scene as described:
PSDL is a command-like system and the commands can be roughly categorized into two parts: header and clause. Commands are normally structured in the following way:
type-category
(type-name
) @name
= clauses
;
where =
is the token that separates the 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)
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 square-bracket enclosed clauses that follow 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 geometry resource named plane
. Now, the intention of the following line should be quite obvious:
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 end with a trailing semi-colon. To disable a command or write a comment, simply put two slashes before the line:
In the next sections, we will formally introduce the syntactic structures of PSDL commands.
type-category
(type-name) @name = clauses;
Describes the category to which the current command belongs. For example, 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-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 the later section), type name can be omitted (will be automatically deduced from the referenced resource) sometimes.
type-category(type-name) @name
= clauses;
The 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:
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 the parameter-name
does not need to start with @
. The values
section can have many forms such as numerical values (as seen earlier), arrays, and even stand-alone data files (we call them PSDL Resource Identifier). Details for resource identifiers will be introduced in later part of the guide.
When defining a clause, type-category
can be classified into value and reference. Value types do not share data and create a new block of data each time a clause is instantiated. On the other hand, reference types can share their data by instance names, with automatic reference counting.
These are common value types* used in a SDL clause:
Type | Value Syntax | Notes |
---|---|---|
integer | An optionally double-quoted single integer literal. 42 , "6789" are all valid inputs. Hexadecimal input like 0xFF is also supported. | Internally, the clause may bind to a lower precision field such as uin16 . Incompatible value literals will be detected and reported.** |
real | An optionally double-quoted single floating-point literal. -123 , "3.1415926" are all valid literals. | Internally, the clause may bind to a field with a type different from float . Incompatible value literals will be detected and reported.** |
bool | true , True , or TRUE for true; false , False , or FALSE for false. | |
string | A string without whitespaces can be specified directly like nospace . Whitespaces like spaces, tabs, etc. can be included using double quotes like " lots of spaces " . | |
vector2 | Two floating-point literals enclosed by a pair of double quotes. The literals should be separated by whitespace(s) like "-1.2 3.4" . If only a single literal is provided, it will be applied to all components. For example, 0.5 is equivalent to "0.5 0.5" . | |
vector3 | Similar to vector2 , except that three literals are allowed. | |
vector4 | Similar to vector3 , except that four literals are allowed. | |
quaternion | Exactly the same as vector4 . | This type represents a quaternion. For vectors or tuples, use vector4 . |
real-array | Array variant of real that can accept N (N >= 0) floating-point literals. All literals are separated by whitespace(s) and should be enclosed by curly braces. For example, an increasing series of 5 elements can be written as {1.1 2.2 3.3 4.4 5.5} . | Accepts resource identifier as input. In this case, it is expected to be a file that contains the value part of the clause. |
vector3-array | Array variant of vector3 that can accept N (N >= 0) vector3 values. For example, {"7 7 7" "7"} defines two vector3 values, where all components == 7. | |
path | Basically a string , except that its value is interpreted as a filesystem path. | It is recommended to use resource identifier where possible so the scene file can be easily distributed without broken links. |
enum | A string that identifies an enumeration entry. | See the scene description reference for valid enumeration identifiers. |
All values can be double-quoted unless otherwise noted.
*: Value types do not have type-name
. The types shown here are both being full type names and type categories. **: Depending on the settings of the bound field and the parser, such warnings/errors may be disabled.
Each command from the example in the introduction section creates a named reference (if there is a @
specifier* before the name). Consider the following command that creates a rectangle:
The reference @plane
will uniquely identify the geometry resource, which is a rectangle, that has been created by the command. Many types in PSDL accept references as input. In this case, we use the type-category
and a corresponding reference in the clause definition. For example:
A material resource named diffuse
is being created by referencing an image named white
as its albedo with the clause [image albedo @white]
. Note that references can be used for resource sharing. For example, another diffuse material diffuse2
can be created with the same clause (referencing white
) and both diffuse
and diffuse2
will be using the same piece of data for their albedo.
*: We call this a persistent specifier. The named target will be persistent throughout the lifetime of the containing scene.
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.