Why do we call it TRS and MVP, instead of SRT and MVP or TRS and PVM? Here's something that's been bothering me while learning graphics. We have two core concatenated matrix sets: "TRS" for transforms, and "MVP" for moving everything into the canonical view volume.

TRS is applied in this manner: T(R(S(p))), i.e. the scale is applied first, then the rotation, then the translation.

MVP is applied in this manner: P(V(M(p))), i.e. we apply the model matrix first, then the view matrix, and finally the projection matrix.

Why is the order in which we name these sets not consistent? I feel like I am getting something very obvious wrong, but I can't help but be confused by this.

Because whether you use $MVP$ or $PVM$ actually depends on how you perform the multiplication: $vMVP$ versus $PVMv$, note that you have:
$(PVMv)^T = v^TM^TV^TP^T=vM^TV^TP^T$, where the last identity does not hold in math, but holds in glsl since vectors can be reinterpreted as either row or column vectors for convenience.

The same holds for $TRS$ and $SRT$. In general CG code and applications have an issue with sticking to standard established conventions, so you get all kinds of funny conventions.


How to simulate a line laser diode? I'm interested in simulating the way a laser line deforms when it strikes an object and runs along the surface of it. Which concepts would be involved? Is there any 3D modeling software out there that does this already? I'd like to implement it into my Eyeshot-based program at some point.

It's a variant to projective texture mapping.

The simple way to do this in the fragment shader by using the position of the fragment to decide whether it is close enough to the plane of the laser to light up.


Rotating scene or complex object using center of AABB All objects have two AABB (Axis Aligned Bounding Box), one in local space and one another in world space. The box in local space is calculated while importing scene from external source, and the box in world space is transformed version of local one

The AABB of scene is combined of all child AABB boxes. I'm using the center of scene's AABB as center of scene. This is where my problems begins.

I'm using the center point to rotate scene using a trackball. After scene is rotated around center of AABB, then new node transforms are applied to each AABB and new AABB for scene is re-computed by combining/joining all AABB boxes.

Problem:
After rotation applied and new AABB is computed, then the new AABB's center is not same as previous one. So after rotation, center and scene is moving a little.

There is no problem in these cases:

If there is only one object in scene then new center is not changing so scene doesn't move after rotation. Everything looks good here. Object/Model/Primitive may have local transform, this doesn't affect the result
for instance if there are two cube without rotations then center is not moving too, except if one of cube has rotation or there are three cube then center is moving.

If my rotating-around-object codes are wrong then it wouldn't work for single object too, right?

Here how I compute center of box,

center = (box.min + box.max) * 0.5

this is not actual code, because I'm using C.

Is it normal to have moving center after rotation? How do you get center of scene? Using center of AABB like I did?? Any suggestions?

Maybe it must work and maybe I have a weird bug is some place I don't know, I tried to find it but I had to ask because maybe it is wrong to get center of scene via AABB boxes :(

Solution:

Instead of re-calculating center, pre-defined center is used for primitives. The pre-defined center is center of AABB if other value is not supplied. Averaging all center of mesh primitives gives mesh center and averaging all center of meshes gives scene center. After a mesh is transformed, center also gets transformed.

Now center is not moving after rotations. Using center of scene's AABB seems not good idea. Because each shape of child AABB is changing after transformations.


Why is browser-resized image crispy and manually-resized image blurry? I've come across this problem several times now and I can't really understand what causes it; my background is in Wordpress, not really in computer graphics.
I hope this is the right place to ask, I was in doubt with https://graphicdesign.stackexchange.com/.
I have a big initial image, say 1500x1017 at 300ppi, 566 KB. I upload it in my Wordpress site: the browser resizes it to a fixed width that depends on the site (in this case 718px), and it looks nice and crispy. See two screenshots.

In general you don't want to upload oversized images and let the browser do the resizing for you: I'm sure everybody here is familiar with the concept of Serving scaled images to optimise site performance. In a few words,

Serving appropriately-sized images can save many bytes of data and improve the performance of your webpage, especially on low-powered (eg. mobile) devices.
You should use an image editor to scale images to match the largest size needed in your page.

Enter Photoshop (or sips or any other resizing tool). I open the image, resize it to 718px width, save without optimisation, i.e. to max jpg quality. I would expect this image to look as crispy as the big one once uploaded: I am just doing the resizing instead of letting the browser do it, right?
Not quite. The image's size matches the displayed size, but the image looks blurry.

What's the deal? Am I resizing with the wrong procedure? Is this about Wordpress media management with its billion of thumbnails?

There are many filters that can be used when resizing images. These filters have names like "box", "tent", "gaussian", "sinc", "lanczos", and many others. Believe it or not scaling an image down in size is actually much more challenging then scaling it up in size. It is easy to lose high frequency information when resampling an image. Look for the filters in the scaling software, but most software does a good job of choosing default filters so unless you changed the filter then the issue might be...
The next possible issue: jpg is not a lossless format and choosing the right size to compression setting is a trade off. Usually with jpg images a medium quality setting gives the best compression to quality ratio and only makes the image a few k bigger. This is a potential culprit. Try a "high quality" setting for the jpg to see if that helps, or even try a lossless format to remove image format as a potential problem.
To be more direct...the jpg is being sent at a larger size, with more info in it, the browser resamples giving a nice crispy image. But if you resize then that extra info is thrown away and isn't available for the browser to resample it. This is why using a higher quality jpg may help.
"Optimized" jpg's only affect the size of the file, making it slightly smaller in size.
But serving images up from the web has a lot of middleware getting involved, and if these suggestions don't fix the problem then it may be the middleware which is beyond the scope of this forum.
BTW: the two images look almost identical in my browser.


Please help me understand what happens as an image is faded to black in order to time-step particle fading I have a game that has simple particles (basically dots) moving around the screen leaving a trail.

My ultimate goal is to be able to change the opacity of the solid black fading texture each drawing call in a way so that I can keep the length of a particle with trails (using a accumulation buffer) is the same even though the particle movement might move with time-stepping.  The way I render my particles is I render the current frame based on the particles position, lets call this texture A.  Then I take the previous frame and draw a solid black texture over it with set opacity in order to fade this, lets call this texture B.  Then I draw texture A over texture B.  This way the particle leaves a trail based on where it has been.  I am currently time-stepping the movement of the particles so that no-mater how much latency their is it always moves the same speed (considering real-world time).

In essence I want to be able to say say that the particle trial will always be 100 pixels (considering the particle moves 60 pixels in a second) , and have it be that way even if the frame-rate drops.  Currently when the frame rate drops the accumulation buffer gets run less times and thus the trail is longer the more latency their is.

The information I need to know to do this is how exactly does fading work. Because I need to change the opacity of the black texture in a way that allows it to fade more when the accumulation buffer is called less times per second, and fade less when it is called many times per second.  Right now I really dont understand what happens to a pixel when a black texture with a specific opacity is on it.

Here is some data I collected.

Data 1:
This is a chart of the particle trails.  The x axis represents the FPS it was running at, and the y axis is how many pixels long the trail was.  On the left it says what opacity the black texture used in the accumulation buffer was.

You can find all the data, and some best fit line formulas at here (on desmos)

It is important to note I stopped counting after V was lower then 20 since the difference between colors starts getting really small.

some things I noticed about this is that their seems to be either a exponential or division relationship between the numbers.  Also I noticed that their were segments for each frame before it was faded, and that the amount of them that were visible were about the same no-mater the fps when considering the same opacity of the black texture.

Data 2:
I recreated what I thought was going on with a fading texture with paint.net.  I made a 100x100 picture and colored it red. I then added a layer with one black pixel at an opacity of 25/255 then I duplicated this and added another pixel, basically I created a gradient.  Then I went through and labeled each pixel considering its rounded darkness (in hsv color space).  Then labeled the difference between the darkness values.

Unfortunately from this I didnt learn much.  Just reaffirmed that it is a non linear relationship. And I also noticed if I did the fade one more time that all the darkness values shifted to the square next to them.  So I could predict the darkness values if I knew how many times the fade had been applied.

So what happens when a semitransparent black texture is blended over another one?
If you are willing to put in some extra thought what would a formula
be that would give me the opacity the black texture needs to be in
order to make the particle trail be about 'N' pixels long, given the
dt since last frame?

The basic equation for alpha blending is as follows:

$$ c_\text{final} = c_\text{source} \cdot \alpha + c_\text{dest} \cdot (1 - \alpha) $$

Here, $c_\text{source}$ is the color of the thing being blended, $c_\text{dest}$ is the background onto which you're blending it, and $\alpha$ is between 0 and 1.

In your case, $c_\text{source} = 0$ (black fading texture), so blending black $n$ times over a background reduces to

$$ c_\text{final} = c_\text{dest} \cdot (1 - \alpha)^n $$

which is indeed an exponential falloff as you guessed. You can plug this formula in and get numbers pretty similar to those you posted (although when I did it, my results were off by one or two—maybe due to rounding differences; I'm not sure).

Regarding your problem of making the trails appear the same regardless of framerate, a simple approach is to run the accumulation buffer passes multiple times per frame if necessary, so that there's effectively a fixed timestep for the trail regardless of framerate. That will probably give better-looking results than attempting to fiddle with the alpha based on the framerate. It might be too slow, though.

A potentially more efficient approach would be to have the particles spawn a new "trail particle" every so often, where each trail particle stays fixed in position, with its alpha going from 100% to 0 over some length of time (and then it gets recycled). You have to re-render all the particles every frame, but it could end up being faster overall if the overhead of the full-screen blending passes for the accumulation buffer get to be too high.

I should point out though that all of these approaches actually perform time-based fading, not distance-based as you asked for (100-pixel trails). If all the particles move at the same speed, you can just tweak the fade time to make the trails the desired length, but if different particles move at different speeds, then you would need to account for that when setting the fade times for their trails. There's also no trivial way to do that with the accumulation buffer approach, since it implicitly uses the same fade time for everything on the screen.


Angle between two points in Cartesian coordinate system C++ I'm trying to rotate a rectangle so that it faces another rectangle in a spiral.

Im using the Bullet pyhics library and freeglut for the 3d application, for anyone interested https://github.com/damorton/bullet-dominos

float x = 0;
float z = 0;
float angle = 0.0f;
int a = 2, b = 2;
float previousX = 0.0f;
float previousZ = 0.0f;

for (int i = 4; i < maxPoints; i++)
{
    angle = 0.1 * i;
    x = (a + b * angle) * cos(angle);
    z = (a + b * angle) * sin(angle);

    GameObject* temp = CreateGameObject(x, 0, z);

    float newAngle = atan2(previousZ - z, previousX - x) * 180 / PI;
    temp->setRotationYaw(newAngle);

    previousX = x;
    previousZ = z;
}

You can see from the top view that the rectangles are not pointing towards the previous rectangles position.

EDIT: After trying the below code

float x = 0;
float z = 0;
float angle = 0.0f;
int a = 2, b = 2;
float previousX = 0.0f;
float previousZ = 0.0f;

for (int i = 0; i < maxPoints; i++)
{
    angle = 0.1 * i;
    x = (a + b * angle) * cos(angle);
    z = (a + b * angle) * sin(angle);

    GameObject* temp = CreateGameObject(x, 0, z);

    float dirX = -(a + b * angle) * sin(angle) + b * cos(angle);
    float dirZ = (a + b * angle) * cos(angle) + b * sin(angle);
    float newAngle = atan2(dirZ, dirX) * 180 / PI;
    temp->setRotationYaw(newAngle);

    previousX = x;
    previousZ = z;
}

The result is:

Console output:

EDIT: Solution. Some things to note are that the result of atan2() was not converted to degrees using atan2() * 180 / PI. Also that I passed in atan2(X, Z) compared to atan2(Z, X) that is sometimes done for hysterical raisins http://www2.tcl.tk/10814.

// create spiral dominos
float x = 0;
float z = 0;
float angle = 0.0f;
int a = 2, b = 2;
float previousX = 0.0f;
float previousZ = 0.0f;

float dominoHeight = 2.0f;

for (int i = 2; i < maxPoints; i++)
{
    if (i % 30 == 0) dominoHeight++;

    angle = 0.15 * i;
    x = (a + b * angle) * cos(angle);
    z = (a + b * angle) * sin(angle);

    GameObject* temp = CreateGameObject(x, 0, z);

    float dirX = -(a + b * angle) * sin(angle) + (b * cos(angle));
    float dirZ = (a + b * angle) * cos(angle) + (b * sin(angle));
    float newAngle = atan2(dirX, dirZ);
    printf("dirX: %f - dirZ: %f - angle: %f\n", dirX, dirZ, newAngle);
    temp->setRotationYaw(newAngle);

    previousX = x;
    previousZ = z;
}

The parametric equation for a spiral is:

$$
\begin{eqnarray}
\begin{aligned}
    x &= &(a + b \theta) \times \cos(\theta)\\
    z &= &(a + b \theta) \times \sin(\theta)
\end{aligned}
\end{eqnarray}
$$

The direction on the spiral point is simply the derivative of the system with respect to $\theta$. Thus the direction is:

$$
\begin{eqnarray}
\begin{aligned}
 x_{dir} &=&-(a + b \theta) \times \sin(\theta) + b \times \cos(\theta)\\
 z_{dir} &=&(a + b \theta) \times \cos(\theta) + b \times \sin(\theta)
\end{aligned}
\end{eqnarray}
$$

Finally angle is is simply atan2 of the direction equation.

Image 1: This is what I get when i plot squares at $(x, z)$ with direction $(x_{dir}, z_{dir})$

Mathematica source for image


Correct form of the GGX geometry term I'm trying to implement a microfacet BRDF in my raytracer but I'm running into some issues. A lot of the papers and articles I've read define the partial geometry term as a function of the view and half vectors: G1(v, h). However, when implementing this I got the following result:

(Bottom row is dielectric with roughness 1.0 - 0.0, Top row is metallic with roughness 1.0 - 0.0)

There's a weird highlight around the edges and a cut-off around n.l == 0. I couldn't really figure out where this comes from. I'm using Unity as a reference to check my renders so I checked their shader source to see what they use and from what I can tell their geometry term is not parametrized by the half vector at all! So I tried the same code but used to macro surface normal instead of the half vector and got the following result:

To my untrained eye this seems way closer to the desired result. But I have the feeling this is not correct? The majority of the articles I read use the half vector but not all of them. Is there a reason for this difference?

I use the following code as my geometry term:

float RayTracer::GeometryGGX(const Vector3& v, const Vector3& l, const Vector3& n, const Vector3& h, float a)
{
    return G1GGX(v, h, a) * G1GGX(l, h, a);
}

float RayTracer::G1GGX(const Vector3& v, const Vector3& h, float a)
{
    float NoV = Util::Clamp01(cml::dot(v, h));
    float a2 = a * a;

    return (2.0f * NoV) / std::max(NoV + sqrt(a2 + (1.0f - a2) * NoV * NoV), 1e-7f);
}

And for reference, this is my normal distribution function:

float RayTracer::DistributionGGX(const Vector3& n, const Vector3& h, float alpha)
{
    float alpha2 = alpha * alpha;
    float NoH = Util::Clamp01(cml::dot(n, h));
    float denom = (NoH * NoH * (alpha2 - 1.0f)) + 1.0f;
    return alpha2 / std::max((float)PI * denom * denom, 1e-7f);
}

TL;DR: Your $G1$ formula is wrong.

Just to avoid confusion, I am assuming the isotropic version of the BRDF, the Smith microfacet model (as opposed to the V-cavity model), and the GGX microfacet distribution.

According to Heitz 2014, the masking/shadowing term $G1$ is

$$
\chi^{+}\left(\omega_{v}\cdot\omega_{m}\right)
\frac{2}{1+\sqrt{1+\alpha_{o}^{2}\tan^{2}\theta_{v}}}
$$

and according to Walter 2007, the formula is

$$
\chi^{+}\left(\frac{\omega_{v}\cdot\omega_{g}}{\omega_{v}\cdot\omega_{m}}\right)\frac{2}{1+\sqrt{1+\alpha^{2}\tan^{2}\theta_{v}}}
$$

Where $\omega_{m}$ is the microfacet normal direction (halfway vector), $\omega_{g}$ is the main (geometric) normal direction (normal), $\omega_{v}$ is the incoming or outgoing direction, $\alpha$ is the isotropic roughness parameter, and $\chi^{+}\left(a\right)$ is the positive characteristic function, or the Heaviside step function (equals one if $a>0$ and zero otherwise).

As you can notice, the half vector $\omega_{m}$ is used only to make sure the $G1$ is zero if the geometrical configuration is forbidden. More precisely, it makes sure that the back surface of the microsurface is never visible from the $\omega_{v}$ direction on the front side of the macrosurface and vice versa (the latter case is meaningful only when also refractions are supported). If the calling code guarantees this, then you can obviously omit this parameter. That is probably the reason why they did so in Unity.

Your implementation, on the other hand, uses the half vector to compute the cosine of the $\omega_{v}$ direction with respect to the microfacet, which leads to computation of something else than the presented formulae.

If it is of any help, then this is my implementation of the $G1$ factor:

float SmithMaskingFunctionGgx(
    const Vec3f &aDir,  // the direction to compute masking for (either incoming or outgoing)
    const Vec3f &aMicrofacetNormal,
    const float  aRoughnessAlpha)
{
    PG3_ASSERT_VEC3F_NORMALIZED(aDir);
    PG3_ASSERT_VEC3F_NORMALIZED(aMicrofacetNormal);
    PG3_ASSERT_FLOAT_NONNEGATIVE(aRoughnessAlpha);

    if (aMicrofacetNormal.z <= 0)
        return 0.0f;

    const float cosThetaVM = Dot(aDir, aMicrofacetNormal);
    if ((aDir.z * cosThetaVM) < 0.0f)
        return 0.0f; // up direction is below microfacet or vice versa

    const float roughnessAlphaSqr = aRoughnessAlpha * aRoughnessAlpha;
    const float tanThetaSqr = Geom::TanThetaSqr(aDir);
    const float root = std::sqrt(1.0f + roughnessAlphaSqr * tanThetaSqr);

    const float result = 2.0f / (1.0f + root);

    PG3_ASSERT_FLOAT_IN_RANGE(result, 0.0f, 1.0f);

    return result;
}


Is there a way to compile part of a shader into a spirv? I want to have separate files for common things for shaders precompiled into a spirv.
For example PBR, I've got these functions and implementations for them
float NDFGGX(float NdotH, float roughness);
float GeometrySchlickGGX(float NdotV, float k);
float GeometrySmith(float NdotL, float NdotV, float roughness);
vec3 FresnelSchlick(float cosTheta, vec3 F0);

and I don't want to generate binaries for them every time I use it in a new shader.
What I want is to generate a SPIRV binary file once and do whatever I want with it.
Is this possible?
What I've tried is to use shaderc library and create the binary as if it were a vertex shader, but it then needs glsl version and entry point. Not every file'd have entry point, doe.

What you want is generally not possible for OpenGL's SPIR-V support. SPIR-V compiles to shader objects, and shader objects theoretically allow you to link multiple objects of the same stage in a program. However, OpenGL's usage of SPIR-V requires that each SPIR-V shader be a complete shader stage with its entrypoint function.
So the requirement of shaderc mirrors the requirements of OpenGL.
The best you could do is combine multiple SPIR-V binaries into a single binary before handing it off to OpenGL. But that's a non-trivial process, since you basically have to renumber every reference in at least one of them, and combine any references that map to the same type.


Understanding Jump Flooding Algorithm (JFA) for Voronoi Diagrams I'm having trouble understanding the JFA. As far as I understood the algorithm, it walks log(n) times through every pixel (no matter if it is a seed or not) and looks at that pixel's neighbors in $(x+i, y+j)$ where $i,j \in \{-step\ length, 0, step\ length\}$.

When finding a seed (i.e., a colored pixel) among those neighbors, it checks whether the distance between the found neighbor seed and the current pixel is less than the distance the current pixel has already stored (after a previous round). If it is, the current pixel will be overwritten with the color of the found seed and the new distance and therefore serves as input seed for the next round.

So I tried to comprehend an example in some slides by the author himself but failed at step length 2, especially with the three bottommost red seeds:

For example, why does the blue circled seed keep its red color even though at step length 2 it finds two green seeds with a smaller distance (in my understanding the circled red pixel has stored a 4 and the distance to its top and bottom green neighbors is 2)? Or why does the other blue circled pixel become red, though its (x+2, y) neighbor is a green one with a smaller distance than its (x+2, y+2) red neighbor?

I also sketched another example on paper but when it comes to step length 1 the algorithm finds more than one neighbor seed with equal distances, so how will it decide? We could also think of a more simple example like this:

What are the diagonal pixels supposed to be according to the algorithm in that case? What am I getting wrong?

I think that there is a bit of confusion in terminology. My understanding is that only the initially colored points, before step 1, are called seeds.

Maybe this helps clarify the algorithm as well. When the a point $ p $ with color $ s $ finds a neighbor $ q $ with color $ s' $, he compares the distance $ d(p,s) $ with $ d(p,s') $ (not $ d(p,q) $) to decide his new color. This is why each pixel crucially holds the $ (x,y) $ coordinates of his seed color (in the paper they used the r,g channels for this) and not just the distance. In each step this data is also passed to the neighbor.

So in that example, in moving from step length 4 to step length 2, that red square (the circled one that remains red) sees the green square who tells red square that the green seed is at $ (8,6) $. Red square then computes his distance to green square to be $ \sqrt{2^2 + 4^2} $, which is bigger than the distance to red ($ 4 $), and so remains red.


Video-games; Rendering textures on scope zoom-in. Texture compression problem? This is general question.
In the multitude of video-games that are not specialized in scoped warfare (like Sniper Elite), I've noticed that when you zoom in with a scope, the textures and normal maps won't "update".
You're standing on coordinate $(0,0,0)$ and the textures will load in full quality to some other $R^3$ coordinate, let's say $(10,10,10)$.
If you look through a scope from $(0,0,0)$ past the "Max quality" distance, let's say $(10+n1,10+n2,10+n3)$ (where $n_i$ is the zoom in factor), the zoomed in textures will not updated as if you were standing on the coordinate $(n,n,n)$.
The best example is the Fallout 4 scope zoom-in.
If you zoom in anywhere, the distant textures to which you zoom in will look washed out.
What are the solutions to such problems? Are they engine related? I've just started to dabble in OpenGL and noticed that problem on the multitude of games which share the same game engine.

Well there's no way to know for sure unless you look at the source code but my guess is that they do zooming by lowering the FOV (field of view) of the camera. This is easy to implement and actually sort of represents how a real scope works (in the way that light rays are bent through an optical lens). A zoom effect where you change the actual position of the camera might be more trouble than its worth. What if there is an object between the player and the desired camera position? So as you can see, the camera position has not changed at all and so there is no reason the textures would update when zooming.

Now you would think that hey maybe they could just scale the distance required to trigger the higher detail textures as the player zooms in but this may or may not be easy depending on how that is implemented in the engine. The game developers may not even be able to change LOD (level of detail) distances dynamically. Like you said, games like sniper elite which are based all around sniping have dealt with this but general purpose game engines might not have this functionality.

Also you have to consider possible popping effects. If you zoom in to an area and suddenly the textures and meshes update dramatically, this would look very bad. This gets even worse if the zoom effect is gradual or the sight is adjustable. I would even go as far as to say that it might be preferable to have lower quality textures than to have really bad popping.


Compute area (not surface area) and perimeter of a mesh I'm currently researching how to compute geometric properties of architectural shapes based on their 3D meshes, and am stuck for some time on the area and perimeter calculations.

First, the area: assuming that I have the proportions set right, if, for example, I have a wall with 3 meters of height, 7.8 meters of width and 0.290 meters of thickness I'm interested in the result of height * width (3 * 7.8), which would give me 23.4 meters in this case. My idea is to obtain a 2D projection of this 3D mesh onto a plane parallel to it, calculate the surface area of each triangle and sum them up, what I believe would give me the mesh area independent of it's shape, assuming that it is planar. The problem is, how exactly can I obtain this triangulated projection? I believe that if the mesh is aligned to the world axis it would simply be a matter of ignoring one of them, but unfortunatelly this is an assumption that can't be made, as there will be meshes rotated in relation to one or more axis, and just ignoring an axis would distort the projection. Aditionaly, is there any method that would work even in the case of a non-planar mesh?

Now, for the perimeter: having the area problem solved, is there any robust algorithm that would give me the contours of this 2D triangulated projection, and that would work with both convex and concave meshes? I believe that with this it would be a matter of simply adding up all the edges of the contour.

There's a small problem with your method. When the mesh self shadows then part of the model will be counted twice.

You can get the projection of a mesh onto an arbitrary plane by finding the rotation from the normal of the plane to the Z axis and rotating the mesh with it. After that you discard the Z component.

However it's more straightfoward to simply draw the mesh with appropriate projection and counting how many pixels it takes up.

An edge can be part of the perimeter only when both the triangles that make it are projected onto the same side of the projected line.

You can use that to walk around the perimeter. Start with the negative x most point after the rotation and follow the lines. When another potential perimeter line crosses the current line you start following that one instead.


Inverse value in a Perspective Matrix I am a new leaner of computer graphics. I'm trying to understand a code I found online and I got stuck in the following formula:

topLeft = [-tan(vfov/2)*(output_width/output_height), -tan(vfov/2), 1];

Source

looking on the internet I found that the formula is that of the Perspective Matrix. However the formula of the code has:

tan(vfov/2)*(output_width/output_height) instead of

1 / tan(vfov/2)*(output_width/output_height)

Here is the Perspective Matrix I found online.

Can you explain to me why I have inverse values?
What does it mean?
Thank you so much

There is the whole derivation of it but I'll be discussing a brief overview.
This is for the perspective projection  where the line joining the eye and the center of the projection/image plane is perpendicular to it. Like here

As we can easily see, by similar triangles $\triangle ABC$ and $\triangle AEF$ we have

$Y_p / Y = D/-Z$

where $Y_p$ is the projected $Y$ coordinate on to the image plane. $AB = D$ is the total distance from eye to the image plane and is usually set to 1.

Hence we have,

$Y_p = (Y*D)/-Z$

Most APIs also set that the camera is facing towards the negative Z axis following the convention for right handed coordinate system, hence the negative sign. The projection plane is also assumed to be a rectangle instead of a square. It's 2 units long in the $Y$ direction and centered at the origin i.e in the range [-1,1] so it's 1 unit long in the positive Y axis and 1 unit long in the negative. However horizontally, its in the range $[-A, A]$ so when calculating $X_p$ we have to correct for this factor.

$A = Width\ of\ rectangle/Height\ of\ rectangle$

Similarly for $X_p$ and $Z_p$ we have,

$A*X_p = (X*D)/(-Z)$

$X_p = (X*D)/(-Z*A)$

$Z_p = D$

We can easily see see that

$tan(Y_{fov}/2) = BC/D = 1/D$

$D = 1/tan(Y_{fov}/2)$

Here, $Y_{fov}$ is the angle of field of view in the Y axis. Since we are only talking about the upper half its $Y_{fov}/2$.

Hence one way to write $X_p$ and $Y_p$ is

$X_p = \frac{X}{-Z} * \frac{1}{A*tan(Y_{fov}/2)}$

$Y_p = \frac{Y}{-Z} * \frac{1}{tan(Y_{fov}/2)}$

This is what you are seeing in the matrix. The $X$ and $Y$ come from the vector at which the transformation matrix is applied and the $-Z$ term is accounted for by the $-1$ in the 4th row. This $-Z$ is stored as the $w$ coordinate which is then used in perspective division in which we divide by $w$.

For more information you can check this site here

Note:- Haven't discussed properly about NDC space, perspective divide and about near and far planes in $Z_p$ as that would take too much time. Just wanted to show you that it can be derived.


What is "Object Space Lighting"? Looking at Star Swarm, a demo for the Nitrous engine, I found this little line:
"Nitrous uses Object Space Lighting, the same techniques used in film, including real-time film-quality motion blur."

I tried looking around for anything on "object space lighting" or "object space rendering" but couldn't come up with anything. When I hear "object space" I think of doing it per-object but I was hoping to find a more detailed description of the method.

Does anyone know anything about "object space lighting" and if so could you go into some technical details(how its done, pros, cons, etc)?

According to the Star Swarm developers this helps them with LOD and enables greater shading scaling. Based on this I guess its simply texture space lighting.

  Because we do what we’re calling object space lighting, we calculate the projected size of each of those objects on screen, and based on that we shade it in a priority manner based on how large they are. We can scale the shading quality at a different frequency than we scale the geometry level or something else.

 A deep dive into the making of the eye-popping Star Swarm demo (interview)


Method for rendering heightmap from a 3D scene I am looking for a method of rendering a heightmap from a 3D scene. The scene may consist of a terrain which is in turn generated from another heightmap, but will also have regular 3D objects.

The generated heightmap should, so to speak, indicate the highest point in the "column" of the 3D scene represented by each pixel in the heightmap.

This does not need to be a fast/realtime operation, and it does not really matter what language or library is used, although I'd prefer using Python (perhaps with Panda3D?). Also, I would prefer being able to run it headlessly, from a command-line tool without the need for an actual on-screen rendering.

Is this a common operation for which there are established/canonical methods, either through a library such as Panda3D or through more direct/low-level use of data structures representing the 3D scene?

I should add that I am quite new to the computer graphics field of programming.

Using OpenGL, or any such library, you could transform your scene with an orthogonal matrix and move your camera view point to be looking above (and parallel to) the scene (in a vertex shader) and then use an empty fragment shader which is going to write to the depth buffer of the current attached framebuffer. Finally retrieving this depth buffer gives you the heightmap of the current view.

If your scene is too big, you could move the camera higher and also move it around taking "chunks" of the map at a time and assembling your heightmap manually by "stitching" these "chunk" heightmaps together.

Hope this helps.


How can I convert signed distance field to a mesh? I can easily make models by Modeling with Distance Functions but I need make mesh from It so I decide to use voxelizing and make triangles for my signed distance field torus like this video.but I haven't Idea that how can I do this.
you can see this torus on my github.

Update

Snail SDF
I found a software as SDF Mesher.this is what I want but not released.
aiekick instagram,
aiekick twitter
he converted shader to mesh?! how could be Implemented!?
aiekick sketchfab

In short I need a way to convert sdf to mesh.for example this:
Input : SDF Model
Output : Mesh

with CGAL you can generate mesh by implicit function. https://doc.cgal.org/latest/Mesh_3/index.html

Search for "implicit". There is an example of generating meshes from the funciton of a sphere.


Extending an orthogonal set of vectors (graphics application?) Sorry if this is OT, but I'm wondering if there's a specific graphics technique in which it is required to extend a preexisting orthogonal set of vectors (not necessarily to a full basis, but perhaps so).  In a matrix theory lecture, the prof said that this computation has a real-world application, but I can't remember him saying what it was.  Could be computer graphics, could be a lot of things.  I realize that it is only an issue in a high-dimensional space.  For example, if you had two orthogonal vectors in 3-space, you could compute their cross product cheaply.  I asked at Math SE, and it was not appreciated.

TLDR:  Just need the application, if any.  You don't have to say how it is computed, but feel free to if you like.  I'll read it.  I know that orthogonal vectors are often easier to work with than oblique vectors, and other very general math facts like that.

The most common use is almost certainly computing normal vectors for a surface, using a cross product. Although strictly speaking, this does not quite qualify as the two initial vectors are usually not orthogonal. This is used for shading calculations and various other algorithms. I know of at least one where the initial surface is explicitly a rectangle so it would qualify.

The sampling of BRDFs is another application. In many cases, the math is done for a canonical space with the surface normal pointing up and must be transformed to the actual surface. This is done by building a full 3D basis from the surface normal vector.

Anisotropic BRDFs typically have two vectors as input: the surface normal and one vector to define the orientation of anisotropy. Depending on the implementation, it may be assumed to be orthogonal to the normal. Otherwise, it is made orthogonal. Then, again, a full basis is built from those two.

There is a class of ray intersection algorithms which work by projecting the surface in two dimensions. This is done by starting with the ray and generating two more orthogonal vectors which define the projection plane.

This is certainly not an exhaustive list but they are the main ones that came to mind. I am not aware of any uses for higher dimensions but I don't know about every corner of computer graphics either.


How to make the lines of a (binary) image dotted or dashed? Let's say I had a binary image (i.e. only contains black and white pixels).

For example, this one:

How would I make all the lines in this image dotted or dashed?

In other words, the eyes would be left alone, but everything else (including the circle on the nose) would become dotted or dashed.

I know that, for example, kernels can be used to blur, sharpen, etc - but I don't know if a kernel could do this.

A kernel can (probably) not help you, because they are very localized. However, you need to know, where a line is, and that may be out of the reach of a kernel (e.g. a 3x3 Pixel kernel would only be able to detect a line 3 pixels wide. Is that meeting your demands of being a line?)

Rather you need to define, when a line is a line with the information you have. For simplicity you could say "Having at least 5 pixels in either X or Y direction black next to each other, but not having any pixels black in any other direction makes a line". Then you can scan the image for those lines and store them in some data structure.

Now that you have your lines figured out, you need to define what to do with them, e.g. "Every line longer than 20 pixels needs to be dashed, every other line dotted".
Also "A dashed line has a white pixel at every third and fourth pixel, except the first and last pixel may not be white" and "A dotted line has a white pixel at every other pixel, except the first and last pixel may not be white". Since you know the lines, you either know or can check the lines, and therefore you can edit them one by one to be dotted or dashed.

This is of course a pretty high level description, but you don't give much to go on with your question. Perhaps though, this suffices for you to get started.

The hard part of course is to identify lines. Try to think what makes a line for you (e.g. direction, thickness/width vs height), what edge cases you may have (a single pixel or square block of pixels) and then you can go about finding them in your image. Note that in a rasterized image, non horizontal and non vertical lines will have "strange" patterns of how they fill the image and you will have to decide how to treat those on your own.
Also, make sure to not have any lines stored twice (or more) when scanning, because your dotting / dashing process could possibly lead to an unwanted outcome.


Why does monte carlo ray tracing perform better than distributed ray tracing? I've heard that the quality of a monte carlo ray tracer (based on path tracing algorithms) is much more realistic than a distributed (stochastic) engine. I try to understand why, but I'm just at the beginning.

In order to dive into this topic and understand the basics, can someone point me into the right direction? What part of the algorithm leads into a more realistic render result?

The term "distributed ray tracing" was originally coined by Robert Cook in this 1984 paper. His observation was that in order to perform anti-aliasing in a ray-tracer, the renderer needs to perform spatial upsampling - that is, to take more samples (i.e. shoot more rays) than the number of pixels in the image and combine their results. One way to do this is to shoot multiple rays within a pixel and average their color values, for example. However, if the renderer is already tracing multiple rays per pixel anyway to obtain an anti-aliased image, then these rays can also be "distributed" among additional dimensions than just the pixel position to sample effects that could not be captured by a single ray. The important bit is that this comes without any additional cost on top of spatial upsampling, since you're already tracing those additional rays anyway. For example, if you shoot multiple rays within your pixel to compute an anti-aliased result, you can get motion blur absolutely for free if you also use a different time value for each ray (or soft shadows if they connect to a different point on the light source, or depth of field if they use a different starting point on the aperture, etc.).

Monte Carlo ray tracing is a term that is slightly ambiguous. In most cases, it refers to rendering techniques that solve the rendering equation, introduced by Jim Kajiya in 1986, using Monte Carlo integration. Practically all modern rendering techniques that solve the rendering equation, such as path tracing, bidirectional path tracing, progressive photon mapping and VCM, can be classified as Monte Carlo ray tracing techniques. The idea of Monte Carlo integration is that we can compute the integral of any function by randomly choosing points in the integration domain and averaging the value of the function at these points. At a high level, in Monte Carlo ray tracing we can use this technique to integrate the amount of light arriving at the camera within a pixel in order to compute the pixel value. For example, a path tracer does this by randomly picking a point within the pixel to shoot the first ray, and then continues to randomly pick a direction to continue on the surface it lands on, and so forth. We could also randomly pick a position on the time axis if we want to do motion blur, or randomly pick a point on the aperture if wanted to do depth of field, or...

If this sounds very similar to distributed ray tracing, that's because it is! We can think of distributed ray tracing as a very informal description of a Monte Carlo algorithm that samples certain effects like soft shadows. Cook's paper lacks the mathematical framework to really reason about it properly, but you could certainly implement distributed ray tracing using a simple Monte Carlo renderer. It's worth noting that distributed ray tracing lacks any description of global illumination effects, which are naturally modeled in the rendering equation (it should be mentioned that Kajiya's paper was published two years after Cook's paper).

You can think of Monte Carlo ray tracing as being a more general version of distributed ray tracing. Monte Carlo ray tracing contains a general mathematical framework that allows you to handle practically any effect, including those mentioned in the distributed ray tracing paper.

These days, "distributed ray tracing" is not really a term that's used to refer to the original algorithm. More often you will hear it in conjunction with "distribution effects", which are simply effects such as motion blur, depth of field or soft shadows that cannot be handled with a single-sample raytracer.


Getting rid of branching to check if a variable is within a range in GLSL I have this GLSL function that I am trying to optimize because it is going to be ran on many pixels of an older devices GPU. There is no room for branching inefficiency. Essentially this function returns a 0 or a 1 based on the variables actualY shouldY and state

float val = 0.0;
if (actualY < shouldY) {
    val = 1.0;
}

if (state >= 20.0 && state < 40.0) { //The equal/not equals is VERY important
  return 1.0 - val;
}
return val;

Usually I am fairly good at removing branching from GLSL code but I really don't know what to do with the range check for the state variable.

This could be done that way:

First condition is float val = 1.0-step(shouldY, ActualY);

Then, the condition: state >= 20.0 && state < 40.0 can be changed to

step(20.0, state) - step(40.0, state). This equals 0.0 if outside of range and 1.0 if inside.

Let a = step(20.0, state) - step(40.0, state)

Then we know that mix function:

genType mix(genType x,
    genType y,
    genType a);

Is $$x * (1 - a) + y * a  = val * (1 - a) + (1 - val) * a  = val - 2*a*val + a$$

So final code is:

float val = 1.0-step(shouldY, ActualY);
float a = step(20.0, state) - step(40.0, state);
return val - 2.0*a*val + a;


In bidirectional path tracing, is a camera subpath with $n$ vertices determined by a fixed number of random numbers? In the Multiplexed Metropolis Light Transport implementation of the book Physically Based Rendering, the proposal samples are generated by the Primary Sample Space Sampler MLTSampler.

I'm not sure if I really understand what the authors mean in the following paragraph:

  In the context of MLT, the resulting sequence of sample requests creates a mapping between components $X$ of and vertices on the camera or light subpath. With the process described above, the components $X_0,\ldots,X_n$ determine the camera subpath (for some $n\in\mathbb N_0$), and the remaining values $X_{n+1},\ldots,X_m$ determine the light subpath. If the camera subpath requires a different number of samples after a perturbation (e.g., because the random walk produced fewer vertices), then there is a shift in the assignment of primary sample space components to the light subpath. This leads to an unintended large-scale modification to the light path.

Does this mean that even for a fixed strategy with $n\in\mathbb N_0$ vertices on the camera subpath, the number of random numbers needed to generate such a subpath may vary? Or do they mean that the shift in the assignment is happening only when we switch to an other strategy?

For a fixed strategy, you can end up consuming a different number of samples depending on your mutation. This can happen for at least two reasons. If your perturbation changes some material along the path to, say, a multi-lobe BSDF, you would need more samples to account for the lobe choice. This would shift everything by the number of extra samples used. If your ray eventually escapes the scene as you are tracing your mutation, or it hits a light source prematurely, you would use fewer samples. In these cases, you'd have to reject this proposal automatically.

One way of mitigating this issue in practice is to separate the two random number vectors for the camera and light subpaths and always mutate all dimensions of the unit hypercube $\mathcal{U}^{o(k)}$, regardless if they are being used or not by the mutation. This doesn't remove the shift caused by BSDF changes (which is unavoidable) but at least you're not spilling your samples between camera and light subpaths.

Note that changing the strategy can also lead to an undesired rippling effect as primary samples will be used to perform a slightly different task (i.e. tracing a different strategy). This can be handled by introducing inverse mappings to preserve the geometry of the path, which is what is done by Reversible Jump MLT.


How do you design the code of a graphics engine to target multiple frameworks I am starting to think about how I can make my app (currently written in Metal) available on older device that dont have Metal as well as Android. This is a predicament because while I could write two separate rendering classes that use the different frameworks it doesn’t teach me anything about how to code for multiple graphics libraries. I can only get away with this because my rendering code is fairly short and has few states and draw calls. I want to learn for the future.

Writing a renderer that supports multiple frameworks especially becomes difficult when thinking of the two libraries I hope to support — OpenGL and Metal — which are quite different in how they expose the GPU.

I am curious how exactly one usually does design their code for apps that can target multiple graphics languages. Here are my theories of what could be done:

Write two different rendering classes keep the data and simulation stuff in its own area and just vary the renderer.
Take high level functions like createTexture or copyTextureOnto and have an if statement checking which language the device supports and have a custom implementation for it.
Coming up with your own graphics objects that are akin to the objects from the framework (such as MTLCommandEncoder or MTLTexture) and use those to build you app and just use the implantation that matches your graphics frameworks. Essentially recode the functions one of your graphics libraries has that you use and just add an if statement to your implementation is called on a OpenGL supporting device.

When you have to code a software to support multiple graphics libraries how do you generally do it? Do you loose any efficiency with the technique you use?

You do it by abstracting away the underlying technology. You know, for example, at a very high level that you'll need to work with images, geometry, and I'm guessing you'll have to write shaders to do your rendering. The textures and geometry can be in the same format for both systems.

So from that, you can design an interface for rendering. You'll probably have a scene of some sort that has the geometry in it. The geometry will likely have the textures applied to it. When rendering the geometry you'll need to use a shader. Those might be good places to start with your abstraction. You might need a scene object that holds all the different objects you want to render. Each object is made up of geometry and the images that will be applied to the geometry. The scene object, the geometry objects and the images can be the same between OpenGL and Metal because they aren't specific to either. (I'm assuming here that the geometry is just a buffer of floating point coordinates, normals, etc. and the image starts out as a buffer of RGBA pixels on the CPU.)

Next you need to come up with a way to render those things on the hardware you're currently running on with the framework you wish to use. So you create an abstract interface. Perhaps you have a Renderer object. It would have methods that allow you to add a piece of geometry with an image to use as the texture. It would allow you to associate a shader with the geometry. And it would have a method to render the geometry to either a texture or the screen.

You then either subclass the Renderer class (assuming you're using something like C++) or write a new class that implements the Renderer protocol (if you're using something like Objective-C or Swift). You have 2 different subclasses or implementations. One that does things using OpenGL and one that does things using Metal.

So you might have an OGLRenderer and a MTLRenderer. The OGLRenderer class will implement the addGeometry() method by creating a Vertex Buffer Object and eventually calling glBufferData() to actually upload the geometry to the GPU. In your MTLRenderer you'll create a MTLBuffer via -newBufferWithLength:options:, and then copying the data into the buffer with memcpy(). And so on for the other functions.

So when writing the main code for your application, you'll code to the Renderer interface without knowing whether the underlying renderer that you're actually going to use is an OpenGL renderer or a Metal renderer. (In fact, you could even make it so they can be switched at run time if that would help in some way.) You can have a factory that either decides at run time which to use based on the OS you're on, or you can decide at compile time by only including the appropriate subclass.


Finding a color perceptually similar to an image I'm working on a program to use randomly-selected images as a desktop background.  Now, not all images are the same shape as a computer monitor.  One idea I had for dealing with this is to set a background color that is perceptually similar to the image.  How would I go about finding this color?

Simple RGB averaging doesn't take into account nonlinearities such as monitor gamma, and doesn't deal with the human vision system.

You could try some form of color quantization algorithm, which generally extract the most dominant N colors. The one I've seen referenced most is modified median cut quantization [.pdf], which is based on median cut quantization [.doc]. The benefit to this kind of algorithm is that instead of simply averaging every color in the image, it extracts and discards other highly prominent colors instead of allowing them to pollute the average.

The concept is that color space (RGB space) is partitioned into 3D axis-aligned rectangular regions (the paper calls them vboxes) and iteratively subdivided by splitting vboxes, attempting to leave half of the pixels on each side of the split. The result is color clusters that should correspond to color clusters in the image. The largest color has a strong likelihood of being "perceptually similar" to the image.

There's a JavaScript implementation and demo of this algorithm called Color Thief.


How does Next Event Estimation work with transformed lights? I am relatively new to path tracing, and I am trying to implement next event estimation. I am following the Monte Carlo integral used to compute the direct illumination from an area light:

$$\frac{1}{N}\sum\limits_{i=1}^{N}f_r(p,\omega_o,\omega_i)L_i(p,\omega_i)Vis(p \leftrightarrow p')cos\theta_i\frac{A_Lcos\theta_o}{||p-p'||^2}$$

(where $p$ is the surface intersection point, $A_L$ is the area of the light, $p'$ is a random point on the surface of the light (uniformly distributed), and $Vis$ returns 1 only if $p$ and $p'$ are mutually visible).

However, I would like to support transformed area lights, that is, lights which have their own model coordinate space separate from the world space (for example, a stretched and rotated sphere).

Samples can easily be generated uniformly in model space (since in model space this light is just a sphere), but obviously then the samples are not uniformly distributed in world space. Does this formula need to be modified to account for the samples being generated uniformly in model space, and what parts need to be computed in model space vs. world space?

Sampling is typically done in local coordinates first and then mapped to world space. You don't have to change the formula for this, but $\mathbf{p}'$ needs to be in world space when you compute the solid-angle-to-area Jacobian determinant. For a sphere for instance, you would have a warping function that maps two canonical uniform random numbers to a 3D point on the unit sphere. Only then would you apply the local-to-world matrix on this sample. If this matrix is a rigid motion (e.g. a combination of translations and/or rotations) with a possible scaling factor, then your samples will remain uniformly distributed in world space. However, if you apply a mapping that distorts areas (e.g. stretching), this will not be the case. It technically still "works" for sampling but some regions of your sphere can be overrepresented. You would have to implement an area-preserving sampling mechanism taking into account this stretching factor.

In practice, it's better to stick with rigid transformations and avoid non area-preserving mappings for analytical shapes. If you truly wish to sample a stretched sphere uniformly, your best bet would be to use an ellipsoid mesh. Then you could sample by area by first choosing a triangle proportional to its area and then picking a point on it by barycentric interpolation. In fact, this is what people have to do to sample area lights of arbitrary shapes.

There is a small discussion at the end pbrt that addresses the possibility of removing analytical shapes from a rendering engine. Analytical geometry primitives are fun because they can teach you stuff like subtended solid angle sampling when you learn GI and importance sampling, but they are limited and your question highlights one such limitation.


Extracting information from EXR Files I am relatively new to computer vision and image processing. I have a single EXR file with 7 channels: 1-3 give me the RGB values, 4-6 give me the surface normals coded as RGB values and 7th channel contains depth information from the camera of the rendered image. I obtained this from the mitsuba renderer using the multi-channel plug-in.

I was wondering if there was any way to view these 7 channels separately. For eg. I would like an image showing only the depth values in grayscale. So far I haven't found a multi-channel EXR file viewer that does this for me. An example of what I'm talking about is shown in the link: https://www.mitsuba-renderer.org/devblog/wp-content/uploads/2014/02/multichannel.jpg

Really looking forward to any help. Thanks!!

I don't know any IDE-based tools that do this but a quick Python script should do the trick. I usually use Thijs Vogels' PyEXR to read the multi-channel EXR. Assuming your depth channel is called distance (which needs to be specified in your Mitsuba XML file under your hdrfilm), you can visualize it with the following code:

import pyexr

fp = pyexr.open('multichannel.exr')
img = fp.get('distance')
pyexr.write('distance.exr', img)


Do I have to have a buffer bound before making a draw call? I have a very simple OpenGL program where the positions are embedded in the GLSL code. The vertex shader looks like this:

#version 440 core

uniform float offsetX;
uniform float offsetY;

out VS_OUT
{
  vec2 tc;
} vs_out;

void main()
{
  const vec2[4] position = vec2[4](vec2(-0.5, -0.5),
                                   vec2(0.5, -0.5),
                                   vec2(-0.5, 0.5),
                                   vec2(0.5, 0.5));

  vs_out.tc = position[gl_VertexID].xy + vec2(0.5);
  vec2 pos = position[gl_VertexID].xy + vec2(offsetX, offsetY);
  gl_Position = vec4(pos, 0.0, 1.0);
}

To run this, to me it seems like I should basically be able to just be able to call glDrawArrays from my application.

However, this is not the case. I my application I have the following code (reused from an earlier example):

// Create buffer
glCreateBuffers(1, &buffer);
glNamedBufferStorage(buffer, sizeof(vertices), vertices, bufferFlags);

// Create vao
glCreateVertexArrays(1, &vao);

// Enable attributes
glEnableVertexArrayAttrib(vao, positionIndex);
glEnableVertexArrayAttrib(vao, texCoordIndex);

// Set up formats for attributes
glVertexArrayAttribFormat(vao, positionIndex, positionSize, GL_FLOAT, GL_FALSE, firstElementOffset);
glVertexArrayAttribFormat(vao, texCoordIndex, texCoordSize, GL_FLOAT, GL_FALSE, positionSize * sizeof(GLfloat));

// Make attributes use binding 0
glVertexArrayAttribBinding(vao, positionIndex, bufferBindingIndex);
glVertexArrayAttribBinding(vao, texCoordIndex, bufferBindingIndex);

// Bind "buffer" to vertex buffer binding point 0
glVertexArrayVertexBuffer(vao, bufferBindingIndex, buffer, firstElementOffset, elementStride);

None of that actually seems necessary because my shaders are now responsible for generating the position and texture coordinates.  However, if I comment out the call to glVertexArrayVertexBuffer my program crashes.

Am I required to have a buffer bound to binding point 0 (even if I do not use any of that buffer's data) before calling glDraw*?

There is nothing in the OpenGL specification that requires you to have enabled attribute arrays in the bound VAO when you render. All of the user-defined vertex attributes will have undefined values, but since you're not reading any of them, that won't be a problem.

What may be a problem is driver bugs. Rendering with an empty VAO is not exactly the most common thing in the world, so it's possible that some drivers won't do the right thing. But the implementation should allow this.

  However, if I comment out the call to glVertexArrayVertexBuffer my program crashes.

Of course it does. You have to not enable the attribute array as well. If you have a vertex attribute enabled, it has to come from somewhere. So there must be a buffer behind it. If you don't want to put a buffer there, then you can't have an attribute array source its data from that buffer.

So while you are not required to have enabled attribute arrays, if you have enabled an array, you are required to provide a buffer for it. If you don't want to use vertex attributes, you have to not use vertex attributes.


Is there a DSA technique for transform feedback? The typical way I see transform feedback being used is:

    glGenBuffers(1, &tbo);
    glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, tbo);
    glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(data), nullptr, GL_DYNAMIC_COPY);

However, new, DSA OpenGL eschews the binding points.  Is there a DSA way to bind a buffer to the transform feedback binding point?

There isn't a DSA way to bind buffers to the feedback buffer bindings. But that's because transform feedbacks are objects, and there is a DSA way to attach buffers to transform feedback objects:

GLuint buffer;
glCreateBuffers(1, &buffer);
//Fill in buffer's data.

GLuint feedback;
glCreateTransformFeedbacks(1, &feedback);
glTransformFeedbackBufferRange(feedback, 0, buffer, offset, size);

You can then bind feedback when you're ready to actually do your feedback operations into those buffers.


How to generate binary gltf array buffers? I'm looking for any way which enables me to quickly generate gltf files including the conversion of plain array buffers (vertex, index, color, etc.) into binary (bgltf, glb, bin) files.

I'm asking because it currently looks like there are only high level applications like Maya, Blender available which can do that or converters to indirectly write glTF from COLLADA.

Are there any way to generate binary gltf array buffers using low level / command line utilities?

Technically any file format where you can dump the entire file into a VBO and then render from that will work for the .bin files. Unfortunately those formats are less well known than they should be.

Then you only need to adjust the bufferview elements to reference the proper subset of the file


Preserving luminance I am writing an application with multiple colored surfaces. I would like to preserve luminance, i.e. a blue surface would appear as bright as a green one, are there tools to help for this?

The usual way of doing this is to work in a color space that has luminance as one of the color components. For example the Y'CbCr color space has a luminance channel (you can think of this as similar to brightness which is a poorly defined term) and 2 chrominance or color channels. There are other color spaces that separate colors in this way, too, such as HSV, HLS, Lab, etc.

There are conversions to go between RGB and these various color spaces. The article linked above shows some of the conversions for going between Y'CbCr and sRGB, for example.

You don't say what type of graphics library you'll be using, so it's hard to give any more detail than what I've given you here. But I've done this in OpenGL, Core Graphics, and others. It shouldn't be too difficult.

Edited to add: I should point out that HSV defines value or "brightness" not as luminance but as the average of red, green, and blue, and as such does not track very will with our intuitive sense of brightness. HLS also suffers from some issues (discontinuities, bad but popular reference implementations) and is generally not recommended by the color scientists that I know.


BC7 texture with alpha has the same size as BC7 without alpha So i've a made a texture. I've saved the RGB one with BC7 compression, then added alpha channel[specular map] with varying levels of grayscale, and saved the file again as RGBA with BC7 compression. The resulting file has the same size as the one without alpha, yet it contain additional information -alpha channel. How it is possible? You can't have cake and eat cake as i understand, so are there any compromises made to ensure same size?

Im using photoshop with intel DDS plugin.

BC7 always effectively encodes 4 channels. That's part of the nature of the format. Turning on alpha means that the compressor will read and use the alpha value in your source image, but that's all.
All BC7 compressed images of a given dimension have the same size, since BC7 compresses each 4x4 group of texels into 128-bits. But that doesn't mean they have the same quality.
BC7 is an adaptive encoding format. While each block has a fixed size (both spatially and bit-wise), each block stores how many channels that block actually compresses and the way that they correlate with one another. The specifics are complex, but the general upside is that the compressor figures out on a per-block basis what manner of compression works best for a particular block. If the compressor can look at a block and see that the alpha for all texels is 1.0, then it can spend more bits of the 128 bits on the colors and fewer on the alpha.
As such, a texture "without alpha" is exactly like a texture with alpha where every texel has an alpha of 1. These blocks will spend the majority of their bits on the non-alpha parts of the texels, only wasting a few bits on a "mode" field that lets the decompressor know that the alpha is a constant 1.0.
This also means that, if your texture has a varying alpha, but parts of it have a constant alpha, BC7 can encode these constant alpha areas with fewer bits, so that more bits can be spent on improved color encoding.
So you shouldn't feel that there is a problem because the two compression switches came out with the same number of bytes.


What is stereo about multi-view stereo? What 3D scene reconstruction methods does the term "multi-view stereo" encompass? Is it only used for methods that apply binocular stereo algorithms (taking 2 views as input) in a pairwise manner? Or only methods based on disparity estimation? If not why is the term "stereo" used?

Multi-view stereo (MVS) is the general term
given to a group of techniques that use stereo correspondence as their
main cue and use more than two images.

A quote from 'Multi-View Stereo: A Tutorial' by Yasutaka Furukawa and Carlos Hernández.
So to paraphrase: We have a set of images that is larger than two, and use them in a pairwise manner by applying techniques that finde stereo correspondences to reconstruct the object shown in them.
If you want to know more about MVS algorithms that paper I linked seems to be pretty good and at least Furukawa is a name that I know and have read papers from, so he seems to know the topic.


Animated rainbow distortion wave effect https://foundation.app/mg/20210227-3lau-makes-history-1790
The link above shows a video animation that has a rainbow wave distortion effect applied to it, that ripples across the video. how, and in which software, can this effect be applied to a video? or a step-by-step guess on how to replicate the effect

The effect is called chromatic aberration; the way it’s usually done in games, and what’s being done there, is by reading the red / green / blue channels of an image at different offset positions. As with your other question (you’re looking to get into the NFT market, I’m guessing?), there are most likely plugins for After Effects that will let you create something along these lines, but the original author probably used a tool like Processing or Shadertoy.


Roughness Value of (Close to) Zero in Physically Based Rendering In my Direct Light Physically Based Renderer, when I set the roughness too low (ie. 0.0 or close) the specular reflection doesn't show, not even at high resolutions and at perfect angle with the camera / light position.

I'm using Cook-Torrance's BRDF with Schlick Smith GGX Geometry Function, Shlick Fresnel Function and Trowbridge-Reitz GGX Normal Distribution Function.

I suspect the whole reason behind this is because when the roughness is 0.0, the result of the Normal Distribution Function is also 0.0 and, consequently, the specular part will also be null.

// Trowbridge-Reitz GGX Normal Distribution Function
float NormalDistributionFunction(vec3 N, vec3 H, float roughness) {
    float a = roughness * roughness;
    float aSquare = a * a;
    float NdotH = max(dot(N, H), 0.0);
    float NdotHSquare = NdotH * NdotH;

    float numerator = aSquare;
    float denominator = (NdotHSquare * (aSquare - 1.0) + 1.0);
    denominator = PI * denominator * denominator;

    return numerator / denominator;
}

// Cook-Torrance Bidirectional Reflective Distribution Function
vec3 BRDF(vec3 L, vec3 V, vec3 N, vec3 radiance, vec4 albedo, float metallic, float roughness, vec3 F0) {
    vec3 H = normalize (V + L);

    float D = NormalDistributionFunction(N, H, roughness);
    float G = GeometryFunction(N, V, L, roughness);
    vec3  F = FresnelFunction(max(dot(H, V), 0.0), F0);

    vec3 numerator = D * G * F;
    float denominator = 4 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0) + 0.001; // Prevent division by zero.
    vec3 specular = numerator / denominator;

    vec3 kS = F;
    vec3 kD = vec3(1.0) - kS;
    kD *= 1.0 - metallic;

    float NdotL = max(dot(N, L), 0.0);

    vec3 color = (kD * albedo.rgb / PI + specular) * radiance * NdotL;
    return color;
}

Does this physically make sense?
The only workaround I see is either not using a perfect mirror value of 0.0 roughness or always clamp the minimum value to something like 0.04.

Yes, I think it's expected that setting roughness = 0, combined with using point lights for illumination, leads to no visible specular highlight. The size of the highlight is infinitesimally small, so the sample points (e.g. pixel centers) almost surely miss it. The math breaks down as well, as the reflectance would become infinite on the zero-sized highlight (a delta function).

Clamping roughness to a minimum seems like a physically reasonable thing to do. 0.04 feels like too large a minimum, though; I might pick 0.001 or 0.0001 or something like that.

If you use area lights, then a perfect mirror surface (roughness = 0) could still work and would show the sharp reflected image of the area light. This would probably still require special-casing the perfect-mirror case in shading code, to avoid the problems with infinities.


How to calculate attenuation and radiance in PBR? (point and directional lights) I would like implement physically based rendering, following this tutorial

I was able to find a list of light sources ordered by lumens, but I have no idea how to use it in the calculations.

float attenuation = 1.0 / (distance * distance);
vec3 radiance = lightColor * attenuation;

What should the lightColor be, if the light source is a 60W lightbulb (780 lm) and in my scene one unit is one cm?

How should I define the radiance, if I have a directional light, for example the sun?

How should I define the radiance, if I have a directional light, for example the sun?

The radiance in physics has different definitions in different books. I will use the definition with irradiance and radiant flux here.

Imagine photons having some energy $Q$. Your radiant flux $\Phi$ is the amount of energy $Q$ (and therefore the amount of photons) per unit time $t$. To get the energy for an instant (an infinitesimally short time), you use the change ($\Delta$) of energy over the change of time for $\lim_{t\rightarrow0}$ i.e.

$$\Phi = \lim_{t\rightarrow0} \frac{\Delta Q}{ \Delta t} = \frac{dQ}{dt}$$

Energy is measured in Joules and time in seconds, therefore radiant flux is measured in $\frac{J}{s}$.

This however doesn't say anything about the surface you're measuring the energy at, but if you want to light an object, that needs to be taken into account.
Therefore, you define irradiance $E$ as your radiant flux per area $A$ (note that irradiance usually means energy arriving at an area, whereas radiosity is energy leaving the area, but is otherwise defined exactly the same way). Since some integrations later on are easier to do with infinitesimally small area patches, we go that route again, but I will not rewrite the limes stuff all the time.

$$E = \frac{d\Phi}{dA}$$

Note that it is assumed, that the photons' traveling direction is assumed to be perpendicular to the surface.
Irradiance is thus measured in $\frac{J}{sm^2}$.

To understand radiance, you need to understand solid angles. I will just assume that you do, otherwise read up on it, this is really an important concept for physically based lighting.

The problem with irradiance is, that you cannot take into consideration any directionality of the light. The directionality can be expressed through solid angles $\omega$, where an infinitesimally small solid angle $d\omega$ can be seen as a vector.

Imagine that you have a sheet of paper parallel to another sheet of paper, one emitting and one receiving light, both equal in size. You can express all you need with irradiance. Now let the emitting sheet of paper transform into your light bulb centered at where the emitting sheet of paper was before. All of a sudden, it makes a difference, if you measure the light at the corners of the receiving sheet of paper or at its center.

Therefore, to take directionality into account, you define radiance $L$ as the irradiance per solid angle of the light. $\omega$ is the solid angle and we want to use the infinitessimally small one again, thus $d\omega$.
$$L = \frac{dE}{d\omega}$$
Thus your radiance is measured in $\frac{J}{sm^2sr}$ where sr is the solid angle unit steradians and really is dimensionles.

Looking at the definitions of Watts it's $W = \frac{J}{s}$ , therefore radiance measurement can be seen as $\frac{W}{m^2sr}$.

Edit 04th of August 2017:
The radiance in the end is exactly what you calculate as a pixel's color, it is what you see. In the real world, it is wave length dependend, but of course in computer graphics it is an RGB color vector. Therefore, you don't define radiance, you calculate it.

  What should the lightColor be, if the light source is a 60W lightbulb (780 lm) and in my scene one unit is one cm?

Light usually uses different wave lengths lambda which determine the color of the light. For example, imagine a photon of red light, i.e. $\lambda=700nm$ , then it has the energy of $\frac{hc}{\lambda}$ where $h$ is Planck's constant and $c$ is the speed of light, leading to about $2.838\times10^{-19}J$ for this red photon.

If your light bulb "uses" just one single wave length and is a $60W=60\frac{J}{s}$ light bulb, then you can calculate the energy, radiant flux, irradiance and finally radiance... If you know the exact spectral emission, you can also calculate this.
However, that is probably not really what you are looking for.

Edited 04th of August 2017:
Therefore, your (or rather the tutorials code) to calculate radiance is an oversimplified way of modeling the lightsource.  It does not take into account the power of the light source directly, it is just modelled by a color vector.

What the tutorial is asking you to do is to think of the color you want your light to be, and write down the RGB value for it. If your light is just white, use an RGB value of (1,1,1), try it in your scene and if you then think it's too bright, lower the values until you're satisfied (or increase them, if it's not bright enough).

Edited 04th of August 2017:
If you want to use the physically based light bulb, then you will need to take more into account and I'd really advice you to read up on this.
A good book for this is Physically Based Rendering (by Matt Pharr et al.).
As that is expensive and takes a long time to read, you can also try to get along with some of the Physically Based Shading course materials of previous years, to be found on the Selfshadow Blog. Especially, there is some explanation on Sebastien Lagarde's Moving Frostbite to Physically Based Rendering

On a side note, the sun is usually modeled as being so distant to the receiver of the light, that you don't take attenuation into account. Thus you would just multiply by the light color (or set the attenuation to 1).


How fast should I expect to render the silhouette of a 20k triangle model? Using VTK 7.0 I have found that rendering a 20k triangle STL model takes approximately 17ms on my Nvidia GTX970. However, I am only interested in the silhouette of this model (like the image below) and was wondering if: a) such speeds are reasonable for this model size, and b) since I am not really interested in a full render, is there a much faster way to compute just that silhouette? I considered a ray tracing approach where I just compute whether or not each pixel hits the model, but since I am only interested in speed I do not know if this is a good route to pursue. As a side note, these questions need not be specific to VTK - I am really just conerned with the fastest way to utilize a GPU to compute a silhouette (suggestions algorithms, theory, or libraries are all all welcome!) and what reasonable times I can expect for such model sizes.

OpenGL (scanline rendering) is always going to be way faster than ray tracing.

Ray tracing computes pixels one by one using physics (at least a good 90% of the time it's going to be real physics). Although some of it can now be done with a GPU, it is not really helping as much as one would expect. Calculating speculative lightning is not something you can easily do in parallel (ray 1 will bounce from object A to object B, ray 2 will bounce from object A to object C... you can't parallelize the computations on B and C.) The GPU helps with the matrix math, though.

In comparison, OpenGL is a total fake in comparison. It renders triangles really fast with shades coming from textures and fast gradient computations from your various light sources.


Creating 3d model building notation using ASCII This question is a little different to your typical questions but I think this is the best community to ask this in.

I've been interested in lego technic for most my life and have been trying to come up with a way to quickly and easily represent axles, pins, axle holes and pin holes on computers universally. I decided to  use plain ASCII since it is quicker and works on mobile devices and on desktops.

I made a good representation of the pins, axles and holes in one axis but the problem is: ASCII is 2D but lego technic is 3D, so rotated or flipped lego parts are very hard to represent and if the entire building axis changes then so do the part orientations.

Is there some way I can do this?

Here is my syntax:

facing the front:

+ axle hole
× axle
o pin hole
. pin

facing the side:

< axle hole
= axle
Z pin hole
- pin

facing the side rotated 90 degrees:

V axle hole
! axle
N pin hole
| pin

if a symbol is underlined it means it is half thickness, if not it is worth 1L

As you’ve found, it’s hard to use a two-dimensional format, even from multiple viewpoints, to represent a 3D structure that’s not axis-aligned. I’m not sure I have a useful suggestion there—there’s a reason most 3D file formats support specifying translation/rotation/scaling of individual parts.

A different direction you might try would be using the existing work in the LDraw project; their file format is technically ASCII, and though it’s closer to a standard 3D format in that the fundamental parts (like studs) are built out of lists of vertices / triangles / etc., the higher-level pieces (bricks, plates, etc.) are built out of references to the fundamental ones, which sounds like it’s roughly along the lines of what you’re after. There’s an assortment of third-party design tools that provide GUIs on top of the LDraw parts library; of those, I’m partial to Bricksmith.


3D projection that increases objects' size as they become more distant tl;dr Is there a name for a type of (non-physical) projection that causes objects to become larger the farther they are from a camera?

With a fisheye projection, an object twice as far from the camera is less than half the size on screen. (I think; my understanding of fisheye math is fuzzy. I gather there are various projections/mapping functions.) There is massive foreshortening, objects shrink very quickly as they move away.
With a rectilinear projection, an object twice as far from the camera is always half the size on screen, regardless of FoV. This is how trigonometry works. Infinitely-far objects have zero size.

With an orthographic projection, an object twice as far from the camera is always the same size on screen. There is no foreshortening. Infinitely-far objects have the same size.
Now, go one step farther. I want negative foreshortening. I want to see an object get bigger the farther away it gets. Infinitely-far objects have infinite size.

After a quick google of 'Inverted perspective' I found out that you have five different names for it; Reverse perspective, inverse perspective, inverted perspective, divergent perspective and Byzantine perspective. https://en.wikipedia.org/wiki/Reverse_perspective

I think that if you want to use it in a render engine using a projection matrix, in the perspective divide, you use multiply by w instead of divide. This is because in a perspective projection, the divide by w is what actually gives the perspective. In a orthographic projection w is always 1, meaning that there is no actual perspective.

For a ray tracer you probably just need to scale the image plane up of course, but probably instead of having the origin of the ray to be the center of the camera, you have some kind of second image plane that is larger than the actual image plane. If both are the same size, the rays are straight and you have an orthographic projection, if the actual image plane is smaller then you have your Reverse perspective.

Quick extra note: If you have proper lenses, you might be able to get this effect in real life. Yes, you would need to have a lens that is a few meters in diameter, but I do not think it is impossible! :P

I hope this will help you and that I have not made any mistakes. Good luck with whatever you are doing!


Gradient descent (Not ML) on arbitrary meshes So I am doing a gradient descent like algorithm on the surface of a mesh and I just noticed something:

The above is the geodesic gradient (the distance to a single vertex)
Look at where the ear connects with the head and notice how the discretized gradient behaves.
It's almost pointing in opposite directions. This is not however an error, this occurs because the gradient at that region is fairly "turbulent".
My algorithm is fairly simple, grab a point in a triangle, compute its negative gradient, intersect the gradient with the triangle, move there, switch active triangle to the neighbour, repeat.
In other words you just follow the gradient down towards the source.
However, when I hit those turbulent regions, my algorithm gets stuck, because the gradient becomes essentially 0 and numerical errors prevent it from intersecting any of the edges of the triangle.
In pictures:

The green points are the path taken by my gradient descent algorithm. The cyan ones are the centres of the faces of the triangles and the yellow arrow is the gradient at the last point.
Notice that this result is correct.
However, at the ears:

As you can see the algorithm stops because the gradient is borderline 0.
And worse there are regions in the ears where the turbulence makes the gradient bounce and start travelling in the opposite direction.
Does anyone have tips on how I could handle the gradient in these regions?

Maybe you can find a heuristic to detect when it gets stuck (e.g. gradient magnitude is too small, or it stays on the same triangle or returns to a recently visited triangle too many times in a row, or it hasn't moved at least X distance over the last N steps, etc) and just take a random step in some direction, e.g. to some randomly chosen neighboring triangle? That might help shake it out of the difficult region and get back to smooth descent.
For an even lower-tech solution, if you don't mind some randomness you could just inject occasional random moves all the time (without attempting to detect whether it's stuck). Kind of like stochastic gradient descent in ML.
If the gradient you're following is a geodesic distance, I think it can have saddle points, but not local minima (except for the global minimum), is that right? If that's a constraint you can rely on, you could try to use a second-order method, finding an estimate of the local Hessian and looking for eigenvectors with negative eigenvalues, which should be directions of principal curvature that will accelerate the gradient descent, and in particular, will pull you out of saddle points. I'm sure there must be a literature on such methods although I don't know much about it.


How to describe a position of a point w.r.t the position and orientation of 3 other points Is it possible to describe a position of a point $A$ (in 3D) w.r.t. the position and orientation of 3 other points? If so, how?

FYI, the 3 other points lie on a plane, whereas the point $A$ is not on the plane.

Just to elaborate, initially I have the info for all four points. My goal is to find where point $A$ is when the other three points changing position and orientation.

FYI, the 3 other points lie on a plane

Of course they do. Any set of three points defines a plane (except in the degenerate case joojaa mentions, where they lie on many planes). If the points are $p$, $q$, and $r$, then $(q - p) \wedge (r - p)$ is the normal to the plane; call it $n$.

This plane defines a co-ordinate system. If you make it the XY plane, then $z = a \dot\ n$. You can also project $a$ onto the plane to get the other two co-ordinates: $x = (a - p) \dot\ (q - p)$ and $y = (a - p) \dot\ (r - p)$.

Note that the co-ordinate system I've described here is pretty rubbish: it isn't even orthogonal. It's good enough to uniquely identify a point, as long as you're careful about all the signs.

But if you want an orthonormal basis, you can construct it from this one. First, instead of $q - p$ and $r - p$, normalize those vectors. Then $n$ will also have length 1, and the $x$ axis will also be normal. The last problem is the $y$ axis, which is not orthogonal to the $x$ axis. You can get a better $y$ axis by crossing the other two and normalizing, and while you're doing that you might as well also choose the order to ensure the basis is right-handed. Your three basis vectors are as follows:

$$
\begin{eqnarray}
\hat{z} & = & \frac{n}{|n|} \\
\hat{x} & = & \frac{q - p}{|q - p|} \\
\hat{y} & = & \hat{z} \wedge \hat{x}
\end{eqnarray}
$$


Hodge Decomposition in fluid simulations I have just started implementing a fluid simulator based on the navier stokes equation.
I am following Jos Stam's paper to do so.
In this paper, it says that the velocity field must be mass conserving. Which I understand as, the velocity that flows into a cell should be the same the velocity that flows out.
To get this mass conserving field, the hodge decomposition is used, and the text says:

"every vector field is the sum of a mass conserving field and a gradient field."
Velocity field = mass conserving field + gradient field

1) Is there a intuitive way to understand why this statement above is true? Maybe I have to read more on Hodge decomposition to understand this.

2) The text also says that the gradient field can be computed by solving the poisson equation, Is there a simple explantion of why the poisson equation can be used to approximate this field? I'm wondering what else could be used instead.

Could you point me to some resources that help understand my two questions intuitively, before delving into all the math?

Suppose I have a fluid which, like water, is incompressible; that is, its density is constant. I can find out how this fluid is flowing; let's say I inject dye at various points and follow how the dye particles move. I can estimate a velocity at each point, a velocity field $\mathbf{w}$. But water is incompressible; this means that the true velocity field $\mathbf{u}$ has to be mass-conserving. I want to "correct" my estimate $\mathbf{w}$ to find the closest mass-conserving velocity field.

The local accumulation or depletion of the fluid is computed with the divergence of the vector field, $\operatorname{div}\mathbf{w}$. (Stam writes the divergence of $\mathbf{w}$ as $\nabla\cdot\mathbf{w}$.) The divergence is a derivative, which is important here because that means it's linear; the divergence of the sum of two vector fields is the sum of their divergences:
$$ \operatorname{div}(\mathbf{u} + \mathbf{v}) = \operatorname{div}\mathbf{u} + \operatorname{div}\mathbf{v}. $$
We want to find a mass-conserving field; that is, we want to find a field with zero divergence. That means that we want to construct a field $\mathbf{v}$ with the same divergence as $\mathbf{w}$; then
$$ \operatorname{div}\mathbf{w} - \operatorname{div}\mathbf{v} = \operatorname{div}(\mathbf{w} - \mathbf{v}) = 0 $$
so we can get our mass-conserving field $\mathbf{u} = \mathbf{w} - \mathbf{v}$.

The only question is how we construct a field with a given divergence. For reasons I'll explain a few paragraphs down, we say that $\mathbf{v}$ is the gradient of some scalar field $q$, $\mathbf{v} = \operatorname{grad}q$. (Stam writes this as $\nabla q$.) Then we have
$$ \operatorname{div}\mathbf{w} = \operatorname{div}\mathbf{v} =
\operatorname{div}\operatorname{grad}q.$$
It's worth looking at what this says. The divergence of a vector field is a scalar field; at each point, it gives the local accumulation or depletion of the fluid. Both the divergence and the gradient are derivatives (which is why they can also both be written with $\nabla$). The equation is thus saying that the scalar field (the divergence of $\mathbf{w}$) is a particular second derivative of the scalar field $q$. This derivative is called the Laplacian (Stam writes it as $\nabla^2 q$). The differential equation relating scalar fields $q$ and $a$
$$ \operatorname{div}\mathrm{grad}\ q = a $$
is the Poisson equation. It's not so much that you use it to estimate $q$ as that it's the actual definition of $q$.

So, to "correct" our estimate $\mathbf{w}$, we can compute its divergence (a scalar field)
$$ f = \operatorname{div}\mathbf{w}, $$
solve the Poisson equation to find the scalar field $q$
$$ \operatorname{div}\operatorname{grad} q = f, $$
then subtract $\operatorname{grad}q$ from $\mathbf{w}$ to find our mass-conserving velocity field
$$ \mathbf{u} = \mathbf{w} - \operatorname{grad}q. $$

Above we just assumed that $\mathbf{v} = \operatorname{grad}q$ for some $q$. What we actually want is to find a field $\mathbf{v}$ that is in some sense the "smallest" field with the given divergence, so we can find the "closest" mass-conserving field $\mathbf{u} = \mathbf{w} - \mathbf{v}$; here I'll explain how the gradient of a scalar field satisfies this requirement.

We have a fixed amount of fluid moving through our space.
If our flow is mass-conserving, then we have a conserved amount of fluid, without local accumulation or depletion. If we have any motion at all, then, the fluid must move in cycles. In the same way as we measure the local accumulation with the divergence operator, we can measure the local cyclic behaviour of the flow by using another vector operator, the curl (which can be written $\nabla\times\mathbf{v}$). The curl at a point gives, broadly speaking, the axis about which the flow is circling near that point.

Now, consider the gradient of a scalar field, $\operatorname{grad} q$. (For instance, $q(x,y) = \sin x \cos y$.) The potential can be drawn as a height field:

Then the gradient of this field puts at each point a vector pointing in the steepest uphill direction:

But since you're always going "uphill" as quickly as you can, I think it's clear that there's no circulation in this vector field! In fact, for any scalar potential $q$,
$$ \operatorname{curl}\operatorname{grad}q = 0 ! $$

There's also a second similar identity: $\operatorname{div}\operatorname{curl}\mathbf{v} = 0$; unfortunately, I can't think of a good intuition for that one. (But look at this Math.SX answer for a more mathematical explanation.) We can use these two identities to explicitly write the Hodge decomposition: $\mathbf{w} = \mathbf{v} + \mathbf{u}$, where $\mathbf{v}$ has no curl, and $\mathbf{u}$ has no divergence, or
$$ \mathbf{w} = \operatorname{grad}q + \operatorname{curl}\mathbf{\nu},¹ $$
for some scalar field $q$ and vector field $\mathbf{\nu}$.

¹The Hodge decomposition is actually more complicated if your space isn't simple, i.e. finite and ball-like; on more complicated spaces, like say the surface of a torus, we have curl-free fields which aren't the gradient of anything, and divergence-free fields which aren't the curl of anything. For most fluid modelling in CG, though, this isn't usually an issue.


How is anisotropic filtering typically implemented in modern GPUs? Anisotropic filtering "retains the sharpness of a texture normally lost by MIP map texture's attempts to avoid aliasing". The Wikipedia article gives hints about how it can be implemented ("probe the texture (...) for any orientation of anisotropy"), but it does't read very clear to me.

There seem to be various implementations, as suggested by the tests illustrated in the notes of the presentation Approximate Models For Physically Based Rendering:

What are the concrete computations performed by (modern) GPUs to choose the correct MIP level when using anisotropic filtering?

The texture filtering hardware takes several samples of the various mipmap levels (the maximum amount of samples is indicated by the anisotropic filtering level, though the exact amount of samples taken in a given filtering operation will depend on the proportion between the derivatives on the fragment.) If you project the cone viewing a surface at an oblique angle onto the texture space, it will result in approximately an oval shaped projection, which is more elongated for more oblique angles. Extra samples are taken along the axis of this oval (from the correct mip levels, to take advantage of the pre-filtering they offer) and combined to give a sharper texture sample.

Another technique know as rip-mapping (mentioned in the Wikipedia article on Mipmapping), which is not commonly found in contemporary GPUs, uses prefiltering of textures. In contrast to mips, the texture is not scaled down uniformly but using various height-width-ratios (up to a ratio dependent on your chosen anisotropic filtering level). The variant - or maybe two variants if using trilinear filtering - of the texture is then chosen based on the angle of the surface to minimize distortion. Pixel values are fetched using default filtering techniques (bilinear or trilinear). Rip-maps are not used in any hardware that I know of due to their prohibitive size: while mipmaps use additional 33% storage, ripmaps use 300%. This can be verified by noting that texture usage requirements don't increase when using AF, rather, only bandwidth does.

For futher reading, you might want to take a look at the specification for the EXT_texture_filter_anisotropic OpenGL extension. It details the formulas used to calculate samples and how to combine them when using anisotropic filtering.


Infinitely long 3D model Let's say that I want to render something like Dimmadome's hat, a hat which has the height of infinity.

A quick answer to this would be to place the top side of the hat high enough for the crown(cylinder) to be cropped(like y=9999999...) half way in the view. I don't like this idea. So what I came up with is using IEEE 754 infinity in vertices.

(-0.5, INF, -0.5)
(0.5, INF, -0.5)
(0.5, INF, 0.5)
(-0.5, INF, 0.5)

(assuming the crown is a cube)

The problem is that after multiplying with the transform matrix, the vertices end up being all (INF, INF, INF), making them unrenderable. I just wrote this to give you an idea.

Is there any technique that can be used to achieve this? rather than using huge number? I wonder how they implemented this.

You can render with a raymarcher and using distance fields. For the hat you would define the center and radius of the cylinder, and would draw any march which falls within such circle, no matter what "height" you are in, it will be infinite. You can also add a restriction, like y > 0 to put a beginning to your hat.


Per Vertex Computation in OpenGL Tesselation I try to implement a position based cloth simulation using hardware tesselation.
This means I want to just upload a control quad to the graphics card and then use tesselation and geometry shading to create the nodes in the cloth.

This idea follows the paper:

Huynh, David, "Cloth simulation using hardware tessellation" (2011). Thesis. Rochester Institute of Technology
http://scholarworks.rit.edu/theses/265/

I know how to use tesselation to create the simulated points.
What I don't know is how to store the computated information into a framebuffer.

The geometry and also the tesselation evaluation shaders have informations needed for the per-vertex computations. But can they directly write into the framebuffer?

The fragment-shader I know can write to the framebuffer, but my information would be interpolated and I would no longer know what to write at which position.

Based on the comment of "ratchet freak" I researched Transform Feedback Buffers and solved my problem that way.

I now generate the simulated points on the CPU and put them into a VertexBufferObject.
I generate a second VBO for the points (along with some others for velocity).
The connectivity of the cloth is given as an vertex-attribute in ivec4.

Using the transform feedback buffers and a Double-buffering trick using the two VBOs i can always read from the last step (using the connectivity info) and write to another buffer. This is in order to solve problems with concurrency.

The calculations are done in the vertex-shader as GL_POINTS.
Binding the output of the first shader into another regular shader using additional index-buffer to generate triangles I can without trouble render the cloth any way I want.

This idea follows the transform feedback buffer example made in the book "OpenGL Superbible" http://www.openglsuperbible.com/