C++: Conditional and template copy/move constructors & assignment operators.

C++: Conditional and template copy/move constructors & assignment operators.

The current (C++14) standard declares copy and move constructors as non-template constructors:

12.8/2: A non-template constructor for class X is a copy constructor …

12.8/3: A non-template constructor for class X is a move constructor …

Likewise sections 12.8/17 and 12.8/19 define copy and move assignment operators in a similar manner.

Unfortunately it means that generic (template) or conditional copy/move constructors and assignment operators require a little bit of trickery. Consider the following: Continue reading “C++: Conditional and template copy/move constructors & assignment operators.”

Light Transport in a Multi-Layered Microfacet Model

Light Transport in a Multi-Layered Microfacet Model

Microfacet BRDFs became very popular in real-time (and otherwise) rendering in recent years, with Epic and Disney jumping on the bandwagon as well, due to their physical-based origins, performance and plausibility.

Microfacet theory was introduced by Torrance et al., 1967 [1] as a physically plausible model of specular reflectance of different materials. As specular reflection is a perfect, mirror-like, reflection by the material surface, the specular highlight should be visible only when the normal vector directly coincides with the half-vector (the vector oriented exactly half-way between the light incident and eye vectors). However many materials have a blurred and imperfect specular highlights, this is explained by Torrance et al. by the existence of many microfacets, small facets that reflect incoming light. The size of a facet is much larger than incoming light wavelength, but too small to discern visually and the roughness of the surface dictates the distribution of slopes of those microfacets.

Continue reading “Light Transport in a Multi-Layered Microfacet Model”

Ordering Rendering Tasks, Ants and Graph Theory (Part 1)

Ordering Rendering Tasks, Ants and Graph Theory (Part 1)

A common problem in real time rendering is ordering draw/compute tasks (henceforth, tasks) in an optimal manner. Different order of execution can greatly affect performance, for example by influencing the amount of API calls. A lot of recent development of the OpenGL API has been focused on reducing draw calls and “Approaching Zero Driver Overhead” [1]. Likewise it is a common practice to group tasks by GLSL programs, FBOs and textures.
This article isn’t about indirect rendering or OpenGL per se, but about a better way of grouping tasks in an attempt to reduce total amount of API calls.

Furthermore, with asynchronous compute and multiple parallel command queues on the horizon, we should not regard task dispatching as a serial queue but as a scheduling problem.

Continue reading “Ordering Rendering Tasks, Ants and Graph Theory (Part 1)”

Dense Voxelization into a Sparsely Allocated 3D Lattice

Dense Voxelization into a Sparsely Allocated 3D Lattice

Sparsely allocated (partially resident) textures are exposed through an OpenGL extension (GL_ARB_sparse_texture), allowing us to allocate virtual textures as a portion of the GPU’s virtual addressing space, and commit to physical memory only specific pages as needed.

This post aims to cover the voxelization process, using a sparse 3D image serving as a lattice for the voxels’ data structure.

Continue reading “Dense Voxelization into a Sparsely Allocated 3D Lattice”

Playing with BRDFs

Been messing around with non-analytical BRDFs for the last few days.
Thanks to Pab Ltd for the data.

A Bi-Directional Reflectance Distribution Function is a 4D function that defines surface reflection. To avoid the 4-th dimension I generated 3D isotropic approximation from Pab’s data. Unlike anisotropic surfaces (e.g. brush metal), isotropic surfaces reflection is invariant of the tangental direction, therefore the two ϕ angles of the incident and exitant vectors in spherical coordinates can be merged. This results in a 3D function which can be easily encoded as a 3D texture.

Continue reading “Playing with BRDFs”

Designing a Lock-Free, Wait-Free Hash Map

Designing a Lock-Free, Wait-Free Hash Map

1. Introduction

Wait-free algorithms attract vast interest and are an area of intense research, the motivation being that true lock-free algorithms and data structures provide great benefits in terms of performance and scalability over lock-based variants. However designing lock-free systems isn’t a simple matter.

Recently I wrote a lock-free hash-map and in this post I will describe the process in detail.

The reader should have basic familiarity with hash tables, lock-free concurrency theory and the C++11 atomic library. From now on, by “lock-free” I mean true “wait-free”.

Continue reading “Designing a Lock-Free, Wait-Free Hash Map”