Hot answers tagged

22

Pixels get grouped into little squares (how big depends on the hardware) and computed together in a single SIMD pipeline. (struct of arrays type of SIMD) This pipeline (which has several different names depending on the vendor: warps, wavefronts) will execute operations for each pixel/fragment in lockstep. This means that if 1 pixel needs a computation done ...


20

Only tangent space normal maps are primarily blue. This is because the colour blue represents a normal of (0,0,1) which would be an unchanged normal when the triangle lies in the plane x and y, i.e. perpendicular to the surface. The tangent, x and bi-tangent, y (also referred to as bi-normal) are encoded in the red and green channels and these form to create ...


19

Whether it's a tile based GPU or not doesn't really affect the texture cache architecture. The memory layout of texture will look like some flavor of Morton order or Hilbert curve in all GPUs. As a result, it's more efficient to render triangles that are close to equilateral triangles because GPU memory system fetches cache lines of texels. So obviously on ...


18

First, gl_FragCoord.xy are screen space coordinates of current pixel based on viewport size. So if viewport size is width=5, height=4 then each fragment contains: Why are uvs needed? For example I rendered geometry to screen quad and then I need to apply some postprocessing on this quad in another rendering pass. To sample from that quad I need texture ...


16

Just adding to imallett's answer, it is true that increasing the number of accesses to different texture data in a shader will increase pressure on the GPU cache(s), but there are several other factors that can significantly influence the effect. It's also possibly complicated by the fact that, like CPU caches, there may be several layers of cache in a GPU, ...


15

Yes, but you need a paradigm shift. What you are accustomed is called forward rendering. You submit your geometry and then you proceed immediately with the shading pass. In the basic forward rendering you can either loop inside the shader for each light or perform one pass per light and blend the result together (with additive blending). But things have ...


14

At the top level, a GPU is subdivided into a number of shader cores. A small GPU in a notebook or tablet may have only a few cores while a high-end desktop GPU may have dozens. In addition to the shader cores there are also texture units. They may be grouped together with one texture unit per shader core, or one texture unit shared among two or three ...


13

On modern hardware if all invocations in a group follow the same path then the unused path doesn't get evaluated. in pseudo code: if(cond){ res = ... }else{ res = ... } becomes if(anyInvocationARB(cond)){ res1 = ... } if(anyInvocationARB(!cond)){ res2 = ... } res = cond?res1:res2; Where anyInvocationARB will be true if any invocation of ...


13

The problem is, glVertexAttribPointer(0, 4, GL_DOUBLE... doesn't do what you think it does. Using actual double-precision vertex attributes and performing double precision computations is a very modern hardware feature (GL4/DX12) and is different from specifying the type GL_DOUBLE in the good old glVertexAttribPointer call. This always worked and does ...


12

You don't need to rebind the attributes, so long as you ensure that their location stays the same in both shaders. (Usually using the layout(location = X) syntax in GLSL, but can also be done with glBindAttribLocation if former is not available.) Uniforms, however, are part of the Shader Object state, and so will need to be set at least once for every ...


12

Because a normal map is covering vectors from -1 to 1 it makes sense to stretch this range into 0->1 so all of it can be fit inside the range of RGB. So usually we apply a transform on the normal to convert it into something we can see. vec3 colour = vec3(0.5) + normal * 0.5; The blue colour is because normal maps are supposed to be used relative to the ...


10

Image 1: A bad case of shadow acne. (Synthetic and a bit exaggerated) Shadow acne is caused by the discrete nature of the shadow map. A shadow map is composed of samples, a surface is continuous. Thus, there can be a spot on the surface where the discrete surface is further than the sample. The problem does persist even if you multi sample, but you can ...


10

Here is a line by line breakdown of my shader: #define mainImage(o,p)\ for( vec2 r = iResolution.xy, q = 2.*(p+p-r)/r.y; o.a++ < 30.; )\ o += length( q = abs(q)/dot(q,q) - iMouse.xy/r) / 2e2 First, it is important to know that the “\” at the end of the first two lines do not count towards the character count and merely serve to make the code ...


9

As you discovered and mentioned in your self-answer, the pattern in the background appears to be a sum of sinusoidal gradients. However, the example linked to in your answer is more complicated than that used by µTorrent. The background of the About window appears to be a static pattern, rather than the animated sinusoidal pattern used in the plasma post. ...


9

Why are they deprecated? Those functions are deprecated because the OpenGL API moved in favor of a programmable pipeline in contrast with the old fixed pipeline. The programmable pipeline allows the flexibility necessary to enable a wide variety of effects and solutions that before were difficult or not possible at all to implement. You can still access ...


9

Given triangle ▲ABC, we bisect angle ∠BAC with line AD, derived with Angle Bisector Theorem: BA / BD = CA / CD Point E represents our objective refined position on the desired resulting inset triangle. As it lies upon angle bisector AD, it is equidistant from sides BA & CA, forming identical right triangles ▲AFE & ▲AGE. We can now use Sine for ...


8

The answer depends on what you mean. Modern hardware (e.g. with bindless textures) really doesn't care too much how many textures are "bound". The real question is how many you use. Textures generally store data in a cache-friendly way (a Morton curve, I believe). If you use more textures, you'll get more cache misses, since now the textures compete with ...


8

As you are taking the mean of a number of sine waves, your colour values will range from -1 to 1. From your example image, it looks like only the top half of this range of values (from 0 to 1) is resulting in colour, with everywhere else remaining black. If whatever you are using to display the result can only handle positive values, then you will need to ...


8

Jittering and dithering are both techniques of adding noise to reduce visible artefacts (such as banding) in an image. They solve different kinds of artefacts so they are used in different situations. Jittering moves sample positions in space to reduce artefacts caused by regular sampling. Dithering changes the way colours are rounded (when reducing ...


7

Without knowing the internals of Blender, I would say it uses shared normals for the quads, splitting the normals only on edges between the quads, not between the triangles. So your idea of uploading a normal per quad is probably close to the result you are looking for. If you load the mesh as quads, you are set. If you are using an old version of OpenGL ...


7

The shader language is bound to the APIs/engines that support it (glsl to openGL & WebGL and hlsl to D3D). There are tools to translate from one to the other but they aren't perfect. This means the main reason to pick one over the other is which platform you will be working on. However by the end of the year a new binary shader representation will come ...


6

The uniform locations are set when the program is linked and are tied to the program. This means that when you create a new program then the uniform locations can change.


6

In order to ensure that the pattern shapes are always either wholly present or absent, never cut off, it's necessary to ensure that the same p value is used for all texels within the shape. In your example of circles, all the texels in a given circle need to agree on p. I assume that you have some way of evaluating p at a given point on the surface (whether ...


6

If your wall geometry is vector graphics you can simply extrude the segment away from the light position. This means 2 triangles per draw call, all the extrusion offsets can can be handled in the vertex shader. Image 1: For each wall generate a shadow volume extrusion. Quick and extremely dirty sample implementation of shadow volumes here: http://...


6

Shader compilers are extremely aggressive about unrolling since early HW often didn't have flow control and the cost on more recent HW can vary. If you have a benchmark you are actively testing against and a range of relevant hardware, then try things to see what happens. Your dynamic loop is more amenable to developer intervention than a static loop - but ...


6

Resolved by adding precision highp sampler2D to my shaders. About default precision settings on ES - https://www.khronos.org/files/opengles_shading_language.pdf page 36.


6

When you use linewidth or line antialiasing or pointwidth or pointsprites, OpenGL creates for you a small rectangle instead of the line or point, with texture coordinates. Nowadays you can even program this yourself using geometry shaders ot even the tesselator. A totally different approach is to use defered shading, using one geometric pass just to store ...


6

The counter you want is built in the shader as gl_VertexID. However you have 16 attributes of 4 components each to work with. Take 2 components for the texture coordinates and you have 62 float values to play with. If you need 6 components per blend shape (3 pos + 3 normal) you get 10 blend shapes to work with per object per frame. If you leave off the ...


6

Rather than trying to speed up your shader by fiddling with the code, can I suggest you make use of the GPU's inherent ability to rapidly fill polygons? This will allow it to eliminate the vast bulk of the cases where there is no need to even make a decision. What I suggest you try is something like the following: Create, say, a heptagon (i.e. the blue ...


6

Doing it in the CPU side during initialization is what I'd go for, this is assuming you are initialising that data once and passing it to the GPU. On the GPU side, doing the calculations per fragment would be too costly and should be out of the question, unless it's really needed for a special effect then you shouldn't add unneeded ALU work to the fragment ...


Only top voted, non community-wiki answers of a minimum length are eligible