projecting 3d onto 2d plane is not showing up correctly I am trying to learn about 3d graphics from first principles, so i have decided to implement a simple thing, create a circle in 3d space & rotate it along some axis. I understand the basics theory.

position circle somewhere in 3d space.
calculate its projection on some plane.

Once i can get this i can use rotation matrix to calculate the new position of vertices. but i am a bit stuck at 2nd step.
this is my code:
import pygame
import math

(width, height) = (600, 500)
screen = pygame.display.set_mode((width, height))
pygame.display.flip()

running = True

K = 8   # view plane distance
cz = 10 # z location of circle initially.

# Pyagme 0.0 is at top left , but i want to center it at window?? is this even coorect to do or is should just continue using top left.

def translate_coords_to_center(x , y):
    return (width/2 - x, height/2 - y)

# plots a pixel
def pixel(x,y,color=(100,20,30)):
    s = pygame.Surface((1,1))
    s.fill(color)
    r,r.x,r.y = s.get_rect(),x,y
    screen.blit(s,r)

# Draw the circle
def circle(cx, cy, cz, radius):
    N = 100
    PI = 3.14
    angle = 360 / N

    for i in range(N):
        x2 = cx + radius * math.cos(PI* angle * i / 180)
        y2 = cy + radius * math.sin(PI* angle * i / 180)

        # Do a 2d projection
        x2 = K* x2 / cz
        y2 = K* y2 / cz

        pixel(x2, y2)

while running:
    x, y = translate_coords_to_center(0,0)
    circle(x, y, cz, 50)
    cz += 1
    pygame.display.flip()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

When i change the z position of circle, i get something like the below image, I am expecting the circle to not change its position but only its size, ( i know this cant be true as i am dividing by z ), am i missing some translation step? :

EDIT:  Adding the translation after projection is also not working:
import pygame
import math

(width, height) = (600, 500)
screen = pygame.display.set_mode((width, height))
pygame.display.flip()

running = True

K = 8
cz = 10

def translate_coords_to_center(x , y):
    return (width/2 - x, height/2 - y)

def pixel(x,y,color=(100,20,30)):
    s = pygame.Surface((1,1))
    s.fill(color)
    r,r.x,r.y = s.get_rect(),x,y
    screen.blit(s,r)

def circle(cx, cy, cz, radius):
    N = 100
    PI = 3.14
    angle = 360 / N

    for i in range(N):
        x2 = cx + radius * math.cos(PI* angle * i / 180)
        y2 = cy + radius * math.sin(PI* angle * i / 180)

        # Do a 2d projection
        x2 = K* x2 / cz
        y2 = K* y2 / cz
        sx, sy = translate_coords_to_center(x2, y2)

        pixel(sx, sy)

while running:

    circle(0,0, cz, 50) # this works correctly, but circles are centered at top left corner of screen,
    cz += 1
    pygame.display.flip()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

Your translate_coords_to_center(0,0) function should be done after you have done the projection from 3d to 2d.
e.g.
for i in range(N):
        x2 = cx + radius * math.cos(PI* angle * i / 180)
        y2 = cy + radius * math.sin(PI* angle * i / 180)

        # Do a 2d projection
        x2 = K* x2 / cz
        y2 = K* y2 / cz

        sx, sy = translate_coords_to_center(x2, y2)

        pixel(sy, sy)

while running:
    circle(0, 0, cz, 50)
    cz += 1
    pygame.display.flip()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

The effect you are seeing is caused by 2 things.

Because a constant x/y offset is incorrectly added in 3d world space the array of circles will appear to the right and below of the camera's position.
Because the 0,0 origin of view/camera space is not the centre of the display, instead it's at the top-left (Adding the window centre coords AFTER projection fixes that)


culling meshes across mulitple layers I am implementing foveated rendering. My FBO is divided into 2 layers which are concentric. The first layer covers 1/3 of the Framebuffer whereas the second one covers the rest of the screen. Now I want to avoid rendering meshes in the outer layer which are already in the inner layer.

I have implemented the following culling algorithm which is only concerned with culling between the layers:

I create rectangles with min and max corners from the radii of the 2 layers. Now these coordinates are in NDC.
I have the min and max corner of each mesh in the local coordinate system. So I transform them into NDC using:

vec4 min = mvp * vec4(min_corner, 1.0);
min = min.xyzw / min.w;

I create a bounding box using min and max corners.
I check whether 2 rectangles overlap or not.

Now, when I transform into clip space, the x or y coordinates of the min are sometimes greater than the max corner. The same issue occurs when I divide them by w. What's going wrong here?

EDIT:
Okay. I found the problem. Now I iterate over all the vertices, transform each of them into NDC using MVP and then calculate the min and max corners which works perfect. But this is much more overhead for each frame. Is there any optimization I can do here?

Regarding optimizations:

Could you calculate the min and max corners in modelspace beforehand? Then you could check on the CPU-side the NDCs of these two points and skip the processing of the whole mesh if it is outside of the desired range. This needs only two matrix-vector multiplications on cpu side. And since for rigid bodies these two points do not change over time, you don't have to iterate the meshes in each frame.


Curve rotation in GLSL fragment shader I'm trying to figure out the correct math to rotate and translate a curve displayed in a fragment shader.

What I try to accomplish is to define a curve, for example a sine curve, in a local coordinate system, rotate it then translate it. Something like this:

That was made in MATLAB with the following code:

dens = 1080;
x = linspace(-1.0, 1.0, dens);
y = 0.1*sin(25.0*x);

imax = 25;
for i = 1:imax

    %transformation matrix:
    ang = (i/imax)*0.5*3.14;
    c = cos(ang); s = sin(ang);
    T = [c,-s;s,c];

    %translation:
    P = [0.5;0.5];

    %transformed coordinates:
    xt = T(1,:)*[x;y] + P(1);
    yt = T(2,:)*[x;y] + P(2);

    plot(xt,yt);
    xlim([0 1.0]); ylim([0 1.0]); drawnow;
end

For the GLSL test I'm using the Book of Shaders Editor with the following code (can also be seen interactively here):

#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif

uniform float u_time;
uniform vec2 u_resolution;

// Plot a line on Y using a value between 0.0-1.0
float plot(vec2 st, float pct){
  return  smoothstep( pct-0.02, pct, st.y) -
          smoothstep( pct, pct+0.02, st.y);
}

float plotTransformed(vec2 st, float pct, vec2 transl, float ang){

    float c = cos(ang); float s = sin(ang);
    mat2 trans = mat2(c,-s,s,c);
    st = trans * st;

    st -= transl;

    return  smoothstep( pct-0.02, pct, st.y) -
          smoothstep( pct, pct+0.02, st.y);
}

void main(void) {
    bool use_plot_function = true;

    float mx =  max(u_resolution.x, u_resolution.y);
    vec2 uv = gl_FragCoord.xy /mx;
    vec3 color = vec3(0.4,0.4,0.4);

    //some screen position:
    vec2 p = vec2(0.5, 0.5);

    //the curve:
    vec2 cp = vec2(
        uv.x,
        0.08*sin(uv.x*40.0)
    );

    //the angle to rotate:
    float ang = -0.4 * 3.14 * sin(u_time);

    //Transform coordinates:
    float c = cos(ang); float s = sin(ang);
    mat2 trans = mat2(c,-s,s,c);
    vec2 cp_t = trans * cp;
    cp_t +=p;

    if(use_plot_function){
        //Attempt 1: plot unrotated original curve translated upwards:
        float curve1 = plot(uv, cp.y + p.y);
        color.g *= curve1;

        //Attemp 2: plot the transformed curve using plotTransformed, rotates first, then translates:
        float curve2 = plotTransformed(uv, cp.y, p, ang);
        color.r *= curve2;

        //Attempt 3: curve is transformed first then ploted:
        float curve3 = plot(uv, cp_t.y);
        color.b *= curve3;
    }
    else{
        float plotThk = 0.02;

         //Attempt 1: change color based on distance from unrotated original curve:
        float dist = distance(uv, cp + vec2(0.0, p.y));
        if(dist < plotThk)
            color.g *= (1.0 -dist)/plotThk;

        //Attempt 2: change color based on distance from transformed coordinates:
        dist = distance(uv, cp_t);
        if(dist < plotThk)
            color.r *= (1.0 -dist)/plotThk;

    }

    gl_FragColor = vec4(color,1.0);
}

In the code above, there are two modes which can be toggled with use_plot_function set to false or true.

First mode attempts to plot using the functions plot() & plotTransformed().
Second mode sets a color to a fragment based on the distance from the calculated curve coordinates.

Result of first mode with use_plot_function set to true:

Result of second mode with use_plot_function set to false:

Obviously I'm misunderstanding how this should be done in a fragment shader.

How should I correctly define a transformed curve in GLSL fragment shader?

You are doing completely different things in Matlab than in your Fragment Shaders.

In Matlab you are generating bunch of points that can be drawn anywhere on the screen and then you are transforming them. This would be loose equivalent of your Matlab code in Fragment Shader:

#define ARRAY_SIZE 256

void main() {
    vec2 st = gl_FragCoord.xy / u_resolution.xy;
    st = st * 2.0 - 1.0;
    st.x *= u_resolution.x / u_resolution.y;

    //the angle to rotate:
    float ang = u_time * 0.5;

    //Transform coordinates:
    float c = cos(ang);
    float s = sin(ang);
    mat2 trans = mat2(c, s, -s, c);

    // our domain is from -1 to 1 so total length is 2.0
    float xStep = 2.0 / float(ARRAY_SIZE);

    // How far we are from current pixel location to the curve
    float minDist = 1e3;

    // initialize points
    for (int i = 0; i < ARRAY_SIZE; ++i) {
        float x = -1.0 + float(i) * xStep;

        // initialize points
        vec2 cp = vec2(x, 0.08 * sin(x * 40.0));

        // transform
        cp = trans * cp;
        minDist = min(minDist, distance(st, cp));
    }

    // Add some contrast:
    float d = pow(minDist, 0.1);

    vec3 col = vec3(fract(d));
    gl_FragColor = vec4(col, 1.0);
}

(Here is the live version: http://thebookofshaders.com/edit.php?log=180516153813 ).

For drawing I'm using distance to points because of simplicity, but better way would be to use distance to line segments that the points should be connected by.

In the other hands, in your fragment shaders you are first calculating something relative to a fixed pixel location (gl_FragCoord.xy), then transforming it in a way that it is not valid from the pixel's point of view any more, and then you are hoping that you can calculate proper distance to it.
Unfortunately this won't work.

(Example of fixed location of a Fragment Shader invocation)

But what you can do is first rotate the domain (and not result of your calculations), and then perform all calculations in it:

// Plot a line on Y using a value between 0.0-1.0
float plot(vec2 st, float pct){
  return  smoothstep( pct-0.02, pct, st.y) -
          smoothstep( pct, pct+0.02, st.y);
}

void main() {
    vec2 st = gl_FragCoord.xy / u_resolution.xy;
    st = st * 2.0 - 1.0;
    st.x *= u_resolution.x / u_resolution.y;

    //the angle to rotate:
    float ang = u_time * 0.5;

    //Transform coordinates:
    float c = cos(ang);
    float s = sin(ang);
    mat2 trans = mat2(c, s, -s, c);

#if 1
   // You need to transform domain first:
   st *= trans;

   // then perform the calculations:
   vec2 cp = vec2(st.x, 0.08 * sin(st.x * 40.0));
#else
    // This won't work (your old way):
    vec2 cp = vec2(st.x, 0.08 * sin(st.x * 40.0));
    cp = trans * cp;
#endif

    vec3 col = vec3(fract(distance(st, cp)));
    col.r += plot(st, cp.y);

    gl_FragColor = vec4(col, 1.0);
}

(Live version: http://thebookofshaders.com/edit.php?log=180516154712 )


Improve accuracy of mesh gradient? So to make it simple. I currently use a method I found online to compute the gradient of a scalar field of a mesh.
To test how accurate this is, I made a sphere and followed the gradient direction of the geodesic field to construct a line. That is to say, pick $p$ on the sphere and define $\phi(X)$ the function that return the geodesic distance between $X$ and $p$.
By a property of the exponential map described by Manfredo Do Carmo, the geodesic gradient (the tangent) at $X$ uniquely describes the geodesic containing both $X$ and $P$.
In short, if you know the correct tangent at $X$ you can just follow that direction in the exponential map and eventually hit the source $p$.
So I went and coded exactly that:

In that image, the source $p$ is at the intersection of the 3 lines in the bottom part of the image. So my line passes very close to it, but it doesn't hit.
My assumption is, this happens because my gradient approximation is quite linearly based and as such even small errors quickly have big effects, especially as the points grow farther apart.
I am wondering  if people know of methods or algorithms that can improve the accuracy of the gradient.
I got the formula for the discrete gradient at page 28 here.

I dont know what you are using to calculate the Cotan, the accuracy should different on the implementation.
But you could do more accurate calculations yourself by approximating the values using taylor expansions.
Or find some other librar that can do it more accurate.
Also, make sure you are using high prec datatypes.


Successive lineTo(x, y) in JavaScript When I was doing some graphic designing with JavaScript, I saw this strange behaviour.
When I ran the following code (with proper HTML and JavaScript of course),

context.lineTo(100, 100);
context.lineTo(200, 200);
context.stroke();

The result was a straight line from (100, 100) to (200, 200), which I wasn't expecting. I expected that nothing would be drawn. I think this would only happen with the following code:

context.beginPath();
context.moveTo(100, 100);
context.lineTo(200, 200);
context.stroke();

Is my thinking wrong? Why is it happening so? Can anyone explain?

Straight from the specification of lineTo:

  If the object's path has no subpaths, then ensure there is a subpath for (x, y).

And "ensure that there is a subpath" links to this bit:

  When the user agent is to ensure there is a subpath for a coordinate (x, y) on a path, the user agent must check to see if the path has its need new subpath flag set. If it does, then the user agent must create a new subpath with the point (x, y) as its first (and only) point, as if the moveTo() method had been called, and must then unset the path's need new subpath flag.

In short, if you call lineTo without an explicit beginPath, then a new path is created implicitly, with the given point as its starting point.


Rounding a 3D corner with Subdivisions Following the instructions from this post on Stack Overflow, I have been able to find points A, B, and C from points V1, V2, and V3 and a radius value (code below). I would like to be able to find a specified number of subdivisions for the arc section labeled 'Arc B.' Can anyone help me find these position values of these points please?

    r = 106 #radius
    V1 = Vector(50, 100, 0)
    V2 = Vector(100, 300, 0)
    V3 = Vector(350, 350, 0)
    a = V2-V1
    b = V2-V3
    a.Normalize()
    b.Normalize()
    halfang = math.acos((a.Dot(b)))/2
    ab = (a+b)/2
    ab.Normalize()
    A = V2 - r/math.tan(halfang)*a
    B = V2 - r/math.tan(halfang)*b
    C = V2 - r/math.sin(halfang)*ab

One very simple way to do it is to just find the straight line distance between the points A and C. Divide that distance by the number of points you want to subdivide+1. Then starting at A moving along the line formed between A and C add that distance for each subdivision. This gives a nice even subdivision without having to argue with PI.
To get the point on the circle, just take the normalized vector between B and your new point and multiply it by the radius of the circle. The result is a subdivision point on your circle/sphere.
float distanceAC = length(C-A);
float stepLength = distanceAC/(SubdivisionsCount+1); // 4 in this case
vector v = C-A; // gives a vector pointing from A to C
v = normalize(v);
for( int i=1; i<SubdivisionCount+1; i++ ){
     point pointOnLine = A + v*i*stepLength; // Need steplength*i steps along v
     point subdivisionLocation = normalize(pointOnLine-B)*radius;
     // save the subdivision location
}

This has the plus of being simple, but the negative is that if you want to do to many steps or you want your steps to be extremely accurate, or you want to subdivide over a very large arc, then accuracy suffers.


The most performant way to organize vertex data on modern GPUs Say I have a model made up of vertices, each with position, normal, tangent, and texcoord attributes, where triangles are specified by index triples.

If we just focus on the vertex attributes, I'm aware of two broad strategies: the structure of arrays, and the array of structures. I've also heard that the array of structures is preferred because it increases the memory locality (and therefore cache locality) of the attributes for a given vertex.

Is it really the case that this improves performance? The main way I could think that this would come about is by vertex indices that require the rasterizer to acquire vertex data that has long since been evicted from cache. If vertex data access is random like this, then keeping all the attributes for a vertex on the same cache line would certainly make things faster, but is this not an issue that could be mostly mitigated by optimizing the order of triangle specification?

Furthermore, it's my understanding that modern GPUs may be better at unpacking long vectors of the same type, than vectors of structures of many types. Would it then be possible for a structure-of-arrays layout to consistently outperform an array-of-structures layout of the same vertex data, if the index order is optimized?

Apologies, I was going to add a comment to your question thread but found I ended up elaborating too much.  My development experience is from a DX 11 perspective so some of this may not hold in OpenGL

The memory locality of the data does certainly play a major part.  But there is a few other items that do play into this, the width of the data as you know.  I've had a few GPUs and have had a stark performance hit on some based upon certain tipping points.  That is the for example, on my old AMD r290 if I recall, you could basically pass up to 4 float4s through to the vertex buffer with no additional cost over 1, but once I posted > 4 then there was a measurable drop (in frame rate).   This is purely off my recollection and so is anecdotal as best.  But it holds that GPU architecture is changing all the time, and what niche techniques that give you a performance edge today maybe the bane of your performance tomorrow.  I've tried myself to stick to the advised known best on the assumption that hardware vendors will build their GPUs to the most common techniques of passing payloads via VB (obviously with some looks from constant buffers).

Having said that, you have asked the question about ordering the vertices, and certainly that will help marginally.  The performance gain is when you combine this with index buffers which then allows the hardware to optimise and cache already calculated vertices.    You certainly may get even more gains from Triangle strips etc which specifically ordered as per your thoughts.  Most of model rendering I do is indice/vertex based optimised models with instancing, I use a small amount of lookups for cyclic motion effects (tree branches for example), in these cases the entire branch of the tree is looking up the same value.  So caching can be taken advantage of here also.

All I can say in summary from myself is:

Try not to overthink optimisation at the start, while your still developing your game/application try not to prematurely optimise.  If you need to come back and add new capabilities, you might lose all the effort.  You have my habit maybe ><, love trying to get the best performance and techniques
GPU architectures are varied, and strengths of one can reflect weaknesses in another.  AMD and Nvidia are famous for getting devs to optimise games to their architecture, for a reason, each has advantages/disadvantages.  Taking the middle road on development might be the best place, don't use any hardware vendor based features (opinion here).  (add to that, some packed formats only exist in AMD).

These are just a few thoughts and experiences I have had.  There are a lots books out there that you should get your hands on around these very topics.  I've not seen to many prescribe what you're proposing, but that doesn't mean its wrong.  Good luck.


Attribute Location in Multiple Shader Programs I'm trying to switch between the rendering of two different scenes as fast as possible using OpenGL.

For all my OpenGL related stuff I wrote a wrapper-class which provides a quite easy way of adding and updating data. Based on the added data it automatically creates the variable naming for the shader. In the past I always used just one instance of this OpenGL class but now I'm trying to use two of them. (Each instance has its own shader program.)

When I do something like:

OpenGLInstance1.AssignModel(*MyModel1);

it automatically adds data and writes into the shader code:

// per vertex attributes
layout (location = 0) in vec3   position;
layout (location = 1) in vec3   normals;
layout (location = 2) in uvec4  BoneIDs;
layout (location = 3) in vec4   Weights;

// per instance attributes
layout (location = 4) in mat4   CameraMatrix;           //dynamic
layout (location = 8) in mat4   ProjectionMatrix;       //dynamic

When I try to do this a second time with an other OpenGL-Class instance and Model:

OpenGLInstance2.AssignModel(*MyModel2);

I get:

// per vertex attributes
layout (location = 12) in vec3  position;
layout (location = 13) in vec3  normals;
layout (location = 14) in uvec4 BoneIDs;
layout (location = 15) in vec4  Weights;

// per instance attributes
layout (location = 16) in mat4  CameraMatrix;           //dynamic
layout (location = 20) in mat4  ProjectionMatrix;       //dynamic

But since the GL_MAX_VERTEX_ATTRIBS gives a maximum number of attributes of 16, this is not possible.

Question 1

Each VAO (vertex array object) has some VBO (vertex buffer object) assigned. Is the location indexing of the VBO just in the scope of each VAO (starting again from zero for each VAO) or is it independent of the VAO?

Question 2

Do you have a suggestion how to work around this problem while keeping the implementation as generic, reusable and scalable as possible? (Just some general hints, I don't want to bother you with details.)

Each VAO, and shader for that matter, has a separate space of attribute locations. It's perfectly fine to have multiple shaders use the same attribute locations. Indeed, it's a good idea to do so if those attributes conceptually mean the same thing to both shaders.

A VAO can be used with a shader if that VAO's attribute locations match those the program expects. Well, technically they don't have to match. It's OK if the VAO provides an attribute that a shader doesn't use. It's more complicated if a VAO doesn't provide an attribute for a location that the shader expects.

So whatever it is that generates your shader prefix strings and VAOs should not be based on what has been generated for other shaders/VAOs. So if you're going to have attributes increase numerically starting from 0, then this should be the case for each independent shader. It should not be based on some constantly increasing global.


Handling Projective Aliasing In Shadow Mapping I'm fiddling with simple procedural 3D modeling to make teeny buildings for 3D printing. An Example:

To make the models more readable onscreen, I've implemented basic shadow mapping for a single directional light. Since my scene isn't changing, I just render the shadow map once using an axis aligned box of the scene to figure out what the bounds of the shadow map should be. The shadows and bounds look like I've got all the matrices right, but coming in a bit closer looks terrible:

From the reading I've done, I understand the peter panning and what I might do about it, but the ragged edges, which I believe is a form of projective aliasing, look so bad that I think something is wrong in my basic implementation.

I hacked the pixel shader to show the shadow texel boundaries:

I've got bilinear filtering on in the texture (without it, I get serious shadow acne). Sadly, my attempt at PCF failed too - it looks just as ragged:

Here's the single sample case with bilinear filtering disabled:

Does this look like "typical" projective aliasing? Could dynamic rendering of the shadow map, using the view frustum clipped to the scene, possibly with cascading, address the issue?

Edit: Adding a closeup of bilinear filtering, post shadow comparison, just to show what I get. Bad shadow acne shows up because of interior edges; I'm modeling with stacked virtual blocks and not doing a proper union operation. From my reading, implementing boolean operations on polyhedra is not trivial, but will also allow me to implement static shadow volumes as well as clean up for some 3D printing software.

Shadow mapping with acceptable quality is quite a journey. So you implemented first step - basic shadow map that encompass whole scene statically. This means that shadow map texel size in light view space to texel size of rendered scene in camera view space ratio is quite big, resulting in aliasing. To reduce this ratio closer to 1:1 there are techniques you mentioned like:

the easiest way is increasing size of your shadow map, to find the value with still optimal performance,
align shadow map with camera view frustum. Then shadow map encompass smaller part of the scene, so it reduces aliasing,
this can be improved to CSM, which does the same but you need to render scene for each of cascade with different center position of light view matrix based on center point of each slice of frustum.

Some of the basic techniques of smoothing the edge of shadow:

obviously PCF, but is it recommended to combine your PCF implementiation with built in hardware PCF (in Opengl - using sampler2DShadow). This would result in less loop iterations from your side and cheaper PCF,
blockiness of edges can be exchanged for noise using rotated Poisson Disk. Samples used to sample from shadow map are rotated randomly with each iteration of PCF loop.

You can also research the edge smoothing techniques like:

rendering shadow map to MSAA applied framebuffer,
further enhancing PCF by interpolation,
increasing number of samples with temporal blend.

PCF basic technique suffers from shadow acne which can be fixed by applying some offset in shadow test. Calculating the size of this offset is also area of research.

Other more advanced shadow map methods include:

Exponential Shadow Maps and Variance Shadow Maps - in most cases do not suffer from shadow acne and offer smooth edges without blockiness, but in cost of some light leaking situations,
Exponential Variance Shadow Maps - probably most advanced technique of 2D depth map shadow mapping, combines great smoothness of VSM and resolves light leaks, in a cost of memory usage doubling,
Percentage Closer Soft Shadows - basic technique of enhancing traditional shadow maps with varying penumbra size,
Multiview Shadow Maps - multiple shadow maps of some technique, arranged on area light, for computing realistic soft shadows with varying penumbra size,
Deep Shadow Maps - for enhancing volumetric scattering with shadows,
Real time ray traced shadows - probably the future.

You didn't fail with PCF, it looks like that:)

I wish there was a way to apply gaussian blur on shadow map in camera view space, but it doesn't work as expected.


What blend mode is this? I asked this on Graphic Design but was unable to get any relevant help from them.

I'm trying to reverse engineer a blending mode I've seen on a picture:

This image was created by someone else using Adobe's Scene7 during a Displacement Map Filter operation. I'm only interested in the blending mechanism, not the distortion.

Unfortunately, I was unable to reproduce this effect on other raster graphics editors. It almost looks like the images were blended with Multiply followed by a recolor operation of some sort. Anyway, I'm trying to figure out the equation used for this type of blending.

If you look at the top left corner of where the images overlap, you can see just a little bit of the background leaking to the foreground image.

The original images have the same dimensions and can be found below:

Any idea on how to duplicate this effect?

That looks like multiplying the front image by the luminance of the shirt behind it.

There are multiple definitions of luminance but for a start, I think you could assume your data is sRGB and follow the transformation to CIE to get the CIE Y component.


Compute shader not updating buffer, or vertex buffer unable to read the updates I'm learning OpenGL compute shaders and following this guy's code, and I have stuff drawing, but not updating.  The particles are spread out in their starting positions, but they stay there.

Particle manager initialization

void ParticleManager::Init(unsigned int programId,
    unsigned int computeProgramId,
    unsigned int numParticles)
{
    ...reset all particles...

    _unifLocDeltaTimeSec = glGetUniformLocation(_computeProgramId, "uDeltaTimeSec");

   _shaderBufferId = 0;
    glGenBuffers(1, &_shaderBufferId);
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, _shaderBufferId);
    glBufferData(GL_SHADER_STORAGE_BUFFER, _allParticles.size() * sizeof(Particle), _allParticles.data(), GL_STATIC_DRAW);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, _shaderBufferId);

    ...vertex array buffer and attribute array initialization...
}

Particle manager update

void ParticleManager::Update(float deltaTimeSec)
{
    glUseProgram(_computeProgramId);
    glUniform1f(_unifLocDeltaTimeSec, deltaTimeSec);

    GLuint numWorkGroupsX = (_allParticles.size() / 128) + 1;
    GLuint numWorkGroupsY = 1;
    GLuint numWorkGroupsZ = 1;
    glDispatchCompute(numWorkGroupsX, numWorkGroupsY, numWorkGroupsZ);

    glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT | GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);

    glUseProgram(0);
}

Particle manager render

void ParticleManager::Render()
{
    glUseProgram(_programId);
    glBindVertexArray(_vaoId);
    glDrawArrays(GL_POINTS, 0, _allParticles.size());
    glUseProgram(0);
}

Compute shader

#version 440

struct Particle
{
    vec2 _position;
    vec2 _velocity;
    int _isActive;
};

layout (local_size_x = 128, local_size_y = 1, local_size_z = 1) in;

layout (binding = 0) buffer ParticleBuffer {
    Particle AllParticles[];
};

uniform float uDeltaTimeSec;     // self-explanatory

void main()
{
    uint index = gl_GlobalInvocationID.x;
    Particle p = AllParticles[index];

    vec2 deltaPosition = p._velocity * uDeltaTimeSec;
    p._position = p._position + deltaPosition;

    AllParticles[index] = p;
}

I've looked through various forum posts (stack exchange, stack overflow, OpenGL forums) and read at least one tutorial and followed another guy's github project (only allowed 2 links in a post), but I haven't been able to figure out why nothing moves.

My top culprits are:

Something in the compute shader's "delta position" is evaluating to 0.
The compute shader is not getting called.
The draw shader is not getting access to the compute shader's updated info.

Doubts:

I hard coded a change in position, so all particles should have moved some on every frame, and when that didn't work, I hard-coded a position, and that didn't work either, so the shader might not even be getting to main().
numWorkGroupsX evaluates to 79 (non-zero), so the compute shader should at least reach main().
I called glMemoryBarrier(...) with GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT, so the vertex array buffer should have access to the updated info.

Also, no errors or warnings are reported during GLSL compilation or at runtime, so the computer is evidently happy with what I provided it.

Help?  Why are my particles never moving beyond initialization?

Got help from someone over in the OpenGL subreddit.  Apparently, as I trimmed the code for posting here and there, I changed the operation of the code.

What I trimmed to this:

void main()
{
    uint index = gl_GlobalInvocationID.x;
    Particle p = AllParticles[index];

    vec2 deltaPosition = p._velocity * uDeltaTimeSec;
    p._position = p._position + deltaPosition;

    AllParticles[index] = p;
}

Was more or less this:

void main()
{
    uint index = gl_GlobalInvocationID.x;
    Particle p = AllParticles[index];

    // update position
    vec2 deltaPosition = p._velocity * uDeltaTimeSec;
    deltaPosition = vec2(0.0f, 0.0f);
    //p._position = p._position + deltaPosition;
    p._position = deltaPosition;

    AllParticles[index] = p;
}

Which should have been this:

void main()
{
    uint index = gl_GlobalInvocationID.x;
    Particle p = AllParticles[index];

    // update position
    vec2 deltaPosition = p._velocity * uDeltaTimeSec;
    //deltaPosition = vec2(0.0f, 0.0f);
    p._position = p._position + deltaPosition;
    //p._position = deltaPosition;

    AllParticles[index] = p;
}

So I really just did that.  The redditor who helped me downloaded my source code via github and found the error.  Standard case of one pair of eyes glossing over an error.

All is well now.


Texture coordinates projection I have some classic texture coordinates and as a normal behaviour they follow the mesh's transformations.

I am trying to use the same texture coordinates behaviour but without being affected by the mesh rotation transformation. The results would be a sort of texture coordinates projection.

I don't know if my explanations are well explained but how could I achieve such effect.

Thanks a lot.

GLSL has built-in fragment shader inputs, and one of them is gl_FragCoord. You can get the $x$ and $y$ value from this and use that as the lookup coordinate of the texture map in a sequence of two passes, but that could be a good or bad thing depending on the application (such as caching the result). This would both be rotation invariant while allowing you to scale and move the mesh.

First Pass

Transform the mesh without rotation. Bind a texture to the fragment shader and write the interpolated UV coordinates to it.

Second Pass

Transform the mesh correctly this time. Bind the texture from the last pass and read from it this time. You preserved the old UV coordinates, and now you can use these to look up whatever texture you have before. Obviously, this works best with a mesh that's a sphere (such as an eye).

vec2 texCoords = gl_FragCoord.xy; // do some sort of scaling
vec2 oldTexCoords = texture(samplerOfUVTexture, texCoords); // sample UV

Now you have both the old UV coordinates and the new UV coordinates. You can use the new UV coordinates for you diffuse map and the old UV coordinates for the occlusion map.


Chromakey Conversion I have a program I wrote that allows chromakey (green screen) using a web cam. I wrote it using DirectShow - I created a custom filter to blend the web cam video with a graphic. It works fine but requires huge amounts of CPU. Also, from what I understand, DS is deprecated - or at least on its way out.

So, I'm thinking about re-doing it with OpenGL and using OpenCV to grab the web cam video. I don't have a lot of experience with OpenGL, so my question is: If I create a chromakey shader will it be executed on the GPU and therefore be faster? Or is this something for which OpenGL is not useful?

I would like the input of someone with experience before I attempt this.

It almost certainly depends on implementation. I have used CPU only keyers that had no problems keying full hd in real time.

But back to the question would a shader be faster? Most likely, especially if your chroma key is a classic color transform. Then the GPU would shine as it would get to use it massive multicore architecture to full potential.


Which method for detecting edges of white object on white background? I would like to segment picture of cloths in order to remove the background. The pictures come from online retailers, they usually have an homogeneous white background.

Using Canny edge detector works in most of the cases, but sometimes the cloths are nearly as white as the background making the edges hard to detect.

I tried to play with the min and max parameters in opencv (python), but I can't recover the clean edge, either I do not get the surrounding of the cloths (holes in the reigion) or the the edge is noisy around the cloth.

Here's one of the tricky example:

Simple growing region for background detection also doesn't work well enough.

So how do you detect the contour of an object if it has nearly the same color as the background?

It's quite difficult. There is so little contrast, even the JPEG compression artifacts have more contrast than the object on the background.

You would require a highly specialized deblock filter to eliminate the compression artifacts first. With knowledge about the block size of the used compression algorithm and the number of coefficients used per block you may be able to predict some of the edges.

For edges you could predict in the previous step, you may try to filter these from the detected edges.

All around the shirt in the photo, there are over-swings due to an excessively  lossy compression. At the edge of each block, the over-swings form a hard edge which you also successfully detected.

The block size is 8x8 pixels for JPEG (and hence also in this image), so every vertical or horizontal edge which falls directly onto position 8*n or 8n+1 X or Y is most likely just a compression artifact and can be ignored.

This approach can only work though if the image hasn't been re-sampled after compression, respectively hasn't been re-compressed multiple times with potentially different block sizes. At that point, isolating the compression artifacts becomes nearly impossible.


Vertices, Vertex Normals and Face Normals Using Open 3D Model Viewer, I have converted an OBJ file to an STL file.
In the source file, the Vertex Normals are specified and in the destination, the face normal of the triangles are present which are different than the normals one would get by (a-b) x (a-c), where a, b, c are the vertex coordinates and x is the cross product. How one would compute the face normal in the presence of vertex normals?
Also, I am given to understand that STL format has a positive octant rule which requires all vertex coordinates to be positive. When the OBJ file has negative vertex coordinates, what should be done in the conversion process?

I'm not familiar with the exact nuances of the STL format, but here are some answers on general computer graphics principles:

In the source file, the Vertex Normals are specified and in the destination, the face normal of the triangles are present which are different than the normals one would get by (a-b) x (a-c), where a, b, c are the vertex coordinates and x is the cross product. How one would compute the face normal in the presence of vertex normals?

There is no general method to convert vertex normals to face normals. Vertex normals (that are not all equal) can express the normals of a curved surface, which face normals cannot. Thus, converting to a format with only a normal vector per face, rather than per triangle vertex, is a lossy process — some information was discarded. The converter must make a compromise.
That said, from some quick research, it seems that the intent of the STL file format is that the normal is the normal perpendicular to the triangle (that can be computed as you specified), not a chosen vector, even though that makes it redundant. So perhaps your converter is wrong (though I can't say much as you didn't say how it was different).

Also, I am given to understand that STL format has a positive octant rule which requires all vertex coordinates to be positive. When the OBJ file has negative vertex coordinates, what should be done in the conversion process?

The only option is to choose some offset by which to translate all of the vertices so that they are positive. This also loses some information — what the origin of the original model was. That's easier to recover if needed, though, since it's just a 3D vector that you could translate back by when loading the model.


What kind of transformation when the aspect is changed for a rotated shape? I have a geometric shape (assuming that is a rectangle). I want to rotate it about it geometric center by an angle of 45° and plot the result using matplotlib with an equal aspect ratio, I get something like this:

However for some reason, I want to plot the result in a figure with a non-equal aspect, I am getting this result:

As you can see, the rotated shape is deformed (skewed). But the original shape seems to be scaled only in the y direction.
I am trying to understand what kind of transformation is occuring to the orange shape from a linear algebra perspective: Is it a shear? a combination of scaling and shear (Affine transformation)? if not what kind of transformation is that?
My goal is to identify the type of transformation, then finding it's inverse to get the following result:

I appreciate any help.

Let's talk about linear geometric transformations in homogeneous coordinates.  In your question there are mainly two kind of geometric transformations involved: planar rotation and planar scaling, the computation-friendly analytical re-definitions of which are found hereUnified frameworks of elementary geometric transformations.

The 2D homogenous rotation matrix that rotates 2D objects clockwise by $\theta$ radians is as below:

$$R=\left[
\begin{array}{ccc}
 \cos \theta & \sin \theta& 0 \\
 -\sin\theta & \cos\theta & 0 \\
 0 & 0 & 1 \\
\end{array}
\right]$$

A 2D scaling due to unequal aspect ratio $\rho$ in this case is a stereohomology with $x$ axis $(0,1,0)^T$ as the stereohomology interface (a line of invariant points), and the normal direction $(0,1,0)^T$ as its stereohomology center per definition 3.9 in page 12 and line No. 5 in Table 1, page 9 of the article Unified frameworks of elementary geometric transformations. Then its scaling matrix can be obtained as below:

$$S=\color{gray}{\left[
\begin{array}{ccc}
 1 & 0 & 0 \\
 0 & 1 & 0 \\
 0 & 0 & 1 \\
\end{array}
\right]+\left(\rho-1\right)\dfrac{\left[
\begin{array}{c}
 0 \\
 1 \\
 0 \\
\end{array}
\right]\cdot \left[
\begin{array}{ccc}
 0 & 1 & 0 \\
\end{array}
\right]}{\left[
\begin{array}{ccc}
 0 & 1 & 0 \\
\end{array}
\right]\cdot \left[
\begin{array}{c}
 0 \\
 1 \\
 0 \\
\end{array}
\right]}=}\left[
\begin{array}{ccc}
 1 & 0 & 0 \\
 0 & \rho  & 0 \\
 0 & 0 & 1 \\
\end{array}
\right]$$

When aspect ratio normally is $\rho=1$, suppose under this circumstance the original object has the homogeneous coordinates of $n$ points in $3\times n$ matrix $X$, and the transformed object in $3\times n$ matrix $Y$, then the geometric transformation between them is the rotation you have mentioned:

$$Y=R\cdot X$$

When the aspect ratio abnormally is $\rho\ne 1$, both $X$ and the $Y$ after rotation are as a matter of fact scaled along the $y$ axis:

$$X'=S\cdot X$$
$$Y'=S\cdot Y$$

Now you want to find the geometric transformation $T$  which satisfies $Y'=T\cdot X'$. Since:

$$Y'=S\cdot Y=S\cdot R\cdot X =S\cdot R\cdot S^{-1}\cdot X'$$

then

$$T=S\cdot R\cdot S^{-1}$$
$$=\color{gray}{\left[
\begin{array}{ccc}
 1 & 0 & 0 \\
 0 & \rho  & 0 \\
 0 & 0 & 1 \\
\end{array}
\right]
\cdot
\left[
\begin{array}{ccc}
 \cos \theta & \sin \theta& 0 \\
 -\sin\theta & \cos\theta & 0 \\
 0 & 0 & 1 \\
\end{array}
\right]\cdot
\left[
\begin{array}{ccc}
 1 & 0 & 0 \\
 0 & \dfrac{1}\rho  & 0 \\
 0 & 0 & 1 \\
\end{array}
\right]=}\left[
\begin{array}{ccc}
 \cos \theta & \dfrac{\sin \theta}{\rho } & 0 \\
 -\rho  \sin\theta & \cos \theta& 0 \\
 0 & 0 & 1 \\
\end{array}
\right]$$

It is a rotation under the generalized meaning.


Compensation for energy loss in single-scattering microfacet BSDF models Single-scattering microfacet-based surface models like the original Torrance-Sparrow BRDF or derived models like the BSDF for rough dielectric surfaces by Walter et al. neglect inter-reflection of light between microfacets, which results in energy loss causing darkening especially at higher roughness values.

The problem can be easily demonstrated using the furnace test. The following images show the behaviour of my implementation of a conductive microfacet BRDF using the Smith model and GGX distribution for roughness parameters from 0.2 to 1.0 (the Fresnel coefficient is deliberately set to 1 here to make the problem easier to see):

Furnace test of rough dielectric (IoR 1.51) BSDF using the Smith model and GGX microfacet distribution for roughness parameters from 0.2 to 1.0:

Eric Heitz et al. have just recently proposed a multiple-scattering model which solves the darkening problem by solving the light interaction completely, but there are performance issues due to stochastic nature of its evaluation routine as metioned by Heitz himself in the LuxRender forum.

Is there a known compensation method for recovering the lost energy of single-scattering models? Not necessarily physically correct, but at least not breaking physical plausibility (Helmholtz reciprocity and energy conservation) too much and, ideally, without the necessity of hand tuning parameters.

In the Disney BSDF, there is a parametrized component called “sheen” (basically a Fresnel-based glossy lobe) which can be used for compensation of darkening at edges, but as they mention in their Siggraph 2015 course it is very ad hoc method:

  “...this is very approximate, and doesn't work as well for other
  roughness values...”

The aforementioned comment from Eric Heitz in the LuxRender forum also suggests using some compensation hack, but, unfortunately, doesn't go into any details:

  To my knowledge, you can use some simpler hacks to improve energy conservation in the single scattering models (like tweaking albedo). However, if you do that, you cannot get a perfectly energy conserving material (for instance perfect white rough glass) without breaking the reciprocity of the BSDF.

To my knowledge, there is no easy and analytic way of recovering the energy lost in single-scattering models. The previous techniques precompute the energy loss and reinject it in the BRDF as a diffuse-like component:

http://sirkan.iit.bme.hu/~szirmay/scook.pdf
http://www.cs.cornell.edu/projects/layered-sg14/layered.pdf

What they propose is energy conservative and reciprocal, and it is probably the simplest way of fixing the visual darkening due to the energy loss. The main drawback is that since the energy loss does not have an analytic expression, it has to be precomputed and stored in a look-up table.


Is it possible to draw the intersection of two squares of known dimension using only x,y coordinates and without an if statement? Say I have two squares, both 10x10, with some small, unknown overlap.

Is there a way to draw the intersection of these two squares using the width, height and x,y coordinates of each square, while also not using an if statement?

Thanks.

Basic calculations
I'm assuming you want to calculate the bounds of the rectangle of intersection, so you can draw it later. As AlanWolfe mentioned, you will want to use the max and min functions. This is so you can retrieve the left-most, right-most, top and bottom squares. We'll call these placeholders right, bottom, left, and top (each of these will point to one of the two squares).
Now that you know these, you can start mathing. The top-left position of the intersection will be at (right.x_left, bottom.y_top). The bottom-right position of the intersection will be at (left.x_left + left.width, bottom.y_top + bottom.height).
Rendering the intersection
To draw this rectangle (unconditionally), first you will need a location and a dimension, because most draw functions require these.
Intersection.width = Intersection.x_right - Intersection.x_left

and the same for the height. Now suppose the squares don't overlap. This would mean at least one dimension is negative. We don't want anything to draw in this case, so we will set any negative dimensions to zero.
Intersection.width = max(Intersection.width, 0)

and the same for the height. And to wrap up, we render our rectangle:
fillRect(Intersection.x_left, Intersection.y_top, Intersection.width, Intersection.height)


`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.


DirectX 12: Uploading multiple buffers to 1 default heap using the UpdateSubresources API without explicit copies Consider a situation where there are 3 different buffers describing a particular mesh piece: vBuffer, nBuffer, iBuffer (vertices, normals, and indices) which equate to totalBufferSize in aggregate.

I want to save these 3 buffers to the same default heap (D3D12_HEAP_TYPE_DEFAULT).  I know I still need to use an upload heap (D3D12_HEAP_TYPE_UPLOAD) as an intermediary but I can't figure out how to eliminate extra copies.

Currently my code (which works) does the following:

    const D3D12_HEAP_PROPERTIES defaultHeapProperties = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT);
    const D3D12_HEAP_PROPERTIES uploadHeapProperties = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD);

...

    const CD3DX12_RESOURCE_DESC resourceDescV = CD3DX12_RESOURCE_DESC::Buffer(totalBufferSize);
    DX::ThrowIfFailed(device->CreateCommittedResource(
        &defaultHeapProperties,
        D3D12_HEAP_FLAG_NONE,
        &resourceDescV,
        D3D12_RESOURCE_STATE_COPY_DEST,
        nullptr,
        IID_PPV_ARGS(meshPart.m_mainBuffer.ReleaseAndGetAddressOf())));

    DX::ThrowIfFailed(device->CreateCommittedResource(
        &uploadHeapProperties,
        D3D12_HEAP_FLAG_NONE,
        &resourceDescV,
        D3D12_RESOURCE_STATE_GENERIC_READ,
        nullptr,
        IID_PPV_ARGS(meshPart.m_uploadBuffer.ReleaseAndGetAddressOf())));

    uint8_t * bufferStart{};
    const CD3DX12_RANGE readRange(0, 0);
    DX::ThrowIfFailed(meshPart.m_uploadBuffer->Map(0, &readRange, reinterpret_cast<void **>(&bufferStart)));

    // Can these be eliminated?
    uint32_t offset{};
    std::memcpy(bufferStart, vBuffer.data, vBuffer.totalSize);
    offset += vBuffer.totalSize;
    std::memcpy(bufferStart + offset, nBuffer.data, nBuffer.totalSize);
    offset += nBuffer.totalSize;
    std::memcpy(bufferStart + offset, iBuffer.data, iBuffer.totalSize);

    D3D12_SUBRESOURCE_DATA bufferData{};
    bufferData.pData = bufferStart;
    bufferData.RowPitch = totalBufferSize;
    bufferData.SlicePitch = totalBufferSize;

    UpdateSubresources<1>(commandList, meshPart.m_mainBuffer.Get(), meshPart.m_uploadBuffer.Get(), 0, 0, 1, &bufferData);
    CD3DX12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(meshPart.m_mainBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER);
    commandList->ResourceBarrier(1, &barrier);

However, I'm trying to figure out if I can eliminate those std::memcpy calls.   All examples of UpdateSubresources I've seen do not explicitly Map+memcpy into the upload buffer.  They just set D3D12_SUBRESOURCE_DATA.pData directly.

I tried calling using UpdateSubresources<3> and passing in an array of D3D12_SUBRESOURCE_DATA, each pointing to the beginning of my mesh buffers, but the validation layer didn't like that and threw an exception.

Is it possible to upload all 3 buffers in one step here -- without the explicit Map and memcpy steps?

UpdateSubresources is a helper function. Inside it is another memcpy. I would recommend simply rewriting it - source is in d3dx12.h. Then you will be able to copy your data no more than necessary.


Move position in smooth gradient I am decrementing/incrementing position x until it reaches y. However, this creates a rectangular-like path. I want position x to smoothly curve towards y (diagonally) on a 2D plane.

What kind of maths would I need to achieve this?
Example image attached.

The math you need is linear interpolation. I think of a player sprite which moves from position X to position Y. Pseudocode:

playerSprite.x = Y.x + t * (X.x - Y.x)
playerSprite.y = Y.y + t * (X.y - Y.y)

where t is a value between 0.0 and 1.0 (floating point). Instead of incrementing the position components of Y you increment t till it reaches 1. When it reaches 1 the playerSprite reached point X. If t is 0, then the playerSprite is at position Y.


How to use 32 bit Integers for Element Indices in WebGL 1.0? WebGL 1.0 specification does not allow to create 32-bit index buffers. Now I'm in trouble, I'm trying to render huge objects with 100 thousands to 1 million indices. In OpenGL this is no issue at all, and I think it will be no issue in WebGL too, in most cases.

I am not able to split my data into smaller subsets as I'm already working with split data sets and can't divide it further without breaking up my full program logic.

Now I came across a new extension for WebGL from 2012, OES_element_index_uint, which looks like it enables unsigned integers (32 bit) for drawElements calls.

/* draw geometry lines by indices */
gl.drawElements(gl.LINES, getIndexBuffer().length, gl.UNSIGNED_INT, idxBuffer);

But when I try to use the gl.UNSIGNED_INT I run into the following error:

Error: WebGL: drawElements: Invalid `type`: 0x1405
uncaught exception: gl.INVALID_ENUM was caused by call to drawElements

How to use 32 bit Integers for Element Indices in WebGL 1.0? How to enable this extension in Chrome or Firefox?

Does this mean in general such a call won't be compatible with most devices running WebGL 1.0?

Enabling the extension is as simple as:

var uints_for_indices = gl.getExtension("OES_element_index_uint");

if uints_for_indices is null then the extension is not available and you'll have to split your data anyway.

If it's not null then you can now pass gl.UNSIGNED_INT for the index type into gl.drawElements.


Projection of a Polyhedron on xy Plane with CGAL I am trying to project a Polyhedron on the xy plane with CGAL, which should result in a (2D) polygon.

I wonder, if there is an elegant way to achieve it?

Of course, I can iterate over all surfaces and build 2D-Segments from the 3D-Segments by throwing away the z coordinate and then reassemble the polgon cycles.

But I feel, that somehow using Projection_traits_xy_3 it should be possible to solve that task more elegant, however, I couldn't find a way. Is this possible?

A possible way to do this is tracing the silhouette edges of the polyhedron and projecting them to a 2d polygon only at the end of the process.

A silhouette edge (in your context) is defined by its neighboring facets having one upwards and one downwards normal (i.e., one positive normal z-coordinate and one negative). This can be checked using Polyhedron_traits_with_normals_3 or you can compute the normals yourself on-the-fly.

If you only need the outside polygon, you can start with an extreme vertex (e.g., the one with minimal x-coordinate), circulate over its incident halfedges (using Halfedge_around_vertex_circulator), take the one that is a silhouette edge and continue tracing with its next vertex until you close the cycle.

If you also need inside (hole) polygons, a possible solution can be to gather the silhouette edges from all the polyhedron, and trace the cycles from this set.


Amount of light reaching the sensor of pinhole camera model Consider hypothetical camera with pinhole (in mathematical sense) lens and is sensor, like in below image. Is it the case that the central region of the sensor will receive more light (pixels will be brighter) than the pixels closer to the border?

Will the darkening be proportional to the cosine of the sensor normal and the direction which the light comes from?

Is this phenomenon occurring in digital cameras, is it corrected digitally?

EDIT:

I mostly interested in case of idealized film. Digital cameras exhibit this effect due to light attenuation caused be some participating media.
I'm asking about pure geometrical effect like in Lambertian law.

This effect is called vignetting. The cases you talk about are specifically natural and pixel vignetting as explained on the wiki page. Digital cameras compensate these effects, but optical vignetting has to be done in image software for DSLR's with interchangeable lenses. For example if you import an image to Lightroom, there's "lens correction" option, which removes vignetting, distortion and chromatic aberration caused by the lens based on the lens profile.


GPU branching if without else It's common knowledge that branching in a GPU program is costly because it may have to run both the if and else logic for every pixel being evaluated in the same wave, but only applying each result to the appropriate pixels.

I was curious if branching was still a performance issue if there is only an if statement and no else statement?

In this case, it seems like it has the ability to be faster compared to branchless logic, for the case when no pixels need to do the work inside the if statement, and can instead skip past it as a group.

Is this true?  Are there any other downsides? like perhaps older video cards still doing the if logic anyways, even though no pixels evaluate to true?

Old Hardware
Some older cards didn't used to jump instructions in warps, so this was indeed an issue. If you have a conditional with these cards, the inside logic of the conditional would still be evaluated even if the block wasn't entered by any of the pixels, vertices, etc. There's little you can do in this case because every instruction will be executed. The worst case is also the best case here.
Modern Hardware
However, if you are working with relatively modern hardware though, this isn't an issue and "if/else" blocks will be skipped when necessary. There really shouldn't be a downside to using "if/else" blocks compared to not using them. You are still branching with an "else"-less statement. In fact, some post-processing effects/deferred rendering specifically benefit from this.
The worst case scenario is that some threads go through the "if" block and the rest go through the "else" block. The best case scenario is that all go through the "if" block or the "else" block. There isn't a downside to using "if/else" conditionals as they are needed (either on old hardware or newer hardware), but there's a possible upside with newer hardware.


Offline path tracer produces a darker image than expected I've been going though Peter Shirley's beginner raytracing books. Upon building the Cornell box and rendering an image, I get a much darker / dimmer image than expected.

The color values are normalized (in the range [0.0f, 1.0f]). The author of the books has stated that for a brighter result, I need to gamma correct the values (calculating the nth root of the color values)The  above image has a gamma correction of 2 (square root). This is the same value that the author uses, but his result is much brighter

I tried making the gamma correction larger (increasing n) and after setting n=4 (each color gets set to the (1/4)th exponent), I get this image.

There are obvious artifacts, like a lack of highlights near the light, and the over-saturated small number of pixels where a wall is close to the sphere.

The way a pixel's color is calculated is like this:

for(int j = height - 1; j >= 0; j--)
{
    for(int i = 0; i < width; i++)
    {
        vec3 color(0.0f, 0.0f, 0.0f);
        for(int s = 0; s < samplesPerPixel; s++)
        {
            float u = ((float)i + RandomNumber(0.0f, 1.0f)) / width;
            float v = ((float)j + RandomNumber(0.0f, 1.0f)) / height;

            ray r = cam.CastRay(u, v);
            color += Color(r, list, depth);
        }

        color /= (float)samplesPerPixel;
        color = vec3(pow(color.x, gammaCorrection), pow(color.y, gammaCorrection), pow(color.z, gammaCorrection));

        int ir = Map(0.0f, 1.0f, 0.0f, 255.0f, color.x);
        int ig = Map(0.0f, 1.0f, 0.0f, 255.0f, color.y);
        int ib = Map(0.0f, 1.0f, 0.0f, 255.0f, color.z);

        output << ir << " " << ig << " " << ib << "\n";
    }
}

And the resulting color values for each channel (red, green and blue) is in the range of [0, 255].

Is there a problem with how I calculate a pixel's color based on all samples? My color function is pretty much the same as it is in the book

vec3 Color(const ray& r, HitableList& hitables, int depth)
{
    float tmin = 0.001f;
    float tmax = 10000.0f;

    HitData data;

    // If the ray hit something
    if(hitables.Hit(r, tmin, tmax, data))
    {
        ray scattered;
        vec3 attenuation;

        // If the material is a light, store its emitted color
        vec3 emitted = data.mat->Emitted(data.u, data.v, data.point);

        // If the number of bounces is below 50 and the ray gets scattered into a random direction
        if(depth < 50 && data.mat->Scatter(r, data, attenuation, scattered))
            return emitted + attenuation * Color(scattered, hitables, depth + 1);
        else
            return emitted;
    } else
        return vec3(0.0, 0.0f, 0.0f);
}

Has anyone come across a similar issue before?

I have found the issue. The gamma correction was the correct value, the same as in the book (1/2), but the light source had the brightness of 1.0f. The book had set the light's brightness to 18.0f for all color channels.

This would introduce color overflow if left at that, and the very light areas (above 1.0f, and subsequently when converted, outside the range [0, 255]) would have wrong colors.

To fix this clamp the the pixel's color values.

Go through all samples and calculate pixel color.
Divide the color by number of samples
Apply gamma correction
Clamp colors in range [0, 1]
Finally, convert values to range [0, 255]

(I will accept this answer as a solution in 2 days because StackExchange doesn't let me to do it now.)


Does light particle loses energy when it hits something? I have some material which I want to represent as a collection of spheres (atoms) and a particle of light (photon). I'm firing this particle and checking for the collision against atoms. What should happen if collision occurs? I see two possible solutions:

Light particle can be either absorbed or reflected, depends on some probability.
Light particle reflected, but loses some part of it's energy. When the energy is zero, particle is absorbed.

Update: I want to see the general behavior of the particle. The particle itself I want to simulate as a ray. Also I want to simulate a variety of materials - I think small spheres placed near each other can lead to specular material. Big spheres placed far from each other can lead to Lambertian material and subsurface scattering. The light transport is nor stochastic nor full valuated - a ray after collision will reflect correctly, not randomly. In the end I want to see the number of photons reflected, transmitted, scattered and their direction.

Both of your two proposed solutions are valid, with different properties. Which you choose is purely a design issue. The difference is that your probabilistic rays/particles (1) don't need to store their energy: they all have the same amount of energy, so you can just count particles to sum the energy. Your partial particles (2) need to store an energy so you can split them up.

The advantage of 1 is that each ray is smaller. Also, it's easy to keep track of where the energy ended up, because you can use the intersections where the ray was dropped.

Because you're only reflecting or discarding rays, the number of in-flight rays will decrease with each bounce, so you might find it harder to keep batches of rays together for better SIMD or parallel performance.

Also, because you're probabilistically discarding rays, you'll get a lot more noise in your results for the same number of rays.

The second solution is closer to a traditional ray-tracer, so you may find it easier to use existing algorithms and code. You can use fewer primary rays, and the number of rays in each batch is constant at first (but gets worse when the brightnesses start to reach zero).

It's also a lot more efficient to track multiple frequencies this way. If you give each ray a spectrum or RGB energies, the material can have a different effect on different colours without you having to fire multiple batches of rays (duplicating the ray intersection work).

On the other hand, you'll need a second data structure to count up where energy was absorbed, if you want to track that.

In your place, I'd probably use the second solution, but it depends on what other software you're trying to integrate with e.g. an existing ray-tracing library or photon representation, and what you need to do with the output/results.


Histogram of image intensities I want to create a histogram of intensities 0.1, 0.2, .... 0.9, 1, from an image rendered using OpenGL and C++. How can I do this? Can I access the pixel intensities in the framebuffer somehow? Also, I'm not using any glsl shaders, and don't intend to.

So far I tried:

unsigned char *framebuffer = frameBuffer = new unsigned char[1920*1080 * 4];

glReadPixels(0, 0, 1920, 1080, GL_RGBA, GL_UNSIGNED_BYTE, frameBuffer);

for (int j = 0; j<1920*1080 * 4; j += 4){
    if(frameBuffer[j] == 0.1)
        // find pixel with R channel at 0.1: this is where the problem is.
        // I know I have surfaces with this intensity but I never enter the if statement
}

Due the way floating point values work, you probably don't want to do an exact equality check. You probably want something more like this in your loop:

uint32 sums [ 11 ] = { 0 };
for (int j = 0; j < 1920 * 1080 * 4; j += 4) {
    size_t bucket = static_cast<size_t>(framebuffer [ j ] * 10.0);
    sums [ bucket ]++;
}

Note that there are 11 buckets because the range includes both 0 and 1. If you want only 10 buckets and want to put any pixels that have a value of 1 in them into the top bucket, you could do:

uint32 sums [ 10 ] = { 0 };

and change the bucket index calculation to:

size_t bucket = static_cast<size_t>(framebuffer [ j ] * 10.0);
bucket = std::min(bucket, 9);


How to convert a thread ID into Screen Space Coord in an OpenGL Compute Shader? I've written an implementation of the sphere tracing algorithm in OpenGL 4+.
As an experiment/toy project, I'm re-implementing it using the OpenGL 4.3 compute shader, but I'm having trouble with the whole local/global invocation ID thing.
The basic idea is to use the compute shader to calculate the image and output it in a texture, then use a trivial program to copy it onto the framebuffer.

This is the compute shader I'm using:

#version 430 core

layout (binding = 0, rgba32f) writeonly uniform image2D output_image;
layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in;

void main()
{
    ivec2 coord = ivec2(gl_GlobalInvocationID.xy);
    imageStore(output_image, coord, vec4(0.0, 0.0, 1.0, 1.0));
}

This is how I initialize the texture:

GLuint offscreen_texture;
glGenTextures(1, &offscreen_texture);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, offscreen_texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, WINDOW_WIDTH, WINDOW_HEIGHT, 0, GL_RGBA, GL_FLOAT, nullptr);
glBindImageTexture(0, offscreen_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);

And these are the trivial vertex shader I'm using:

#version 430 core

void main()
{
    const vec4 verts[4] = vec4[4](vec4(-1.0, -1.0, 0.5, 1.0),
                                  vec4( 1.0, -1.0, 0.5, 1.0),
                                  vec4(-1.0,  1.0, 0.5, 1.0),
                                  vec4( 1.0,  1.0, 0.5, 1.0));

    gl_Position = verts[gl_VertexID];
}

And fragment:

#version 430 core

layout (location = 0) out vec4 color_out;
layout(binding = 0) uniform sampler2D source_image;

void main()
{
    color_out = texture(source_image, gl_FragCoord.xy);
}

And this is the render code:

compute_program.use();
glDispatchCompute(WINDOW_WIDTH / 16, WINDOW_HEIGHT / 16, 1);
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);

copy_program.use();
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

Up to this point everything works correctly and I see my screen completely blue instead of the usual clear color.

Things start to break down when I try to use the Invocation ID to generate actual data (like the rays from the camera).
I tried to switch to a compute shader like:

#version 430 core

layout (binding = 0, rgba32f) writeonly uniform image2D output_image;
layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in;

void main()
{
    ivec2 coord = ivec2(gl_GlobalInvocationID.xy);
    imageStore(output_image, coord, vec4(0.0, 0.0, coord.x / 1280.0, 1.0));
}

which uses the global ID to generate the blue tint of the pixel.
As I understand from the OpenGL Suberbible book and the OpenGL wiki, I should be able to use the global ID as screen space coordinates (it's pretty easy to do the math using local IDs and work groups IDs and confirm that), much like gl_FragCoord, and this is confirmed by the previous trivial compute shader which paint every pixel.

I would expect a sort of horizontal gradient going from black to blue as an output of this compute shader, but instead everything turns black.
I've tried several combination of "painting" based on the local/global IDs of the threads, but I haven't got any luck no matter what.

Did I misunderstand the way the whole threads ID work?
What is the correct way to use them/map them to screen space coordinates like gl_FragCoord?

EDIT: Just to add, I've tested this with both my integrated Intel HD 5100 and my discrete Nvidia 765M GPUs and the result is the same, so there is clearly something wrong on my side.

The problem is actually in your fragment shader:

color_out = texture(source_image, gl_FragCoord.xy);

The texture() function accepts normalized coordinates which range from 0.0 to 1.0. The gl_FragCoord built in contains window coordinates which range from (0.0, 0.0) to (window width, window height).

To fix this, change the fragment shader to this:

color_out = texture(source_image, gl_FragCoord.xy / vec2(1280.0, 720.0));

That is assuming your window is 1280x720, change as necessary.


What is the modern equivalent of display lists? Display lists were an OpenGL feature that could, in theory, accelerate any part of the API by storing a group of commands for later use. In my understanding, this makes a lot of sense with regards to the current effort to reduce the driver overhead.

Display lists were deprecated in version 3.1 though. What is the modern API equivalent and does DirectX expose a similar feature? If there is no such functionality anymore, what is the rationale?

Nvidia has an extension for creating command buffers in modern GL.

The reason for the lack of similar functionality is that there is a lot of state involved regarding how to render and the display list be affected by a lot of different state. For example changing the blend state requires patching the fragment shader on some hardware.

NVidia solved it by capturing all state and reseting to the state after a dispatch:

  1) What motivates the design?

  The primary goal is to be able to reuse pre-validated command buffers.
  Other APIs and proposals have addressed this with various incarnations
  of command  lists or state objects, but a recurring problem is that
  interactions between various stages of the pipeline prevent this
  prevalidation and reuse. These  interactions are often
  hardware-specific (and differ from vendor to vendor  or even
  generation to generation) and new interactions are introduced by  new
  features that were not imagined when the prevalidation scheme was
  proposed.

  We attempt to address this by having a monolithic state object that
  encompasses (almost) the entire state of the pipeline. This should
  provide enough information for all implementations to do any needed
  cross- validation. We try to create these in a way that minimizes the
  new API  footprint - since we want ALL state (including any added in
  the future), we just capture it from the current state of the context.

  [...]

  23) In what condition is the state left, that is modified by tokens,
  after the dispatch call?

  RESOLVED: state is reset.

(from the extension text linked above)

However the true successor is the command buffer functionality in DX12 and vulkan. Those will also capture all render state into a single object to use when creating and filling the command buffer. The NVidia extension is based on that architecture as a result of NVidia's involvement in the Vulkan design.


Image regeneration with nearest neighbor search So what I would like to achieve is this:

User submits Image 1 - this image is then broken down into X by X sized blocks
User submits Image 2 - then the program/algorithm takes all the blocks generated in the above step, and reconstructs Image 2 using them

Example Image 2:

Example Output:

What I would like to know is, are there any libraries, or some easy way of doing this (ideally in Javascript, as I don't know any other languages) - or even some standalone software tool to accomplish this?

I would have done it with a script and NETPBM like so:

1) reducing Image1 (the tiles) to size X by X -> Image1R

2) recording the mapping from pixel values of Image1R to coordinates (no need to worry about duplicates as an exact RGB match of two or more averaged pixels is unlikely)

3) remapping Image2 using Image1R as the color map -> Image2M

4) reading pixels of Image2M, consulting the map, and picking the tile corresponding to the coordinates

5) concatenating the selected tiles across and down

There is a separate tool for all the above image manipulations in NETPBM.

Any scripting language that allows spawning other processes and supports associative arrays, would do.


How should I fill a shape consisting of Bezier curves and straight lines? I have been working on a graphics library for some time now and have gotten to the point where I have to draw Bezier and line based fonts. Up to this point I am stuck with this:

The green lines are the Bezier paths, and the white part is what gets rendered.

The code I use for Beziers is here. The one for lines is here. For those who don't know that is Lua.

Path rendering (lines) : 32 - 39
  The algorithm is as follows:

Iterating from 0 to 1 at certain intervals
calculating the x and y with this formula: (1-index)^2*x1+2*(1-index)*index*x2+index^2*x3

Up to this point everything works fine. The green lines are generated using the path method.

The white part is rendered in a completely different way:

I get the x coordinates of the Beziers and lines at a particular Y, the put them into a table.
I iterate through the table and each time I encounter a point I change the value of state. In the same for loop is also check whether state is on. If it is, I draw a pixel to the screen.

To find the x values of a y, I use the getX method (line 46 in Bezier and line 31 in Line).

The code I use for the drawing itself is this one:

local xBuffer = {}
local state = false

for i=0,500 do
    for k,v in pairs(beziers) do
        a,b = v.getX(i)
        if a then
            xBuffer[round(a)] = 1
            if b then
                xBuffer[round(a)] = 1
            end
        end
    end
    for k,v in pairs(lines) do
        a = v.getX(i)
        if a then
            xBuffer[round(a)] = 1
        end
    end
    state = false
    for x=0,600 do
        if xBuffer[x] then
            state = not state
        end
        if state then
            love.graphics.points(x,i)
        end
    end
end

Quick explanation: for i,v in pairs iterates through the table given as an argument to pairs. love.graphics.points(x,y) sets a point at x,y.

Thanks in advance.

If you are in a hurry to get your renderer working and you already have the filled polygonal routine functioning correctly, can I suggest an alternative, possibly easier approach? Though I'm not familiar with Lua, it seems you are solving for the exact intersection of a scan line with the quadratic Bezier which, though admirable, is possibly overkill.

Instead, tessellate your Beziers into line segments and then throw those into the polygon scan converter. I suggest just using (recursive) binary subdivision: i.e. the quadratic Bezier with control points, $(\overline {A} , \overline {B} , \overline {C})$ can be split into two Beziers, $(\overline {A} , \overline {D} , \overline {E})$ and $(\overline {E} , \overline {F} , \overline {C})$
where
$$
\begin{align*} & \overline {D}=\dfrac {\overline {A}+\overline {B}} {2}\\ &
\overline {E} =\dfrac {\overline {A}+2\overline {B}+\overline {C}}{4}\\ &
\overline {F}=\dfrac {\overline {B}+\overline {C}} {2}
\end{align*}
$$
(which is also great if you only have fixed point maths).

IIRC, each time you subdivide, the error between the Bezier and just a straight line segment joining the end points goes down by a factor of ~4x, so it doesn't take many subdivisions before the piecewise linear approximation will be indistinguishable from the true curve. You can also use the bounding box of the control points to decide if you can skip out of the subdivision process early since that will also be a conservative bound on the curve.


Eye Parallax Refraction I am trying to implement the Parallax Refraction effect explained by Jorge Jimenez on this presentation:  http://www.iryoku.com/downloads/Next-Generation-Character-Rendering-v6.pptx and I am facing some difficulties. Here is a screenshot of the interesting part.

But this document lacks a bit of explanations especially the second part with the Physically based Refraction.

Here is what I've achieved for the moment.
This is the simple Parallax Refraction effect and, as you might notice in the screenshot, there is small glitch at grazing angles in the iris when the Parallax Scale value is too high.

This is caused by the parallax calculation but are there some tricks to avoid or minimize such issue ?

I don't want to go deeper with parallax mapping for the moment, so I don't want to use Steep Parallax Mapping or Parallax Occlusion Mapping.

Here is the code. Nothing really special.

// height value comes from a texture
float2 offset = height * viewDir;
offset.y = -offset.y;
texcoord -= ParallaxScale * offset;
// Next there is the texture sampling with the texcoord value

I also have another question about the Physically based Refraction part which is not really well explained and I am missing how some values are calculated such as refractedW, frontNormalW or heightW. If anyone could provide some explanations about those values.

Thanks a lot.

Here is the way I calculate the refraction vector according to Snell's law.

float cosine = dot(viewDir, worldNormal);
float sine = sqrt(1 - cosine * cosine);

float sine2 = (_IOR * sine);
float cosine2 = sqrt(1 - sine2 * sine2);

float3 x = -worldNormal;
float3 y = normalize(cross(cross(viewDir, worldNormal), worldNormal));
float3 refractedW = x * cosine2 + y * sine2;

This is integrated with the Physically based Refraction and it gives interesting results but I still don't know how to get rid of the high parallax scale issue which appear at grazing angles...

Any idea how to get rig of that ?


Is it possible to create minimal glTF files with vertex and index buffers? I am currently looking into glTF to use as a transfer format for my WebGL project. I already have the geometries I wish to render on my WebGL client available as preprocessed vertex and index buffers (and color buffers, but let's ignore them for now).

For example:

[       // vertex buffer
  0,0,0,
  0,1,0,
  1,0,0,
  1,1,0,
]

And to draw simple LINES:

[       // index buffer
  0,2,
  2,4,
  4,0,
  0,1,
  1,4,
]

I wonder how to create glTF files containing these buffers? Is this possible?

I want to avoid using COLLADA and COLLADA2GLTF as this would only add an additional step and might just bloat the resulting glTF files.

While creating a set of glTF models for a tutorial, I also intended to create THE minimal glTF file.

Update: The following referred to glTF 1.0/1.1. See below for an update of this example to glTF 2.0.

As already mentioned in the answer by 5chdn, one issue may be the material. According to the Appendix A: Default Material of the specification, an asset that does not contain a material should be rendered with a default material that simply shows the object in a uniform, 50% gray color.

Some viewers might not support this, and even if they do, there have been some minor subtleties in the spec regarding this point: In glTF 1.0, it was still necessary to define an "empty" material, because the mesh.primitive.material property was not yet optional. But this should be fixed in glTF 1.1.

So the following should indeed be THE minimal possible glTF asset (version 1.1) :

{
  "scenes" : {
    "scene0" : {
      "nodes" : [ "node0" ]
    }
  },
  "nodes" : {
    "node0" : {
      "meshes" : [ "mesh0" ]
    }
  },

  "meshes" : {
    "mesh0" : {
      "primitives" : [ {
        "attributes" : {
          "POSITION" : "positionsAccessor"
        }
      } ]
    }
  },

  "buffers" : {
    "buffer0" : {
      "uri" : "data:application/octet-stream;base64,AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAA",
      "byteLength" : 36
    }
  },
  "bufferViews" : {
    "positionsBufferView" : {
      "buffer" : "buffer0",
      "byteOffset" : 0,
      "byteLength" : 36,
      "target" : 34962
    }
  },
  "accessors" : {
    "positionsAccessor" : {
      "bufferView" : "positionsBufferView",
      "byteOffset" : 0,
      "componentType" : 5126,
      "count" : 3,
      "type" : "VEC3",
      "max" : [ 1.0, 1.0, 0.0 ],
      "min" : [ 0.0, 0.0, 0.0 ]
    }
  },

  "asset" : {
    "version" : "1.1"
  }
}

It also shows a single triangle:

The version without embedded buffers is available at https://github.com/javagl/gltfTutorialModels , as well as a triangle with indices, at https://github.com/javagl/gltfTutorialModels/tree/master/Triangle

Update for glTF 2.0:

The concepts and top-level elements of glTF 2.0 are basically the same as for glTF 1.0. But there still have been some changes in the format. Most importantly (for this small example), the top-level dictionaries are now arrays. The following is the same "Triangle" model as above, updated accordingly:

{
   "scenes":[
      {
         "nodes":[ 0 ]
      }
   ],
   "nodes":[
      {
         "mesh":0
      }
   ],
   "meshes":[
      {
         "primitives":[
            {
               "attributes":{
                  "POSITION":1
               },
               "indices":0
            }
         ]
      }
   ],
   "buffers":[
      {
         "uri":"data:application/octet-stream;base64,AAABAAIAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAA=",
         "byteLength":44
      }
   ],
   "bufferViews":[
      {
         "buffer":0,
         "byteOffset":0,
         "byteLength":6,
         "target":34963
      },
      {
         "buffer":0,
         "byteOffset":8,
         "byteLength":36,
         "target":34962
      }
   ],
   "accessors":[
      {
         "bufferView":0,
         "byteOffset":0,
         "componentType":5123,
         "count":3,
         "type":"SCALAR",
         "max":[
            2
         ],
         "min":[
            0
         ]
      },
      {
         "bufferView":1,
         "byteOffset":0,
         "componentType":5126,
         "count":3,
         "type":"VEC3",
         "max":[
            1.0,
            1.0,
            0.0
         ],
         "min":[
            0.0,
            0.0,
            0.0
         ]
      }
   ],
   "asset":{
      "version":"2.0"
   }
}

This and other glTF sample models can be found in the glTF sample models repository.


Fragment shader's output variables EDIT: This is a duplicate of a question from stack overflow:
https://stackoverflow.com/questions/9222217/how-does-the-fragment-shader-know-what-variable-to-use-for-the-color-of-a-pixel

If you want to send a value from vertex shader to fragment shader, the vertex shader should declare one variable as out, the fragment shader should declare other variable as in and both variables must have their names and types equal. But this doesn't happen when you want to send the color value from the fragment shader. In fact, you can call the output variable as you want. Why? In older version there was one variable called gl_FragColor
How the program links your output fragment variable with gl_FragColor?

It works almost exactly the same way as vertex shader inputs.

In vertex shaders, you have inputs. And these inputs represent vertex attribute indices, the numbers you pass to glVertexAttribPointer and glEnableVertexAttribArray and so forth. You set up which input pulls from which attribute. In GLSL 3.30, you use this syntax:

layout(location = 2) in color;

This sets the color vertex shader input to come from attribute location 2. Before 3.30 (or without ARB_explicit_attrib_location), you would have to either set this up explicitly with glBindAttrbLocation before linking or query the program for the attribute index with glGetAttribLocation. If you don't explicitly provide an attribute location, GLSL will assign a location arbitrarily (ie: in an implementation-defined manner).

Setting it in the shader is almost always the better option.

In any case, fragment shader outputs work almost exactly the same way. Fragment shaders can write to multiple output colors, which themselves get mapped to multiple buffers in the framebuffer. Therefore, you need to indicate which output goes to which fragment output color.

This process begins with the fragment output location value. It's set very similarly to vertex shader input locations:

layout(location = 1) out secColor;

There are also the API functions glBindFragDataLocation and glGetFragDataLocation, which are analogous to glBindAttribLocation and glGetAttribLocation.

If you don't do any explicit assignments, implementations usually will assign one of your output variables to location 0. However, the OpenGL standard does not require this behavior, so you should not depend on it either.


Converting raster shape/blob into displacement map I am a beginner in digital image processing and computer graphics. I would like to program a similar behavior than the Shadermap 3 normal editor (displacement layer more specifically).

As shown in this Shadermap 3 demonstration video, the displacement brush allows the user to paint a displacement map (grayscale)

The brush strokes produce shapes with a smooth value transitioning from the middle of the shape to its edge, in this case giving the shape a slightly curved profile. As it is also shown, the shape's profile can be fine-tuned with the brush curve editor.

What combination of filters and/or algorithms could Shadermap 3 possibly use to convert a pixel blob or shape to displacement map with a given width and curve?

One way I can think of is to make a "signed distance transform" of the image where there is information for each pixel about how far the pixel is to the closest surface of the shape.  Since it's signed, youll be able to know if the pixel is inside or outside he shape, and by how much.

Using this knowledge, you could easily make a new image, where the pixel is black if the distance is greater than -10, else it is white.  That would make the shape shrink by 10 pixels.

You can use smoothstep or other curves to transition between black and white over a number of pixels, to soften it anti alias the edges.

You can make the distance transform by brute force, but another method would be to make a voronoi diagram first and then turn that into a distance transform.

There is lots of info out there on both voronoi diagrams as well as (signed) distance transforms but these two links will probably be helpful to get you started:

http://blog.demofox.org/2016/02/29/fast-voronoi-diagrams-and-distance-dield-textures-on-the-gpu-with-the-jump-flooding-algorithm/

http://blog.demofox.org/2016/03/02/actually-making-signed-distance-field-textures-with-jfa/


convert image pixel dimensions to UV Hi i am rather new to computergraphics but i am trying to map an equirectangular image (360 video) to the inside of a sphere now i found the following formula to do this.

phi = 2*Pi*u
cos(theta) = 2*v -1

But how do i get u and v ? In the article he talks about this:

  So we can just project the sphere points in the xy plane onto the unit radius cylinder and unwrap it!   If we have such an image with texture coordinates (u,v) in [0,1]^2

But how do i get those texture coordinates from and image with lets say the following dimensions 4096x2048 pixels?

Sorry if this is a bit vague, i am trying to understand it myself. If clarification is needed i am happy to edit my question!

UV coordinates are defined such that (0, 0) is your lower left (or upper left, depending on what you're working with) corner of the image and (1, 1) the opposite corner (technically (1, 1) is outside the UV range, but we ignore this for easiness sake). Thus, if you want the exact middle, you obviously get (0.5, 0.5)

Now with your image, the first pixel lower left is the pixel at (0, 0) as well. The pixel in the opposite corner is (4095, 2047).
To get to the (1, 1) corner, you need to take that corner pixel and divide it's coordinates by the image's width and height respectively. here you will see, that the (1, 1) does not fit exactly:

$u = 4095 / 4096 = 0.99976$
$v = 2047 / 2048 = 0.99951$

The same principle applies to any other pixel of your image, you just have to divide by the image's width in pixels.
Your center pixel is at (2047, 1023) (or the image borders on this pixel and three of its neighbours). The resulting UVs are:

$u = 2047 / 4096 = 0.49975$
$v = 1023 / 2048 = 0.49951$


understand a pseudo angle implementation I'm trying to understand a go library for Delaunay triangulation and found out this function to calculate the pseudo angle
Here is the implementation of the psuedo angle
    func pseudoAngle(dx, dy float64) float64 {
        p := dx / (math.Abs(dx) + math.Abs(dy))
        if dy > 0 {
            p = (3 - p) / 4
        } else {
            p = (1 + p) / 4
        }
        return math.Max(0, math.Min(1-eps, p))
    }

Here is were it have been used :
func (t *triangulator) hashKey(point r3.Point) int {

    d := point.Sub(t.center)
    return int(pseudoAngle(d[0], d[1]) * float64(len(t.hash)))
}

Do you have any idea of where this implementation is coming from mathematically ?

The "pseudo-angle" this function defines runs from 0 to 1 counterclockwise around the circle, with 0 at the negative x-axis, and each 25% of the range mapping to one quadrant (so 0.25 at the negative y-axis, 0.5 at the positive x-axis, etc).
First, the expression dx / (math.Abs(dx) + math.Abs(dy)), can be seen as normalizing the vector in the 1-norm or taxicab norm as opposed to the usual Euclidean norm. In other words, it's projecting the vector onto the unit diamond:

After that, it looks at the sign of y and remaps x accordingly. For the lower half of the diamond (negative y), it maps x linearly from [−1, 1] to [0, 0.5]. For the top half it maps x from [1, –1] to [0.5, 1] (reversing the direction of the mapping this time). So, as you start from the point (−1, 0) and go counterclockwise around the diamond, the pseudo-angle result will increase from 0 to 1.
It is probably used because the system wants to sort vectors by their angle (or in this case, incorporate the angle in a hash apparently), but it doesn't need the actual Euclidean angle which would require an expensive atan2 function to calculate. It just needs something monotonically related to the angle but cheap to calculate, and this pseudo-angle fits the bill.