Compute sphere tangent for normal mapping I'm implementing normal mapping on my toy pathtracer. I need to compute the tangent (and bitangent) of any sphere point in order to create the matrix that will transform tangent space to world space.

More specifically, I want the tangent that runs along the u texture coordinate, and the bitangent that runs along the v coordinate.

Here's how I implemented it:

At the intersection point P, compute the spherical coordinates
(theta, phi) of P.
Add a tiny delta to the angle that relates to the u texture
coordinate (phi), finding another point Q on the sphere.
Compute Q - P and normalize it to have the tangent.
The bitangent is then computed by doing the cross product of the
tangent and the normal at the point P.

Relevant code on the sphere collision function:

    hitRecord.point = ray.pointAtParameter(t);

    Vec3 localCoord = hitRecord.point - center;
    float theta = asin(localCoord.y / radius); //[-pi/2,pi/2]
    float phi = atan2(localCoord.z, localCoord.x); //[-pi,+pi]

    float deltaPhi = phi + FLOAT_BIAS;
    Vec3 deltaPoint(radius * cos(theta) * cos(deltaPhi),
        radius * sin(theta),
        radius * cos(theta) * sin(deltaPhi));

    //Assume local space to be aligned with world space
    //So this is also the tangent in world space
    hitRecord.tangent = deltaPoint - localCoord;
    hitRecord.tangent.normalize();

    hitRecord.normal = localCoord / radius;
    hitRecord.bitangent = hitRecord.tangent.cross(hitRecord.normal);
    hitRecord.bitangent.normalize();

This seems to work, but all this trigonometry is not light and makes me wonder if there is a better way of doing it. Does anyone has any ideias/pointers?

You can do this a little bit more efficiently and accurately by calculating derivatives of $P$ with respect to $u, v$—or the derivatives with respect to $\phi, \theta$, equivalently (up to a scalar multiple).

Start by expressing $P$ in terms of the spherical coordinates:
$$\begin{aligned}
P_x &= r \cos \theta \cos \phi \\
P_y &= r \sin \theta \\
P_z &= r \cos \theta \sin \phi
\end{aligned}$$

Now you can get the tangent as $T = \partial P / \partial \phi$, which works out as:
$$\begin{aligned}
T_x &= -r \cos \theta \sin \phi \\
T_y &= 0 \\
T_z &= r \cos \theta \cos \phi
\end{aligned}$$

Once you normalize it, the $r \cos \theta$ factors drop out and you're left with just $T = (-\sin \phi, 0, \cos \phi)$. Pretty simple!

You can similarly get the bitangent as $B = \partial P / \partial \theta$, or you can just calculate it as the cross product $N \times T$, which is probably faster. (Note it should be $N \times T$, not $T \times N$, assuming you want $T, B, N$ to form a right-handed basis in that order.)

The above approach will work for pretty much any kind of surface that can be parameterized, not just spheres. However, in the case of spheres with the usual $\phi, \theta$ coordinates, there's an even quicker shortcut that you can do with just vector math, no trig at all. Let $C$ be the center of the sphere, and $A$ be a vector representing the axis of the spherical coordinates—i.e. pointing from the center toward the north pole. Then you can just calculate $T = \text{normalize}\bigl(A \times (P - C) \bigr)$, then $B = N \times T$ as before.


Why is the transposed inverse of the model view matrix used to transform the normal vectors? When rendering 3D scenes with transformations applied to the objects, normals have to be transformed with the transposed inverse of the model view matrix. So, with a normal $n$, modelViewMatrix $M$, the transformed normal $n'$ is

$$n' = (M^{-1})^{T} \cdot n $$

When transforming the objects, it is clear that the normals need to be transformed accordingly. But why, mathematically, is this the corresponding transformation matrix?

Here's a simple proof that the inverse transpose is required. Suppose we have a plane, defined by a plane equation $n \cdot x + d = 0$, where $n$ is the normal. Now I want to transform this plane by some matrix $M$. In other words, I want to find a new plane equation $n' \cdot Mx + d' = 0$ that is satisfied for exactly the same $x$ values that satisfy the previous plane equation.

To do this, it suffices to set the two plane equations equal. (This gives up the ability to rescale the plane equations arbitrarily, but that's not important to the argument.) Then we can set $d' = d$ and subtract it out. What we have left is:

$$n' \cdot Mx = n \cdot x$$

I'll rewrite this with the dot products expressed in matrix notation (thinking of the vectors as 1-column matrices):

$${n'}^T Mx = n^T x$$

Now to satisfy this for all $x$, we must have:

$${n'}^T M = n^T$$

Now solving for $n'$ in terms of $n$,

$$\begin{aligned}{n'}^T &= n^T M^{-1} \\
n' &= (n^T M^{-1})^T\\
n' &= (M^{-1})^T n\end{aligned}$$

Presto! If points $x$ are transformed by a matrix $M$, then plane normals must transform by the inverse transpose of $M$ in order to preserve the plane equation.

This is basically a property of the dot product. In order for the dot product to remain invariant when a transformation is applied, the two vectors being dotted have to transform in corresponding but different ways.

Mathematically, this can be described by saying that the normal vector isn't an ordinary vector, but a thing called a covector (aka covariant vector, dual vector, or linear form). A covector is basically defined as "a thing that can be dotted with a vector to produce an invariant scalar". In order to achieve that, it has to transform using the inverse transpose of whatever matrix is operating on ordinary vectors. This holds in any number of dimensions.

Note that in 3D specifically, a bivector is similar to a covector. They're not quite the same since they have different units: a covector has units of inverse length while a bivector has units of length squared (area), so they behave differently under scaling. However, they do transform the same way with respect to their orientation, which is what matters for normals. We usually don't care about the magnitude of a normal (we always normalize them to unit length anyway), so we usually don't need to worry about the difference between a bivector and a covector.


Can a glass plate act like a lens? I am trying to implement rough dielectrics on my renderer. I compared the results of my renderer and Mitsuba renderer. However, a thin glass plate which is a cube scaled by (0.4, 0.4, 0.01) magnifies the object in front of it in Mitsuba while it does not magnify in my renderer. Do I miss something or does Mitsuba renderer do something wrong?

edit: IOR of glass is 1.1 and outside is air.

Result of my renderer:

Result of mitsuba:

The box.obj file has no vertex normals, and by default Mitsuba will generate smooth normals for OBJ files that don't specify their own normals. This creates the magnification effect: the box with smooth normals forms a convex lens!

By adding this line to the box object in the scene file:

<boolean name="faceNormals" value="true"/>

I got results that look equivalent to yours:


Debugging tools for OpenGL on macOS I am porting some code from Metal to OpenGL since we want to run our app on Windows too. Xcode is my preferred IDE, but the newer versions of Xcode do not support any OpenGL debugging.

Question: What do people usually use as a debugger for OpenGL? Eg: Frame capture on Metal is great and allows you to do shader debugging etc and nicely view the call hierarchy. Is there any thing similar for OpenGL?

If there are some good solutions on Windows, i can consider switching to Visual Studio.

There's nothing like frame capture for OpenGL on macOS, unfortunately. But there are 2 other tools that are useful for GL debugging: OpenGL Profiler and OpenGL Driver Monitor. You can read about them here. (Warning the images in the article are really old. They look like normal apps today without all the brushed metal, etc.) To download them, you need to log in to your developer account on developer.apple.com, click on "Downloads" on the left side. On the downloads page in the upper right is a tiny "more" link. If you click on that, you'll get the search tool. Enter "OpenGL Profiler" for your search and you'll be presented with a number of packages for different versions of Xcode. Choose the one that matches whichever version of Xcode you have. It's in the "Graphics Tools" section of the download.

OpenGL Profiler can show you the resources currently in use by a program. You can set breakpoints on any OpenGL call and when it breaks you can see all textures, shaders, FBOs, etc. and see what their contents are as well as all OpenGL state.

OpenGL Driver Monitor will graph over time how many textures are in use, or how much texture memory, etc. It can tell you the frequency of page-ons and page-offs for the GPU and other useful statistics.


Creating depth map from a 2-D image? My question is oriented towards the generation of depth map using any of the state of the art depth sensor.

However, each of these method required the presence of an 3-D object in front of the sensor. Is it possible the generate a depth map even if a 2-D image is presented to the sensor?

No, it's not. The way many of the 3D sensors work is by projecting an infrared pattern onto the surface and measuring how it distorts. But with a 2D image, the pattern will simply be projected onto the flat 2D image, not onto the objects in the scene. So the 3D sensor will only sense a flat card.

Other methods work by combining 2 images taken with different cameras at different angles. This will have the same result as above. The 2D photo will be interpreted as a 2D surface by the combination of the 2 cameras.


Is there a way to draw spherical objects without triangles? It seems that in all existing graphics libraries, 3D objects are always described in terms of triangles. Drawing triangles can be implemented very efficiently on video hardware and since any 3D object can be approximated with triangles, triangles are the only basic element needed. Triangles can be represented by 3-tuples and are simple to work with.

I have always wondered whether other approaches have been tried. There are certain complications when approximating spherical objects with triangles. Have there been any alternative approaches to drawing spherical objects (for example, without using polygons for approximations)? What are the problems with such approaches that make using triangles the best option?

A standard technique is to use a ray/sphere intersection test inside a pixel shader. One draws a billboard large enough cover the area the sphere could appear on the screen (or drawing a bounding cube) to reduce the number of wasted intersection tests (other geometric shapes could be used). The fragment is killed if the intersection test fails; if an intersection occurs, the appropriate depth value is calculated in the pixel shader and output for further visibility tests.


Non-Polygonal 3D cube rasterization Given a cube defined as:

struct Cube
{
    float min[3];
    float size;
};

What would be the fastest rasterization method? On the internet I only found methods that used polygons, but I think for only drawing a cube thats extremely ineffective. I don't need any depth information, I want the result to be a shadeless silhouette.

Since the cube is a convex object, you could first find the silhouette edges of the cube, by using dot product between cube face normals & view vectors. Then you can sort the edges by the smallest screen y-coordinate for each edge and rasterize the cube a scanline at the time by filling the span between two active edges for each scanline. For each scanline you progress the two edges by adding the edge slopes (x1-x0)/(y1-y0) to the current x-coordinate of the edges.


Bump mapping with triangles and height maps I'm trying to add bump mapping to my ray tracer, and I'm currently struggling to add bump mapping to it, as I don't seem to get the transformations from texture space to world space correctly.

I have an arbitary Triangle in world-Space defined by it's vertices.
Each of the vertices store a normalized UV-Coordinate to interpolate the position on the height map for an Intersection Point.
The height map is a gray-Scale Image
So when I intersect with the Triangle, I calculate the x and y derivatives of the height map at the corresponding uv-coordinate, transform the x and y unit Vectors (of the Texture) to world-Space, and calculate the changed normal. This currently looks like this:

        Point p = lerpbar(uv_vert1, uv_vert2, uv_vert3,
               intersection.barycentric.u, intersection.barycentric.v);
        float gx = this->_bmap->getColorDX(p);
        float gy = this->_bmap->getColorDY(p);
        Vector wx = (To_World_Matrix * Vector(1, 0, 0))).normalize();
        Vector wy = (To_World_Matrix * Vector(0, 1, 0))).normalize();
        Vector n = intersection.normal();
        return n + (gx * cross(n, wy) - gy * cross(n, wx));

However, I just can't figure out what Matrix I'd need to use so this produces correct results, as I just don't really understand how to map from unit Vectors to World-Space Vectors when I only know how arbitay Triangle Edges relate to arbitay Vectors in Texture Space.

The normal of a given point on the height map is perpendicular to the 2 vectors defined by gx and gy. The original surface normal is not relevant to this. So in tangent space, the normal is:

Vector tangent = Vector(1, 0, gx);
Vector bitangent = Vector(0, 1, gy);
Vector normal = normalize(cross(tangent, bitangent));

You then need to convert the normal from tangent space to world space. For this you need the so-called "TBN matrix" (tangent, bitangent, normal matrix). There are plenty of articles around explaining this. But the gist is:

Vector T = normalize(To_World_Matrix * intersection.tangent());
Vector B = normalize(To_World_Matrix * cross(intersection.tangent(), intersection.normal()));
Vector N = normalize(To_World_Matrix * intersection.normal());
mat3 TBN = mat3(T, B, N); // GLSL syntax

The last thing is to do a change of basis to move the normal from tangent space to world space:

Vector normal_world_space = normalize(TBN * normal);

Keep in mind that the order of some cross-products might be inverted in what I wrote if you get normals pointing inside the surface.


Is it Possible to send data directly to the GPU via a custom hardware interface? Is it possible to directly bypass the CPU while transferring data to the GPU? could there be hardware which gives the GPU direct memory access to a data stream for real-time GPU processing and rendering?

On a desktop (or laptop) the GPU is connected to the PCIe bus. This gives it direct access to the physical RAM.

If you map the buffer you want to fill and then read a file into that mapped memory. The OS will tell the disk drive to dump the file into the physical ram (the disk also has direct memory access), then when you go to use the mapped buffer the driver will tell the gpu to copy it into the vram. All the while the CPU never touched that bit of ram.


NURBS knot multiplicity In Splitting of NURBS curves there the answer relied on "maximum knot multiplicity". In order not to mix-up different topics I would like to kindly ask to answer it in another question: what is this "knot multiplicity" all about?

When you have a curve you can adjust the knots so that they lie on top of each other. This is essentially a bit like having several control points on top of each other, except there's only one point. This is sometimes known as multiplicity or duplicity.

When you have as many knots on top of each other as you have degrees in the curve smoothness, you end up with a cusp, also known as as sharp corner. Once you have a sharp corner you can just go and delete the points on the opposite side as they no longer affect points no the other side of the corner.

Image 1: Curve and control cage (Top) and basis functions (bottom). In this case the curve acts as 2 adjoining bezier curves, The image is using the knot vector [0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2].

If we look at a knot vector then the multiplicity looks like a seqence of n knots that have the same number. Note if you do not add ecactly as many knots on top as there is smoothness then you get a partially sharp corner.

Image 2: Animation with interpolation of knot form [0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2] to  [0, 0, 0, 0, 0.34, 1, 1.66, 2, 2, 2, 2] and back. If you do proper point insertion then the curve does not change. Just talking about what multiplicity is.

Alternatively to changing parametrization you can just add points on top of each other. This is equivalent although slight misuse of resources, but useful in surface modeling. Having many control points on top could also be useful for the uniform nature of the knot distribution.


Can one VAO store multiple calls to glVertexAttribPointer? If no, Should I create a new VAO for every VBO that has its own vertex attribute configurations?

Could you please give me a snippet code example that shows how to use one VAO for multiple VBOs? All examples I find on the internet call to glVertexAttribPointer before drawing a buffer, but if you have to call that method everytime you want to draw a buffer, then VAOs doesn't make sense.

PS: The tutorial I'm following uses Opengl 3.3

In version 4.3+ the vao layout can be set independently from the VBO buffer which allows you to rebind the vbo without having to call vertexAttribPointer every time:

//in init
glBindVertexArray(vao);

glVertexAttribFormat(posAttrLoc, 3, GL_FLOAT, false, offsetof(Vertex, pos));
// set the details of a single attribute
glVertexAttribBinding(posAttrLoc, 0);
// which buffer binding point it is attached to
glEnableVertexAttribArray(posAttrLoc);

glVertexAttribFormat(normalAttrLoc, 3, GL_FLOAT, false, offsetof(Vertex, normal));
glVertexAttribBinding(normalAttrLoc, 0);
glEnableVertexAttribArray(normalAttrLoc);

glVertexAttribFormat(texAttrLoc, 2, GL_FLOAT, false, offsetof(Texture, tex));
glVertexAttribBinding(texAttrLoc, 1);
glEnableVertexAttribArray(texAttrLoc);

Note that there is no mention of any VBO during init, just the binding points. That binding point is then used during draw to specify which vbo to pull the vertex data from:

//draw

glBindVertexArray(vao);
foreach(mesh in meshes){
    glBindVertexBuffer(0, mesh.vbo, mesh.vboOffset, sizeof(Vertex));
    glBindVertexBuffer(1, mesh.texVbo, mesh.texVboOffset, sizeof(Texture));
    // bind the buffer to the binding point
    glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount);
    //draw
}

In pre 4.3 you would create a VAO per mesh and per mesh call glVertexAttribPointer for each attribute:

glBindVertexArray(mesh.vao);
glBindBuffer(GL_ARRAY_BUFFER, mesh.vbo);

glVertexAttribPointer (posAttrLoc, 3, GL_FLOAT, false, sizeof(Vertex), mesh.vboOffset + offsetof(Vertex, pos));
glEnableVertexAttribArray(posAttrLoc);
//...

Then during draw bind the per mesh vao before drawing it:

foreach(mesh in meshes){
    glBindVertexArray(mesh.vao);
    glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount);
}


How to perform an image normalization after for example adding a constant to it? I had some magical tasks to do on my lessons. I had to write an app which performs some operations: basic (adding, subtracting, multiplying a constant and a second image), geometric, filtering, histograms etc. There were ~50 tasks.

I've made them all, even with Prewitt filters and other down/upbandwith and gradient things.

Now, my teacher sent me an info, that I did my normalization wrong in basic operations, for example in adding a constant.

As he wrote in his document there are 3 ways of handling the pixel overflow >255 or <0:

cutting the overflow - which means a simple clamp
scaling images before processing
normalization of the final image - scaling and moving the image function with a specified range that the final image fills the given range.

I've left first two and got the third one, because he said it's the correct way. I've read somewhere that I still need to combine it with a clamp (0,255).

Now, I got his formula:

$$\large f_{norm}=Z_{rep}[(f-f_{min})\div(f_{max}-f_{min})]$$

And  I thought it's easy to understand, but I have some problems with it.

As I understand:

$f_{norm}$ - final pixel (normalized)
$f$ - given pixel
$f_{min}$ - minimum
$f_{max}$ - extremum
$Z_{rep}$ - clamp 0-255?

I have the following questions:

Are $f_{min}$ and $f_{max}$ taken from the given image, or from the image after the operation (for ex. adding a constant)? I know what extremes are, but I can't figure it out which two should I use in this formula.
Is $Z_{rep}$ really a clamp method as I thought which just cuts to 0-255? I've read somewhere that even with normalization there can be an overflow.
Does normalization work like: no matter what value you'll add or subtract from the image, I'll make for you a beautiful 0-255 values? Or am I wrong?

I've even made some calculations, made some images in photoshop with extremes 30,200 and even 0,255, put them into the formula and got some results, but I still don't know if it's done well.

I'm sitting here for 3 weeks, really and can't get which extremes should I use and if I should clamp or not.

I believe that Zrep is the output range. In 8-bit it would be 255. Let's say fmin was 25, fmax was 132. You want to scale that range to 0-255. The part of the equation in brackets: [(f-fmin) / (fmax-fmin)] will give you a percentage - a value between 0 and 1. If f is 25, you'd get 0%. If f is 89, you'd get ~60%. If it's 132, you'd get 100%

So once you have the percentage, you then need to multiply that by the output range, Zrep. That converts from a percentage to whatever range you need it in, and ensures that the largest value in the input is mapped to the largest output value, and the smallest input is mapped to the smallest output value.


Animating a smooth linear transformation After watching this video on matrices, I tried to make a simple animation of 2D linear transformations. Starting with a set of 2D points in a grid, I applied a 2x2 matrix to each point and obtained a set of transformed points.

I'm not sure how to animate the transition between the initial and final states. At first, I made each point move along the straight path between its initial and final position. This caused problems for rotation matrices. For example, a 180$^{\circ}$ rotation should show the points rotate about the origin in circular arcs, but my method made it look like the whole grid flipped around, without rotating.

A better rotation animation can be made by applying a very small rotation, say 1$^{\circ}$, multiple times. The matrix for a 1$^{\circ}$ rotation is close to the identity matrix:
$$\begin{bmatrix} 0.9998 & -0.0175 \\ 0.0175  &  0.9998 \end{bmatrix}$$

Is there some general formula that can generate a differential transformation matrix, given the full transformation matrix? I would like it to work for any 2x2 matrix, without needing to specify the type of transformation.

As a general rule, you cannot interpolate transformation matrices. In stead, you decompose them into their individual values, then interpolate those and recompose.

The Möbius transformation as suggested in the comments sounds interesting, but tradionally I'd just extract scale and rotation and interpolate those.

Assuming a transformation matrix

    | a  b |
T = | c  d |

the scale is [sqrt(a² + c²), sqrt(b² + d²)]
The rotation angle is atan(c/a)

You'd now interpolate this scale and rotation angle, recomposing the matrix at each frame.

[Edit] Corrected the angle (as spotted by Nathan Reed) [/Edit]


The reciprocity of BRDF Many books describe that a BRDF has the following property (reciprocity):

$$f_r(x, \Theta \to \Psi ) =  f_r(x, \Psi \to \Theta)$$

Why is the above equation correct?

I think the above equation should be changed as follows:

(because the two symbols $\Theta$ and $\Psi$ are direction vectors)

$$f_r(x, \Theta\to \Psi ) =  f_r(x,  -\Psi \to -\Theta)$$

What is my mistake?
(I am very confused about the concept.)

You probably know that the BRDF is to calculate the reflected light, from a light source to a camera (In examples a light source and a camera is used, but it does not need to be just that).

The property that you are talking about, basically says that when you swap the light source with the camera, it still gives the same result.

Lets look at an example I quickly made.

Ok, so here you see the basic setup. You have a light source, a camera and a point on a surface. Wi is the direction towards the light, the incoming direction. Wo is the direction towards the camera, the outgoing direction. N is the normal of the surface.

The property says that if we switch Wi and Wo with each other the result is the same.

The example would then look like this.

This looks normal and logical. You said that you should invert the direction vectors. If we do that, this is then our result.

You can see that it now looks like the surface is illuminated from the other side, and since the normal is not inverted, it will end up looking black.

So that is where you made your mistakes. The property says that you can swap the incoming and outgoing vectors and the result will still be the same. This is called the Helmholtz reciprocity. And where you might got confused was this part "how a ray of light and its reverse ray encounter matched optical adventures" (from the wikipedia). But it is not talking about the inverse (multipled by -1) but about the outgoing ray of the event in something like a reflection or refraction.

I recommend reading up on the Helmholtz reciprocity. For example on the wikipedia: https://en.wikipedia.org/wiki/Helmholtz_reciprocity

I hope I explained this properly, and if I made any mistakes, I am happy to learn and fix this answer.

Good luck with your adventures through the computer graphics universe!


Why do Nvidia and AMD have to update their drivers for game releases? I like to know the technical aspects of it. Game developers use APIs like OpenGL or DirectX. The functions provided by these APIs, I would assume, work flawlessly with all graphic cards because they are fixed and do not change - except if there is a new version of it - and are of some sort mathematically correct. So how does it come that Nvidia and AMD have to update their drivers to fix visual bugs or performances? What are the problems? Furthermore, I would like to know if Nvidia and AMD are providing these improvements on their own behalf or if the game developers cooperate with them by making some sort of paid contracts.

Games, Triple A games in particular, tend to push graphics cards to their limits, computation capabilities, bandwidth, and drivers all get stressed heavily. This tends to cause even the smallest bug, or inefficiency in the driver to become a glaring problem resulting in "glitches", slow frame rates, game crashes and rendering quality issues.
These "bugs" and inefficiencies can be very specific and often only occur when certain sequences of operations happen, which are often specific to a particular game. The range of issues that they run into tend to run the gamut from simple brain dead bugs, to show stopping monsters that everyone spends weeks agonizing over, to minor tweaks that improve visuals.
During game development vendors will provide driver updates that address these issues directly to game developers, or put the updates in a "beta" driver and release it publicly so anyone, including the developers, can install it. This allows games to be tested, developed and updated before being released.
How closely a vendor works with a game developer is going to depend heavily on the size of the project and the issues they are encountering. Sometimes this will mean going so far as having engineers from the GPU vendor actually join the game development team, and spend time on site working through the various problems that come up. Other times it can be just an updated driver dropped on the public beta website.
When the game is nearing release game developers and vendors will work together to release the updated driver with the game, this sometimes even includes shipping the updated driver with the actual game. For smaller projects vendors might no be as accommodating. It is in the best interest of both game developers and GPU vendors to work together, especially on large projects.
It would be naïve to assume that the two don't come to some sort of monetary agreement when developing a game, especially when a game gets advertised with statements like "Made for XYZ gpu vendor."


GL_STATIC_DRAW vs GL_DYNAMIC_DRAW vs GL_STREAM_DRAW: does it matter? In OpenGL the buffer object functions (glBufferData, glBufferSubData, and probably a few others) have a parameter usage, described by the documentation as a hint of the intended usage, likely meant to help the implementation yield better performance.

  usage

  Specifies the expected usage pattern of the data store. The symbolic constant must be GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY, GL_STATIC_DRAW, GL_STATIC_READ, GL_STATIC_COPY, GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, or GL_DYNAMIC_COPY.
  [...]
  usage is a hint to the GL implementation as to how a buffer object's data store will be accessed. This enables the GL implementation to make more intelligent decisions that may significantly impact buffer object performance. It does not, however, constrain the actual usage of the data store.

The wiki is similarly vague:

  These are only hints, after all. It is perfectly legal OpenGL code to modify a STATIC buffer after it has been created, or to never modify a STREAM buffer.
  [...]
   These are questions that can only be answered with careful profiling. And even then, the answer will only be accurate for that particular driver version from that particular hardware vendor.

In fine, how relevant is this parameter, if at all? Do drivers actually take it into account, and if they do, in your experience how much does it impact performance in practice? Do you have data to share?

I have written a thin graphics API abstraction layer meant to be implemented as either of the existing APIs, and it is tempting to just ignore this parameter altogether and hide it from the exposed abstraction.

This will vary between implementations, but the driver I worked on did use these, mainly to decide memory layout. The optimizations enabled by these hints are much smaller than you would like, mainly because of the restriction that you can do any use whatever hints you give. e.g. it would make cache invalidation a lot cheaper if buffers hinted for read access only could not be written at all, but this optimization is impossible.

Some notable games which are widely used for benchmark comparisons between GPUs do not use these hints correctly, so GPU vendors have an incentive to make all uses fast even if they doesn't match the hints.


How can I implement next event estimation? I am trying to implement next event estimation to reduce the noise of path tracer and I need a pseudocode.

Edit: I know how to sample direct illumination but the visibility function is the real problem I face. How to code the visibility function without iterating over the objects in the scene?

You can provide an intersect_any(ray, scene, min_t, max_t) function, that returns true at the first intersection. So it has the option to exit early compared to the usual intersect function. Additionally you do not care about normals, texture coordinates, positions, so you can avoid computing those in many cases. You need max_t though to limit the ray to the segment between the two points you are testing.

In the worst case scenario (there is nothing between the two points) you will still need to iterate over all objects unless you are using acceleration structures.


Why do we have graphics frameworks like OpenGL and DirectX, when games could just draw pixels directly? Games and other graphically intensive applications use frameworks like OpenGL and DirectX. Also they require features like pixel shader and DX12.

But why would we need all these frameworks and GPU features when we could just draw everything pixel by pixel?

First, the game would have to be compiling in a way so it is drawn pixel by pixel. This is likely to make the game executable big, but will it be faster and work on any 32-bit color GPU (even old ones)?

I know that the first 3D games were drawn pixel by pixel, but why aren't they doing it now?

Speed is the most common reason why this is not done. In fact you can do what you propose, if you make your own operating system, its just going to be very slow for architectural reasons. So the assumption that its faster is a bit flawed. Even if it would be faster, it would be less efficient in terms of development (like 1% speed increase for 10 times the work).

Copying the data over from the CPU to the graphics card is a relatively slow operation. The less you copy the faster your update speed can be. So ideally you would have most of the data on your GPU and only update small chunks of data. There is a world of difference between copying over 320x200 pixels compared to 1920x1200 or more. See the number of pixels you need to update grows quadratically when the sides grow.

Example: It's cheaper to tell the GPU to move the image 10 pixels right than copy the pixels manually to the video memory in different locations.

Why do you have to go trough an API? Simply because it's not your system. The operating system can not allow you to do whatever you want for safety reasons. Secondly because the operating system needs to abstract hardware away, even the OS is talking to the driver trough some abstracted system, an API if you will.

In fact I would rate the likelihood that your system would be faster, if you just did all the work yourself, close to near zero. It's a bit like comparing C and assembly. Sure you can write assembly, but compilers are pretty smart these days and optimize better and better all the time. It's hard to be better manually, even if you can your productivity will be down the drains.

PS: An API does not make it impossible to do this update just like old games did it. It's just inefficient that's all. Not because of the API mind but because it is inefficient period.

PPS: This is why they are rolling out Vulkan.


transformation from cartesian coordinates to spherical coordinates without calculations Given this graph in the 3d cartesian coordinates i should figure out the spherical coordinates representation but without the use of calculations .
I've been trying to solve this the whole day but i don't seem to get it and i've searched on all around the internet also no results .
I'll appreciate any help if anyone has an idea about the topic .

NOTE: this is not a homework :)

If we take some ring around the sphere such that $\theta=const$, we can see that such a ring transforms into a line on the polar space.

Converting every possible ring to the polar space gives the desired surface. However this would involve computing many different values to get an approximation or doing some algebra, which we don't want. (I'm assuming you want to keep mathematical notation to a minimum here). However we can get a pretty close idea by figuring out just a few easy to compute values.

Now. If we grab the ring that goes around the center of the sphere and transform that one, it is clear that it ends up as a line with $\theta=45^o$ and $r=\sqrt{2}R$ (that is because its vertical distance from the origin equals its horizontal distance at every point).

There are two more rings that are useful to us here: the two very small rings around the poles of the sphere.

The ring around the bottom pole transforms into a line with $\theta=90^o$ and $r=0$.

The ring around the top pole transforms into a line with $\theta=0^o$ and $r=2R$.

We now have three lines through which we can fit our surface. You can do this with pen and paper. I'm not quite sure of what kind of curve you end up with (I haven't done the algebra haha) but my guess would be some kind of sideways parabola.

EDIT: I did the math, $r=2R\cos(\theta)$

NOTE: I measure my $\theta$ as the angle between some line crossing the origin and the Z axis


Get intersection Ray with square I have a class Ray and Square

public class Rayo {

public Point origen;
public Vector direction;

Square{
X,Y,Widht, height;
}

I need intersection between this two, how? my code crossProduct in java is

public static Vector productoCruz(Vector a, Vector b) {
        return new Vector(a.Y * b.Z - a.Z * b.Y, a.Z * b.X - a.X * b.Z, a.X * b.Y - a.Y * b.X);
    }

To apply the product point you need two vectors, and I only have 1 (the ray vector), where do I get the other vector?

The best algorithm depends on the condition like whether or not the square is axis aligned for example. I'm gonna discuss the more general case which can find find intersection for any arbitrary oriented square. The algorithm works by first checking the intersection of ray with the plane containing the square or rectangle etc. Then check if the ray is within bounds of the square.

For this you require the following information

Ray's in the form $R =e+td $ where $e$ is the origin or eye point and $d$ is the direction vector.

Secondly you need to define your square by using the following information

Poisition - This might be the vector to the center or any corner of the square. The algorithm I'm describing assumes it is one of the corners.
Normal - Self explanatory.
Width and Height not as scalars but as vectors. These can be called the two edge vectors. I will denote them as $e1$ and $e2$. Note that both edge vectors need to grow outward from the corner of the square chosen in point 1.

After you have the following information you first need to compute Ray - plane intersection. The plane being where your square lies. This is done as follows. We know the point normal form of a plane as,

$(p-p1).n= 0$

If we suppose $p$ is our ray here and $p1 = position$, then we will have,

$(e+td - p1).n=0$
$(e+td - p1).n=0$
$e.n + td.n - p1.n = 0$
$t = p1.n - e.n/d.n$
$t = (p1-e).n/d.n$

If $t \geq 0$ then we have an intersection. Now all we need to do is check whether the ray lies inside the square or anywhere else on the plane. This is easy to do.

$intersect\_point = e + td$
$v = intersect\_point - p1$

$width = ||e1||$
$height = ||e2||$

$proj1 = v.e1 /width $
$proj2 = v.e2 / height$

$if((proj1 < width \;\&\&\; proj1 > 0) \;\&\&\; (proj2  < height \;\&\&\; proj2 > 0) )$
$return \, true$

Note that the above assumes that the edge vectors grow outward from the corner, i.e. A square with the corners A,B,C,D in clockwise fashion starting from  the top left. If we choose corner $A$ then the edge vectors are $\vec{AB}$ and $\vec{AD}$.


Why does skinny triangle is avoided in triangulation algorithm? I recently learned about Delaunay triangulation algorithm.. This algorithm prevents the generation of skinny triangles.. I haven't really seen any good explanation of why we don't want skinny triangles.. Can anyone explain the reason?

Thanks..

We don't want to avoid skinny triangles as much as we want to avoid really long triangles.

Long triangles make interpolation of properties less accurate because the points in which the data is stored are farther apart. This is equivalent to – when using a 2160p (4K UHD) screen – the preference of watching a 1080p video in fullscreen mode to watching the same video but in 720p, also in fullscreen mode. The 720p video is streched 3 times when the image is rescaled to fullscreen while the 1080p video is only streched 2 times; hence the pixels in the 720p video are streched farther apart compared with the pixels in the 1080p video and the interpolation of the colors in the pixels become less acurate (simply because the 720p video can't contain as fine details as the 1080p video can), which is another way of saying that the 1080p video looks better than the 720p video when viewed in fullscreen on a 2160p screen.

However, the skinnier our triangles are, the longer they have to be in order to cover the same area, unless we use more triangles in total. The former is undesirable because of above mentioned reason. The latter is usually undesirable too since it increases the required memory consumption as well as the computational load on the algorithms that work with them since there are more triangles to loop through. We usually therefore want to avoid skinny triangles.


What is the difference between world coordinate, viewing coordinate and device coordinate in computer graphics? The 2D pipeline involves with the construction of world coordinate scene followed by converting world coordinate to viewing coordinate, then transforming viewing coordinate to normalized coordinate and lastly converting normalized coordinate to device coordinate.

I am confused. Isn't viewing coordinate and device coordinate the same things?
Can someone give me the detail differentiation among these?

The 2D pipeline involves ... [coordinate transformation terms]
Can someone give me the detail differentiation among these?

This is something I very recently learned while trying to understand how software handles 3D graphics behind the scenes. I've never encountered these terms in reference to 2D graphics before, but the ideas still apply. 2D graphics are just 3D graphics without a few fancy tricks.
Very Generally
Most of these different coordinate spaces don't technically exist. They come about by considering the objects you wish to draw from some reference point. When you change that reference point, you change the coordinate space. Math gets involved, but I won't do any here.
The Drawing Device and Device Coordinates

... converting normalized coordinate to device coordinate.
Isn't viewing coordinate and device coordinate the same things?

Short answer, no, but they can be in certain 2D cases. In 3D, pretty much never.
There seems to be a confusion not just between view and device coordinates, but also with the distinction between normalized and device coordinates. Lets start with normalized and device, and we'll get to view later.
In 3D systems (and 2D systems setup to work like them) you are presented with a "drawing device" consisting of two parts: drawing tools (usually functions accessed from application code) and a drawing area. Ignoring the tools, the important thing is that the drawing area has a coordinate system independent of pixels which adds a lot of flexibility and generality to the device.
Any time something is setup to work numerically in a range from 0 to 1 it is "normal", and often the range 0 to -1 is included too. With a drawing device the coordinates for both the X and Y directions of your drawing area range from -1 to 1, with -1 meaning "all the way left" for X and "all the way down" for Y, and 1 meaning "all the way right" or "all the way up" for X and Y respectively.
You can easily add a Z direction too (also ranging from -1 to 1) for "3D" drawing, but all this does is give you a layered 2D image. There is no perspective (or "depth") in your final drawing which is great for 2D games and graphics. The reason for this is that the drawing device will simply divide the space up into pixel size steps along X and Y then draw each pixel back to front (-Z to +Z). If you want real 3D though, you'll need some extra mathematical steps.
It is possible (and common) for the device to understand and work with coordinates outside the -1 to 1 range. However, if we want an object to appear on screen than it must be "normalized" so that any coordinates it refers to are within -1 to 1. After this is done to an object the terms "normalized coordinates" and "device coordinates" are practically synonymous, just one refers to the object you altered so that it would fit within the drawing area and the other refers to the drawing area itself.
Object and World Spaces

The 2D [or 3D] pipeline involves with the construction of world coordinate scene ...

Yes, but you start in "object space".
When someone creates a model of an object (or draws a sprite) all that matters to them, coordinate-wise, is where zero is within the space they're working. This consideration is called "object space" because the artist isn't concerned with the -1 to 1 drawing area, only accurately representing the object they'd like to draw. A model of a pen might be 6 units long and a model of a person might be 5.5 units tall. The important thing is that all of the points that make up some object are positioned with regard to the coordinate (0, 0, 0) and nothing else.
When later loaded into memory they will be too big for the drawing area (which is only 2 units tall and wide) and the pen will appear larger than the person. It's up to us humans to know what the units mean and adjust them properly. Resizing and positioning all objects in relation to each other instead of each individually being sized with relation to zero transforms the objects into "world space".
From the shortness of your question I wasn't sure if you knew that yet or not, but I thought I'd include that for completeness, as a good foundation for answering the next part of your question.
View Space

... followed by converting world coordinate to viewing coordinate ...
Isn't viewing coordinate and device coordinate the same things?

Note that in my explanation above nothing ever happened to the drawing device, or the coordinates of the drawing area. The only thing that ever changed was the objects we wanted to draw. The drawing area is fixed and unchanging, only ever drawing any object that fits within the coordinates -1 to 1.
Each object loaded appears at the center of the drawing area at whatever size it was designed to have (object space) which is practically always too big for the drawing device. After rearranging and resizing every object around each other (object space → world space) we still have a final scene that is too big for the drawing area, and we have no way to move around within the scene. This is where we transform everything into "view space" and work with "eye coordinates". Again, there is no such space, but what we do to work within it is to consider an imaginary camera and, treating the entire world as one giant object, we resize and reposition everything with respect to the position of the camera. That is "view space", the movement of everything around a camera, and the terms "view coordinates" (or "eye coordinates") refer to the positions of everything in relation to the camera.
View to Viewport
At this point everything that you want to see should be within the device space, but there are still a few last tasks to perform to get everything to draw.
If you were working on a 3D scene instead of a 2D one, you would perform a "perspective transformation" to create the illusion of depth. This is where you squish and warp things to make them look like they're shrinking into the distance.
Anything outside the drawing area needs to be thrown out. This saves on work for the computer, and it also is considered another transformation from view space to "clip space" because you are "clipping away" the extra data.
And finally, after clipping, you'll do a "viewport" transformation that turns the -1 to 1 coordinates into pixel coordinates.
Summary
Well... I didn't intend for this answer to get so long. My apologies if I covered anything you already knew. It's hard to guess what someone does or does not already understand. Please leave a comment if you have any further questions.
Object Coordinates: The positions of points relative to a zero point. The points referred to are the building blocks of some single object.
World Coordinates: The positions of collections of points (objects) relative to a single shared standard zero point.
View Coordinates: The position of all points (the whole scene) relative to a camera.
Device Coordinates: Any position within -1 to 1 on both the X and Y axis (and Z too for 3D). Any point within the drawing area of the device.
Normalized Coordinates: The positions of points of any object (or the whole scene) that have been transformed to fit within the -1 to 1 space of the drawing device.


Remove clearly not visible vertices from a polygon For a visibility algorithm I want to remove verts of polygon that are guaranteed not visible from a vert S. The idea is to remove pockets that points are on the backside of a plane formed by the vector n, the perpendicular vector between S and 0, and a point S.

The prerequisites are:

the points of a polygon are in ccw order
the labeled points are the cutting-points between g(t) and the edges of the polygon

sorted by occurrence with respect to S
only the points with a positive t are retained
the points are part of a new created polygon, we are working with

The difficult task is to identify a pocket respectively the pair of indices a pocket starts and ends.

Here are my approaches:

Use the natural order of cutting-points and remove items with a smaller t to their previous ones (works on I, III and IV).
Sort the cutting-points by t. If the second point has the highest index in the original order, then all other cutting-points are part of the pocket and can be ignored (works on II).

Now the questions are:

When should I use the first and when the second approach (I can't see it)?
Is there an easier way?

I solved it myself. Here is a result:

The example is out of this post: here


How is data stored into a frame buffer? I am an electronic engineer. I am trying to design (personal project) a 3D graphics hardware renderer. It shall only render wireframes at this stage, no filling and no shading, not even backface culling and whatever else we take for granted.

I understand that the most efficient method to draw a line on screen is via Bresenham's integer line drawing algorithm. Provided that I have implemented the algorithm in VHDL and am able to calculate all pixel values for the line one by one, how do I store them into the frame buffer?

E.g I have 100 lines, I can take say 10 lines and calculate their pixel values in parallel, longer lines will take longer to calculate. Every clock cycle I am able to get the next pixel value for the line, now if I just read 1 byte from memory, overwrite it with the line pixel data and write that byte back and do it for every pixel for every line, that 1 byte read-write method appears to be rather cumbersome and inefficient. So, do you know how it is worked out how to store data into the frame buffer efficiently or do people just use a very fast memory but the actual method is cumbersome and inefficient?

Real GPUs, like CPUs, have a cache hierarchy. So the rasterizer doesn't directly store to memory, but stores into a cache that eventually gets flushed to memory.

Rasterization will usually have some spatial locality (it will generate writes to nearby pixels close together in time), so if those pixels are in the same cache line it will reduce the overall number of memory transactions. This is more effective for filled polygon rasterization than for lines, but even lines have some locality (especially if multiple nearby lines are being rasterized at once).

Another trick is to store the framebuffer in a tiled format instead of linearly left-to-right  and top-to-bottom. You'd pick a tile size such as 4×4 or 8×8 and store the pixels in each tile in a contiguous memory block, then make the whole framebuffer out of an array of tiles. This gives you locality in both dimensions, not just one, which improves cache performance. And tiling is easy to do in hardware, as it comes down to just swizzling the order of some X and Y address bits.


Surface shading on an triangle Let's assume that in a triangle we have computed the brightness on the vertices of a triangle and we have found that it is maximum.

Can any other point which lies on that triangle have more brightness than the maximum brightness on those vertices ?

That completely depends on how you are computing the shading. If you are then just linearly interpolating the shaded colours across the triangle, i.e. Gouraud shading then, clearly, the answer is "no".

However, if you are doing per-pixel shading by, say, interpolating normals and light directions, then you can easily get a brighter area away from the vertices.


How to translate object to origin? I want to rotate a 3D object. On this website http://paulbourke.net/geometry/rotate/

the first step says:

(1) translate space so that the rotation axis passes through the origin

What is meant by "space"? Is it every point on my object? If so, the matrix he provides would just mean that all the points would end up being 0,0,0 when I multiply it by that matrix. That would mean the rotation matrices would have no effect.

No, he's talking about subtracting the position of the cube from the vertex positions, so that your cube is positioned at the origin.

If you positioned the cube at (10, 30, 15), you subtract that value from every vertex.

Next, you rotate the vertices.

Lastly, you add the position to the vertices again so the box goes back to where it was, but the vertices have been rotated around the location of the box.

Doing rotation like this makes an object spin in place.

If you didn't subtract the position before rotating, the object would orbit the origin, instead of spinning in place.


Why thumbnail shows just another pic? Download this picture and see it as a thumbnail, like in whatsapp or your phone gallery and you'll find that it shows another picture in the thumbnail.

If you can't see the thumbnail:
You can simply do some changes in color, or do some filters on it using PicsArt and you'll notice the difference.  I've searched the whole internet, but haven't got the answer yet.
Please explain how is this happening.

Note: I know about the trick with PNG files, but this is a JPEG file and the trick works with this too.
I added video a to elaborate.

You can't see it in the image you uploaded because it's a JPEG, but PNG files which have a full alpha channel can do the trick you mentioned. It works with websites or apps where the "thumbnail" image is displayed on a white background and the "full" image is displayed on a black background. In the thumbnail display, white pixels and completely transparent pixels look the same, because of the white background; in the full image, black pixels and completely transparent pixels look the same.

Thus, you can have a white-on-black picture and a black-on-white picture in the same image, and the background hides one of the two images. You can easily see what's going on if you look at the image against a background of some other colour.


Specular exponent spectrum I read the MTL specification for materials and noticed that the specular exponent Ns must be a scalar value instead of a spectrum. Would a specular exponent with three color channels (i.e. RGB, XYZ, ...) make sense (i.e. could represent (the specular exponent is of course not physically based at all) something physically plausible)?

Using independent settings for each colour channel is like using settings dependent on wavelength when doing spectral rendering. So the question could be re-formulated as:

  Is a material which changes its roughness with wavelengths physically plausible?

With some kind of nano-fabrication process you could build a material surface using some microfacets reflecting certain parts of spectrum and distributing each type of microfacets in a different way. So not only it is physically plausible, but it is also physically realisable. On the other hand, you normally don't encounter such behaviour in "common" materials.


What are the performance implications of the optional flags used when mapping a buffer? The docs for glMapNamedBufferRange list several optional flags that can be used when a buffer is mapped such as GL_MAP_INVALIDATE_RANGE_BIT.

The docs say:

  The following optional flag bits in access may be used to modify the mapping:
  GL_MAP_INVALIDATE_RANGE_BIT indicates that the previous contents of the specified range may be discarded.

It seems like the right thing to do would be to always specify that flag yet it is optional.  Even if you do not specify GL_MAP_INVALIDATE_RANGE_BIT or the other, similar flags I do not see how you could retrieve this data or what its value would be.

Are there performance reasons (or other reasons) why you would not want to invalidate the data that is in a buffer that you are writing over?

It seems like the right thing to do would be to always specify that flag yet it is optional.

You can map buffers for reading; invalidation is negatively useful for that. Also, you can map a buffer and only overwrite part of it. Invalidation is negatively useful for that too.

glMapBufferRange has to be able to work outside of the narrow use case of mapping for overwriting an entire range.

  Are there performance reasons (or other reasons) why you would not want to invalidate the data that is in a buffer that you are writing over?

Invalidation is a mechanism to allow the implementation to not delay the act of mapping the buffer (due to prior GPU commands that read from it) if you're going to overwrite all of the area in the buffer. The implementation can allocate a chunk of memory, and you can write to that. Then, it'll schedule the DMA from that chunk into the actual buffer storage when you unmap it, handling the synchronization operations as well. For whole buffer invalidation, it can allocate GPU-accessible memory and completely replace the buffer's storage.

Of course, this only matters if you're mapping frequently. If you're using persistent mapped buffers for streaming (and you should be, if you're using DSA), then you don't care about invalidation. You're going to handle synchronization manually.


Most efficient way to render many OO meshes in OpenGL I am writing a large 3D game in Java with OpenGL.
Question #1
As of now, I am rendering my 3D objects using a Model class that I defined. This class contains vertex, color, model matrix, code (a custom attribute I defined), and index arrays. I defined a method addModels that can concatenate an array of Model instances into a new, larger Model (it concatenates all the attribute arrays using System.arraycopy). For instance, to draw a forest; for every tree, I create a Model; and at the end I combine them all into one forest Model, which I render. This procedure is a very object-oriented way of doing it, and consists of fitting together many bundles of attribute arrays into larger ones.
Simple example code:
Model[] models = new Model[trees.length];
for (int i=0; i<trees.length; i++) {
    models[i] = getTreeModel(trees[i]);
}
Model result = addModels(models);
return result;

However, this procedure may be bad practice memory-wise, since I create many Model instances per frame. (Nonetheless, I read in this answer that objects do not take much memory.) Would it be better practice to lean towards a more data-oriented approach; like first declaring large attribute arrays (vertex, color, etc.), and creating them individually? Simple example code:
float[] vertices, colors;
for (int i=0; i<trees.length; i++) {
    float[] treeVertices = getTreeVertices(trees[i]),
            treeColors = getTreeColors(trees[i]);
    // copy treeVertices into vertices, and treeColors into colors at appropriate positions
}
return new Model(vertices, colors);

Please note that either option results in one model that is going to be rendered finally.
Are there any better ways of doing this?
Question #2
When I render a Model, I convert each attribute array into an attribute buffer (e.g. float[] into FloatBuffer). Would it make my game run faster to, first, load data into a buffer without using the array at all? (I'm using arrays because they're easier for me to manipulate.)
Question #3
Would it be more efficient to call glBufferSubData then to concatenate all the attribute arrays into longer ones and then call glBufferData (or a similar method)?
Question #4
One tutorial I read defined a Model class as containing multiple Meshs. Then, they drew each mesh separately to the screen. Is this good practice if I have a lot of meshes (trees) per model (forest)? I heard it isn't good to make a lot of glDraw* calls.

Don't copy around huge chunks of data if you don't have to.

I would delay collecting and building the final forest mesh for as long as possible.

However when you have multiple of the same mesh that just needs to be translated and rotated a bit you can use instancing. Which lets you draw thousands of copies of a tree with a single draw call.

The most efficient way of getting data to the gpu is to map the buffer and fill that. In java that means using a Buffer.


procedurally generating a texture overlay simulating shrink wrap I'm looking for a way to procedurally create a realistically looking texture overlay simulating the object being shrink wrapped.

It is only used to be added to single images, so it does not need to behave correctly in an animation with changes of position or angle of the object, camera or light source(s).

I already tried by implementing a grayscale plasma effect. It looks nice but not real:

Below you can find some examples of what I am hoping to achieve.

Do you have any suggestions on how something like this could be generated? I'm looking to produce thousands of unique textures, so there should be some variation/randomness involved.

I finally arrived at a solution that is not perfect, but seems to be good enough for my application right now.

The pipeline is as follows:

-> grayscale perlin noise with affine transformed (stretched and rotated) coordinate system
-> gaussian blur (sigma 3.0)
-> normalize (range 0.0 to 1.0)
-> pixels = pixels - 0.5
-> pixels = pixels * 2
-> threshold (change everything below 0 to 0)
-> add pixels to original image with an alpha value of 0.7

Here are some of the results:


Projected points and screen coordinates I'm trying to understand part of the contents of a slide, but I'm not really understanding. So, here's the interested part.

I've a few questions.

Are the projected points $q_1$ and $q_2$ the points with respectively the screen coordinates $(x_1, y_1)$ and $(x_2, y_2)$, i.e., $q_1 = \begin{pmatrix} x_1 \\ y_1\end{pmatrix}$ and $q_2 = \begin{pmatrix} x_2 \\ y_2\end{pmatrix}$?
Regarding how to obtain the projected points. What I understand from the slide is that the projected $3D$ points are obtained by dividing all coordinates of $p_1$ (e.g.) by its $z$ coordinate, i.e., $p_1^z$, so that we obtain $q_1 = \begin{pmatrix} \frac{p_1^x}{p_1^z} \\ \frac{p_1^y}{p_1^z} \\ \frac{p_1^z}{p_1^z}  \end{pmatrix} = \begin{pmatrix} \frac{p_1^x}{p_1^z} \\ \frac{p_1^y}{p_1^z} \\ 1 \end{pmatrix}$. So, I guess, that at this point, we obtain the sccreen coordinates by ignoring the $1$ as the 3rd coordinate. Is that right?

It's not 100% clear what the author means here, but I'll choose to interpret "screen coordinates" as "pixel coordinates". These would be related to the projected points by a 2D coordinate transformation.

You're correct that projection is done by dividing each component of a point by its $z$ component. (That's not quite true—actually, we usually use homogeneous coordinates, which have four components $xyzw$, and divide by the $w$ component, which has previously been set to eye-space $z$ by the projection matrix. This frees up the $z$ component of the vectors to be used for the z-buffer.) The projected points $q_i$ are then in "normalized device coordinates" or NDC space, which has a range of [−1, 1] on each axis.

To calculate the resulting pixel coordinates on the screen, we then need to perform a 2D scale-and-translate operation, to map the [−1, 1] range to the desired range of pixels. For example, if we want a 640×480 viewport, we could calculate
$$x_i = 640 \cdot \frac{q^x_i + 1}{2} \\ y_i = 480 \cdot \frac{q^y_i + 1}{2}$$
You might also need to flip the $y$ axis in this transformation, for instance if the NDC space is Y-up but the pixel coordinates are Y-down.


why does black text have orange and blue pixels Why is it that when you zoom in to some black text you find that it is made up of orange, slightly black and blue pixels like the picture below.

This is called subpixel rendering.

The different primary colors in your monitor are not stacked on top of each other. Instead they are arranged near each other. Different monitors have different patterns but most commonly they are aligned so that the colors are side by side.

If you know the physical arrangement, then you can prepare the image so that you have calculated a different sample position for each color channel. In essence your boosting the resolution of your image so that you are treating each individual color as a separate pixel.

This, of course, means that you need to know the display orientation and have some data that can be shifted. The image wouldn't be all that useful on other monitors with different pixel alignments. So this is reserved for things that are dynamically generated, most often fonts.

It also means that when zoomed or presented on a medium with different or no subpixels, the effect will register as a blur. So zooming in on the pixels of a subpixel rendered image is not very good idea. For this reason it migth be a good idea to disable the effect if you make images for others to use and the subpixel alignment is unknown.


Texturing an "infinite" plane I am rendering an infinite plane as described in the following answers:

https://stackoverflow.com/questions/12965161/rendering-infinitely-large-plane
https://stackoverflow.com/questions/7380250/how-to-render-a-plane-of-seemingly-infinite-size

Specifically, I am rendering an "infinite" XZ plane using the following five 4D vertices:
$$(0, 0, 0, 1)\quad(1, 0, 0, 0)\quad(0, 0, 1, 0)\quad(-1, 0, 0, 0)\quad(0, 0, -1, 0)$$

In my engine, this is displayed as a ground plane at origin.

What I would like to do is texture this plane. For now, it would be nice to just have a checkered grid. In my fragment shader, I am doing this via the varying $x$ and $z$ positions. This works fine for other "non-infinite" meshes, but for the infinite plane, it is incorrect. This is because the interpolated positions that are passed to the fragment shader don't really make sense in world space, as far as I can tell.

How can I compute the world-space position coordinates in my fragment shader?
Is it possible to compute them from the vertex positions, since they represent points at infinity?

The next step would be UV coordinates, but as I understand that might not be possible. I am interested more in being able to easily procedurally texture the plane rather than apply an image to it.

$$
\def\mvec#1{\begin{pmatrix}#1\end{pmatrix}}
\def\ivec#1{\left(\begin{smallmatrix}#1\end{smallmatrix}\right)}
\def\mmat#1{\begin{bmatrix}#1\end{bmatrix}}
\def\vec#1{\mathrm{\mathbf{#1}}}
\def\mat#1{\mathrm{\mathbf{#1}}}
$$
If you have the screen-space x and y coordinates as well as the depth of your fragment, you can directly compute the coordinates of the corresponding point in world-space. To do so, first compute the clip-space coordinates of your fragment
\begin{equation}
 \vec p'' = \mvec{
  2\cdot\frac{x}{r_x} - 1 \\
  2\cdot\frac{y}{r_y} - 1 \\
  2 \cdot z - 1 \\
  1
 }
\end{equation}
where $x$ and $y$ are the screen-space (pixel) coordinates of the fragment, $z$ is the fragment depth, and $r_x$ and $r_y$ are the width and height (resolution) of the viewport. The above computation is assuming that you're using OpenGL with the default depth range. If you're using Direct3D, use $z$ directly without applying a scaling and offset. If you're using a depth range different from the default, apply whatever is the the appropriate inverse transformation in your case to get from screen-space to clip-space $z$.

Once you have the clip-space coordinates of your fragment, you can simply unproject the fragment by transforming with the inverse view-projection matrix:
\begin{equation}
 \vec p' = \mat M^{-1} \vec p''
\end{equation}
where $\mat M$ would be your view-projection matrix. (Note: you will most likely want to pass the inverse view-projection matrix to the shader as a uniform as inverting the view-projection matrix in the shader for every fragment would most likely introduce quite some unnecessary overhead.)

The final step is then to homogenize to get the world-space coordinates of the point
\begin{equation}
 \vec p = \frac{1}{p'_w} \cdot \mvec{
  p'_x \\
  p'_y \\
  p'_z
 }.
\end{equation}

By the way: It would seem to me that rendering this "infinite plane" should be possible using just a single triangle with all corners at infinity in different directions instead of four triangles. Since the boundary of your polygon is pushed to infinity, it shouldn't matter how many edges it has…


How to plot an input signal in image? Given an input signal(ex. sine) how can one go about plotting an image like below ones(the stripped black and white image)?

The images are from these slides on image processing.

Or this one:

If you're using Python, you can use a library such as matplotlib for this. It can take a numpy array and plot it as a standard chart using the function plot or as an image using imshow. The resulting image/plot can be displayed in an interactive window, or saved to a file, or it shows inline in your Jupyter notebook if you're using that.

There are other (better?) Python chart plotting libraries but the functionality is basic and IMO matplotlib is easier to get started with (perhaps just because it's older and more established).

You can also do this using OpenCV, if your input is an OpenCV image. Its plotting functions are named similarly to the matplotlib ones. OpenCV is available in Python, C++, and a handful of other languages.


My (ADS) shader doesn't render the light direction correctly This is what I'm doing:

vertex shader:

#version 400
layout ( location = 0 ) in vec3 vertex_position;
layout ( location = 1 ) in vec3 vertex_normal;

uniform mat4 ModelViewMatrix; //view*model
uniform mat3 NormalMatrix; //transpose(inverse(modelviewmatrix))) //top 3x3 row of model*view
uniform mat4 priv_mat; //projection*view*model

out vec3 normal;
out vec3 position;

void main()
{
  normal=normalize(NormalMatrix*vertex_normal);
  position=vec3(ModelViewMatrix*vec4(vertex_position,1.0));
  gl_Position=priv_mat*vec4(vertex_position,1.0);
}

fragment shader:

#version 400
in vec3 normal;
in vec3 position;

uniform vec4 LightPosition; // *needs to be in view-space* (view*lightpos)
uniform vec3 LightIntensity;

uniform vec3 Kd;            // Diffuse reflectivity
uniform vec3 Ka;            // Ambient reflectivity
uniform vec3 Ks;            // Specular reflectivity
uniform float Shininess;    // Shininess

vec3 ads( ){
    vec3 n = normal;
    vec3 s = normalize( vec3(LightPosition) - position );
    vec3 v = normalize( vec3(-position));
    vec3 r = reflect( -s, n );
return
    LightIntensity *
    ( Ka +
    Kd * max( dot(s, n), 0.0 ) +
    Ks * pow( max( dot(r,v), 0.0 ), Shininess ) );
}

void main()
{
     gl_FragColor = vec4(ads(), 1.0);
}

But when I run it, I get this:

Where the light doesn't just come from the wrong spot, but it also doesn't change when I move the planet around, like so

Where the diffuse value somehow gets the wrong direction? The math is beyond me however.

So, the diffuse value is calculated by getting the dot(s,n), where s is (lightposition - position), and position is (view * model * vertex_position). But like you can see, the results are not as expected

It seems to me, to be that your different positions and normals are not in the same space. Having them in the same space is important because else it might think the normal is pointing left while it should point to the right.

If you don't know what I mean with space in this context it's basically a coordinate system. Think about a grid, grid A. On grid A you have a point. Then you have another grid, grid B. You place grid A on grid B. If you move grid A around, the point on grid A does not move relative to grid A. It does however move relative to grid B, so they are different spaces. Hope that clarifies it for you, if not I am so sorry.

You have a few coordinate spaces:

Local: This is the vertex locations relative to the model position.
World: This is the location relative to the actual world origin.
View: This is the location relative to the camera.

You have the light position, vertex position and normal:

Light position is in world space.
Normal is in world space, since you multiplied it with a model matrix making it go from local to world.
Vertex position is in view space, since you put it to world space with the model matrix and then to view space with the view matrix.

Do you see that you have one of the three variables in a different space?
I have a strong feeling this is the problem and if you do not multiply the vertex position with the view matrix, in the vertex shader, this should be fixed.

I hope that this helps you and good luck!


Photo-realism blind experiment I need a lot of real time rendered images and real images where it's recorded which one is which to prove either way whether existing gaming computers have the hardware to be photo-realistic to someone I know (which they will have if they're unable to tell the difference, statistically) at their best. Please can someone link me to what I'm looking for? Thank you.

Path tracing is a common method for making photo realistic images.  If I were you, I'd start off doing a google image search for path tracing to find some images.

You may get lucky and find a site that has a lot of them.

Here are a few examples I found doing that:


Sort half-edges around common vertex in 3d I'm trying to figure out this problem for very long time and am no getting nowhere. I'm working on a simple 3d modeler that uses half-edge data structure.
Say I have non-manifold geometry where two triangles share a common vertex, as shown in the image below. And I want to add another triangle such that now three triangles share a common vertex. Once we add the new triangle we need to reorder the half-edges around the common vertex. In 2d this ordering is done by sorting the half-edges from the common vertex clockwise, as explained in this post.
However in 3d this becomes a nightmare. If the same three triangles share the common vertex but have an arbitrary orientation in 3d space and are not coplanar. How can one possibly sort the half-edges?
I experimented with using the common vertex normal to construct a plane, and project all the half-edges around the vertex to that plane. After which we could sort them clockwise relative to the plane. But I've found this approach to have a lot of issues. And now I'm all out of ideas.

If projecting them onto the plane of the vertex normal doesn't do the job, I'm not sure what would. There isn't any unambiguous way to do this in 3D. Imagine the new triangle that you are on there joining is perpendicular to the existing two triangles? What would you want the answer to be in that case?
I suppose you could try "voting" by dotting the new triangle's normal with each of the existing triangle's normals. A positive dot is a vote to keep the current orientation, a negative dot is a vote to flip it. Maybe weight the votes by the triangles' areas, or their angles at that vertex. Of course you'd have to decide how to break ties, and this might just give you similar problems to the plane of the common vertex normal.
This would make more sense if you were constructing a new triangle that shared an edge with one of the existing triangles. Then you could copy the orientation from the triangle that it was joined to. I'm not sure what kind of 3D modeling operation you're doing that produces this situation, but if there's any way you can accomplish it by building things in terms of common edges rather than common vertices, you'll probably have a much better time.


BSDF sampling versus light sampling I wish to understand the specific application of Multiple Importance Sampling (MIS) to weighting BSDF sampling and light sampling together.
Refer to the following diagram from these Stanford course notes:

I understand the source of noise in the left diagram (a), but not in the right (b), and I think this stems from understanding what "sampling the BSDF" means, but not understanding what "sampling the light sources" means.

To confirm my understanding I'm going to grossly simplify the general path tracing procedure, and specialize it to a single bounce in this scene, to get the point across:

BSDF sampling (diagram (a)) procedure:

Cast a ray from the camera for a given pixel.
Upon hitting the glossy surface, sample the surface's BSDF, then continue along the newly sampled ray.
Hopefully, you hit the light, in which case you contribute energy to the given pixel.

This will obviously yield the noise profile we see in diagram (a); the noise goes down as the surface gets glossier (sharpening the distribution of the BSDF) and as the light gets bigger (making the target easier to hit by chance).

However, I don't understand the nature of the noise in diagram (b), and I therefore clearly don't understand what "sampling the light source" means. My guess would be a procedure like:

Light source sampling (diagram (b)) procedure(???):

Cast a ray from the camera for a given pixel.
Upon hitting the glossy surface, uniformly sample the solid angle that subtends the light source (i.e., a "shadow ray"), then continue along the newly sampled ray.
If you hit the light (i.e., no obstructions) contribute energy to the given pixel, weighted inversely by the BSDF of the glossy surface evaluated at the shadow ray, (and probably also multiplied by some other weight representing the fraction of our total solid angle that the light takes up, as in regular importance sampling).

(Again, I have grossly simplified, and have reduced the problem to a single bounce in this particular scene for illustrative purposes.)

However, the procedure I have described above cannot possibly be what is meant by "light source sampling" in the linked paper, because then it wouldn't result in more noise with larger area lights.

What's going on in diagram (b)?

Edit: I suddenly understood the issue. The noise in the top right corner of (b) is because it's struggling to find the tiny fraction of angles in which the BSDF is not extremely close to zero. My assertion "... because then it wouldn't result in more noise with larger area lights" is precisely wrong, because larger area lights correspond to sampling over a larger fraction of the solid angle, and thus sampling the inverse BSDF weights with higher variance.

I'm now looking for how to delete my question. Hitting the "flag" button just sends me to the top of the page, and doesn't do anything else...

Edit: I suddenly understood the issue. The noise in the top right corner of (b) is because it's struggling to find the tiny fraction of angles in which the BSDF is not extremely close to zero.

Yes your reasoning here is correct.

Taken to the extreme if the top most surface was perfectly mirror (dirac delta BRDF), then it would never* sample the right ray from the light source that was perfectly aligned with the camera's view direction. For such a BRDF $\omega_i$ must equal $\omega_o$.


How can I detect edges between different colours of the same brightness? I'm looking for an algorithm that can identify edges across which colour is changing sharply, rather than just finding changes in brightness.

Is this just a matter of using a different colour space with existing edge detection algorithms, or is there a better approach?

I think you can convert from the RGB space to the HSV one, or whatever color space has the HUE in a single channel.

Take the HUE channel, and make the edge detection on that one.

Here a simple Matlab script to achieve the result.

I = imread('image.png');
hsv = rgb2hsv(I);
hue = hsv(:,:,1);
edges = edge(uint8(hue),'sobel');
imshow(edges);


Fill an irregular region with 2D shapes I am creating a 2D CAD drawing generator in C# using .netDXF library. Given a area I want to fill it with rectangles/circles (convex). For example, the regions marked with numbers in below image. This is just an example, the pattern may change.

I'am not an expert in the area of graphics. What should be my approach to this problem? Is there any algorithm that I can follow? What would be a generalized (not specific to .netDXF) way to fill an irregular region with 2D shapes.

Any help is appreciated!

There is no general algorithm for packing problems. Only some of the special cases have known, and optimal, solutions. If you are packing one shape then finding a reasonable solution is possible. Like the known cases of hexagonal packing etc.

However, if you have multiple diffenently sized objects then easy just flew out of the door. Some heurestics have been developed, since there is a very big demand for such algorithms in manufacturing. But they are not usually very fast (performant?) or simple to implement. Many of them use a genetic algorithm. A free one that you may test can be found atsvgnest.com but faster ones and ones working on shaking and collision also exist.

Anyway your question is sufficiently vague, so i dont actually know if
 you want to do packing. I mean it is perfectly possible you mean tiling, which is pretty trivial.


Determining Rational Quadratic Bezier Curve Weights for Circle I am trying to create a spherical interpolation with 3 points. I'm currently using Quadratic Bezier Interpolation but have been told I should use Rational Quadratic Bezier Curve in order to get a perfectly circular curve. I have tried implementing this based on the formula I found here (3 control points A,B and C, 3 weights W1, W2, W3 and a time t):
CurvePoint = (A*W1*(1-t)^2 + B*W2*2t(1-t) + C*W3*t^2) / (W1*(1-t)^2 + W2*2t(1-t) + W3*t^2).
How do I determine the correct weight values for this to work as a circle? Is that even possible without moving the middle point? Thank you.
Here is the code I am using (with all weights set to 1.0) and the curve it produces:

def ArcPoints(node):
    points = node.GetAllPoints()

    # The three points of the point object
    a, b, c = points[:3]

    samples = 6
    arcPoints = list()
    for i in range(samples):
        t = float(i)/(samples - 1)
        w1 = 1
        w2 = 1
        w3 = 1
        p2 = (a * w1 * (1-t) ** 2 + b * w2 * 2*t * (1-t) + c * w3 * t ** 2 ) / (w1 * (1-t) ** 2 + w2 * 2*t * (1-t) + w3 * t**2)
        arcPoints.append(p)

    return arcPoints

Check out the section on Circular Arcs and Circles, from Ching-Kuang Shene's excellent computational geometry course notes:

[G]iven three control points P0, P1 and P2 such that P0P1 = P1P2 holds, if we choose w, the weight for P1, to be sin(a), where a is the half angle at control point P1, the resulting rational Bézier curve is a circle.

The second diagram on that page is particularly useful. If P0 is at (0,0), P1 is at (1,0), and P2 is at (1,1), then the angle at P1 is 90 degrees; half that is 45, so assigning weights w0 = w2 = 1 and w1 = sin(45) = 1/sqrt(2) will produce a circle.
EDIT: To actually implement this from your code: The three points are [a,b,c]. If you know that the distance from a to b is the same as the distance from b to c, then you can set w1 and w3 to 1, and w2 to the sine of half the angle between them. Look up the half-angle formula for sine to see that sin(x/2) = sqrt((1 - cos x) / 2). The cosine of the angle between two vectors is the normalized dot product, i.e. cos x = dot(a-b,c-b) / (a-b)^2. Thus, you can do something like
ba = a - b
bc = c - b
cosx = ba.Dot(bc) / ba.Dot(ba);
w2 = math.sqrt(0.5 * (1 - cosx));

Again, this will only work if the distances ba and bc are the same. (You can still make a circle otherwise, but the weights will be more compilcated.)


Stereoscopic 3D app development I want to create an application to visualize image pairs in stereoscopic 3D. I want it to have a cursor that can move left and right, but also in and out. I think the way to achieve this is to draw a cursor on top of each image and then draw the images on screen (which would be a 3D capable screen).

How do I create such an application?

The experience I have is console programming in C, C++, Python. And I once used GTK+ to create a windowed app.

I've searched around and my problem is that I don't know where to start learning.

More details:

This app is meant to run on windows (although it would be nice if I could made multi-platform)

This is a very broad question. The basic way to do this is to generate 2 frames - one for each eye. You can do this using any modern 3D API from OpenGL to DirectX to Vulkan, Metal, or DX12.

You'll need to understand things like interocular distance, depth cues, and 3D compositing.

You'll also need some way to allow the user to move the curser in and out, so you'll want to read up on various user interface, visual interface, and user experience (UI, VI, and UX, respectively) techniques.


What is the most physically accurate model of surface materials possible in computer graphics? I  am looking for theoretical and implemented models to represent surface materials in software that strives for physical accuracy.

Is BRDF really the best model? What alternatives are better? Why? What drawbacks beside performance do these models have?

BRDFs are not accurate for any dielectric surface, as all of them have some degree of subsurface scattering. A BSSRDF is also just an approximation based on the assumption of a semi-infinite slab. Ideally, you'd run a volumetric path trace for all surfaces, which would be much more accurate than BRDFs or BSSRDFs, but significantly more expensive. Although, Disney has already used brute force path tracing over BSSRDFs in production, see the SIGGRAPH 2015 course notes, section 2.5.


Strange stripes on the gradient On the picture below you can see mathematically perfect smooth transition from black to white. But I noticed that on all gradient picture I see strange strips and the color transition doesn't feel smooth. I even see that if you pass from black to white, there are some small jumps back to a bit darker color, when theoretically the color should become always whiter and whiter.

Can somebody explaing me this phenomena?

The 'jumps' to 'a bit darker' are an optical illusion due to how human perception works. Check out Mach bands in wikipedia. Now as for why you get a step function even though you have a smooth transition in code: this is due to quantization. Your monitor can reproduce a finite amount of grey levels, so you quantize your otherwise continuous range.


Ray-triangle intersection algorithm not intersecting (C++) I've been trying to implement the Moller-Trumbore ray-triangle intersection algorithm in my raytracing code. The code is supposed to read in a mesh and light sources, fire off rays from the light source, and return the triangle from the mesh which each ray intersects. Here is my implementation of the algorithm:

//Moller-Trumbore intersection algorithm
void getFaceIntersect(modelStruct m, ray r, hitFaceStruct& hitFaces)
{
    // Constant thoughout loop
    point origin = r.p0;
    point direction = r.u;
    hitFaces.isHit = false;

    for (int i = 0; i < m.faces; i++)
    {
        // Get face vertices
        point v1 = m.vertList[m.faceList[i].v1];
        point v2 = m.vertList[m.faceList[i].v2];
        point v3 = m.vertList[m.faceList[i].v3];

        // Get two edgess
        point edge1 = v2 - v1;
        point edge2 = v3 - v1;

        // Get p
        point p = direction.cross(direction, edge2);
        // Use p to find determinant
        double det = p.dot(edge1, p);

        // If the determinant is about 0, the ray lies in the plane of the triangle
        if (abs(det) < 0.00000000001)
        {
            continue;
        }

        double inverseDet = 1 / det;

        point v1ToOrigin = (origin - v1);

        double u = v1ToOrigin.dot(v1ToOrigin, p) * inverseDet;

        // If u is not between 0 and 1, no hit
        if (u < 0 || u > 1)
        {
            continue;
        }

        // Used for calculating v
        point q = v1ToOrigin.cross(v1ToOrigin, edge1);
        double v = direction.dot(direction, q) * inverseDet;

        if (v < 0 || (u + v) > 1)
        {
            continue;
        }

        double t = q.dot(edge2, q) * inverseDet;

        // gets closest face
        if (t < abs(hitFaces.s))
        {
            hitFaceStruct goodStruct = hitFaceStruct();
            goodStruct.face = i;
            goodStruct.hitPoint = p;
            goodStruct.isHit = true;
            goodStruct.s = t;
            hitFaces = goodStruct;
            break;
        }
    }
}

The relevant code for hitFaceStruct and modelStruct is as follows:

typedef struct _hitFaceStruct
{
    int face; //the index of the sphere in question in the list of faces
    float s; //the distance from the ray that hit it
    bool isHit;
    point hitPoint;
} hitFaceStruct;

typedef struct _modelStruct {
    char *fileName;
    float scale;
    float rot_x, rot_y, rot_z;
    float x, y, z;
    float r_amb, g_amb, b_amb;
    float r_dif, g_dif, b_dif;
    float r_spec, g_spec, b_spec;
    float k_amb, k_dif, k_spec, k_reflective, k_refractive;
    float spec_exp, index_refraction;
    int verts, faces, norms = 0;    // Number of vertices, faces, normals, and spheres in the system
    point *vertList, *normList; // Vertex and Normal Lists
    faceStruct *faceList;       // Face List
} modelStruct;

Whenever I shoot a ray, the values of u or v in the algorithm code always come out to a large negative number, rather than the expected small, positive one. The direction vector of the ray is normalized before I pass it on to the intersection code, and I'm positive I'm firing rays that would normally hit the mesh. Can anyone please help me spot my error here?

The syntax for your dot- and cross-product are a bit strange.
The methods are members of a vector, but still take two arguments. Are they static methods? Or are you really sure they do what you would expect?

Otherwise the only real difference in your implementation and the one you linked that I can see is your test against the parameter t.

The implementation you linked tests for

if(t > EPSILON)

your code tests for

if(t < abs(hitFaces.s))

I don't see in your code how you set the value for hitFaces.s since you fire this ray against a model and don't know jet if it has hit anything.
My understanding would be, that you first test if t is large enough to signal a hit ( > EPSILON ) and then in a second step sort for the smallest t (closest to the ray origin).

In my head you can't get a value for hitFaces.s without calculating this intersection test as you wrote it, and the intersection test needs the hitFaces.s to determine if an intersection was made. But I could be in the wrong here.


Threads per compute shader group The maximum allowed number of threads per compute shader group is 1024 for Shader Model 5.0. Is it advisable with regard to performance to stay close to this maximum number?

In order to resolve SSAA and MSAA (down-scaling with appropriate tone mapping), I wrote some compute shaders.

One general compute shader works in all cases and performs one task without synchronization for each output texel and uses [numthreads(16, 16, 1)] (= 256 threads/group which is a multiple of NVidia's warp size of 32 and AMD's wavefront size of 64). Algorithmically, this does not result in the best performance, since for MSAA $T$x, each task performs $T$ texture loads from the radiance, normal and depth textures, and for SSAA $T$x, each task performs $T \times T$ texture loads from the radiance, normal and depth textures.

So instead of dispatching jobs in terms of output texels, I have some specialized compute shaders performing tasks with synchronization for each input texel (for SSAA) or for each subsample of an input texel (for MSAA). Here, each task performs $1$ texture load from the radiance, normal and depth textures and stores the results in group shared memory. Next, a GroupMemoryBarrierWithGroupSync takes place and only one job per output texel continues to finish the work. This is not ideal in case of many SSAA and MSAA samples, but for few samples such as MSAA 2x, one expects to see some gains. In practice, however, the general compute shader outperforms all the specialized compute shaders for both small and large numbers of samples/ouput texel?

SSAA 2x [numthreads(4, 16, 16)] = 1024 (multiple of 64): ~655 FPS vs ~577 FPS

SSAA 3x [numthreads(9, 8, 8)]   =  576 (multiple of 64): ~265 FPS vs ~200 FPS

SSAA 4x [numthreads(16, 8, 8)]  = 1024 (multiple of 64): ~127 FPS vs  ~75 FPS

Can this be solely due to dispatching more threads/group? Can this be due to the synchronization of all threads per group (close to the maximum allowed number of threads)? Or is there some performance one needs to sacrifice in case of using a 3D instead of 2D block of threads per group?

There shouldn't be any performance penalty inherent in using a 3D group over a 2D one, the dimensions are just an aid for programmers to map invocations on to memory locations (since you can read or write wherever you like).

The group size affects which invocations can access the same block of groupshared memory, so it forces all warps from the same group to run on the same SMP. If you have a shader that needs to move stuff around a lot in its local memory block (e.g. a bitonic sorter), a large group size is preferable, but in your case it shouldn't make much difference.

I suspect your problem is with the idle threads within your warps. If I understand your question properly, you're using a thread per input texel or sample to do the texture reads, but then only a subset of these threads to do the processing? If so, you're sacrificing a lot of compute power within each warp. Remember, texture reads are done in minimum 2x2 blocks, and the results get cached in a way optimized for locality for the dimension of the texture (see this question). So although your general purpose shader might seem slow with all the texture reads, a lot of them will be effectively almost free. Also, the GPU does latency-hiding on slow memory reads, swapping in other warps until the result of the read is available. So your general purpose shader actually seems like the smart option here, as it maximizes compute power.


Ocean Wave Rendering How could I generate the waves for a water body with whitecaps & foam and variable intensity of the waves? Is the surface a mesh with a normal map? Is there a formula for generating that? Is there something similar to determine where and how the whitecaps are rendered?  I came across this paper but it's not very clear.

In the paper, I understand the part where it talks about wave generation. There is a section dedicated to whitecaps and foam and it does present a formula to generate them but how do you only apply it to the parts of the water that need it? Based on what I observed it just represents F as the area that will need whitecaps, could someone clarify how that works aswell?

In the paper you referenced $f$ refers to the fraction of water covered by foam that modifies optical properties on the water’s surface. It is explained on page 256 in: "Oceanic Whitecaps: Their Role in Air Sea Exchange Processes" (1986), by E. Monahan and G. MacNiocaill.

  How could I generate the waves for a water body with whitecaps & foam and variable intensity of the waves?

There are more techniques for rendering oceans than there are oceans to render. Some are based on speed (with reasonable results) and some are based on accuracy. On the fourth page of "Deep Water Animation and Rendering" is a discussion of rendering foam, with the prior pages covering other calculations.

Maya has a number of preset demos that can be altered or you can start from scratch. See this YouTube tutorial "Crafting the Wave: How to Render an Ocean in Maya".

Which of those references is more applicable depends on: if you simply want to understand more about it, if you are writing your own software, or if you want to render realistic oceans without necessarily knowing all the calculations behind it.