What determines the color gamut of a display? I’m not sure if I’m posting this question in the right area but, I’m wondering what determines the color gamut of a display?

Is or hardware down to the RGB filter built into a display like a monitor etc or is it software like a different color profile?

Question stems from the curiosity of if one display’s color gamut can be changed or not

The physical imaging elements of your monitor define your gamut. So things like how bright the elements can be as well as the color spectra of the color elements define the gamut. But, thats quite the simplification, its also affected by such things as the screen surface material and background lighting conditions.

Can the gamut be changed? Sure, if you want a smaller gamut then you can restrict your colors to a subrange of your gamut.


Defining "inside" and "outside" of a 3D space I am not sure if this is the correct SE to ask this question. However, lets say I have been given 3D models of several enclosed spaces.

I want to populate spaces with, lets say, planes flying through them, taking the optimum route from A to B. Since there are many of them, I want to write an algorithm that does this; I already have the 3D models of the planes.

I am looking for resources I can use to learn how to do define the boundary conditions for the opimization algorithm given the 3D model.

As no one else seems to want to suggest something, given that you said you wanted to navigate within an arbitrary enclosed volume, perhaps you could use an approach similar to that of the 1995 game Descent.

IIRC the world model of the 'mine' the spacecraft and enemy robots navigated was made up of "cuboid" units/voxels that pieced seamlessly together, some of which had solid walls that then formed the boundaries of the enclosing volume. The source code is freely available online e.g. here .

If, in the likely scenario you can't force the enclosing volume to have quadrilateral facets, you might want to consider "tetrahedral" volumes.


OpenGL Vertex - Texture Mapping I have a mesh loaded by an obj file (wavefront), complete with normals and texture coordinates per face, and its relative texture available. In my C++ / OpenGL code (assignment for a computer graphics class) I bind correctly the texture, but fail at correctly mapping texture coordinates with face vertexes. Below I show the code for texture binding and the chain of calls to rasterize the object. I also show images for the expected result and the actual results (2 of them, one for each render setting). To be specific, it seems that the first render "tessellates" the plain image on the rasterized shape of the whole object, while the second maps the image once on the shape of the object.

What is going on here?

Bind procedure:

SDL_Surface *s = IMG_Load(filename.c_str());

glBindTexture(GL_TEXTURE_2D, textureIndex);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB,
        s->w, s->h, GL_RGB, GL_UNSIGNED_BYTE, s->pixels);
glTexParameteri(GL_TEXTURE_2D,
        GL_TEXTURE_MAG_FILTER,
        GL_LINEAR );
glTexParameteri(GL_TEXTURE_2D,
        GL_TEXTURE_MIN_FILTER,
        GL_LINEAR_MIPMAP_LINEAR );

Raster procedure (pseudo code intended):

// gl pushMatrix, Traslation and rotations;
glPushMatrix();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textureIndex);
glColor3f(1,1,1);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glDisable(GL_LIGHTING);
glBegin(GL_TRIANGLES);
for (face f in faces) {
  glNormal3d(faceNormal.x, faceNormal.y, faceNormal.z);
  for (i = 0, i < 3, ++i) {
    glTexCoord3d(texturePoint[i].x, texturePoint[i].y, 0);
    glVertex3d(vertex[i].x, vertex[i].y, vertex[i].z);
  }
}
glEnd();
glPopMatrix();
// gl PopMatrix to exit from traslation / rotation context.

for (i = 0, i < 3, ++i)
    glTexCoord3d(texturePoint[i].x, texturePoint[i].y, 0);
    glVertex3d(v[i]->x(), v[i]->y(), v[i]->z());

This code calls glTexCoord3d three times and glVertex3d only once. You need more braces around your for loop.


Alternatives to Clipping in avoiding display problem I know in computer graphic, we can set a world window in world coordinate system, and then mapping it to viewport which is the display window. Things that are not in the world window should not be displayed and we can do this through Clipping (like in OpenGL). I have a question that do we have alternative methods?

"Go not to the CG Elves for counsel for they will say both no and yes".
Yes and No. As noted in another post, these issues don't exist with ray tracing but I'll assume you are interested in standard rasterisation.

It's possible to dispose of near clipping by using homogeneous rendering but that can introduce additional cost. (e.g more expensive triangle set up, more difficulty in identifying which screen regions are covered in tile-based renderers)

You could eliminate XY clipping by using float representations for the X and Y coordinates in the rasteriser but that can lead to catastrophic cancellation when computing triangle determinants which, AFAICS, is a necessary step. In my experience, hardware rasterisers* usually work in fixed-point so that everything is 'exact'.

As a compromise to XY clipping, guard-band clipping was introduced so that clipping only needs to be done on triangles that extend a 'long'** way off screen. Culling, however, is still be done with the standard frustum planes to eliminate those that are trivially off-screen.

*Dreamcast being a notable exception.
**for certain definitions of 'long', e.g. a small integer multiple of the screen width/height.


Ordering a set of unorganized points along a curve I have a set of 3D points (which I recover from a library that performs the tessellation of a solid body) that belong to a curve (i.e., an edge of the solid). That means that the curve surely passes by each of these points.

Nevertheless, the point set is unordered so I need to sort them in order to be able to draw this curve correctly.

Is there any known approach for these type of problem?

Some additional information:

The curves are parametric in general (splines/bezier, circle slices.. ).
The points are given as floating point coordinates.
The points are packed very densely (but they can be as dense as I want it to be). To give you an idea, for a curve which occupies 19 units in x, 10 units in x and 5 units in z, I quote a sequence of points in a segment of curve: (20.7622, 25.8676, 0) (20.6573, 25.856, 0) (20.5529, 25.8444, 0) (20.4489, 25.8329, 0) (20.3454, 25.8213, 0)

You have an instance of a problem called curve reconstruction from unorganized points. Now that you know what to search for you'll find several methods, such as the crust, NN-crust, etc. Here are a few links:

The Crust Curve Reconstruction Applet
Curve Reconstruction by Tamal Dey
Curve and Surface Reconstruction: Algorithms with Mathematical Analysis, book by Tamal K. Dey, Cambridge University Press, 2006

Since you're dealing with curves and the samples are dense, I suggest you compute an Euclidean minimal spanning tree.


Microfacet shading for diffuse materials I recently replaced the Lambertian BRDF in my path-tracer with Oren-Nayar, under the assumption that I could adjust it to use the GGX distribution model with appropriate masking/shadowing.

PBR suggests this is't viable, though - Oren-Nayar is formulated without any clear $D$/$F$/$G$ parameters, and a note under the Torrance-Sparrow model states that "one of the nice things about the Torrance-Sparrow model is that the derivation doesn't depend on the particular microfacet distribution being used" (implying this isn't the case for Oren-Nayar).

If Oren-Nayar is extensible, how would I do that? I suspect I could replace my $\sigma$ values with an NDF taking some $\alpha$ parameter (effectively convolving against the implicit Gaussian in the Oren-Nayar definition), and multiply the evaluated Oren-Nayar function against $G$ to capture masked segments of $dA$, but won't this clash with assumptions made by the derivation? PBR states that the function natively accounts for Gaussian-distributed masking, so applying another function over the top should result in over-darkening...

If it isn't extensible, can I adjust Torrance-Sparrow instead? Locking $F(\omega_o)$ to $1$ should remove Fresnel effects, and the specular assumption can be negated by extracting the $d\omega_h = \frac{d\omega_o}{4\cos\theta_o}$ relationship to create the modified BRDF $f(\omega_o, \omega_i) = \frac{D(\omega_h)G(\omega_o,\ \omega_i)d\omega_h}{d\omega_o\cos\theta_o}$

You can combine Oren-Nayar with GGX, if your normalize the result. A BRDF is defined by two properties: Helmholtz reciprocity and energy conservation.

$f(l_i, l,_o) = f(l_o, l_i)$

$f(l_i, l_o) \leq 1$

Your Oren-Nayar is the diffuse part $f_d(l_i, l_o)$ and your GGX is your specular part $f_s(l_i, l_o)$. If both are energy conserving, then both are at most $1$, but combined they may be $\geq 1$ and here lies your problem. Oren-Nayar has been combined with specular terms before (see for example The Rendering of Ryze from Crytek, you should have a look at how others did it. If you combine them, keep in mind that you need two different roughness values. The ones of Oren-Nayar and GGX don't match (which by the looks of it you know already) but neither can you convert from one to the other via an algorithm.

A better solution imo is to use a different diffuse term. Have a look at the papers Physically Based Shading at Disney by Brent Burley and PBR diffuse Lighting for GGX+Smith Microsurfaces by Earl Hammon Jr.. Physically Based Shading discusses several diffuse lighting BRDFs, including Oren-Nayar and then goes on to introduce an own diffuse BRDF which can use the same roughness value as GGX (be careful, as the roughness here is squared before using, iirc, because that was easier to use for artists). This resulting BRDF is not energy conserving, which was accepted by the author, since

  This seems to provide a reasonable match to the MERL data and was also found to be artistically pleasing.

A solution for this was introduced by Sebastien Lagarde and Charles de Rousiers in Moving Frostbite to Physocally Based Rendering, they renormalized the entire BRDF.

PBR diffuse Lighting for GGX+Smith Microsurfaces by Earl Hammon takes a different approach, he calculates an approximation like Oren and Nayar did, only he did it for GGX NDF and Smith shadowing/masking. Both the Disney Diffuse and Hammon's Diffuse BRDF can easily be combined with the GGX specular term and are visually more pleasing than Lambert.


Why are Homogeneous Coordinates used in Computer Graphics? Why are Homogeneous Coordinates used in Computer Graphics?

What would be the problem if Homogeneous Coordinates were not used in matrix transformations?

They simplify and unify the mathematics used in graphics:

They allow you to represent translations with matrices.
They allow you to represent the division by depth in perspective projections.

The first one is related to affine geometry.
The second one is related to projective geometry.


Should JPEG encoding take into account gamma? When an image is encoded using JPEG, the RGB pixels are first encoded into YUV, and then the UV channels are downsampled. Before actually doing the DCT and encoding the coefficients, JPEG doesn't gamma correct the Y channel. Is this correct? Shouldn't we determine the DCT coefficients that will most affect our viewed result?

The short answer is "no", for reasons covered in Alvy Ray Smith's memo, Gamma Correction. Gamma is not about nonlinearity in human perception, it's about nonlinearity in display devices (and, I suppose, acquisition devices too).


Proper architecture for rendering history of streamed data (points) Overview

My program receives some data points (0-400 per sec).

// simplified example of point's data structure
struct Point {
    QPoint p;
    QTime t;
    quint32 value;
}

I need to render some filtered points (eg. that point.time > currentTime-5 and point.value>5).
I need to store data history (up to ~50'000 points).
The data can be used also on the CPU.
I will use object-picking.
Points are rendered in 3d.
Camera position can change, but points data is constant.

Question

What is the best architecture to implement this kind of problem? What are best practices with this kind of data and what are practices to avoid?

Possible solutions

Storing and filtering data.

Store the data on the CPU (world coordinates), filtering data on a CPU and sending filtered data to VBO, calculating screen-space coordinates with shaders.
Store the data on a CPU and a GPU (update a VBO when some new point arrives).
Filter points on CPU and calculate offsets and use glMultiDrawArrays.
Store the data only on a GPU (update VBO when point arrives).
Filter it with shaders, get data from VBO to CPU when needed.

Solution 1. is fairly easy, but I think it is a bad practice.
Solution 2. has data duplication, but it is easy to filter the data.
Solution 3. has data reading GPU->CPU.

I tried those solutions, and Solution 2. occurs to me as the best, but there are some issues with it:

Multiplication of data has to be handled gently.
It is not the easiest-to-read-and-modify solution.
When there are changes in data there is a lot of things to change.
I used something like circular buffer on VBO and send offsets to render on it.

Environment

OpenGL 3.3
Qt 5+ bindings
Linux

PS
I am fairly new to computer graphics and openGL, so maybe this kind of problem even has its name. I changed my implementations few times, it took me a lot of time and I am not happy with it due to its complexity. Any materials, guides and thoughts are welcome.

My advice would actually be to stick with solution 1 unless and until something more is needed. It's the simplest and easiest to understand, and it should be quite feasible to make it perform well.

On the one hand, it may seem wasteful to re-filter the points and re-upload a bunch of data to the VBO every frame. I guess that this is why you say it is a "bad practice". But consider the total amount of data involved. An order-of-magnitude estimate shows that processing this amount of data every frame is not much work for a modern computer.

The Point struct you quote looks like it's about 20 bytes (assuming that p is 3 floats and t is one float or int). With 50,000 points, the total size of the data is about 1 MB. Even if your actual data struct is a bit larger, still the total size of the data is only a few MB—a small amount by today's standards. The time needed to process this amount of data on the CPU, and transfer it to the GPU, is on the order of ~0.1 ms. (Assuming ~20 GB/sec CPU bandwidth, and ~8 GB/sec PCIe transfer bandwidth.) So, this is an entirely reasonable amount of data to re-process each frame, and in fact you could handle many times more without stressing your system at all.

So, just keep things simple and efficient for memory access:

Store the points in a big flat array (maybe using a ring buffer to allow new incoming points to overwrite old ones).
Each frame, scan the points using a tight loop on the CPU, and copy the ones that pass the filter into the VBO.

For best efficiency, probably you should use GL_DYNAMIC_DRAW usage when you create the VBO, then use glMapBufferRange each frame and copy the filtered points directly into the mapped buffer.
Use GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT for the access parameter to glMapBufferRange; this will allow the GL driver to perform under-the-hood double-buffering to stream the data to the GPU efficiently. For more information on what's going on here, see Buffer Object Streaming.

Then unmap the buffer and issue the drawing commands, using a vertex shader to transform the points to screen-space as usual.


Silhouette curve for isometric surface of revolution I am trying to figure out how to convert a flat representation of a curve into the silhouette of a surface of revolution in a isometric projection. In essence in want the planar cut of the surface edge to be converted to the silhouette.

Image 1: Starting point.

The geometry in this case is a Bézier curve although if somebody has solutions for any functions or higher order curves would be fine. So in essence im open to conics and NURBS also.

Image 2: End result. How to transform the magenta curves?

The way I've done this now is by sampling several forms and in this case draw the new curve over the points. But id like to do this automatically and more precise. Please note: I am perfectly aware on how to do this with discrete data, I am looking for a more analytical solution if possible.

Image 3: The shape was derived using an old draftsman's trick.

Please note: Most applications polygonize NURBS or Bézier surface for rendering. Also trivial root finding does not really work well as result should not be pixels but a curve. Let us to avoid this, as I am perfectly capable of discretisizing the solution and project the edges on the back face culling edge, and doing a secondary fitting, or even fitting on the NURBS underworld and then to 2d*. That is exactly the same solution as I am using now. Seem to me there should be a somewhat analytical transformation possible.

Image 4: I am perfectly capable of doing this with subdivision/discretisation of the domain.

* Though if you know a robust way to do the projection to a curve on surface I'm interested in that too.

The silhouette curve of a quadric surface is a conic (ellipse, parabola, hyperbola, etc.). Suppose you have the quadric $\mathbf{X}^T \mathbf{M} \mathbf{X} = 0$ and your eye is at the point $\mathbf{Y}$. Then the silhouette curve is the intersection of the quadric and the so-called polar plane of $\mathbf{Y}$, which is $\mathbf{Y}^T \mathbf{M} \mathbf{X} = 0$.

For anything more complex than quadrics, things get nasty in a hurry, and you won't find any analytic solutions; you'll need numerical methods to trace the curve. Even the silhouette of a torus is pretty complex. So, in essence, the best you can do is compute discrete points along the curve, and use these to construct either a polyline or a spline of some sort. But, of course, you can always get a polyline just by tesselating the surface and finding the silhouette of the tesselation.

One approach would be to approximate your surface of revolution by quadrics, but that may not be any better than tesselating. You'd get a piecewise conic curve, instead of a polyline, which might be an improvement.

Note that if your surface is not G2, then it's silhouette will not be G1 (i.e. it may have sharp corners). Tracing a curve with corners is tricky.

There are silhouette generation functions in geometry kernels like Parasolid and ACIS. Maybe in OpenCascade, too.

To illustrate the difficulty, suppose we have a surface with parametric equations $(u,v) \mapsto \mathbf{S}(u,v)$, and we are viewing it from an eye- point $\mathbf{E}$. Let $\mathbf{N}(u,v)$ be the surface normal at parameter values $(u,v)$, which we can calculate as the cross product of partial derivatives: $\mathbf{N}(u,v) = \mathbf{S}^u(u,v) \times \mathbf{S}^v(u,v)$.
If a point $\mathbf{P}$ is on the silhouette curve, then the surface normal at this point is perpendicular to the vector $\mathbf{P} - \mathbf{E}$. So, the silhouette curve is the locus of points where
$$
(\mathbf{S}(u,v) - \mathbf{E}) \cdot \mathbf{N}(u,v) = 0
$$
Substituting for $\mathbf{N}(u,v)$, this becomes
$$
(\mathbf{S}(u,v) - \mathbf{E}) \cdot (\mathbf{S}^u(u,v) \times \mathbf{S}^v(u,v) ) = 0
$$
If $\mathbf{S}(u,v)$ is even a very simple surface, like a torus or a biquadratic or bicubic patch, the silhouette equation will not have any analytic solution.


How to apply wire texture for realistic rendering of embroidery? I am building an algorithm which takes a bitmap image as input and render the image as an embroidery design.

The different steps are :

Vectorize the image, I keep only 5 colors  (Done)
Generate
stitches lines (Done)
Apply wire embroidery texture to the lines,
add lights and show a realistic rendering ( It's this step that I am
having trouble with)

Let's take an example.
The original image is :

From there, I vectorize the image and obtain an SVG file.

After that, I generate stitches lines automatically which you can find here (svg file): https://www.dropbox.com/s/jmi6rz1ixgkjjpb/flowers_fill_0.7_vLongShort_space_randomLength.svg?dl=0

When you zoom in, it looks like this :

If I export the svg as png, I get :

As you can see; having this result is not enough to render realistically the embroidery design.

I am looking to have a texture more like this :

I tried generating a normal map and the use it adds some depth, but again, the result looks very plastic ... :

I don't know what I should do now to have a realistic rendering ...
At first, it wasn't supposed to be a computer graphic problem so I am not a specialist in the area, but I think using webgl or opengl is the best choice.

However, I don't know how to give the rights textures to the lines ...

Picking up from step 2, where you generated line segments to represent individual stitches, I would first suggest that you apply rounded ends to each segment, rather than square ends.

I would then convert each segment to an outline, (i.e. each rounded stitch becomes an separate poly-line representing the outer boundary.)

For example, suppose you start with point A & point B, representing a single stitch in line segment form. We can derive the rounded outline of this segment with the following Javascript code using THREE.js:

    function outlineSegment (Ax, Ay, Bx, By, radius){
        var radius = radius || 0.5; //millimeters?
        var A = new THREE.Vector2(Ax, Ay);
        var B = new THREE.Vector2(Bx, By);
        var C = B.clone().sub(A).normalize().multiplyScalar(radius);
        var angle = C.angle();
        var outline = new THREE.Shape();
        outline.moveTo( B.x + C.y, B.y - C.x );
        outline.absarc(B.x, B.y, radius, angle-Math.PI/2, angle+Math.PI/2);
        outline.lineTo(A.x - C.y, A.y + C.x);
        outline.absarc(A.x, A.y, radius, angle+Math.PI/2, angle+Math.PI*3/2);
        outline.autoClose = true;
        return new THREE.ShapeGeometry(outline);
    }

The above function finishes by triangulating the polyline into faces, (See the orange area in the included picture.)

Next, send these faces to be rendered by the GPU, applying a vertex shader which sets a vec2 varying variable (sounds redundant, but it's not) indicating the vertex position relative to the original line segment (which we have included as vertex attributes)

Now, we move on to the fragment shader, where we use the varying variable created in the vertex shader to derive a normal.

Let's say that "linePos" is the position along the line segment, (i.e. the x-value, if the line is horizontal. y-value if it is vertical, etc.)

Furthermore, let's say "lineDist" is the distance from the central line segment, e.g. -2 if it's 2 units to the left of the line (purple arrows) or +5 if it's on the right (blue arrows).

We can use these two values, derived from the varying variable, to create a normal for the point on the thread.

A bit of this code might be:

abs(sin(linePos+lineDist))

but there's a fair bit more than that to write.
I can't go through and write the entire program for you here & now, but hopefully these ideas & diagram will shine some light in the right direction.

Best of luck.


Different types of Gaussian blur? The Gimp has two different options in how you can perform Gaussian blur: "IIR" and "RLE".  What's the difference between them?

From the GIMP docs:

IIR
IIR stands for “infinite impulse response”. This blur works best for large radius values and for images which are not computer generated.
RLE
RLE stands for “run-length encoding”. RLE Gaussian Blur is best used on computer-generated images or those with large areas of constant intensity.

and also

They both produce the same results, but each one can be faster in some cases.

So the short answer is that IIR is optimised for photographs, and RLE is optimised for images with areas of flat colour.
The claim seems to be that the only difference is the time taken to calculate the blur, and that the end results are identical. I haven't tested this, so if you need to rely on that claim you should test both and check for any differences in the results.


How are Normal Maps created? How does one go about taking a single photograph, like a picture of a rock wall, and getting a decent normal map out of it?

If you can, I'd like to learn about the mechanics behind it, and not a piece of software like CrazyBump that does it for me.

"decent" is quite subjective and if you are restricting the capture to certain types of surfaces and controlled lighting conditions. For example normals and other SVBRDF parameters for shiny metallic surfaces are very difficult to capture compared to non-metallic, matte and bright surfaces without texture.

There are tools proposed in comments (CrazyBump, AwesomeBump) that try to do what you ask for and may generate normal maps sufficient to your requirements, but you could argue how "decent" the results are and how robust these tools are in capturing different types of surfaces. I don't know about the algorithms these tools use, but I believe they use more of an "artistic" than robust/accurate methods in generating the results.

There is some recent work to estimate normal map and other SVBRDF parameters using two images or from a single image (using neural networks), which is probably your best bet. However these algorithms assume a level of repeating pattern in the input images, but this might be ok for you since you mention rock wall as an example. There are likely other constraints as well such as requiring the captured surface to be dielectric hard surface material.

For more robust SVBRDF capturing you can check paper on frequency domain capture, but this is more complex capturing setup and far from a single image capture.

To my knowledge there's no known generic algorithm to accurately extract SVBRDF parameters from a single image of a non-repeating surface because of the fundamental issue that a single image can't unambiguously represent SVBRDF parameters. E.g. two different normal & albedo combinations of a Lambertian surface may result in same pixel color in a single image.


Prove radiance contributions of deeper paths fade away When ray tracing, I find it intuitively clear that deeper paths have a lower contribution to the overal picture than shorter paths. This is the main reason why it is generally okay to render a picture only to a certain depth, but I am currently not able to prove this.
Formally, we can write the rendering equation as
\begin{align*}
    L_o(\vec{p}_0, \omega_0) &= L_e(\vec{p}_0, \omega_0) \\
    &+ \int_{\Omega} f_r(\vec{p}_0, \omega_0, -\omega_1) \cos{\theta_1} L_e(\vec{p}_1, \omega_1) \text{d} \omega_1 \\
    &+ \int_{\Omega^2} f_r(\vec{p}_0, \omega_0, -\omega_1) \cos{\theta_1} f_r(\vec{p}_1, \omega_1, -\omega_2) \cos{\theta_2} L_e(\vec{p}_2, \omega_2) \text{d} \omega_1 \text{d} \omega_2 \\
    &+ \dots \,,
\end{align*}
where $\vec{p}_{j+1}$ is defined as the intersection of a ray with origin $\vec{p}_j$ and direction $-\omega_{j+1}$ and $\theta_{j+1}$ is the angle between the normal of the surface at $\vec{p}_j$ and $-\omega_{j+1}$. Each term represents the radiance contribution of respectively paths with depth 0, 1, 2, and so on. Let's denote the contribution of depth $d$ with $L_o^{(d)}(\vec{p}_0, \omega_0)$. I suspect that, under mild conditions on the scene, the contributions of these terms will asymptotically decrease exponentially: $$L_o^{(d)}(\vec{p}_0, \omega_0) = \mathcal{O}(t^d) \,\text{ as } d \rightarrow \infty$$ for some $t$ with $0 < t < 1$, where I have used the big-O notation.
Of course, I expect this only to hold when the scene is somehow "realistic", which I define as follows.
Firstly, all light sources should have only a limited amount of power. Note that infinite radiances, like with point lights, should be permitted, as long as their power is finite.

The total power of all light sources should be finite.

Secondly, we should exclude scenes that consists only of mirrors or diffuse white materials, or any other material that perfectly conserves energy. In other words, the scene should always absorb a little energy. These materials should still be permitted though, as long as their reflected light eventually ends up in materials that do not conserve the energy. I tried to formalize this the following way.

There exists an integer $k$ with the following property: for every point $\vec{p}$ in the scene there should be a path of length $k$ that starts in $\vec{p}$ and which has a throughput smaller than 1.

Questions.
Using these assumptions, is it possible to prove my suspicion? How would you do it?
If it isn't possible, are there other "realistic" conditions that will make it proveable? Any conditions you come up with should not limit scenes that are used in practice in any way. (I know, sometimes people create materials that transmit more light than what comes in. You can ignore these materials).

What I tried so far.
I was able to prove this with some stronger conditions, namely

There is an upper bound $L_{max}$ on emitted radiance $L_e$.
There is an upper bound $t < 1$ on the percentage of energy that materials conserve.

With these conditions, the prove is straightforward, but they do not allow point lights or perfectly white diffuse materials and such.
Proof.
\begin{align*}
    L_o^{(d)}(\vec{p}_0, \omega_0) &= \int_{\Omega^d} \left(\prod_{j=1}^d f_r(\vec{p}_{j-1}, \omega_{j-1}, -\omega_j) \cos{\theta_j} \right) L_e(\vec{p}_d, \omega_d) \text{d} \omega_1 \dots \text{d} \omega_d
\end{align*}
Using condition (1):
\begin{align*}
    &\leq L_{max} \int_{\Omega^d} \prod_{j=1}^d f_r(\vec{p}_{j-1}, \omega_{j-1}, -\omega_j) \cos{\theta_j} \text{d}\omega_j \\
    &= L_{max} \int_{\Omega} \text{d}\omega_1 f_r(\vec{p}_{0}, \omega_{0}, -\omega_1) \cos{\theta_1} \int_\Omega \dotsm \int_{\Omega} \text{d}\omega_d f_r(\vec{p}_{d-1}, \omega_{d-1}, -\omega_d) \cos{\theta_d}
\end{align*}
By applying condition (2) recursively on the innermost integral:
\begin{align*}
    &\leq L_{max} t^d
\end{align*}

If you are asking whether:

$$
\int fr(...) cos\theta_1Le_1 > \int fr(...)cos\theta_1 fr(...)cos\theta_2 Le_2
$$

(simplified terms from the render equation you posted above), I don't think you could prove this. Le_2 could just be much greater than Le_1.

For example you could have a set of mirrors which only hit a light source after two bounces. Then all the light would come from the second integral.

EDIT: Updating answer after your response.

If you are trying to prove that, ignoring the layout and lights of the scene, deeper paths contribute less to the overall equation, then you could try ignoring Le and assuming it is always 1. You are then trying to prove:

$$
\int_\Omega fr(...)cos\theta_1  > \int_{\Omega^2}fr(...)cos\theta_1fr(...)cos\theta_2
$$
or
$$
\int_{\Omega_1} fr(...)cos\theta_1 dw_1 > \int_{\Omega_1} fr(...)cos\theta_1\int_{\Omega_2} fr(...)cos\theta_2 dw_2 dw_1
$$

We also know that if the fr is energy conserving:

$$
0 \leq \int fr(...)  \leq 1
$$

And if 0 < cos < 1 we can say that:

$$
0 \leq \int fr(...)cos\theta \leq 1
$$

Substituting this knowlege into the equation into the inner integration of the right hand side doesnt give us much, as it could always be equal to 1 which would give us:

$$
\int_{\Omega_2} fr(...)cos\theta_2 dw_2  = 1
$$
$$
\int_{\Omega_1} fr(...)cos\theta_1 dw_1 > \int_{\Omega_1} fr(...)cos\theta_1 dw_1
$$

which disproves your idea. However if your bxdf is never perfectly energy conserving, eg:

$$
0 \leq \int fr(...)  < 1
$$

I think subsitituting this in does prove the above as we get something like:

$$
0 \leq n(w) < 1
$$
$$
\int_{\Omega_1} fr(...)cos\theta_1 dw_1 > \int_{\Omega_1} fr(...)cos\theta_1 n(w)dw_1
$$

As each term can only be less than the integral on the left.

Hopefully my math is okay here I might have made a mistake. You may need to clean it up and do some more formal proofs. I am sorry if this still doesnt help answer your question.


Visualizing the Lane-Riesenfeld Algorithm Ok so, I keep reading papers about this and non of them have pictures. The lane Riesenfeld algorithm provides a way to subdivide set of points with B-spline conversion.

The quesiton is simple HOW? If you can give me a set of pictures with the explanation that's be the best explanation, more than the math.

The first step (i.e duplication of the original vertices) seems clear enough, but I do not fully understand how the mid point averaging works.

Currently my very, very poor understanding is producing this:

Starting with the following 4 points

We duplicate each point (denoted by the grey area)

We take all odd points in our new set, and move them to the middle of the line connecting 2 consecutive points:

What do I do now? From here on I am just completely lost

The Lane-Riesenfeld algorithm subdivides the control polygon of a B-spline to create a new control polygon with the same limit spline.  It's made up of two steps: first, duplicating all of the control points $P_i$ into $P^\prime_{2i}$ and $P^\prime_{2i+1}$; then, moving each point to the midpoint between it and the next point, so $P^\prime_i \rightarrow \frac{1}{2} P^\prime_i + \frac{1}{2}P^\prime_{i+1}$.  These steps are illustrated in the figure:

On the left is an initial control polygon.  In the middle, I've duplicated the vertices.  On the right, the vertices have moved halfway to the next vertex.  Notice that only half of the vertices move in the first movement step: this is because $P^\prime_{2i} = P^\prime_{2i+1},$ but $P^\prime_{2i+1} \neq P^\prime_{2i+2}.$  These eight vertices are a refined control polygon for the linear B-spline defined by the initial four vertices.

Now, we can do a second movement step (without another duplication):

On the left, we've moved each vertex to the midpoint between it and its neighbour; note that all of the vertices move this time (since none are in the same position).  On the right, we have drawn the polygon with these eight vertices.  This is a refined control polygon for the quadratic B-spline defined by the initial four vertices.  You may also recognize this as the same polygon you get by Chaikin corner-cutting, which also gets you the quadratic B-spline.

Now we can perform more duplicate-move-move steps to further refine the polygon, and thus more closely approximate the quadratic B-spline curve:

Here's an animation of this process:

If, instead, we do a third movement step without a duplication step (that is, one duplication followed by three successive movements) we get a refined control polygon for the cubic B-spline defined by the initial four vertices:

An animation of this process:

In general, doing $k$ movement steps after each duplicate gives us the refined polygon for the $C^k$ B-spline.

EDIT: Added animations.


glMultiDrawArraysIndirect does not work when specifying an offset I'm trying to use glMultiDrawArraysIndirect to render a batch of object.

In my example I have a cube and a sphere (in this order) in a VBO and a GL_SHADER_STORAGE_BUFFER (SSBO) that contains matrix transforms as well as a GL_DRAW_INDIRECT_BUFFER (DIB) that contains the draw commands.

The allocation of both the SSBO and DIB are managed by a custom class.

I can currently render both objects successfully, each using their own transform. The problem I'm encountering is rendering just the sphere by specifying an offset. As per the OpenGL spec:

  If a buffer is bound to the GL_DRAW_INDIRECT_BUFFER binding at the
  time of a call to glMultiDrawArraysIndirect, indirect is interpreted
  as an offset, in basic machine units, into that buffer and the
  parameter data is read from the buffer rather than from client memory.

but doing the following code to render results in nothing being rendered:

// Calculates the offset & size and calls BindBufferRange
this->_indrMatrixBuffer.BindBufferRange(0, 1, 1);
// A simple call to glBindBuffer, binding to GL_DRAW_INDIRECT_BUFFER
this->_indrBuffer.BindBuffer();
// Render
glMultiDrawArraysIndirect(GL_TRIANGLES, (void*)sizeof(DAICmd), 1, 0);

The DAICmd is a struct of four unsigned int (as per the spec)

At first I though it might be my custom class but calling glMultiDrawArraysIndirect(GL_TRIANGLES, 0, 1, 0); and keeping the matrix buffer offset renders the cube in the spheres position!

What am I missing to get this to work?

Extra notes

Both the SSBO & DIB are mapped using the flags GL_MAP_WRITE_BIT, GL_MAP_PERSISTENT_BIT and GL_MAP_COHERENT_BIT and are created with the same flags plus GL_DYNAMIC_STORAGE_BIT
I'm using OpenGL 4.5
Using glMultiDrawArraysIndirect(GL_TRIANGLES, (void*)sizeof(DAICmd), 1, 0); does not produce an error when using glGetError()
Using KHR_debug produces no errors either

The problem was my class handling the population fo the draw indirect commands.

Each time I added a new command to the indirect buffer I also incremented the baseInstance, so the cube had baseInstance = 0 and the sphere had baseInstance = 1.

The reason why it doesn't render the sphere is because glMultiDrawArraysIndirect pretty much evaluates as glDrawArraysInstancedBaseInstance(mode,  cmd->first,  cmd->count,  cmd->instanceCount, cmd->baseInstance); (as per the OGL wiki).

The drawID is calculated as (gl_InstanceID / divisor) +baseInstance (link), which means that the drawID is out of range when trying to render with an offset, as the sphere now appears as the first element in the indirect buffer.


Refraction: given an incoming and transmitted direction, can I deduce the normal? It's easy to find guides to calculating the transmitted direction of light given an incoming direction, the normal, and indexes of refraction. However, I can't find anything about determining the normal, given all the other information. That's understandable because it's a bit of an odd thing to do, but I think I need it in my bidirectional path tracer to correctly weight paths that involve a microfacet surface. Even if it turns out that I don't, at this point I'm curious. I know that it's not possible if both indexes of refraction are the same, but that's fine.

See equation (16) in Microfacet Models for Refraction through Rough Surfaces : $-(\eta_i w_i + \eta_o w_o)$ which you'll probably want to normalize. $\eta$ are the two indices of refraction and $w$ the two vectors (they use $i$ and $o$ in the paper). Also look at the left part of figure 7 on the same page to see where all the vectors are pointing.


Floating Point Operations in Line Drawing Algorithms When it comes to line drawing, DDA is the simplest and most intuitive algorithm, the core idea being:

compute the slope of the line
for every increment in x, increment y by the slope

However, DDA is not favored due to its use of floating point operations. In fact, avoiding floating point operations is a common theme in graphics. I am wondering about the relative cost of floating point operations versus integer operations in modern GPU's

I could do some benchmarking but my CUDA is rusty. There is a question on SO and the common wisdom there seems to be, "it depends".

My question is specific to computer graphics and line drawing. If a more general answer can be given, that will also be appreciated.

To state my question specifically, is it important with modern GPU architectures to avoid floating point operations in favor of integer operations?

is it important with modern GPU architectures to avoid floating point operations in favor of integer operations?

Almost certainly not. CPUs have a long history where for many years they only handled integers natively and floating point operations were all done with slow math libraries. That changed about 20-25 years ago, but the thinking has remained entrenched for many years. (And certain applications like finance may require it for other reasons.)

Modern GPUs, though, have always been about doing lots of floating point calculations in parallel. If you think about how most 3D rasterizers (like OpenGL, Metal, DirectX, etc.) work, they take all the vertices, transform them into normalized device coordinates, and then interpolate between them to draw the actual geometry. While you certainly could do that all with fixed point math, it probably wouldn't gain you much. But you also aren't doing those calculations yourself, unless you've written your own rasterizer as a compute kernel.

Now depending on what type of work you're doing, the precision of the floating point operations may be reduced. In a language like glsl (in OpenGL ES, anyway) you can specify the precision of the uniforms. On mobile hardware, it might be worth doing the calculations as floating point, but with only 16 or 24 bits instead of 32 because it saves power,   for example. (And even some desktop GPUs have used lower-precision floating point in the past.) But the desktop hardware of today is optimized for doing floating point work.

In short, I don't see a compelling reason to stick to integer math when working on the GPU.


unwanted patterns in simplex noise I want to create a "river biome" where there are rivers cutting to a flat land mass, to start I wrote a little js to generate a random height map (with simplex noise) but that's where I'm stuck.

this is what it generates:

as you can see there are clear diagonal lines in there.
I tried looking up how to fix this and on my search I found these:

Is all grid based noise inevitably anisotropic?
Why does my Perlin Noise look "blocky"?

I don't know if this is my problem of if it's something else entirely.

here's the significant part of my code:

for(var y = 0;y < myRivers.height;y++){
    for(var x = 0;x < myRivers.width;x++){
        lightness = simplexnoise(x/50,y/50); // number between -1 and 1
        myRivers.context.fillStyle = lightnessToRgb(lightness); //maps lightness to a color
        myRivers.context.fillRect(x * 4, y * 4, 4, 4); // fills a pixel with the color
    }
}

a codepen: https://codepen.io/anon/pen/gooyMj

I know im a bit late, but hopefully this can help other people. you can add detail by using Fractal Brownian Motion. There is a great article here that i used as a guide to make my own version in c#. Also I would check to make sure your vars are ints.


Artefacts on top and bottom of utah teapot I am implementing a simple Phong shader in OpenGL GLSL, and the test object is the utah teapot. However on the bottom I get a solid red circle, and on the top there is are sharp sectors that are coloured incorrectly.

Is there any way to fix these issues? What would be the issue in the first place?

I'm fairly certain your problem lies in not handling so-called degenerate Bezier patches correctly, in particular (as Joojaa noted), the computation of the surface normal.  I say "so-called degenerate" because, geometrically, the surfaces are often perfectly well behaved. It's just that some assumptions people frequently make regarding the parametric equations may not hold.

Books such as Gerald Farin's, snappily titled, "Curves and Surfaces for CAGD. A Practical Guide" will give more details, but I'll try to summarise two simple cases. Now assuming your Bezier is defined as $\bar{B}(u,v)$ the usual two causes of problems are:

Zero derivatives:

To compute the normal at $(a,b)$ one normally (pardon the pun) computes the two derivatives,

$\frac{\partial }{\partial v}\bar{B}(a,b)$ and $\frac{\partial }{\partial u}\bar{B}(a,b)$

or scaled versions thereof, to obtain two tangents and then take the cross product.

(Implementation note: Since we can use a scaled version of the tangent in the calculation, we really don't have to calculate the actual derivative. For example, especially at the corners, differences of control points can yield a scaled tangent. However for brevity in this discussion we will assume the actual derivatives).

A common occurrence, at least at the corners, is that the 1st partial derivatives at the location can be zero, which leads to an incorrect normal, i.e. a zero vector.

In the case of the tops and bottoms of the teapot, one whole edge of a number of the (bicubic) Bezier patches has been collapsed to a point, i.e. all 4 control points are the same, and thus, say

$\bar{B}(0,v)==\bar{B}(1,v)$   and   $\frac{\partial }{\partial u}\bar{B}(0,0)=\bar{0}$.

The surface, however, is completely well behaved so you can simply choose another derivative that starts at that collapsed point. In this case, say, choosing

$\frac{\partial }{\partial v}\bar{B}(1,0)$

for the second tangent.

Having said this, you still have to check that your first derivatives are not zero for another reason (e.g 2 or 3 coincident control points), in which case, you can fall back (thanks to L'Hopital's rule) on the second (or if that's zero, even the third!) derivative(s) to obtain valid tangents.

Parallel tangents:

Another similar problem can arise if your two tangents, are parallel. - Farin has a good example in his book.

In this case, I think you may need to look at using something like $\frac{\partial^2 }{\partial u \partial v}\bar{B}$ or, possibly, just fall back to using a small UV offset to approximate a vector.


Monte Carlo Importance Sampling I am following the "Ray Tracing - the Rest of your Life" book by Peter Shirley and I am facing some troubles in the implementation of Monte Carlo importance sampling, and  Direct light sampling.
Monte Carlo theory is clear to me. During the implementation, the way rays are scattered does not actually change and remains random. What changes looks to be the contribution of each ray.
So my first question is:
Do I understand this correctly? Rays, after hitting a surface, are still scattered randomly, but the value of the color is adjusted based on the probability of that direction?

For those familiar with the book
When the author implements the Direct light sampling, he modifies the function color(), while we previously modified scatter() and scattering_pdf(). This way, scatter() and scattering_pdf() are sampling based on a specific pdf - proportional to cos(theta) - while color() introduces a new pdf related to the direction of the light. It is not clear to me how these two things coexist, and if I am supposed to disregard the previous changes to scatter() and scattering_pdf().

During the implementation, the way rays are scattered does not actually change and remains random.

Actually the way rays are scattered does change, specifically when you sample a light. In chapter 8 he makes a mixture pdf in order to sample either the light or the bsdf.

  What changes looks to be the contribution of each ray.

This does change, but not specifically due to the sampling of the lights but rather due to importance sampling. But that was already introduced in chapter 4.

Basically you have the following:
$$I = \int_{\Omega}f(x)\,dx = \int_{\Omega}\frac{f(x)}{p(x)}p(x)\,dx = E\left[\frac{f(X)}{p(X)}\right] = \frac{1}{N}\sum_{i=1}^{N}E\left[\frac{f(X_i)}{p(X_i)}\right] \approx \frac{1}{N}\sum_{i=1}^{N}\frac{f(x_i)}{p(x_i)}$$
Where $X$ and $X_i$ are distributed according to the probability density $p$.
As evident the main difference to the Monte Carlo formulation you are probably used to is the $p(x)$ factor, and the fact that $x_i$ are not uniformly sampled but rather sampled according to $p$. Note that for uniform sampling $p(x)=1$ and the equality still holds. Thus this is simply a generalization.


How to correct point cloud distortion I am using Unreal Engine to export custom render passes for the scene depth in world units. Every pixel in the render pass has a value which is the distance from the camera to that pixel in standard UE4 units. For example, a pixel with a value of 500 (more precisely 500,500,500) would be 500cm away from the camera.

I am then taking these render passes and trying to project them into point clouds inside Houdini. I have this all working, but I'm having trouble figuring out how to correct for the distortion that arises in the point cloud.

In my attempt to understand this, I have created a box which is the same aspect ratio as my output (1920 x 1080) and positioned the camera in such a way that it fills the frame more or less exactly.

Below is the point cloud, with a wireframe showing where the box was in Unreal Engine. After distortion correction, all those points should align with the face of box nearest the camera on the left. The centre pixels are in the correct place, but as you can see the further away from the centre the more offset they become from their true spatial location.

I understand that this distortion is arising because the render pass is essentially drawing a line from each pixel to the camera, so the further away from centre, the longer the line, giving the false impression of increased depth across what should be a flat plane.

I have been doing a lot of experimenting with varying distances, sizes of boxes, focal lengths, and so on, trying to figure out what the formula is to correct this distortion, but I'm completely stuck.

I feel like the formula must involve a combination of the distance of camera to pixel, as well as the angle formed between the camera-to-pixel line and the line pointing straight out of the camera. But I might be totally off-base, because I'm not a mathematician by any means.

Can anyone help me out or point me in the right direction?

I've figured a difference approach to projecting the point cloud inside Houdini.

I had assumed that the 'Scene Depth World Units' would provide the depth of each pixel along a vector parallel with the camera vector, rather than angled to point at the camera as a single point.

So rather than projecting the point cloud as if the depth was correct, and then trying to adjust for the distortion this creates, it makes more sense to just project the points in the same way they were created.

So, knowing the position and rotation of the camera, I can then use the depth pass to project the points outwards from this location.


How can I check if a polygon can completely contain a circle of a certain radius? How can I check if a polygon (can also be irregular) can completely contain a circle of a certain radius? I do not want to actually draw a circle inside the polygon but just a boolean outcome whether or not it can be fit. I need this for an application that I'm developing in Java. Note that I'm not looking for the inscribed circle, but the largest circle that a polygon can contain. I suppose there can be multiple circles with the same area.

Could someone share an algorithm or code snippet (any language is fine) or guide me to any relevant resource?

This is likely more complicated than you would prefer, but: Compute the medial axis, which immediately yields the largest disks that fit inside the polygon:
their centers are vertices (degree $\ge 3$) of the axis (see the
figure below).

  Chin, Francis, Jack Snoeyink, and Cao An Wang. "Finding the medial axis of a simple polygon in linear time." Discrete & Computational Geometry 21.3 (1999): 405-420.

(Image from Alexander Tsvyashchenko.)

See also, Largest circle inside a non-convex polygon for an ad hoc approach
(whose correctness I did not attempt to verify).


Best practice for managing many shaders and merging multiple shaders into one? I have managed to greatly minimize draw calls on my recent project, but as I'm adding more shaders, I see that I have to switch more times and that is causing a lot of draw calls. What is the best practice for managing multiple (dozens) of shaders in a scene with many materials?

I read that it's best to combine them together and you have a shader variable "mode" that you switch upon inside the shader, to end up with the specific branch of code in the shader that is to handle the fragment.

Since shaders do have alot of parameters populated from the model material/mesh and sent down to the fragment shader, I fear that unifying the shaders and passing too many parameters in the VBO each frame/vertex/fragment, would be really bad for performance. I target mobile/tablet devices with my product so this is important, I understand that this is less of a concern with desktop GPUs. I see modern engines like unity and unreal allowing full flexibility on adding shaders & materials at-will and their scenes render perfectly - how do they do that without increasing their shader switching and draw calls?

So how many parameters are too much? And what is the best recomendation to manage multiple shaders in a drawing a scene. I understand and have allready applied grouping and rendering each material at once to minimize shader switching, but that has its limitations if there are dozens of shaders.

Is there a technique or capability I'm missing?

I target mobile/tablet devices with my product
  this is less of a concern with desktop GPUs.
  unity and unreal allowing full flexibility on adding shaders & materials at-will

Well, Unity and Unreal can also be used to make games targetting mobile/tablet devices, right?
Do you think you can throw at them all the shaders & materials you want, and expect them to magically output a performant application every time?
Try to do it and you will find that they also struggle at some point.

This can also happen on desktop ; the newest smartphones are totally faster than my oldest laptop.

  What is the best practice for managing multiple (dozens) of shaders in a scene with many materials?
  how many parameters are too much?

The best practice is to test on the real hardware that you are targetting. If you target a wide range of mobile devices, then you have to decide the lowest spec that your product will officially support.
Then, it is a matter of finding a good balance between performance (few materials/shaders) and visual quality (more variety/complexity).
If you are comfortable with the process, you can prepare a number of performance profiles based on the type of device that will run your product (lower-end, higher-end?), with better quality for the higher end.

  Since shaders do have a lot of parameters populated from the model
  material/mesh and sent down to the fragment shader, I fear that
  unifying the shaders and passing too many parameters in the VBO each
  frame/vertex/fragment, would be really bad for performance.

You meant Uniform Buffer Object, not Vertex Buffer Object, right?
I expect that the size of the uniform data that you pass to the GPU is not that big?
However if your shaders are complex, it could take time for the GPU to execute them.

Here again it is a balance, between the amount of parameters that you pass, and the complexity of the shader, that you have to find.
You just can try different solutions on real hardware, note down the performance and aspect of each one, and somehow compare them ; to find the optimal solution for your product.


How to calculate the RGB intensity values at center of face using flat shading? Consider a triangular face of three vertices A(0,2,1), B(3,0,1) and the origin, and the normal vectors at the vertices are nA=(0,0,1), nB=(1,1,0) and nO=(-1,-1,1), respectively. The incident light is white and directional in the direction of L=(0,3,4) and the intensity is 1, the background ambient light intensity is 0.1, and the diffuse reflection coefficients for (red, green, blue) are (0.6,0.7,0.8). No specular light contribution need be considered.

How do I find the (red, green, blue) intensity values at the centre of the face using flat shading?

Flat Shading:

I = Ia x Ka + Fatt x Il x (Kd x (N x L))

Final intensity = ambient reflection x ambient reflection coefficient + (attenuation x incident light intensity x (diffusive reflection coefficient x (surface normal x Light intensity))

My lecturer told me that because ambient reflection coefficient and attenuation are not given, I can forget about it. Also specular light contribution need not be considered.

The surface normal is:

A = (0, 2, 1) B = (3, 0, 1) O = (0, 0, 0)

U = A - O = (0, 2, 1) V = B - O = (3, 0, 1)

Surface normal = U x V (cross-product) = (2, 3, -6)

I = 0.1 + (1, 1, 1) x ((0.6, 0.7, 0.8) x ((2, 3, -6) x (0, 3, 4)))

I = 0.1 + (1, 1, 1) x ((0.6, 0.7, 0.8) x (0, 9, -2.4))

I = 0.1 + (1, 1, 1) x (0, 6.3, -1.92)

I = (0.1, 6.4, -1.82) = RGB intensity values

Is this correct?

You shouldn't solve for $\cos^{-1}(\theta)$.

The ambient component is as follows (we are assuming the ambient light is white):
$$ambient\ color = (ambient\ light\ color)(ambient\ intensity)(diffuse\ color) = (1,1,1)(0.1)(0.6,0.7,0.8) = (0.06,0.07,0.08)$$

The diffuse component is as follows:
$$diffuse\ color = (light\ color)(light\ intensity)(diffuse\ color)(\cos(\theta)) = (1,1,1)(1)(0.6,0.7,0.8)(0.8) = (0.48,0.56,0.64)$$

Now we just need to add them up:
$$final\ intensity = (diffuse\ color) + (ambient\ color) = (0.06,0.07,0.08) + (0.48,0.56,0.64) = (0.54,0.63,0.72)$$

For more information, here's a pretty decent summary of various lighting calculations.


Shading: Phong vs Gouraud vs Flat How do they work and what are the differences between them? In what scenario should you use which one?

Flat shading is the simplest shading model.  Each rendered polygon has a single normal vector; shading for the entire polygon is constant across the surface of the polygon.  With a small polygon count, this gives curved surfaces a faceted look.

Phong shading is the most sophisticated of the three methods you list.  Each rendered polygon has one normal vector per vertex; shading is performed by interpolating the vectors across the surface and computing the color for each point of interest.  Interpolating the normal vectors gives a reasonable approximation to a smoothly-curved surface while using a limited number of polygons.

Gourard shading is in between the two: like Phong shading, each polygon has one normal vector per vertex, but instead of interpolating the vectors, the color of each vertex is computed and then interpolated across the surface of the polygon.

On modern hardware, you should either use flat shading (if speed is everything) or Phong shading (if quality is important).  Or you can use a programmable-pipeline shader and avoid the whole question.


Reading thesis on cone tracing, did the author make a mistake? I am reading this document that talks about signed distance field rendering.

In that document section 6.3, on the topic of cone tracing, it says:

  Cone tracing is an extension of the sphere tracing algorithm. In
  addition to the ray, a cone is created and expanded in the marching
  direction. At each sampling step, the current cone radius is compared
  with the minimum distance from the distance field. If the SDF value is
  smaller than the current radius, the cone has intersected an object
  [14]. This incurs very little additional cost to the normal sphere
  trace, while providing useful intersection information.

In particular: If the SDF value is smaller than the current radius, the cone has intersected an object.

Am I reading this wrong? there's no way that's true. Consider the following diagram:

From that diagram, it seems obvious that for any cone radius $R$ there exists an SDF value $\epsilon$ such that $R > \epsilon$ and the cone doesn't intersect the sphere.

Am I interpreting the document wrong?

It’s kind of inaccurately stated—by comparing the SDF with a linearly increasing radius, the shape that’s being traced out is a cone with a hemisphere on the end, something like this:

At any point along the horizontal center line, if the distance to the nearest surface is less than the current test radius, the cone-plus-hemisphere has intersected that surface.


Apply distortion to Bézier surface I am trying to simulate the image warp effect, that is used in Adobe Photoshop.

The rectangular image is warped according to a cubic Bézier surface (in 2D, all Z components are 0). Having any Bézier surface, vertical distortion $d \in[0,1]$ can be applied to it.

Left: input bézier surface, $d=0$, Right: output surface,  $d=0.8$

Do you have any idea, what is done to the Bézier surface (16 points), when converting from the version on the left to the output on the right?

Edit: changed the answer according to new images and clarification.

for every control point p(k, n)
   p'(k, n) = ( p(k, n) - p(k) ) * d * l(k) + p(k, n)

where k is the row index and n is the column index of control point. l is the elevation factor and is equal to {-1, -1/3, 1/3, 1}. p(k) is the center of the k'th row.

Rationale:

From the new images, red and blue lines are drawn from the center of the line (p(k) which is basically (k, 0)) to that point. On the first line, all control points, including the ones on the graph (red lines) are moved to the same point on that line. p(k, n) - p(k) gives the vector which moves a point from p(k) to p(k, n) which now should be applied to the other way, moving the point to the desired location. On your graphs, d = 1 so that all first line points would be moved to the center. You can easily solve the equation to verify this. d * l(0) is -1, so it would be -p(k, n) + p(k) + p(k, n) which would give p(k).

On the second line, your blue line is again from point to the center, but this time it stopped before reaching it. I cannot tell if it really is cut from 1/3 but that would be a good starting point. So the same formula still applies. l is -1/3 d is 1, so the point would be moved in 1/3 of the way. 3rd is the same as the second but it now moves outwards, thus l is 1/3.

On the final line, all control points are moved out from the center point of that line. This is quite clear since your lines meet up at that center.

The only problem this formula can have is assumption of 1/3, other than that I do not see the reason why it should fail.

Note: I used row, column while indexing, thus if you are using x, y you should switch their locations.


How to achieve gimbal lock with Euler angles? I was studying about Euler angles and I came across the problem gimbal lock which can occur by using Euler angles. In gimbal lock we lose one axis of rotation.

But how? And when does it happen? On what conditions?

All I know about Euler angles is that rotation always occurs about the object axes not upright axes (axes whose orientation is always the same as the world axes). And the object axes will remain perpendicular to each other in each rotation.

Could someone use Euler angles and show me how to get to that point of gimbal lock?

How can it affect animations?

Rotations in 3D are normally done with matrices. The xyz Euler angles can be converted to matrices so that it can be used in the rotation.
That is where something called rotation order comes in.
Basically it says in what order you rotate the object.
First you rotate the object around the x axis, then the y axis and lastly the z axis for example.

This means that when you rotate the object around the x axis first, you change the way the y axis and z axis rotate.
Of course this changes depending on the rotation order.

This GIF shows how changing one axis value can change the others, but it doesn't work that way for everything.

Here you can also see at the end that I add in that gimbal lock.
This is where I lose one axis of rotation.

This could be fixed by changing the rotation order to an order, where it doesn't break the way it should work.
It could also be fixed by not using Euler angles but Euler angles are handy and simple in 3D animation.

In 3D animation it could lead to weird rotations since the values of the rotations have to be changed a lot to get a certain rotation that you want.
If you would look at the xyz Euler angle values in a graph, you would see spikes because of that.
This could lead to weird interpolation of the keyframes and a weird end result.

If you would like to read more about the math behind it, I would recommend reading about rotation matrices in 3D.
https://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations

A little extra explanation for the animation:
Rotation in this case is around axis (shown as circles) and by rotating on one axis, you rotate the other axis. The consequence is that with a normal rotation sphere (the sphere in the animation, but then without the axis being rotated) in the animation, you don't see these axis being rotated. If you get a gimbal lock, one axis is the same as another one, but with a normal rotation sphere it still tries to rotate as if that axis wasn't the same as another one, this means that it uses weird values to get to that rotation and this can make an animation look weird.

I hope this helps!


Questions about Blur effect I am working on a specific blur effect that implies several behaviours. But before I would like to know what you think about those blurring algorithms according to performances and quality :
Kawase blur, Box blur and two pass Gaussian blur.

Next are the effects I am currently working on and I would be glad to have your thoughts on those on the proper way to achieve this. Here is a schematic view followed by my questions.

I would like to blur the content of those 4 spheres using the same offset no mater their position. If I apply the same blur on all objects, far object's content will appear more blurry than ones on the foreground and I want to avoid that. I think that the depth make could help but any precision would help me.
If I blur the whole image and apply the result on the sphere, the white background will bleed onto the sphere shape and I want to avoid that. I also don't want that the blue (3) and yellow (4) sphere merges with the red (1) and green (2) ones. But I would like that the green and red ones merges. Again This could be done using the depth but if you have more precision about how to do it it would be interesting.

Any ideas about those questions would be helpful.

Thanks a lot.

If I blur the whole image and apply the result on the sphere, the white background will bleed onto the sphere shape and I want to avoid that. I also don't want that the blue (3) and yellow (4) sphere merges with the red (1) and green (2) ones. But I would like that the green and red ones merges. Again This could be done using the depth but if you have more precision about how to do it it would be interesting.

You will need to blurr in multiple passes to achieve this:
once for the blue and once for the yellow, as well as once for the red and green (together). That is: you need to render to texture, you need three textures in this instance to render to, you need to blur the individual textures and then combine them in another render pass.
If you know beforehand that the green and red spheres may blur together, you can just hardcode it, otherwise you need to come up with a way of determining, which spheres may blur together, and group your spheres to render into the same texture.

If you do this, keep in mind that for combining the three individual blurred textures, you need z-values for correct visibility determination.

  I would like to blur the content of those 4 spheres using the same offset no mater their position. If I apply the same blur on all objects, far object's content will appear more blurry than ones on the foreground and I want to avoid that. I think that the depth make could help but any precision would help me.

Yes, you can scale your blur filter with a depth value (where you should "invert" the value to make the blurriness scale to larger effects on closer proximities, i.e. smaller depths). For a box filter, you take ratios of the pixels neighbourhoods, but you need to make sure that those ratios add up to one. For this, you'd ideally increase the ratio for the center pixel based on the proximity and reduce the ratio for the neighbouring pixels accordingly.

  performances and quality : Kawase blur, Box blur and two pass Gaussian blur.

As to performance, I can't say anything about the three. As to quality, the Box Filter is rather simple, but that doesn't mean it doesn't suffice for your specific need. Just test them against each other.


What is a scaling factor of the screen? I'm reading DXGI flip model article and some parts are not clear:

  DirectFlip with panel fitters: Your window client region covers the screen, and your swapchain buffers are within some hardware-dependent scaling factor (e.g. 0.25x to 4x) of the screen. The GPU scanout hardware is used to scale your buffer while sending it to the display.

What is this hardware-dependent scaling factor? What it does? Why?

  The traditional pattern for apps in the past has been to provide the user with a list of resolutions to choose from when the user selects exclusive fullscreen mode. With the ability of modern displays to seamlessly begin scaling content, consider providing users with the ability to choose a rendering resolution for performance scaling, independent from an output resolution, and even in windowed mode.

I understand what they mean by the traditional pattern, it's pretty common - I'm selecting a resolution in the options screen and enjoying fullHD 800*600 picture. But I have no clue what are they describing next - displays seamlessly scaling content, resolution for performance scaling, output resolution. Could someone explain the same with simple words and examples (I bet there are already games out there that uses the technology)?

What they're saying is you don't have to render the game at the same resolution that it's displayed. For example you could be in a display mode of 1920×1080, but have the game rendering at only 1280×720, to run faster. The OS and display hardware can automatically upscale the frames to the display resolution under the hood.

Usually, the OS runs a window compositor, a background process that draws the desktop, all app windows, menus, etc and presents them to the display. In windowed mode, any upscaling needed would be done by the compositor. However if the game's window is covering the whole display ('borderless fullscreen') and nothing else is on top, then the OS can switch off the compositor and let the game present to the display directly.

But then if the game is at a lower resolution than the display, it still needs to be upscaled. The GPU can do this in hardware (scanout) as long as the scaling factor isn't too big. For instance, there may be a limit of 4x scaling. So, if your rendering resolution is more than 4x smaller than the display, the OS can't use the hardware upscaling and would need to keep using the window compositor instead. All of this stuff happens automatically in Windows 10, without the app needing to know about it or do anything special.

Given all this, they point out that there's no real reason for the rendering resolution of the game to be limited to the classic display modes like 800×600, 1024×768, 1280×720, etc. You might as well have a continuous resolution slider instead of a fixed set of modes. There's no problem with choosing a "weird" resolution like, say, 1000×562 or something. The upscaler/compositor will just take care of it.

This what they mean by "consider providing users with the ability to choose a rendering resolution for performance scaling, independent from an output resolution". In other words, in your game's options screen, you should give the user a slider to control rendering resolution, so they can tune it for performance vs visual quality. But it need not be tied to the actual display resolution.


Ray-based rendering terms There are a number of terms for rendering techniques based on the particle model of light: forward ray-tracing, reverse ray-tracing, ray-casting, ray-marching, and possibly others.  What's the difference between them?

Forward ray-tracing means that rays starts from the light source and are traced towards the eye (light-surface-eye), this is a highly inefficient but accurate method. Reverse raytracing is simply starting in the eye and then trace them towards the light source. These are two classes of ray tracers.

  Ray casting is the use of ray-surface intersection tests to solve a variety of problems in computer graphics and computational geometry. The distinction is that ray casting is a rendering algorithm that never recursively traces secondary rays, whereas other ray tracing-based rendering algorithms may do so.

Ray-marching is an implementation of a ray tracer, often used to visualize volumes. Normally ray casting uses a formulae to determine the point of intersection with the surface. In ray marching such a function is not required, instead the intersection is evaluated at several points along the ray. Either these points have a fixed distance between them or every iteration the distance to the next point is based on the distance to the closest surface.

The difference between those are that ray-tracing is a concept to solve the rendering equation, in the end resulting in a certain color for each pixel. Forward and reverse ray-tracing are classes of ray-tracers, ray-casting is a simple algorithm to do ray-tracing and ray-marching is another algorithm to do ray-tracing. As by the comment many other algorithms have been developed to solve the problem with different advantages and disadvantages.


Is Jump Flood Algorithm Separable? JFA (the algorithm described here: http://www.comp.nus.edu.sg/~tants/jfa/i3d06.pdf) can be used to get an approximation of a Voronoi diagram, or a distance transform.  It does so in logarithmic time based on the size of the resulting image, not on the number of seeds.

What do you do if your image is not the same size on each axis though?

If they were similar sizes, I'm sure you could just let the shorter axis have extra JFA steps of size 1, while the larger axis finished it work (like having a 512 x 256 sized image).  For vastly different sized axis dimensions this could be a lot more inefficient though - say that you had a volume texture that was 512 x 512 x 4.

Is it possible to run JFA on each axis separately and still get decent results?

Or at that point is a different algorithm more appropriate to use? If so, what algorithm might that be?

In my situation ideally I'm looking to support both single point seeds, as well as arbitrary shaped seeds.  Possibly even weighted seeds, where the distance to a seed is adjusted by a multiplier and/or an adder to give it more or less influence.

Quick answers to your individual questions

What do you do if your image is not the same size on each axis though?

The paper uses square images with side lengths that are a power of 2. This is for ease of explanation, but is not necessary for the algorithm to work. See section 3.1:

  Without loss of generality, we can assume n is a power of 2.

That is, this assumption is not required in order for the algorithm to work.

Is it possible to run JFA on each axis separately and still get decent results?

Running on each axis separately is likely to give more incorrect pixel results, and take longer to run in most cases. In extreme cases where one of the image side lengths is less than 8 (the number of jump directions), it may be faster as the algorithm treats those 8 directions sequentially, but for any wider image, separating the axes loses the advantage of treating them in parallel.

In my situation ideally I'm looking to support both single point seeds, as well as arbitrary shaped seeds

The paper mentions arbitrary shaped seeds in section 6 under the subheading "Generalized Voronoi Diagram":

  ...our algorithms treat such generalized seeds as collections of point seeds and thus expect to inherit the good performance obtained for point seeds.

So provided it suits your purpose to model arbitrary shapes as collections of pixels, you don't need to make any adjustment to the algorithm. Simply feed in a texture that labels all pixels in an arbitrary shaped seed with the same seed number, but different locations.

Possibly even weighted seeds, where the distance to a seed is adjusted by a multiplier and/or an adder to give it more or less influence

For "weighting on seeds such as multiplicative and additive", the paper only mentions the possibility in passing in section 8, as potential future work. However, this should be straightforward to implement provided your desired weighting can be included in the seed data that is passed from pixel to pixel.

The current algorithm passes <s, position(s)> to specify a seed and its position, and only one seed is stored per pixel at any one time. Extending this to store <s, position(s), weight(s)> provides all the information required to weight the distance function and calculate whether the new seed being passed to a pixel is closer to it than the one it is currently storing.

You could even include two weights, one multiplicative and one additive, and just set the multiplicative one to 1 and the additive one to 0 when not required. Then your algorithm would include the possibility of being used for multiplicatively weighted seeds, additively weighted seeds, or even a combination of both at once or some of each. This would just need

<s, position(s), multiplicative(s), additive(s)>

and the current algorithm would be equivalent to this new algorithm using

<s, position(s), 1, 0>

Detailed explanation of why

As in the paper, all uses of $\log()$ refer to the base 2 logarithm.

The algorithm does not need to be adapted for different side lengths

If the side lengths are not equal, and are not powers of 2, there is no need to adapt the algorithm. It already deals with pixels on the edge of the image for which some of the jump directions lead outside the image. Since the algorithm already omits the seed information for directions that lead outside the image, a width or height that is not a power of 2 will not be a problem. For an image of width W and height H, the maximum jump size required will be

$$\large2^{\lceil\log(\max(W,H))\rceil-1}$$

For the case of equal width and height N, this reduces to

$$\large2^{\lceil\log(N)\rceil-1}$$

In the case of a side length N that is a power of 2, this reduces to

$$\large2^{\log(N)-1}=N/2$$

as used in the paper.

In more intuitive terms, round the maximum side length up to the next power of 2, and then halve that to get the maximum jump size.

This is always enough to cover every pixel in the image from every other pixel in the image, as the offset to any pixel will be in the range 0 to N-1 if the longest side length is N. Combinations of the powers of 2 from 0 to N/2 will cover every integer up to N-1 if N is a power of 2, and if N is not a power of 2 the range covered can only be larger than required, due to taking the ceiling of the logarithm (rounding up to the next power of 2).

Images with sides not a power of 2 will not be drastically less efficient

The number of jumps depends on the longest side length, say L. If L is a power of 2 then the number of jumps is $\log(L)$. If L is not a power of 2 then the number of jumps is $\lceil\log(L)\rceil$. For a reasonably large image this will not be a large difference.

For example, a 1024 by 1024 image will require 10 jump iterations. A 512 by 512 image will require 9 jump iterations. Anything between the two sizes will also require 10 iterations. Even in the worst case of an image only just over a power of 2, like a 513 by 513 image, it will only require 1 additional iteration, which at this scale is approximately 11% more (10 instead of 9).

Non-square images are less efficient per area

Since the number of iterations required is determined by the longest side length, the time taken for a 1024 by 1024 image will be the same as for a 1024 by 16 image. A square image allows a larger area to be covered in the same number of iterations.

Separating axes is likely to reduce quality

Section 5 of the paper describes possible errors. Every pixel is reachable by a path from every other pixel, but some paths do not bring the correct nearest seed, due to that seed not being the nearest to a previous pixel in the path. A pixel that does not allow a seed to propagate past it is said to have "killed" that seed. If the nearest seed to a pixel is killed on all paths to that pixel, then the pixel will record some other seed and there will be an incorrect colour in the final image.

Only one path needs to exist that does not kill the seed in order for the final result to be correct. Incorrect colours only occur when all paths from the correct seed to a given pixel are blocked.

If a path involves alternating horizontal and vertical jumps, separating axes will make this path impossible (all horizontal jumps will be taken before all vertical jumps, making alternating impossible). Diagonal jumps will not be possible at all. So any path that alternates or contains diagonal jumps will be excluded. Every pixel will still have a path to every other pixel, but since there are now fewer paths there is more chance of a given pixel being blocked from receiving the correct seed, so the final result will be more error prone.

Separating axes is likely to make the algorithm take longer

The efficiency would probably be reduced by separating axes, as the flooding would no longer be done in parallel, but would instead be repeated for each axis. For 2D this would likely take approximately twice as long, and for 3D approximately 3 times as long.

This may be somewhat mitigated by the lack of diagonal jumps, but I would still expect an overall reduction in efficiency.


Classify acceleration structure using surface area heuristic My professor gave me the following example exam question:

  Given 4 spheres with diameter = 1. Their centers are located on
  coordinates (2,4,0), (4,2,0), (4,6,0) and (6,4,0), as seen in the
  picture below. Three different hierarchies of tightest possible
  axis-aligned bounding volumes (AABB) are given:

  A single AABB around every sphere
  An AABB around the spheres with center (2,4,0) and (4,2,0) and    another around the spheres located at (4,6,0) and (6,4,0).
  An AABB around the spheres with center (2,4,0) and (6,4,0) and    another around the spheres located at (4,2,0) and (4,6,0).

  For every one of these the all-containing AABB is constructed.

The questions are:

  Rank these 3 structures based on efficiency for intersecting a ray    with these spheres (best to worst)
  Does this ranking change if we change the spheres with a (scaled) tea-pot that still fits within the bounding volume?
  Can this ranking depend on the position of the camera, when we only    consider visibility rays (so no shadow rays, for example)? You can assume you're working with an orthographic camera.

He insisted on not giving a 'philosophical' answer (like: 'this depends on ...') but rather actually calculating the cost using the surface are heuristic etc.

Only, I have no idea how to start. The cost function we have seen is defined as follows
$$Cost(cell) = C_t + \frac{S_L}{S_{Cell}} \times N_L \times t_i + \frac{S_R}{S_{Cell}} \times N_R \times t_i$$
With:

$C_t$ the cost of traversal (which is an arbitrary constant, I think)
$S_L$/$S_R$ the surface area of the left/right child cell
$S_{cell}$ the surface area of the entire cell
$N_L$/$N_R$ the number of objects in the left/right child cell
$t_i$ the cost of object intersection (which is also an arbitrary
constant)

However, the first hierarchy has 4 child cells, how would I calculate the cost here? Any tips on how to start this exercise would be very helpful.

EDIT: Okay, so for the second and third setup, is it as simple as filling in the formula? For the second setup, this would lead to (assuming I made no numerical errors :) ):
$$\begin{align*}Cost(cell) &= C_t + \frac{2*3^2 + 4*3*1}{2*5^2 + 4*5*1} * 2 * t_i + \frac{2*3^2 + 4*3*1}{2*5^2 + 4*5*1} * 2 * t_i \\ &= C_t + \frac{120}{70} * t_i \end{align*}$$

For the third setup this would, analogously, lead to:
$$Cost(cell) = C_t + \frac{88}{70}*t_i$$.

So now my question would boil down to: can I just do the same for the first setup, but instead evaluate 4 sub-cells? Also, am I correct in assuming $C_t$ and $t_i$ are fixed constants or do they depend on the setup?

You gave the formula as:

$$Cost(cell) = C_t + \frac{S_L}{S_{Cell}} \times N_L \times t_i + \frac{S_R}{S_{Cell}} \times N_R \times t_i$$

(You put $r_i$ at the right-hand end, but I assume that was a typo.)

There's a more general form of this formula

$$Cost(cell) = C_t + \sum_{k\ \in\ K} \frac{S_k}{S_{Cell}} \times N_k \times t_i$$

where $K$ is the set of all child nodes; that is, to get back to the two-children form you started with, $K = \{L, R\}$.

By generalising the formula like this, you can now calculate the cost for the first possibility the same way as the second two.

You're right that this is a slightly odd question. In practice, your traversal cost is going to be less for a binary tree than a $(> 2)$-ary tree.

  Does this ranking change if we change the spheres with a (scaled) tea-pot that still fits within the bounding volume?

To answer this, you'll need to consider how this affects the surface area, and how this changes each score in turn.

  Can this ranking depend on the position of the camera, when we only    consider visibility rays (so no shadow rays, for example)? You can assume you're working with an orthographic camera.

There's two things to consider here.

1) Does any part of the heuristic depend on the position of the camera? Can moving the camera change any of the numbers that feed into the score?

2) Moving the camera can change how the boxes overlap. Remember that rays that pass through the box need to be tested against the box behind, so needless overlaps make the structure worse.

I think the point is that the heuristic is only a general rule. It's not hard to construct an example with two proposals a and b, where a scores much better but b is actually a better split for a particular camera, and this last part of the question is trying to get you to think about this.


What graphic languages are simpler than SVG for database diagrams? This is PNG was exported from Inkscape.  I created it manually and used the
connector tool to link tables.

I find the plain SVG for this diagram more complicated than I was expecting so would like to know if there are simpler graphic languages or specifications for this task?

I would like to write something using Python.

Here's the pastebin: SVG for database diagram

Graphviz is a popular tool for making network diagrams. It takes a text format ("DOT language") describing the nodes and edges as input, and can render the resulting diagram to SVG or other image formats.


SSAO artefacts on iPhone (OpenGL ES) I've never written shaders before, and now I'm trying to implement SSAO with SceneKit on OS X and iOS. I'm trying different SSAO shaders that I find, e.g. from Three.js, this one, and this one.

On OS X they all work as they should, but on iPhone all of them giving me the same artefacts (images show SSAO pass only). The lines move when I move the camera. So it must be because of some differences of OpenGL ES. Anyone knows what's wrong?

Resolved by adding precision highp sampler2D to my shaders.

About default precision settings on ES - https://www.khronos.org/files/opengles_shading_language.pdf page 36.


Tone mapping bright images I am rendering the sun in an image, and the sun comes out white and is basically very unrealistic. I have tried searching for  tone mapping algorithms but I'm very lost. Can someone guide me to do this? or perhaps help me with the pseudo

There are multiple different ways to do tone-mapping, including both local and global methods. I won't discuss local methods (i.e. methods based on using surrounding information as part of the tone mapping process) here. Global methods can be broken down into two components:

A formula for mapping from $[0,\infty)$ to $[0,1]$.
A method of applying this to the color.

The simplest formula out there is just $out = in / (in + 1)$, but the results are also fairly boring. A fancier curve is the filmic tone mapping function developed by John Hable, which is popular in the video gaming industry:

float hable(float x)
{
    float A = 0.15;
    float B = 0.50;
    float C = 0.10;
    float D = 0.20;
    float E = 0.02;
    float F = 0.30;

    return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;
}

You can also get even fancier if you can constrain the input domain to a known, fixed peak value.

As for how to apply this function to an actual color value, there are again multiple techniques. A very simple way is to do it per-channel, i.e. color.r = map(color.r); color.g = map(color.g); color.b = map(color.b);. But this has the downside of warping the appearance of bright colors towards white (e.g. orange becomes yellowish under tone-mapping). Some in the movie industry tend to like this look, for whatever reason.

To do color-preserving tone mapping, you can perform the calculation on a single value only and then apply the same scale to all three channels. A good choice for the value to use is to choose the “brightest” of the three components:

float sig = max(color.r, max(color.g, color.b));
color.rgb *= vec3(map(sig) / sig);

However, this approach also has downsides, namely that it takes very bright objects to unnaturally saturated versions of
themselves. For example, a bright sun might suddenly appear various shades of yellow and orange - which also looks unnatural on photographic content.

So ultimately, what I do is first desaturate the color based on how bright it is, and then apply tone mapping after the fact, leading to an algorithm that looks something like this:

// Calculate the desaturation coefficient based on the brightness
float sig = max(color.r, max(color.g, color.b));
float luma = dot(color.rgb, vec3(0.2126, 0.7152, 0.0722));
float coeff = max(sig - 0.18, 1e-6) / max(sig, 1e-6);
coeff = pow(coeff, 20.0);

// Update the original color and signal
color.rgb = mix(color.rgb, vec3(luma), coeff);
sig = mix(sig, luma, coeff);

// Perform tone-mapping
color.rgb *= vec3(map(sig) / sig);

But YMMV.

References:

https://github.com/haasn/libplacebo/blob/master/src/shaders/colorspace.c#L664
You can also poke at ITU-R Report BT.2390-2 for some more ideas and guidelines.


How to calculate interpolation between multiple skeleton poses? I found out that I should use spherical linear interpolation to blend two poses of a joint. I cannot find what to do if I have hundreds of poses to blend except applying the SLERP iteratively.

What are the default methods to interpolate between multiple skeletal poses? For example, which algorithms are used by Unity3D, UE4, 3DS Max, Maya, etc? How do they solve the problem of rotation non-commutativity?

I'm looking for an analytical well-differentiable (with respect to blending weights) formula if one exists.

I will suggest something for the rotational part but I do not know how fast it is. Assume you have a 3D coordinate system centered at the pivoting point of the joint and fixed with respect to one of the bars that meet at the joint. The other bar moves in this coordinate system always attached the origin of the system. So its motion is a curve on a sphere centered at the joint's pivoting point and radius the bar's length $l$. Assume you have a sequence of positions $\vec{x}_0, \, \vec{x}_1, \, \vec{x}_2, \, ..., \vec{x}_m$ of the moving bar with respect to this system. Recall the bar has length $l$. Then calculate the cross products:
$$\vec{n}_j = \vec{x}_0 \times \vec{x}_j$$ and the cosine of the angle $$c_j = \cos(\theta_{j}) =  \frac{1}{l^2} \, (\vec{x}_0 \cdot \vec{x}_j) $$ as well as the magnitude $\|\vec{n}_j\| = \sqrt{ (\vec{n}_{j} \cdot \vec{n}_j) }$. Normalize
$$\vec{N}_j = \frac{\vec{n}_j}{\|\vec{n}_j\|}$$
So now you have the list of pairs
$$\big(\vec{N}_1, \, c_1\big), \, \big(\vec{N}_2, \, c_2\big), \, ... ,\, \big(\vec{N}_m, \, c_m\big)$$
Apply a cubic or some other appropriate spline interpolation to the list of data. The result is the pair of smooth families
$$\vec{N}(t), \, c(t)$$
Use  Rodrigues' rotation formula to obtain the smooth family of rotation matrices
$$U(t) = \text{Id} \, \pm \, \Big(\,\sqrt{1 - c(t)^2}\, \Big)\, \hat{N}(t) \, + \, \big(1 - c(t)\big)\, \hat{N}(t)^2$$ where $\hat{N}(t) = \big( \vec{N}(t) \times \cdot \big) $ is the three by three skew symmetric matrix that acts on a vector $\vec{x}$ by
$\hat{N}(t)\, \vec{x} = \vec{N}(t) \times \vec{x}$. Notice the presence of the $\pm$ sign, which is negative when the angle between the vectors $\vec{x}_0$ and $\vec{x}_j$ starts to exceed $180^{\circ}$. This really depends on the range of motion of the joint. Anyway, then the joint moves smoothly by
$$\vec{x}(t) = U(t)\, \vec{x}_0$$ and at each moment of time $t_j$ for which
$c(t_j) = c_j$ and $\vec{N}(t_j) = \vec{N}_j$ due to the interpolation scheme we get
$$\vec{x}_j = U(t_j)\, \vec{x}_0$$
All of this can be done with quaternions, the idea is analogous. It is up to you.

The case of framed joint: If you have one coordinate system attached firmly to the first bar of the joint and a second coordinate system attached firmly to the second bar of the joint (both have origin at the pivoting point of the joint, i.e. I am ignoring translations), then the position of the second bar with respect to the coordinate system of the first one is described by the position of the second coordinate system with respect to the first. Then, if $\vec{u}_1, \, \vec{u}_2, \vec{u}_3$ are the unit orthogonal column-vectors of the second coordinate system written with respect to the first coordinate system, the orthogonal matrix that maps the first system to the second is $U = [\vec{u}_1 \,\, \vec{u}_2 \,\, \vec{u}_3]^T$ (the vectors are 3 x 1 columns of coordinates of the basis vectors of the second coordinate system with respect to the first coordinate system). Consequently, in this case (of framed joint motion) you may actually have a sequence of orthogonal matrices, describing the positions of the second system relative to the first at different times:
$U_1, \, U_2, \, ..., \, U_m$. In this case, calculate the skew symmetric matrices $$\hat{n}_j = \frac{1}{2} \big( U_j - U_j^T \big)$$ and calculate the traces
$$\|\hat{n}_j\| = \sqrt{ - \frac{1}{2} \, \text{trace}\big(\hat{n}_j^2\big) }$$ Then
$$\hat{N}_j = \left(\frac{1}{\|\hat{n}_j\|}\right) \, \hat{n}_j$$ is a skew symmetric matrix with the property that there exists a unique unit vector $\vec{N}_j$ such that for any vector $\vec{x}$
$$\hat{N}_j \, \vec{x} = \vec{N}_j \times \vec{x}$$
and
$$c_j = \cos(\theta_j) = \frac{\text{trace}(U_j) - 1}{2}$$
As before, you have the list of pairs
$$\big(\vec{N}_1, \, c_1\big), \, \big(\vec{N}_2, \, c_2\big), \, ... ,\, \big(\vec{N}_m, \, c_m\big)$$ or equvialently the list of pairs (whichever works better for you, although they are equivalent)
$$\big(\hat{N}_1, \, c_1\big), \, \big(\hat{N}_2, \, c_2\big), \, ... ,\, \big(\hat{N}_m, \, c_m\big)$$
Apply again a cubic or some other spline interpolation to either of the lists of data. The result is the pair of smooth families
$$\hat{N}(t), \, c(t)$$
Just as before,  by the properties of rotational matrices, you obtain the smooth family of rotation matrices
$$U(t) = \text{Id} \, \pm \, \Big(\,\sqrt{1 - c(t)^2}\, \Big)\, \hat{N}(t) \, + \, \big(1 - c(t)\big)\, \hat{N}(t)^2$$ This $U(t_j) = U_j$ for all $j = 1, .., m$.


Earth curvature and horizon in modeling large scenes If I want to model a large environment, how can I solve the problem of earth curvature and horizon?

I use an environment map for the sky, but for the ground what can I do?

Do I have to model the ground with a big plane, disk or a spherical cap?

Is there a general procedure to solve this problem in computer graphics?

Having the horizon fall off is simply dropping the ground in the distance down somewhat.

A point $x$ km away if you follow the curve of the planet will be $r-r\cdot \cos \frac{x}{r}$ down and $r\cdot \sin \frac{x}{r}$ out horizontally where $r$ is the radius of the planet you are modeling (~6.3k km for earth). In the vertex shader you can account for that before you apply the view and projection matrix.


Pseudo rounded cube in OpenGL If I have a cube in OpenGL, how can I have it appear like rounded?
 I think it's too complicated to really have the cube rounded so is there any "light trick" to have something like this:

The cubes in the image seem to be rounded on the top. The screenshot is from the game Voxatron

Another view of the cubes (see how they seem rounded on the top):

If silhouette is not important, you could bend the shading normal near edges.

Since it's a cube you can probably compute the normal procedurally in the shader based off of the uv. I.e. if uv is in range [0,0.1] or [0.9,1.0] start bending the normal towards horizontal.

If silhouette is important, drawing a rounded cube model with vertex normals would make the most sense. There are cube models which have the beveling to look like a rounded cube.


Can I raytrace gravitational lensing using only a single point source of gravity? I'd like to simulate the magnification of very distant objects by the lensing effect of a less distant galaxy. Will I need to model large numbers of point masses or can I get away with just a single average point mass?

I can see how to raytrace using hyperbolae for the rays influenced by a single point mass, but I wouldn't know where to begin with multiple point masses. So before I attempt to build this raytracer I'd like to know whether I'm going to be able to avoid multiple masses, and still have believable results.

As you have probably observed, in general, you cannot solve in closed-form the equations for ray trajectories around multiple distorting objects.

The standard approach for such things is just to discretize it.  This looks like Eulerian integration.  Just step your ray a little bit toward the object, calculate gravity from all sources and bend it, then step it more, und so weiter.  This is called raymarching.

Since you're interested in problems on an astrophysical scale, you can assume the ray is linear far enough away from the object, with minimal error.

Here's a scene I rendered a while ago using a homebrew photonmapper (no QMC) using this raymarching technique.

I present: relativistic photon mapping: black hole in a Cornell box!