Displaz allows full control over how points are displayed in the 3D window by allowing the user to edit and recompile the shader program which is accessible via View->Shader Editor. Shaders are written in the OpenGL shading language with some extra hints in GLSL comments describing how to connect shader variables to the controls in the Shader Parameters dialog box. After editing a shader, pressing Shift+Return will cause the shader to be recompiled and the 3D view updated.
As a fairly minimal example, consider the file simple_example.glsl from the shaders directory.
#version 150 // Copyright 2015, Christopher J. Foster and the other displaz contributors. // Use of this code is governed by the BSD-style license found in LICENSE.txt uniform mat4 modelViewMatrix; uniform mat4 projectionMatrix; uniform mat4 modelViewProjectionMatrix; //------------------------------------------------------------------------------ #if defined(VERTEX_SHADER) // Shader parameters which may be set via the user interface uniform float pointRadius = 0.1; //# uiname=Point Radius (m); min=0.001; max=10 uniform float exposure = 1.0; //# uiname=Exposure; min=0.01; max=10000 // Point size multiplier to get from a width in projected coordinates to the // number of pixels across as required for gl_PointSize uniform float pointPixelScale = 0; // Each point has an intensity and position in float intensity; in vec3 position; // Point color which will be picked up by the fragment shader flat out vec3 pointColor; void main() { gl_Position = modelViewProjectionMatrix * vec4(position,1.0); gl_PointSize = 2*pointPixelScale*pointRadius/gl_Position.w; pointColor = exposure*intensity/400.0 * vec3(1); } //------------------------------------------------------------------------------ #elif defined(FRAGMENT_SHADER) // Input color per point flat in vec3 pointColor; // Output fragment color out vec4 fragColor; void main() { // Trivial fragment shader copies the colour and makes it opaque fragColor = vec4(pointColor, 1); } #endif
Each shader source file consists of both a vertex and fragment shader, distinguished by use of the VERTEX_SHADER and FRAGMENT_SHADER macros.
At the least, the vertex shader should perform a perspective transformation to set the built in gl_Position and gl_PointSize variables as shown. If you're interested in a nontrivial colour, you should also set a colour output variable which will need to match a colour input variable in the fragment shader.
The fragment shader must set a per pixel colour - in this case it is inherited very simply from the vertex shader. It can also decide to discard fragments so that point shapes other than squares can be created (see for example the default shader las_points.glsl in the shaders directory.)
To make it easy to quickly modify the shader uniform parameters, these can be annotated on the same line with a special comment beginning with //# of the general form:
uniform <type> varname = <default>; //#key1=value1; [ key2=value2; ... ]
The key value pairs define the behaviour and appearance of the corresponding GUI control. Uniform float parameters will be rendered as a spin box. Configuration keys are:
Uniform integer parameters may be rendered as a spin box or combo box:
Displaz can load the following point cloud types:
las: | Point clouds in the ASPRS laser scan exchange format |
---|---|
laz: | Compressed las files using Martin Isenberg's laszip format |
ply: | Point clouds in the Stanford triangle format containing the position.{x,y,z} or vertex_position.{x,y,z} properties as described below. |
txt: | Simple plain text point clouds in space-separated XYZ format |
Simple triangle and line meshes are also supported:
ply: | line segments files containing position and the edge.vertex_index property |
---|---|
ply: | triangle meshes containing position and the face.vertex_index property |
The main file format is the ASPRS LASer format; this is particularly appropriate for airborne laser scans. Internally these formats are read using the LASlib (by default), so any standards-conforming las file should be read correctly.
The ply format is a very flexible format for storing vertices and vertex connectivity. Due to its simplicity ply was chosen as a general format to communicate point cloud, mesh and line segment information to displaz. Unfortunately the standard values for ply metadata are poorly specified which leads to interoperability problems. The metadata conventions chosen in displaz are documented below.
Having all fields as a mix of properties on the vertex element seems to be a common way to store point clouds in ply format. Properties of the vertex element are loaded into displaz shader variables as follows:
(x,y,z) -> vec3 position (nx,ny,nz) -> vec3 normal (red,green,blue) -> vec3 color (r,g,b) -> vec3 color
Other attributes are processed as follows:
prop[0], ..., prop[N] -> N-element array per point with name "prop" propx, propy, propz -> 3-element vector per point with name "prop" prop_x, prop_y, prop_z -> 3-element vector per point with name "prop"
Here is a complete header structure in this format from the file standard_ply_points.ply. In it we define variables position, normal, color and a two element array a:
ply format ascii 1.0 comment Point cloud test containing some standard ply field names + extras element vertex 20 property float x property float y property float z property float nx property float ny property float nz property uint8 red property uint8 green property uint8 blue property float a[0] property float a[1] end_header
To get data into displaz from the various language bindings, a native serialization format is under development. The format a valid ply file, with metadata designed to be unambiguous, and data layout simple and efficient for binary serialization from in memory arrays. Each ply element should be named vertex_<field_name>; the vertex_ prefix is stripped off by displaz during parsing, with a resulting field <field_name> visible in the shader. The semantics of the field are determined by the names of the first property: "x" implies a vector, "r" a color, and "0" an array.
For example, the example file displaz_ply_points.ply has the header:
ply format ascii 1.0 element vertex_position 20 property float x property float y property float z element vertex_mycolor 20 property uint8 r property uint8 g property uint8 b element vertex_myarray 20 property float 0 property float 1 end_header
will be parsed and made available to the shader in the form:
vector float[3] position color uint8_t[3] mycolor array float[2] myarray
Basic support for triangle and line meshes is available using what I hope is the standard ply format for these. For both triangles and lines, the array of vertex positions are defined by properties vertex.x, vertex.y and vertex.z. Triangles are defined by connecting three vertices by specifying indices into the vertex array in the property list face.vertex_index. Similarly, edges are defined by connecting any number of vertices into a polygonal line using the property list edge.vertex_index. For example, the following header structure defines a mesh with 10 faces, and 3 polygonal lines:
ply format ascii 1.0 element vertex 20 property float x property float y property float z element color 20 property float r property float g property float b element face 10 property list uchar int vertex_index element edge 3 property list uchar int vertex_index end_header
Q: I see weird rendering artefacts. Points which are in the background sometimes hide those in the foreground.
A: Some graphics cards (for example integrated Intel cards on many laptops) seem to work badly with displaz. First, ensure that your graphics drivers are up to date. For laptops which have a higher power discrete GPU (such as from NVidia or ATI), you should ensure that you're actually using it - many systems also have a low power Intel GPU which is used by default on windows.
Q: I can't see any colour, even though my las file is meant to have colour included.
A: Try setting exposure to 256. If this works, you have a las file with colours scaled between 0-255, whereas they should be scaled into the full range of 0-65535 according to the las standard.