Manually fetching 8 neighboring texels from 3D texture greatly decreases performance I'm implementing manual interpolation between texels in a 3D texture to be able to discard some of them when needed. Compared to hardware interpolation, this process takes a lot of time. If I simply leverage hardware interpolation using texture function, rendering takes ~5ms, but with manual fetch using texelFetch it rises to ~13ms (using texture to fetch 8 texels manually increases frame time even further - to ~35ms). The multiplication/summing part of the manual lerp does't matter much - I've tried fetching same texel manually 8 times and the performance is close to hardware interpolation. I thought fetching neighboring texels should give me good cache behavior, but maybe that only applies to 2D textures because neighboring layers of 3D tex are not so cache friendly? Don't know what to think here.. It would be nice if there was some way to use hardware interpolation but discard some texels from the process. The absence of a textureGather function taking a 3D texture also makes me think I'm missing something here.

What's probably happening is that you're doing indirect texture fetches. Are you doing something like this:

vec4 a = texture3D(sampler, coord);
vec4 b = texture3D(sampler, coord + vec4(0, 0, 1));
vec4 c = texture3D(sampler, coord + vec4(0, 1, 0));
vec4 d = texture4D(sampler, coord + vec4(1, 0, 0));
//...etc.

If so, that can slow you down. What you can do instead is to pass the texture coordinates for each sampler call into your vertex shader from your CPU code. You'd set it up as if you were doing multi-texturing, but all the texture units would point to the same texture, just sampled at different coordinates.

Taking the 2D case, instead of passing in a single texture coordinate like this:

float2 texCoords[] = {
    { 0, 0 },
    { width, 0 },
    { width, height },
    { 0, height }
};

You'd pass in 4 of them:

float2 texCoords[] = {
    // texture 0 coords
    { 0, 0 },
    { width, 0 },
    { width, height },
    { 0, height },

    // texture 1 coords
    { 1, 0 },
    { width + 1, 0 },
    { width + 1, height },
    { 1, height },

    // Texture 2 coords
    { 0, 1 },
    { width, 1 },
    { width, height + 1 },
    { 0, height + 1 },

    // Texture 3 coords
    { 1, 1 },
    { width + 1, 1 },
    { width + 1, height + 1 },
    { 1, height + 1 }
};

In your fragment shader, you'd do something like this:

vec4 pixel0 = texture2D(sampler0, coord0);
vec4 pixel1 = texture2D(sampler1, coord1);
vec4 pixel2 = texture2D(sampler2, coord2);
vec4 pixel3 = texture2D(sampler3, coord3);

Now you have the 4 pixels needed for interpolation, but there was no fragment shader math done to get the texture coords, so there are no indirect look-ups which are slower than direct look-ups.


How to implement a trackball in OpenGL? After so much reading about transformations it is time to implement a trackball for my app.
I understand I have to create a vector from the origin to where the mouse is clicked and then another from the origin to where the mouse is released.

My question is, do I have to transfor the (x,y) pixel coords to world-coords or should I just do everything in image space (considering image space is the 2D projection of the scene measured in pixels)?

EDIT

Richie Sams' answer is a very good one. However, I think I'm following a slightly different approach, please correct me if I'm wrong or I'm misunderstanding something.

In my application I have a SimplePerspectiveCamera class that receives the position of the camera, the position of the target we are looking at, the up vector, the fovy, aspectRatio, near and far distances.

With those I build my View and Projection matrices. Now, If I want to zoom in/out I update the field of view and update my projection matrix. If I want to pan I move the position of the camera and look at by the delta the mouse produces.

Finally, for rotations I can use either angle-axis transformation or quaternions. For this, I save the pixel-coords where the mouse was pressed and then when the mouse moves I also save the pixel-coords.

For each pair of coords I can compute the Z-value given the formula for a sphere, i.e., sqrt(1-x^2-y^2), then compute to vectors that go from the target to PointMousePressed and from target to PointMouseMoved, do cross product to get the axis of rotation and use any method to compute the new camera position.

However, my biggest doubt is that the (x,y,z) values are given in pixel-coords, and when computing the vectors I'm using target which is a point in world-coords. Isn't this mixing of coordinate system affecting the result of the rotation I'm trying to do?

Assuming you mean a camera that rotates based on mouse movement:

One way to implement it is to keep track of the camera position and its rotation in space. Spherical coordinates happen to be convenient for this, since you can represent the angles directly.

float m_theta;
float m_phi;
float m_radius;

float3 m_target;

The camera is located at P which is defined by m_theta, m_phi, and m_radius. We can rotate and move freely wherever we want by changing those three values. However, we always look at, and rotate around, m_target. m_target is the local origin of the sphere. However, we are free to move this origin wherever we want in world space.

There are three main camera functions:

void Rotate(float dTheta, float dPhi);
void Zoom(float distance);
void Pan(float dx, float dy);

In their simplest forms, Rotate() and Zoom() are trivial. The just modify m_theta, m_phi, and m_radius respectively:

void Camera::Rotate(float dTheta, float dPhi) {
    m_theta += dTheta;
    m_phi += dPhi;
}

void Camera::Zoom(float distance) {
    m_radius -= distance;
}

Panning is a bit more complicated. A camera pan is defined as moving the camera to the left/right and/or up/down respective to the current camera view. The easiest way we can accomplish this is to convert our current camera view from spherical coordinates to cartesian coordinates. This will give us an up and right vectors.

void Camera::Pan(float dx, float dy) {
    float3 look = normalize(ToCartesian());
    float3 worldUp = float3(0.0f, 1.0f, 0.0f, 0.0f);

    float3 right = cross(look, worldUp);
    float3 up = cross(look, right);

    m_target = m_target + (right * dx) + (up * dy);
}

inline float3 ToCartesian() {
    float x = m_radius * sinf(m_phi) * sinf(m_theta);
    float y = m_radius * cosf(m_phi);
    float z = m_radius * sinf(m_phi) * cosf(m_theta);
    float w = 1.0f;

    return float3(x, y, z, w);
}

So, first, we convert our spherical coordinate system to cartesian to get our look vector. Next, we do the vector cross product with the world up vector, in order to get a right vector. This is a vector that points directly right of the camera view. Lastly, we do another vector cross product to get the camera up vector.

To finish the pan, we move m_target along the up and right vectors.

One question you might be asking is: Why convert between cartesian and spherical all the time (you will also have to convert in order to create the View matrix).

Good question. I too had this question and tried to exclusively use cartesian. You end up with problems with rotations. Since floating point operations are not exactly precise, multiple rotations end up accumulating errors, which corresponded to the camera slowly, and unintentionally rolling.

So, in the end, I stuck with spherical coordinates. In order to counter the extra calculations, I ended up caching the view matrix, and only calculate it when the camera moves.

The last step is to use this Camera class. Just call the appropriate member function inside your app's MouseDown/Up/Scroll functions:

void MouseDown(WPARAM buttonState, int x, int y) {
    m_mouseLastPos.x = x;
    m_mouseLastPos.y = y;

    SetCapture(m_hwnd);
}

void MouseUp(WPARAM buttonState, int x, int y) {
    ReleaseCapture();
}

void MouseMove(WPARAM buttonState, int x, int y) {
    if ((buttonState & MK_LBUTTON) != 0) {
        if (GetKeyState(VK_MENU) & 0x8000) {
            // Calculate the new phi and theta based on mouse position relative to where the user clicked
            float dPhi = ((float)(m_mouseLastPos.y - y) / 300);
            float dTheta = ((float)(m_mouseLastPos.x - x) / 300);

            m_camera.Rotate(-dTheta, dPhi);
        }
    } else if ((buttonState & MK_MBUTTON) != 0) {
        if (GetKeyState(VK_MENU) & 0x8000) {
            float dx = ((float)(m_mouseLastPos.x - x));
            float dy = ((float)(m_mouseLastPos.y - y));

            m_camera.Pan(-dx * m_cameraPanFactor, dy * m_cameraPanFactor);
        }
    }

    m_mouseLastPos.x = x;
    m_mouseLastPos.y = y;
}

void MouseWheel(int zDelta) {
    // Make each wheel dedent correspond to a size based on the scene
    m_camera.Zoom((float)zDelta * m_cameraScrollFactor);
}

The m_camera*Factor variables are just scale factors that change how quickly your camera rotates/pans/scrolls

The code I have above is a simplified pseudo-code version of the camera system I made for a side project: camera.h and camera.cpp. The camera tries to imitate the Maya camera system. The code is free and open source, so feel free to use it in your own project.

In case you want to take a look into a ready solution.I have a port of THREE.JS TrackBall controlls in C++ and C#


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.


What kind of anti-aliasing is used in font rasterization? I'm writing my own TrueType font rasterizer as an exercise to improve my knowledge in computer graphics (along with a basic vector graphics engine). At this stage, I have implemented most of the TTF file parsing, decoding glyph outlines, scaling, and scan converting the outlines into a bitmap.
(I'm not doing any font hinting/grid fitting for the time being).

When it comes to anti-aliasing the glyph bitmaps, what process or method is typically used (or best)? So far I have tried two methods. Bilinear filtering and setting the alpha value at the edges according to the pixel coverage of the outline.

Bilinear sampling is too blurry to be effective in font rendering, and using pixel coverage is not continuous enough. Here are some images as reference of a lowercase Arial 'c' being rendered at 24 points:

Raw bitmap with no anti-aliasing:

Bilinear filtering:

Here is the same character rendered at the same size with a library (stb):

And finally, here it is rendered as it would appear on OS X (using CoreText I presume):

I'd be happy with whatever method is used by the stb library for my purposes.

Sean Barrett, the author of the stb libraries, wrote an article on how stb_truetype's rasterization works. It's quite readable.

The article describes two methods of antialiasing, both based on scanline rasterization. In scanline rasterization, you iterate through the lines (rows) of pixels and keep track of which edges from the glyph outline are intersecting the scanline (considered as a mathematical zero-thickness line); then you can identify which pixel-centers are inside the outline by tracking enter/exit intersection points along that line.

You can do horizontal antialiasing by calculating partial pixel coverage, using the position of the intersection points relative to the pixel grid. For example, if you have an entering point at $x = 4.6$ on the current scanline, then pixel index 4 would be set to 60% empty and 40% covered. This sounds somewhat like what you tried to do. However, this doesn't help with vertical antialiasing since the scanline is still considered as a mathematical line with zero thickness. So, the article recommends to just supersample along the vertical axis: that is, process multiple "scanlines" spaced out vertically within each pixel row, and average the results together.

The second method performs both horizontal and vertical antialiasing at once, by evaluating the area of intersection of the glyph outline with each pixel square. It's still based on scanline rasterization, but now treats the scanline as a 1-pixel-tall rectangle and tracks all edges that touch the rectangle. To evaluate pixel coverage, the trapezoidal rule is used to calculate a signed area for each glyph edge—positive or negative depending on the edge's orientation—and these are summed up to give the total coverage area within the pixel square. (There are a lot more implementation details covered in the article, plus you can read the source.) This is somewhat faster and more accurate than the supersampling method, though more difficult to implement.

Finally, it's important to consider whether you want gamma correction when rendering text (as with rendering anything else). Theoretically, the antialiased coverage values shouldn't be used directly as pixel values; they should be treated as an alpha, and used for linear-color-space blending between the background color and text color, followed by conversion to output gamma. However, in practice almost no one seems to do this; we're accustomed to seeing non-gamma-correct text, and screen fonts are designed to look good rendered this way. (Print fonts are another story.) On the other hand, if the text is animated, or rotated or not aligned with the pixel grid for any reason, gamma correction will help it look more consistent regardless of its placement relative to the pixel grid.

So, the choice of whether to apply gamma correction comes down to personal preference and the needs of the application. Either way, you may see artifacts such as the font appearing to get heavier or lighter depending on color and font size.

This is how anti-aliasing works:

render the outline in bilevel rendering at four times the size
take the averages of each 4×4 block
blend them with correct gamma between the foreground and background


How to use Shaders with vertex & index buffers? I'm trying to render a randomly generated terrain with vertex buffers and OpenGL. I want to use a shader to color the terrain, but it seemms like my shader isn't used. I have used shaders before when drawing triangles manually on the CPU and didn't have any problems there.

activate and deactivate is just glUseProgram(m_ShaderProgram) and glUseProgram(0);

This is my draw method:

void Terrain::drawTest() {

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IndexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);

    // setup position & normal pointers
    glVertexPointer(3, GL_FLOAT, sizeof(TerrainVertex), BUFFER_OFFSET(0));
    glNormalPointer(GL_FLOAT, sizeof(TerrainVertex), BUFFER_OFFSET(12));

    m_ShaderProgram.activate();
    glDrawElements(GL_TRIANGLES, indicesCount, GL_UNSIGNED_INT, BUFFER_OFFSET(0));
    m_ShaderProgram.deactivate();

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
}

And my shaders look like this:

Vertex shader:

varying vec3 Normal;
varying vec3 Position;
varying vec2 Texcoord;

void main(void) {
    Position = (gl_ModelViewMatrix * gl_Vertex).xyz;
    Normal = gl_NormalMatrix * gl_Normal;
    Texcoord = gl_MultiTexCoord0.xy;
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

Fragment shader:

varying vec3 Normal;
varying vec3 Position;
varying vec2 Texcoord;

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

Result:

As you can see the fragment shader doesn't seem to do anything and I can't figure out what the problem is.

Apparently there was just a problem with the loading of the shader. A bug that crept into the code from an old project...

EDIT: The GLuint of the compiled shader was never saved in the class and only local to the load function. Just a stupid mistake really.


Why would I specify image format in a shader layout qualifier? The OpenGL wiki entry for layout qualifiers says:

  Image uniform variables have qualifiers that define the format that all reading operations will convert the data into...

When is it a good idea to declare the image format in a shader?

i.e. layout (binding = 0, r32f) readonly uniform image2D input_image

Wouldn't this shader work just as well if I did not specify the r32f?

From the same wiki

  Image variables can be declared with a format qualifier; this
  specifies the format for any read operations done on the image.
  Therefore, a format qualifier is required if you do not declare the
  variable with the writeonly memory qualifier. Write-only variables
  cannot be used as in any reading operations; this includes calling
  load and atomic (read/modify/write) functions. So if you want to read
  from an image, you must declare the format.

  The format defines how the shader interprets the bits of data that it
  reads from the image. It also defines how it converts the data passed
  for write operations when it writes it into the image. This allows the
  actual Image Format of the image to differ between what the shader
  sees and what is stored in the image, sometimes substantially.

I had the exact same question until I learned about Compute shaders & was playing around with it. I think Compute shader is one possible use case where you read/write into an image. This is where specifying these formats is important.


How to convert a 3D model into an OpenGL fixed pipeline representation I have a CAD model in Solidworks (which can be converted to STL, OBJ, STEP , VRML etc.) that I need to render in an old application, which still uses fixed pipeline.

Ideally, I would like to convert my model into a series of glMaterialfv, glBegin, glVertex3f, glEnd commands that I can compile directly into a C library so that I can avoid loading data from an external file. If this approach will be too painful, however, perhaps someone could alternatively suggest an open-source lightweight fixed pipeline model renderer that I can embed into my code.

You can compile it into a

Vertex vertices[] = {{posx, posy, posz, texu, texv, ..},
                     {posx, posy, posz, texu, texv, ..},
                     //...
                    }

and then loop over them:

glBegin(GL_TRIANGLES);
for (int i = 0; i < arraycount(vertices); i++){

    glTexCoord2f(vertices[i].texu, vertices[i].texv);
    //...
    glVertex3f(vertices[i].posx, vertices[i].posy, vertices[i].posz);
}
glEnd();

Another solution would be to mimic what the modern vertex buffer based solutions do by creating a VertexAttributeLayout struct and setting it up. Then in the loop you interpret the layout struct and interpret the data as needed.

As pointed out in the comments, the most straightforward way to do this is to loop over an array of vertices, which is supported by both fixed and programmable pipelines in OpenGL.

The motivation for requesting a fixed pipeline solution in question is simple: that is what the existing code base uses! At the moment, the code base has no means of importing models and the models that do already exist in the code base have been hand coded using a series of fixed pipeline OpenGL function calls.

All things considered, I believe the best workflow (and answer to this question) would be as follows:

Export the CAD models to Wavefront OBJ format
Integrate the fixed-pipeline rendering implementation of this open-source OBJ viewer into the code base.


Should new graphics programmers be learning Vulkan instead of OpenGL? From the wiki: "the Vulkan API was initially referred to as the 'next generation OpenGL initiative' by Khrono", and that it is "a grounds-up redesign effort to unify OpenGL and OpenGL ES into one common API that will not be backwards compatible with existing OpenGL versions".

So should those now getting into graphics programming be better served to learn Vulkan instead of OpenGL? It seem they will serve the same purpose.

If you're getting started now, and you want to do GPU work (as opposed to always using a game engine such as Unity), you should definitely start by learning Vulkan. Maybe you should learn GL later too, but there are a couple of reasons to think Vulkan-first.

GL and GLES were designed many years ago, when GPUs worked quite differently. (The most obvious difference being immediate-mode draw calls vs tiling and command queues.) GL encourages you to think in an immediate-mode style, and has a lot of legacy cruft. Vulkan offers programming models that are much closer to how contemporary GPUs work, so if you learn Vulkan, you'll have a better understanding of how the technology really works, and of what is efficient and what is inefficient. I see lots of people who've started with GL or GLES and immediately get into bad habits like issuing separate draw calls per-object instead of using VBOs, or even worse, using display lists. It's hard for GL programmers to find out what is no longer encouraged.
It's much easier to move from Vulkan to GL or GLES than vice-versa. Vulkan makes explicit a lot of things that were hidden or unpredictable in GL, such as concurrency control, sharing, and rendering state. It pushes a lot of complexity up from the driver to the application: but by doing so, it gives control to the application, and makes it simpler to get predictable performance and compatibility between different GPU vendors. If you have some code that works in Vulkan, it's quite easy to port that to GL or GLES instead, and you end up with something that uses good GL/GLES habits. If you have code that works in GL or GLES, you almost have to start again to make it work efficiently in Vulkan: especially if it was written in a legacy style (see point 1).

I was concerned at first that Vulkan is much harder to program against, and that while it would be OK for the experienced developers at larger companies, it would be a huge barrier to indies and hobbyists. I posed this question to some members of the Working Group, and they said they have some data points from people they've spoken to who've already moved to Vulkan. These people range from developers at Epic working on UE4 integration to hobbyist game developers. Their experience was that getting started (i.e. getting to having one triangle on the screen) involved learning more concepts and having longer boilerplate code, but it wasn't too complex, even for the indies. But after getting to that stage, they found it much easier to build up to a real, shippable application, because (a) the behaviour is a lot more predictable between different vendors' implementations, and (b) getting to something that performed well with all the effects turned on didn't involve as much trial-and-error. With these experiences from real developers, they convinced me that programming against Vulkan is viable even for a beginner in graphics, and that the overall complexity is less once you get past the tutorial and starting building demos or applications you can give to other people.

As others have said: GL is available on many platforms, WebGL is a nice delivery mechanism, there's a lot of existing software that uses GL, and there are many employers hiring for that skill. It's going to be around for the next few years while Vulkan ramps up and develops an ecosystem. For these reasons, you'd be foolish to rule out learning GL entirely. Even so, you'll have a much easier time with it, and become a better GL programmer (and a better GPU programmer in general), if you start off with something that helps you to understand the GPU, instead of understanding how they worked 20 years ago.

Of course, there's one option more. I don't know whether this is relevant to you in particular, but I feel I should say it for the other visitors anyway.

To be an indie games developer, or a game designer, or to make VR experiences, you don't need to learn Vulkan or GL. Many people get started with a games engine (Unity or UE4 are popular at the moment). Using an engine like that will let you focus on the experience you want to create, instead of the technology behind it. It will hide the differences between GL and Vulkan from you, and you don't need to worry about which is supported on your platform. It'll let you learn about 3D co-ordinates, transforms, lighting, and animation without having to deal with all the gritty details at once. Some game or VR studios only work in an engine, and they don't have a full-time GL expert at all. Even in larger studios which write their own engines, the people who do the graphics programming are a minority, and most of the developers work on higher-level code.

Learning about the details of how to interact with a GPU is certainly a useful skill, and one that many employers will value, but you shouldn't feel like you have to learn that to get into 3D programming; and even if you know it, it won't necessarily be something you use every day.

You should be learning OpenGL first, as that is the standard for Graphics, across so many platforms.

Even if there is a newer library, understanding the basics, and working with a language that is used all over the industry, is very important... Especially since Vulkan wont be used in Big Companies for awhile, since.

No one wants to adapt right away and end up screwing themselves over with a non-stable Framework/Library.
They would need to hire / re-train their current Open-GL programmers, and there is no need to.

Also, I've heard that OpenGL, and Vulkan, aren't exactly the same.  I hear Vulkan is a lower level API, and closer to machine code, than OpenGL.

This answer I just found seems to have a lot of great info

https://gamedev.stackexchange.com/questions/96014/what-is-vulkan-and-how-does-it-differ-from-opengl

Another thing that is something to consider is the issue that happened back with OpenGL 1.

OpenGL 1 to OpenGL 2 had MAJOR changes, and since many people were using OpenGL1, and hardware supported it, there is heavy backwards compatibility needed to be implemented in some applications/engines, and that sometimes is really painful for the devs to keep supporting it.

Besides the support, the language shifted so much, that you had to learn new stuff.

This has happened with frameworks such as JavaFX (from 1.x to 2.x) and Play! Framework (Also 1.x to 2.x).  Complete changes to the framework, meaning we have to relearn... everything...

So essentially what you should do is wait until Vulkan is STABLE.  That means wait until Probably the 2.0 patch.  IT doesn't mean you cannot learn about the basics of Vulkan, but just know this might change.  I would assume that a group like Kronos would provide a very stable API from the start, especially since there are multiple Nvidia and AMD engineers working on Vulkan, including a high up Nvidia person overseeing the project apparently, as well as The base of Mantle; however, like any software, we the coders will see how well it works from the start, but many are wary and waiting to see what happens.


Image warping using pixel normals I want to insert a logo into an RGB image with proper 3D transformations. I can get the estimated pixel normals of this image using the code here: https://github.com/yindaz/surface_normal. Pixel normals are encoded into RGB channels as described as follows:

  The estimated normal will be saved in 16-bit PNG format, where 0-65535 in R,G,B channel correspond to [-1, 1] for the X,Y,Z component of the normal vector. We use the camera coordinates defined as - X points to the camera right, Y points to the camera forward, and Z points to the camera upward. For example, right facing wall are very red, floor are very blue, and you rarely see green as it's parallel to the camera viewing direction.

How can I transform the 2D logo to put it onto a planar surface in the image? I have tried to calculate the rotation angles of the normal to rotate it so that it has the same direction as the camera normal, and rotate the logo according to these angles, but I have no success so far.

As far as I understand from the quote above, normal of the untransformed logo should be $(x:0, y:-1, z:0)$ and let the pixel normal be $(x:a, y:b, z:c)$ with magnitude $M$. I rotate the logo around $X$ by $arccos(a/M)*180/pi$, around $Y$ by $arccos(b/M)*180/pi$, around $Z$ by $arccos(c/M)*180/pi$, and if $b < 0$ rotate around $Y$ by an additional 180 degrees.

Is there anything reasonable in these? Is it possible that I can do this using the estimated normals?

Maybe you should try to find Virtual Tangent Plane like in Surface Normal In the Wild


`worldViewProjection` doesn't work for a single component I have implemented a couple of classes which are drawn using shaders where the vertex position is always calculated the same way:

gl_Position = u_worldViewProjection * a_position;

The u_worldViewProjection-uniform is calculated using a viewProjectionMatrix which comes from a camera class. This is how I calculate the viewProjectionMatrix:

const projectionMatrix = mat4.create();
mat4.perspective(projectionMatrix, this._fieldOfViewRadians, this._aspect, this._zNear, this._zFar);
mat4.rotateY(projectionMatrix, projectionMatrix, MathHelper.degToRad(this._cameraAngleDeg));

// Setup camera
const cameraMatrix = mat4.create();
const up = vec3.fromValues(0, 1, 0);
mat4.lookAt(cameraMatrix, this._cameraPosition, this._viewDirection, up);

const viewProjectionMatrix = mat4.create();
mat4.multiply(viewProjectionMatrix, projectionMatrix, cameraMatrix);

return viewProjectionMatrix;

After that I would draw some component where I would set the u_worldViewProjection-uniform something like this:

protected _calculateMatrixData(viewProjectionMatrix: mat4): void {
// Set the world-matrix aka model matrix, position rotation and scaling
const worldMatrix = mat4.create();
mat4.translate(worldMatrix, worldMatrix, this.translation);
mat4.scale(worldMatrix, worldMatrix, vec3.fromValues(this._scale[0], this._scale[1], this._scale[2]));
mat4.rotateX(worldMatrix, worldMatrix, MathHelper.degToRad(this._rotationAngleDegree[0]));
mat4.rotateY(worldMatrix, worldMatrix, MathHelper.degToRad(this._rotationAngleDegree[1]));
mat4.rotateZ(worldMatrix, worldMatrix, MathHelper.degToRad(this._rotationAngleDegree[2]));

this._worldMatrixData.value = worldMatrix;

// Create worldViewProjection matrix
const worldViewProjectionMatrix = mat4.create();
mat4.multiply(worldViewProjectionMatrix, viewProjectionMatrix, worldMatrix);
// ...
// set the uniforms some time later

Until now this worked for every object. Now I introduced a new shader-pair:

vertex shader:

#version 300 es

in vec4 a_position;
uniform mat4 u_worldViewProjection;

void main() {

  gl_PointSize = 10.5;
  gl_Position = u_worldViewProjection * a_position;
}

fragment shader:

#version 300 es

// Set fragment shader's precision to "medium precision"
precision mediump float;

out vec4 outColor;

void main() {
  outColor = vec4(1, 0, 0.1, 0.5);
}

Seems simple. The problem is those do not render the component. I did realize that the component is being drawn if I omit the u_worldViewProjection in the gl_Position calculation.

gl_Position = a_position;

The above snippet will draw the component, but of course this will not take any changes in account that were made to the camera. Thus I guess that my u_worldViewProjection is the source of the false behaviour.

This is how I calculate the worldViewProjectionMatrix for the above shaders:

const worldMatrix = mat4.create();
mat4.scale(worldMatrix, worldMatrix, vec3.fromValues(1.0, 1.0, 1.0));

// Create worldViewProjection matrix
const worldViewProjectionMatrix = mat4.create();
mat4.multiply(worldViewProjectionMatrix, viewProjectionMatrix, worldMatrix);

The resulting matrix is not null or undefined.

I know it is kind of impossible to point out the origin of the problem but maybe there some approach to find the source or maybe I am doing something completely wrong?

Any help would be appreciated. If there is some other information I should provide please let me know.

This was entirely my fault. I simply forgot to set the uniform locations before rendering!

I implemented a function setUniformLocations() which sets the uniform locations passed to it:

public static setUniformLocations(
    gl: WebGL2RenderingContext,
    uniforms: IUniform[],
    program: WebGLProgram): IUniform[] {

    const vao = gl.createVertexArray();
    gl.bindVertexArray(vao);

    for (const uniform of uniforms) {
        uniforms.find((u) => u.name === uniform.name).location = gl.getUniformLocation(program, uniform.name);
    }

    return uniforms;
}

I normally call this function in the constructor of the according class.

this._uniforms = GLHelper.setUniformLocations(this.gl, this._uniforms, this._program);

This time I forgot.


Return x; y; coordinates of vertex C of triangle I would like to return the XY coordinates of vertex C using math formula.
I have 5 input data what I always know and can be used for solution (green in the image): I know X; Y; coordinates of point A and point B (Ax, Ay, Bx, By), and I know the length of all three sides of triangle (AB, AC, AD). Please help how to get the values of X Y coordinate of point C, what is 70/30 in the example, but I have no formula to get back them.

I know that more than one solution of this formula, but:

Coordinates cannot be in negative areas. All coordinates must be positive.
I always use 1 direction for vertex labelling, but because I always know the length of AC and BC, I think to change the label from A to B will not change the position of C.

Thanks!

You can get the coordinates of C by using circle equations for one circle C_A with point A as center and AC as its radius and one circle C_B with point B as its center and BC as its radius.

Now you can calculate their intersection points, which leaves you with 2 points (iff C is not on a line between A and B).

I am not entirely sure how you want to determine which of the two candidates C_1 and C_2 is the correct one. If I understand correctly, you always label the triangle counterclockwise. There is a neat way to check this, so you should have everything to find your point.

As mentioned by previous answers, the best way to solve your issue is to compute the intersections of the two circles centered at A and B. Since you will have two candidates, you will need to choose a specific order for your edges to only select one candidate.


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

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

They simplify and unify the mathematics used in graphics:

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

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

simpler formulas
Fewer special cases
Unification and
Duality


What's the meaning of the "dynamic" in "high dynamic range"? What's the meaning of the "dynamic" in "high dynamic range"?

Why use this word?

Dynamic, adjective:

  1: pertaining to or characterized by energy or effective action; vigorously active or forceful; energetic:

  ...

  4: of or relating to the range of volume of musical sound.

HDR allows you to deal with high light energies. And such high energies could be characterized as being "vigorously active or forceful; energetic".

But I think the fourth definition is more suitable. Graphics and rendering are forms of signal processing, much like sound. So they share a lot in common. For example, the term "aliasing" originated in digital conversion of sound.

"High light energies" are the visual equivalent of "volume" in sound. So the "dynamic range" that you can record, the "range of volume" is high, as opposed to low.

High Dynamic range, somtimes use as a feature in still image or in higher level in rolling image.
It means that your shot has been captured by camera that can hold all information about exposure (at least in 3 modes: Overexpos, Normal and Underexpos).
It is happening in high-end camera and high-end project.
With this feature, you have alot of control in CC step like a pro.


How will the z-buffers have the same values even if polygons are sent in different order? I know when we use Z-buffer to eliminate the hidden faces, the polygons can be in any order. But my teacher said that this does not mean that two images generated by sending polygons in different orders will have identical values in their z-buffers and in their frame buffers. How does this happen?
And if this is the case, When or how will the z-buffers and the frame buffers have the same values even if polygons are sent in different order?

What your teacher means is that at the end of the frame, once all polygons in the scene have been drawn, the z-buffer will have the same values. This is because the z-buffer keeps the minimum Z within each pixel, over all the polygons drawn to that pixel, and the minimum doesn't depend on the order.

If you look at the z-buffer in the middle of the frame, when some polygons, but not all, have been drawn, then naturally the contents of the z-buffer will depend on what's been drawn so far, which would depend on the order in general.

With regard to the color buffer, the same things are true if all the Z values within each pixel are distinct. However there's one case where the results do depend on the order: when multiple polygons have the same Z value at a given pixel. This could happen if the same polygons are rendered twice with different colors, or some such. Then, the behavior depends on the setting of the depth test (i.e. glDepthFunc in OpenGL). If it's strictly "less", then the first polygon drawn that has the minimum Z will "win" and its color will end up in the color buffer at the end. But if the depth test is set to "less-equal", then each polygon that has the minimum Z will overwrite the one before it, and the last one drawn will end up in the color buffer at the end. So in that case, the order of drawing polygons, and the state of the depth test, do make a difference.

Though polygons can be sent in any order some polygons may lie in the same plane. Their respective zs can be calculated using the formula z=(-Ax-By-D)/C, and if the two polygon surfaces are at same depth then they can have same value of z.


What are the usages of software rasterization in modern game engines? I am taking a Computer Graphics course this quarter.
One of our lab project is about software rasterization.

Now I am planing the project proposal and
thinking about how to make it useful for other people in contemporary game development.

After some brief search,
I learned a technique called Software Occlusion Culling.
It does software rasterization on buffers of various resolutions.
And we can query for occlusion using the hierarchical z buffers.

My question: What are the usages of software rasterization
in modern game engines besides the Software Occlusion Culling?

To my knowledge, Software Occlusion Culling (which you already mentioned), is pretty much the only thing a software rasterizer would still be used for. Procworld makes use of a similar technique to display its huge voxel environments.

Most other culling methods like frustum culling do work on the CPU, but, to stick with the example, the test against the frustum happens on object level, probably with an axis-aligned bounding box (AABB). This intersection test is way simpler than using a full-blown software rasterizer.

In certain cases, software rasterization could be used for mouse picking of objects. In game engines, this is often solved using a physics engine and ray-triangle collision with a simplified mesh.

With the CPU being idle while waiting for the GPU in modern interactive 3D applications, one could think that it might be beneficial to use these idle cycles to render on the CPU using a software rasterizer. The problem here, besides the rendering getting horribly complex and convoluted, will often be the bandwidth. Images rendered on the CPU need to be transferred to the GPU before getting displayed, which might cancel out the benefit.

Rasterization is a huge topic with many parts and I'm no engine programmer, but I'll do my best to give some sort of overview (this will be far from a complete list!).

Some very basic, lowlevel stuff include:

Frustrum culling: throws away everything outside the camera's frustrum (think of it as the viewing area of the camera).
Backface culling: throw away every polygon not directing to the camera.
Painter's algorithm: draw objects in order of their distance to the camera, start with objects far away, then go toward to the camera.

More advaned stuff used in games include things like:

Tesselation: actually pretty much like LOD (see below), but now the latest DirectX Versions introduced tesselation, which provides automatic mesh division or reduction. This gives huge boost in graphics performance, because you can get polys if you need them and get rid of them if you don't want them any more.
LOD: A level-of-detail system replaces the mesh of an object based on the distance between object and camera. for example, your character has three meshes: one with 10,000, one whith 5,000 and another with 1,000 polys. if you stay right in front of him, the high resolution mesh (10,000 polys) is shown, if you move away, after 100m the character is replaced by the medium mesh and after another 100m it is replaced by the low resolution mesh. Instead of replacing the mesh you can reduce it, but this would be more complex to code.
binary space partitions: the space is divided into two volumes. this will be repeated until you reach your goal, e.g. until the space does contain only polys that should be drawn on screen
Portals and cells: (aka Portal culling) is used in indoor scenes and/or first person shooters. The scene is divided into cells (e.g. rooms of a building) that are connected throw portals (e.g. doors). you can set portals to be open and closed.

Assuming you have a basic understanding of the graphics pipeline, I tried to focus on rasterization. you may also take a look at lighting and shading or other stuff..

These include just a few possible technologies to include into your project. since i have not enough reputation on stackexchange, I cannot provide many links, but you'll find all that stuff in google :)


Bokeh from depth map How do I generate bokeh that simulates shallow depth of field given a perfect depth map?

Here's what I tried:

Generated a sample scene using blender and corresponding depth map

Using Python, generated what sigma (standard deviation) to use at each pixel for gaussian blurring: This one makes it look like the far end of the pink cube is perfectly focused.

sigma_map = np.array(np.round(abs(np.array(depth, dtype='float32') - preferred_focus_depth)).clip(0,255), dtype='uint8')

black = 0, no blur; white = 255, large blur

Applied gaussian blurring (using the sigma_map) at every pixel and this is what I got

Flaws observed: Averaging kernels just near the edges are taking in the pink color nearby hence the pink bleed. How do I avoid this?

Note: It's not completely blurred look closely at the zoomed in image on the right. The pixels that I wanted to remain untouched are still untouched (even though it appears they were blurred as well because of the blurring near the edges)

This blog on Portrait mode on Pixel 2 says, "Actually applying the blur is conceptually the simplest part", is there any simpler way of doing it then?

The blog post that you talked about, is not about generating bokeh for a computer generated image. It is instead about generating a believable depth of field effect from an image captured by a smartphone camera, as the effect is desired for portraits to make the subject stand out. It generally works by splitting the image in to two parts. One part is the subject, which should not be blurred. The other part is the background, which should be blurred but the pixels of the subject should have no influence and would thus have a weight of zero. Slightly more sophisticated algorithms may make the blur kernel size variable across an image to create a smoother transition, but the subject's pixels would still be ignored.

In games and CGI, post process depth of field is done differently. There are multiple ways for it. A simple google search shows multiple. You could do depth of field like you have, and simply ignore the pixels which should not be blurred to remove the ghosting. However, this is not true to how depth of field occurs inside of a camera. So, in order to get a good algorithm to simulate depth of field, I will first try to explain how you get the depth of field effect in an actual camera.

Let us say, that we have an object, a single lens and an image sensor. We look at them from the side.

Light scatters in many different directions when hitting the object. To simplify we only take one point. From this point, I will show the light that would hit the lens as a gray solid.

The lens bends the light towards a single point. That is the focal point.

You can see that the focal point is in front of the sensor. This causes the light from that single point on the object, to fall on a large portion of the sensor. If the focal point is behind the sensor, the same would happen. But, if the focal point lies on the sensor, there would only be one point on the sensor where the light falls on. This area where the light falls on the sensor, is called the circle of confusion (CoC). This is also the cause of the depth of field effect.

One important thing to know, is that when the point on the object moves around, the focal point also moves around. If the point moves closer to the lens, the focal point moves closer to the lens, which would alter the size of the circle of confusion. This gives you the gradual change in blurriness that you have with depth of field, since the circle of confusion gradually becomes larger when an object moves away from the area in focus.

If we add in an aperture we simply block out a part of the light, which causes the circle of confusion to be smaller. This allows us to determine how much light to let in (to make the image brighter or darker), and how strong the depth of field effect is.

From this, we can conclude a few things on how we should implement depth of field.

Every point whose light enters the camera lens, has a circle of confusion.
The circle of confusion is the area where the light, from that point, falls on.
The circle of confusion changes size when the point moves closer to or further away from the lens, or when the aperture changes size.
The area of the circle of confusion has no falloff. Every point inside the circle of confusion has the same weight. This results in a box blur.
If a point is in focus, its circle of confusion would be either zero or something so small, that it is not noticed.

The algorithm is quite simple. For each pixel in the image, we use the depth to calculate the circle of confusion. Then, we add the colour of that pixel to all the other pixels that lie in the circle of confusion. However, if that other pixel is closer to the camera (a lower depth value), it would block the light from our pixel, and we should not add the colour of our pixel to the blocking pixel.

In pseudo code it would look something like this;

// for each pixel in the all-focus image
for(x = 0; x < width; x++){
    for(y = 0; y < height; y++){
        // How much blur? Zero or close to it if it should be in focus.
        float CoCRadius = calcCoCRadius(depth(x, y));

        // For every pixel in the square with the size of CoCRadius.
        for(i = x - CoCRadius; i <= x + CoCRadius; i++){
            for(j = y - CoCRadius; j <= y + CoCRadius; j++){
                // Discard pixels outside of the shape. Square -> Circle
                if(isInBokehShape(i - x, j - y)){
                    // Discard pixels that would block it.
                    if(depth(i, j) >= depth(x, y){
                        // Add the colour.
                        newColour[i, j] += colour(x, y);
                        // Add the weight, for normalizing.
                        weight[i, j] += 1.0f;
                    }
                }
            }
        }

    }
}
//Normalize the values with the weight.
for(x = 0; x < width; x++){
    for(y = 0; y < height; y++){
        newColour[x, y] /= weight[x, y];
    }
}

This would give you a depth of field effect that is quite true, and does not give you the ghosting effect. $calcCoCRadius$ is a method that calculates the radius in pixels of the circle of confusion. It could be anything, but if you want it as true to an actual camera, then you can use the formula from this Wikipedia page. $isInBokehShape$ is a method which returns a boolean on whether the point is inside the bokeh shape. With the two for loops we just get a square, but if we want to get a circle shaped bokeh, we need to discard the pixels that would lie outside of the circle. This discarding is also the reason why we keep track of the weights and normalize afterwards with the weight, since we do not know how many pixels we need to discard. The weight is also useful if you do want a falloff in the circle of confusion, for example if you want a gaussian blur.

Another important thing to know, is that the implementation listed here, is not very optimal. The problem is basically that you write to multiple different pixels. This causes race conditions. Instead, it is better to rework the algorithm so that you only need one write. Basically, you loop through every pixel and you then you check all other pixels (or pixels inside of a maximum CoC radius) whether their CoC radius is large enough that they contribute to the pixel's colour. This way, you can also put the normalizing of the values inside the first loop over all the pixels instead of having to do that later.

This should be a fairy good way of implementing depth of field as a post processing effect. There are also other ways, but this is one.

Does the effect need to be physically accurate? I've implemented this using a cheat before. @bram0101's answer is great. If you need accuracy, then by all means, implement that. I've been able to get something convincing to the eye by simply doing a threshold of the luminance of the image and placing a semi-transparent polygon or circle centered at every point that's above the threshold.

You also need to take into account distance from the focal plane. The distance can be used to control the size of the bokeh, with the size being 0 at the focal plane, and some maximum size at some farther distance.


Convert triangulated object to a polygonized object Is there an efficient algorithm to convert a 3D object described with a set of triangles to a 3D object described with a set of polygons. Polygons can have an arbitrary number of points, more is better. I'd like to minimize the number of polygons necessary to describe the 3D object but it does not have to be optimal.

The 3D object should stay the same.

Polygons can be non-planar.

I guess what you wanna achieve is mesh simplification. Then those materials can be useful for you.

http://graphics.stanford.edu/courses/cs468-10-fall/LectureSlides/08_Simplification.pdf

https://pages.mtu.edu/~shene/COURSES/cs3621/SLIDES/Simplification.pdf


How to do linear interpolation? Here in my book they have shown interpolation using parametric equation of line but I am unable to figure out how do they found out t=|y1-ys|/y1-y2 , t=|AD|/|AB| , t=|CE|/CB ,t=|EP|/|DE| here is the  pic

Since this is linear interpolation it boils down to solving a linear equation
$y = a + b t$
You can substitute the following $y = y_s$, $a = y_1$(intercept) and $b = y_2 - y_1$ (slope) to get the following
$$y_s = y_1 + t(y_2 - y_1)$$
$$y_s - y_1 = t(y_2 - y_1)$$
$$\frac{y_s - y_1}{y_2 - y_1} = t$$
The same thing happens for points where you can write
$$D = A + (B-A)t$$
$$ (D-A) = (B-A)\cdot t$$
$$ (D-A)^2 = ((B-A)\cdot t)^2$$
$$ \sqrt{(D-A)^2} = \sqrt{((B-A)\cdot t)^2}$$
$$ \sqrt{(D-A)^2} = \sqrt{(B-A)^2 \cdot t^2}$$
$$ \sqrt{(D-A)^2} = \sqrt{(B-A)^2} \cdot\sqrt{ t^2}$$
$$ |D-A| = |B-A| \cdot t$$
$$ t = \frac{|D-A|}{|B-A|}$$

I4=I1  ( 1-t ) + t.I2  ; from parametric equation of line
I4=I1 - I1.t + t. I2
I4=I1+ t (I2-I1)
Let's take line AB apart from triangle

below in the equation I multiply t2 to numerator an denominator


Accurately printed CIE diagram This is more just for curiosity rather than actually wanting to get one, but is there a place where I could buy a printed version of the CIE xy colour space diagram which accurately recreates all of the visible colours outside of the regular printing gamuts?

Its not actually possible to do. Because that paper you print on needs to have properties not avalialbe. The color on the edge are very pure and can not be mixed. I dont also see any way they could be reflected either. Also the xy diagram is not the full color space just a slice of it.

I think there is no point pursuing "objective accuracy" for colors, because individual perception of colors is different. The current standard is merely a statistical result for human eye perception.
That is to say, it is possible for someone else to perceive the colors you regard identical as different.


3ds max: Z-fighting when working with Large Objects I had a z-fighting/z-clipping issue with a scene containing some very large objects yesterday in 3ds max. It can be seen in the image below:

For some reason downscaling the scene significantly (a factor of 100 approx) resolves the z-fighting issues... Please help me understand how reducing scene scale could resolve this issue and why this issue only occurs with very large scenes/objects.

From what i understand z-fighting occurs in this case because the near and far planes are very far apart compared to the minimum and maximum distance of the rendered object(s) relative to the viewport.

Please correct me if I'm wrong, my basic understanding of the z-buffer is as follows:

1) The distance of each rendered pixel of the object(s) is compared to a standard value stored in the z-buffer.

2) if the depth of the current pixel is smaller than the currently stored value for this pixel location in this image...the value for this pixel in the z-buffer is overwritten with the new and lower value.

3) before the z-depth value is stored in the z-buffer it is divided by a certain value (floating point type value), not sure why the number is devided. perhaps to reduce memory usage by storing smaller values...

I managed to fix the z-fighting in the viewports by increasing the near plane (in viewport settings) from 0.1 ish to a larger value.

Please take a look at the image below:

The red planes are the camera's near and far planes. The green planes I have drawn myself and they indicate the minimum distance of the object relative to the camera and the maximum distance of the object relative to the camera. When scaling the scene by a factor x the ratio between the variables A,B,C,D (please see the dimensions drawn in the image) should stay approximately the same (as in the ratios A/B , A/C, A/D, B/A etc. should be approximately equal before and after the scaling process takes place).
Therefore the max and min depth relative to the near and far viewport planes should be approximately equal. And as a result the depth precision of the object should not change when scaling (I think).
My understanding is clearly incorrect since the z-fighting disappears when downscaling. Why is it that scaling has any effect on the z-fighting? Does 3ds max automatically adjust the far and near plane distances relative to the viewport when scaling the object/scene?

I've read about something called depth precision (https://developer.nvidia.com/content/depth-precision-visualized). Assuming this  (objects(their pixels) that are closer to the camera being stored more accurately in the z-buffer) is true in 3ds max it makes sense that when zooming in really close to the object in the viewport...the z-fighting disappears. however, when I zoom out quite a lot in the viewport, the z-fighting also isn't visible anymore even though it should in my mind get worse since the precision of the depth info stored in the z-buffer is lower for objects further away from the camera. Am I missing something ?

PS: the viewport clipping distances are set to the default in the image below and the first image of this post.

If I have been unclear or incomplete about anything please let me know and I will try my best to explain/elaborate. Any help will be greatly appreciated. Thank you very much!

Unfortunately, I don't know how 3ds max handles its Z-buffer or its near and far planes so I can't give a definite answer. There are many ways the software could handle this.

However, you are on the right track. Z-fighting occurs when there is not enough numerical precision to distinguish two "objects" from the scene rendered at the same pixel. In such cases, the two pixels "fight" one another over which one is closest to the camera and flickering occurs.

These factors influence how a scene is susceptible to Z-fighting:

Number of bits used by the depth buffer (typically 24 or 32).
Whether the depth buffer uses float values or integers.
Whether the Z value 0 is used for the near or far plane (inverted depth buffer).
How close objects are to each other.
The size of the range between the near and far planes.

Of these, you really only have control over the near and far planes from what you say.  It looks like your model is too big for the default way 3ds max handles this so I suggest making the near plane value bigger. An increase of the near plane from 0.1 to 1.0 (*10) will give the same precision increase as dividing the far plane by 10.

For your other question, you usually get less Z-fighting when an object is closer because there is more precision in the depth buffer closer to the near plane.

Also, for your other question: Why do GPUs divide clip space Z by W, for position?

A nice Z precision visualizer: http://dev.theomader.com/depth-precision/

Right Click on the viewport PERSPECTIVE and enable viewport Clipping.
On the right of the screen, 2 yellow arrows will appear. Drag the bottom arrow up a little. Worked for me.


Mapping sample to a disk So I have been reading this wonderful book on ray tracing by Kevin Suffern, Ray tracing from Ground Up. I am reading this book after finishing Peter Shirley's first two book on ray tracing & implementing multi-threaded ray tracer, adding features like Intel's denoiser, assimp integration etc.

What struck me was before I read the third book, it would be good idea to read more on sampling. Which is why am skimming through this current book. At this moment, am stuck on a topic which explains how sample point in unit square is mapped onto unit radius disk.

I am stuck at the part where book mentions how equations are mapped. Radius part is clear to me, however, am not very clear about the angle (phi) part. Is there any derivation as to how this was deduced? Or is it done to avoid atan() calculation and is a neat approximation of it? After putting in test values I have understood how values get converted, however, am very keen to understand how this formulas for Phi was deduced based on different quarters, unless it's very obvious and I have overlooked it :(

Regards.

EDIT:
After more digging, i have understood that if i assume first quadrant value, then second, third & fourth values can be deduced by rotating/adding (Pi/2) to angle phi & switching axis due to quadrant change. However, first quadrant value is still not clear :|

Check the last column in the table for the deciphered version of the existing Map Equations for easier comprehension.


What tris and quads need for? I know that 3D artists make a 3D model with quads. And they advise to remesh with quads only (if it's possible).

So I have some questions:

Why do we use quads in CG (for games, cartoons, film, etc) if the graphic card (or render, I'm not sure) convert quads to tris all the same?
Why many 3D apps (Max, Blender, Maya, etc) have a triangulate function? Eventually, the graphic card (or render) does that.

I want to clarify this question for myself since I know it incompletely.

Because the geometry will be subdivided into quads. Anyway the primary reason for this is if you have a function with 2 directions it is easer for humans to think it out andcanticipate results if its a quad.

Software renderers dont have to rely on triangles. And did not for a long time. But then if you microdice your surface who cares its not like you can see the micropolygon anyway.

For more on this read this post
You might want to control the triangulation yourself. Interpolation does not happen the same way regardless of how the triangles are laid out. So being able to triangulate and then flip offending triangles is useful.

In addition to what other people have said, for cpu / raytracing it is more memory effecient to store quads even though they may be intersected as two triangles.

When you have millions of polygons, this memory saving is useful and there are no real performance side effects.


iPhone GLU(OpenGL Utility Library) This link says iPhoneGLU says, this libraray supports below futures.

Matrix manipulation
Polygon tessellation

I would like to know whether I can use this library to draw primitives(lines,points,triangles,simple polygon).

Thank you.

I personally like glad. The have an online generator as well http://glad.dav1d.de

It will generate exactly what you need for your platform.


Overlaying graphics on particle simulation How can I overlay graphics on particle simulations? For instance if I am representing a liquid or gas with tons of little points how can I make those points look like a liquid or gas? Take Nvidia Flex for instance, they simulate liquids and gases with tons of small points but can render them as realistic liquids and gases instead of small balls.

For rendering of gases, I think the usual approach is to simply render each particle as a tiny disc. Gases don't really coalesce into surfaces like liquids do, so this should produce acceptable results. You could perhaps apply a light blur over the gas layer afterwards to soften it and hide the fact that it is made of discrete elements.

Liquids, on the other hand, tend to coalesce together to form droplets and smooth surfaces, so you need to derive a surface from the particles somehow. One way to do this is to use Metaballs, which also display this behavior and can be tweaked to suit different liquids and particle densities. By interpreting each particle as a metaball, you will have an implicit equation representing your liquid surface. To render this implicit surface you can then use an algorithm like Marching Tetrahedra to convert it to triangles, or utilize Ray Marching to directly render it. (Ray marching can be easily done in realtime in a fragment shader these days.) You can also use this approach for gases if you want a somewhat softer look.

A good reference for game physics is this chapter 4 describes the basic free deformable surfaces (nurbs and bspline are of course cited and treated enough well) fluid and gases are instead treated in chapter five (basically the author derivate simplified model of navier stokes equations, suitable for real time applications).

So actually i guess what i've written commenting your post was correct, i.e. combine the physical deformation of the point that controls the shape of the surface with a ffd computations.

The book i cited should provide somewhere/somehow on the web source code, and itself it cites some example involving the technique i cited. If that is what you need let me know for a more specific explanation.


An idea for an implementation of continuous collision detection of circles So I'm making a 2D pool game in OpenGL (you might've guessed as soon as I've mentioned collision of circles). I'm having a little trouble with collision detection. What I mean by that is that I have an algorithm that currently works but I'm thinking of improving it.

So far I've used discrete collision detection, disregarding the possibilities that it might not work at high velocities. However, I've noticed that I in fact sometimes do need the circles (pool balls) to travel at velocities at which the discrete collision detection might fail. The reason for that is that some of those velocities are quite realistic in a real-life game of pool (I've calculated that an average professional break shot in pool can make the ball travel as fast as six times the ball's diameter per 33 milliseconds which is the time interval that one frame lasts on 30FPS machines). Therefore in every such shot my discrete collision detection is very likely to fail.

This is the idea I've had:

The dashed circles represent the positions of the balls in the previous frame. The lines from them represent the velocity vectors and, obviously, the circles that they're connected to are their positions in the current frame.

One thing I would do immediately is check whether the velocity vectors are collinear in which case there's no need to check for any kind of collision. If they're not collinear, I'd find the intersection point of the line segments represented by the points of previous position and the next position (if they don't intersect I just disregard everything) . After that I'd manually translate the balls "before" the point of intersection (I was too lazy to actually compute where the balls would touch so I just put them somewhere near that point for the purposes of illustration, but it doesn't really matter). After I've done all that I would just let the discrete collision detection algorithm, which I already have, do the work.

Couple of things I'm worried about here:

(1) Since I have more than 2 balls on the table (16 to be precise) can the manual translation step somehow impact eventual collision of one of the balls that have been translated and some other, third ball? It seems to me like it shouldn't, but I'm not sure.

(2) On one hand I'm thinking that this might cause some glitching since I'm translating the balls "back" after I've already drawn them at their positions. On the other hand since this will only be happening at high velocities it might not matter that much. This also causes me to wonder whether I should do draw - collide or collide - draw. That is, should I use the principle I've described here (first draw the balls, then check whether they've been drawn too far) or maybe I should "look ahead", as in check whether the next position could cause problems instead of whether the previous position has caused them?

Not looking for any code, just ideas and thoughts.

Thanks in advance.

I think you should determine the "next collision point" in your whole 16-ball-and-table-border system and adjust your simulation 'Delta t" depending on it. Rendering should be de-coupled from this anyway, or it will show irregular ball movements... .

Some further thoughts:

Collinear velocity vectors do not mean there is no collision - if v1 != v2 ...
In good pool games you can define the 'hit point', where the queue hits the ball. Then "curvy" ball trajectories are generated, etc. etc.
Your system should also consider friction, therefore: v->0 over time. This should also affect your collision calculations.

I don't know if you just didn't write it or really intended not to do it, but in general it's now enough to check the velocity vectors for inersection. First off, the vectors might intersect but the balls pass the intersection point on different times, resulting in no collision. Second, you do not take the radius of each ball into consideration.
From my (limited) experience, contiuous collision detection is either done with a technique called conservative advancement, signed distance field or (which would apply for your case) solving for a mathmatical equation dependent on time $t\in[0,1]$. Even with bent trajectories you are able to do this.
Once you have solved for $t$ and computed all pair-wise collisions (all 16 balls with each other and possibly the edges in some way), you can sort them by their collision time $t_i$ (earliest collisions should be handled first) and solve the collision restrains with some phyiscal response. Because of the nature of continuous collision detection, you will not have an actual intersection where you would get the contact normal and penetration depth from. Usually you will have some distance of two balls that qualify (numerically) as a collision, like $d(B_1, B_2) < \varepsilon$. But there are mutliple easy ways to fix this, particularly for you scenario.
After you have solved all the collisions and updated all velocities, you have to repeat the whole process because there might now be different collisions between different balls. In theory, you would have to repeat this until all collisions have been properly solved. However, there might be cases where there are somewhat cyclic collisions (think Newton's cradle) and these will be tough to properly handle. Again, this is up to implementation but a good start (at least to avoid infite collisions) would be to use a limited number of iterations per frame for this.
Then, after finishing all collisions for one frame, you finally can render you scene.
Good luck with your project! I know how tough it can be to implement a proper collision detection, let alone a continuous collision detection.


Color space of MERL BRDF database? I know that by now it might be considered as a kind of sad recurrent joke, but by chance, does anyone here has the least information about the colorspace of RGB values in the MERL BRDF measurement database ?

Was interested in this myself and did some digging, I was wondering if they where spectral, but it appears not (although some interesting work on spectral BRDF is here http://web.cs.wpi.edu/~emmanuel/courses/cs563/write_ups/cliffl/cliffl_spectral_brdf.html )

This chat seems to indicate they are camera native linear, probably with sRGB primaries.

https://groups.google.com/forum/#!msg/pbrt/p9zMvZlaodA/4RD7-We8h4gJ

Disney have a tool that analyses the database.

http://www.disneyanimation.com/technology/brdf.html

Is browsing the source code for this an option?

https://github.com/wdas/brdf

You could contact the authors perhaps?


Does a sphere projected into 2D space always result in an ellipse? My intuition has always been that when any sphere is projected into 2D space that the result will always mathematically be an ellipse (or a circle in degenerate cases).

In the past when I was actively doing my own graphics programming and brought this up with other people they were adamant that I was wrong. If I recall correctly they believed the result could be something vaguely "egg shaped".

Who was correct?

Since there is already one answer submitted, I don't wish to totally change my question but I realize I left out important details due to losing familiarity with the field over the years.

I intended to ask specifically about perspective projection where the projection is a linear application.

The other projections are of course interesting for many uses so I wouldn't want them removed at this point. But it would be great if answers could have perspective projection as their most prominent section.

Assuming a perspective projection and a view point external to the sphere, then the 'boundary' formed by the view point and the circle on the sphere which forms the horizon WRT the view point, will be a cone.

Doing a perspective projection (onto a plane) is then equivalent to intersecting this cone with the plane which thus produces a conic section. FYI the four, non-degenerate, cases are shown in this image from Wikipedia

An ellipse/circle is thus a possibility, but not the only one - unbounded parabolas or hyperbolas (and I guess if the plane passes through the eye, even degenerate cases ) are possible.

There are no parabolas or hyperbolas formed when slicing a sphere once. There are no ellipses either except for the special case which is a circle.The result is always a circle. If you project the sphere onto a tilted plane you get an ellipse


File format for swept profile with changing normal I have to create a file describing a 3d surface with the following properties:

a circular arc cross section is swept along a closed 2d curve spine defined with equations
the normal direction of the arc is not always tangential to the spine, the direction is defined with an equation
the surface should be analytic (defined by equations), but a tesselated surface is also acceptable (with an external script I can derive the x,y,z coords of the vertexes for a tesselated surface)
the file will be modified by an external script (python), so it should be editable with text editor
the file should be opened by Creo(Proe), Catia and NX

The question:
Which is the best file format for making this feature?

What I tried:

step: buying the ISO standard is unavoidable, as I cannot figure out on my own how the definition works
vrml: only tesselated seems to be feasible
x3d: same as vrml, as it has a sweep (extrusion) feature, but the normal direction is the same as the local spine direction, and Proe does not seem to open it

The egg-shaped curve is the trajectory, the arc is the curve to be swept along it.
The plane of the arc is close to parallel to the plane "Top", but this angle varies between 0-30 degrees

Well realistically your choices are either IGES or STEP. IGES is slightly simpler but you will not successfully write either format without buying the standard (which in case of step is actually so many pages that by the time you have read them a year has passed, and lots of money is wasted on paper). You could also use one of the nonstandard kernel internal formats like Parasolid as its also commonly supported. Most other formats are polygon data so not suitable.

I would explore an alternative option to writing your own exporter, buy a commercial or take a free CAD kernel and let the kernel (open CASCADE) do the exporting for you.

On the other hand this is not hard to do inside your CAD application. Which you will need anyway to verify the result. Most CAD applications have a COM API's (don't know about NX most likely, but both creo and catia do have this) so you can edit, even do the generation from a text editor via python if you so wish. This is by far the least amount of effort (and it's usually less work to set up than using just the kernel).

Image 1: Swept with spine angle $60 \cos(4 t)+110$ and polar trajectory with $r = \cos(4 t)+3$ in Creo. All input from program injection.

So the approach depends on why you want to do what you do. And what your budget/time constraint is.

PS: NURBS (the underlying format of CAD data) solutions are not necessarily analytic, but parametric fits to analytical solutions. Sometimes these are exact sometimes not so exact as not all functions can be fitted to rational spline (though many can). Even when they can fitting is a more general solution.

Here is what I finally did, maybe somebody finds it useful.

I wrote a script with Excel VBA what does the following:

gets the coordinates of n discrete points on the trajectory
gets k points of the circular cross-section at each n, in a horizontal plane
applies a rotation on these cross-sections (moves all points)
creates (n-1)*(k-1) facets (assigns 4 corner points to each)
exports the points and the facets to a vrml file

The result:

The script might have been easier in python, but I chose Excel VBA
because this way I don't have to deal with the GUI.
The format is vrml, because a) most software handles it b) the
definition is available (mostly) and simple
prepare the file by script instead of a CAD software: in my experience they can't build this surface reliably enough. The features will be super-sensitive to the input parameters, they will tend to crash after small changes

There are a couple of issues remaining:

Catia can't open the result, possibly because the vertex normals are not defined in the wrl file. This feature of the vrml is not really documented. Opening and saving it with Creo solves the issue, as it adds the normals automatically. Creo and NX are ok.
Can't convert the result to quilt in Creo, hence sectioning, measuring, etc is problematic

Any suggestions with the issues above are most welcome.


How does UnrealEngine handle depth? Today I found something really interesting (I've never seen something like that). While debugging the buffers used in lightning, I see that the depth information is stored in what looks like cascades of depth.

What's going on there? Is that a technique to improve depth precision?

Thanks!

This is just a visualisation. Type the command vis scenedepthz uv0 to see the actual depth buffer used. UE4 uses a "reversed" depth buffer for the scene.

While I have no idea how UnrealEngine handle depth I have thought of a technique which would result in that kind of depth output.

The idea is to better manage Z-fighting by rendering multiple (stacked) frustums with shorter distance between ner and far planes. Each step in the cascade would represent one of those frustums. Using near/far plane clipping, stencil masking and optional vf-culling you can easily render the cascade front-to-back, or each frustum to each own framebuffer and consolidate afterwards, with only minor hit in performance.

This should scale better than increasing depth buffer bit depth which has diminishing returns. Besides not all platforms support high bit depth. OpenGL ES require only 16 bits!

It is just a theory though :-)


Techniques for making tesselated shapes appear smoother? What are some common techniques for making the edges on a tesselated shape less apparent without increasing the amount of tesselation which is actually carried out?

As an example, I followed along with this tutorial on tesselation shaders, and one can control the inner and outer tesselation levels. With relatively low levels of both, one can achieve a pretty good sphere. However, in order for the surface to actually appear smooth, a fairly bright light seems to be required.

This particular implementation uses triangular tesselation beginning from an icosahedron to approach a sphere.

My understanding is that performing the tesselation with quads would result in a smoother surface.

Here is a picture which illustrates how direct lighting makes it much harder to see the level of tesselation. On the top right of the sphere, where the light is hitting it strongly, no edges are visible, wheres on the bottom left, the edges can easily be seen. Perhaps in practice, simply applying a texture would mask many of the edges?

GL_SMOOTH interpolates the vertex attributes of the primitive (triangle), it looks like your normals are setup per face, rather than per vertex.

If using normal per face (i.e. a single normal for the triangle), increasing the number of triangles will produce a less faceted look as there is more granularity when interpolating the normals over the surface of a given surface area given the increase in the number of triangles within that area. It is recommended to use normals per vertex for smooth surfaces when feature edges are not important (i.e. Not for cubes!).

If using normal per vertex (i.e. a normal for each vertex, resulting in each triangle having 3 vertices), each 3 vertices of a face will be slightly different if the neighbouring triangles are not coplanar to the triangle in question (i.e. not a flat surface). This will aid in the smoothness of the shading.

Normals per vertex can be easily calculated by averaging the three normals of the three vertices defining a triangle, however your surface needs to be defined with shared vertices for this. The exception to this is if you have a sphere or ellipsoid, in which case you can calculate a more precise normal easily by unitising vertex - sphereOrigin rather than averaging the three normals of the face.

On a side note: Are you using two lights in the scene of the screen shot you posted or one? If two it looks like the normals are currently not correct as the shading does not appear correct since there is a well-lit area of the surface on the bottom left region. With a single light, either the front (top right) of the sphere would be lit, or the bottom left, but not both.

Also note that simply increasing the power of the light simply over exposes the surface colour rather than improving the smoothing. You lose the surface definition.

glShadeModel(GL_SMOOTH); - probably in PezInitialize - should do what you need.