Anyone knows what coordinates this GLSL function would produce? - opengl

I am trying to experiment with pixel shaders in WPF, and I want to try out this code:
-1.0 + 2.0 * gl_FragCoord.xy / resolution.xy
But I am not sure what range of values that would produce. I am applying mine to image as a filter and I have access to u and v values [0-1]. When I do this:
-1.0 + 2.0 * {U,V};
I am not getting the same result. I know the above also must be a normalized value range but not sure if -1 to 1, or 0 to 1, etc.
Any ideas?

gl_FragCoord.xy / resolution.xy gives you the range [0,1].
Multiplying by 2 gives you the range [0,2].
Substracting 1 gives you the range [-1,1]
example:
http://glsl.heroku.com/e#7712.0

reading through this like a compiler would. -1.0 + 2.0 get's reduced to 1.0. The statment then becomes 1.0 * glFragCoord.xy / resolution.xy. 1 * x = x, given that, the equastion then becomes glFragCoord.xy / resolution.xy.
In effect, you're going to wind up with a range of [0, 1/resolution].
If What you mean the equasion to be is -1.0 + (2.0 * glFragCoord.xy / resolution.xy) then you have [0, 2/resolution], subracting 1 becomes [-1, (2/resolution)-1].

Related

Motion Vector - how to calculate it properly?

I'm trying to wrap my head around calculating motion vectors (also called velocity buffer). I found this tutorial, but I'm not satisfied with explanations of how motion vector are calculated. Here is the code:
vec2 a = (vPosition.xy / vPosition.w) * 0.5 + 0.5;
vec2 b = (vPrevPosition.xy / vPrevPosition.w) * 0.5 + 0.5;
oVelocity = a - b;
Why are we multiplying our position vectors by 0.5 and then adding 0.5? I'm guessing that we're trying to get from clip space to NDC, but why? I completly don't understand that.
This is a mapping from the [-1, 1] clip space onto the [0, 1] texture space. Since lookups in the blur shader have to read from a textured at a position offset by the velocity vector, it's necessary to perform this conversion.
Note, that the + 0.5 part is actually unnecessary, since it cancels out in a-b anyway. So the same result would have been achieved by using something like
vec2 a = (vPosition.xy / vPosition.w);
vec2 b = (vPrevPosition.xy / vPrevPosition.w);
oVelocity = (a - b) * 0.5;
I don't know if there is any reason to prefer the first over the second, but my guess is that this code is written in the way it is because it builds up on a previous tutorial where the calculation had been the same.

Z value bigger than 1 after w division

What I am doing in vertex shader is:
shadowCoord = shadowVP * mMatrix * vec4(vertex_position,1.0);
Now to get it back in the range [-1, 1] I did this in the fragment shader:
vec3 proj = shadowCoord.xyz / shadowCoord.w;
But if I test the z value of such point I get a value bigger than 1.
The perspective matrix I use is obtained via:
glm::perspective(FOV, aspectRatio, near, far);
And it results in:
[2.4142 0 0 0
0 2.4142 0 0
0 0 -1.02 -1
0 0 -0.202 0]
and the shadowVP is:
shadow_Perp * shadow_View
Shouldn't proj.z be in the range [-1,1]?
Shouldn't proj.z be in the range [-1,1]?
No. It is in the range [-1,1] if the point lies inside the frustum. And the frustum is defined as -w <= x,y,z <= w for any vetrex in clip space (and that w varies per vertex). But you don't do any clipping, so any value can result here. Note two things:
While I said the implication "v inside the frustum" => "NDC coords in [-1,1]" holds true, the opposite does not. That means you can get the NDC coords inside [-1,1] for points which lie outside of the frusutm (that might even lie behind the "viewing position").
You might also get the division by 0 here.

Calculate saw and triangle wave from specific data

I need to calculate a triangle and saw wave but it is a little complicate because of my model and the data I'm able to work with (but maybe I'm just confused).
I'm able to calculate my sine wave but I'm not really using a frame counter. What I do is, calculate a theta_increment variable which I can use the next time I need to calculate a sample. This works like this:
float x = note.frequency / AppSettings::sampleRate;
float theta_increment = 2.0f * M_PI * x;
float value = 0;
if(waveType == SINE){
value = sin(note.theta) * fixedAmplitude;
}
Now that I have the value of the currend frame/sample I store theta_increment inside my note.theta member so I can use it for the next sample:
note.theta += theta_increment;
I've looked at tons of examples on how I should calculate a saw or a triangle but I can't figure it out. (I only have the data mentioned above at my disposal) This is my last attempt but it's not working and giving me tons of glitches:
value = 1.0f - (2.0f * ((float)note.theta / (float)44100));
If you have a loop generating your values like this:
for (size_t frame=0; frame!=n_frames; ++frame) {
float pos = fmod(frequency*frame/sample_rate,1.0);
value[frame] = xFunc(pos)*fixedAmplitude;
}
Then you can use these functions for different types of waves:
float sinFunc(float pos)
{
return sin(pos*2*M_PI);
}
float sawFunc(float pos)
{
return pos*2-1;
}
float triangleFunc(float pos)
{
return 1-fabs(pos-0.5)*4;
}
The basic idea is that you want a value (pos) that goes from 0.0 to 1.0 over each cycle. You can then shape this however you want.
For a sine wave, the sin() function does the job, you just need to multiply by 2*PI to convert the 0.0 to 1.0 range into a 0.0 to 2*PI range.
For a sawtooth wave, you just need to convert the 0.0 to 1.0 range into a -1.0 to 1.0 range. Multiplying by two and subtracting one does that.
For a triangle wave, you can use the absolute value function to cause the sudden change in direction. First we map the 0.0 to 1.0 range into a -0.5 to 0.5 range by subtracting -0.5. Then we make this into a 0.5 to 0.0 to 0.5 shape by taking the absolute value. By multiplying by 4, we convert this into a 2.0 to 0.0 to 2.0 shape. And finally by subtracting it from one, we get a -1.0 to 1.0 to -1.0 shape.
A sawtooth wave could be calculated like this:
value = x - floor(x);
A triangle could be calculated like this:
value = 1.0 - fabs(fmod(x,2.0) - 1.0);
where x is note.theta.

GLSL gl_FragCoord.z Calculation and Setting gl_FragDepth

So, I've got an imposter (the real geometry is a cube, possibly clipped, and the imposter geometry is a Menger sponge) and I need to calculate its depth.
I can calculate the amount to offset in world space fairly easily. Unfortunately, I've spent hours failing to perturb the depth with it.
The only correct results I can get are when I go:
gl_FragDepth = gl_FragCoord.z
Basically, I need to know how gl_FragCoord.z is calculated so that I can:
Take the inverse transformation from gl_FragCoord.z to eye space
Add the depth perturbation
Transform this perturbed depth back into the same space as the original gl_FragCoord.z.
I apologize if this seems like a duplicate question; there's a number of other posts here that address similar things. However, after implementing all of them, none work correctly. Rather than trying to pick one to get help with, at this point, I'm asking for complete code that does it. It should just be a few lines.
For future reference, the key code is:
float far=gl_DepthRange.far; float near=gl_DepthRange.near;
vec4 eye_space_pos = gl_ModelViewMatrix * /*something*/
vec4 clip_space_pos = gl_ProjectionMatrix * eye_space_pos;
float ndc_depth = clip_space_pos.z / clip_space_pos.w;
float depth = (((far-near) * ndc_depth) + near + far) / 2.0;
gl_FragDepth = depth;
For another future reference, this is the same formula as given by imallett, which was working for me in an OpenGL 4.0 application:
vec4 v_clip_coord = modelview_projection * vec4(v_position, 1.0);
float f_ndc_depth = v_clip_coord.z / v_clip_coord.w;
gl_FragDepth = (1.0 - 0.0) * 0.5 * f_ndc_depth + (1.0 + 0.0) * 0.5;
Here, modelview_projection is 4x4 modelview-projection matrix and v_position is object-space position of the pixel being rendered (in my case calculated by a raymarcher).
The equation comes from the window coordinates section of this manual. Note that in my code, near is 0.0 and far is 1.0, which are the default values of gl_DepthRange. Note that gl_DepthRange is not the same thing as the near/far distance in the formula for perspective projection matrix! The only trick is using the 0.0 and 1.0 (or gl_DepthRange in case you actually need to change it), I've been struggling for an hour with the other depth range - but that is already "baked" in my (perspective) projection matrix.
Note that this way, the equation really contains just a single multiply by a constant ((far - near) / 2) and a single addition of another constant ((far + near) / 2). Compare that to multiply, add and divide (possibly converted to a multiply by an optimizing compiler) that is required in the code of imallett.

Percentage calculation around 0.5 (0.4 = -20% and 0.6 = +20%)

I'm in a strange situation where I have a value of 0.5 and I want to convert the values from 0.5 to 1 to be a percentage and from 0.5 to 0 to be a negative percentage.
As it says in the title 0.4 should be -20%, 0.3 should be -40% and 0.1 should be -80%.
I'm sure this is a simple problem, but my mind is just refusing to figure it out :)
Can anyone help? :)
What we want to do is to scale the range (0; 1) to (-100; 100):
percentage = (value - 0.5) * 200;
The subtraction transforms the value so that it's in the range (-0.5; 0.5), and the multiplication scales it to the range of (-100; 100).
percent = ((value - 0.5) / 0.5) * 100
This will generate from -100 to 100. You want to subtract your zero value (0.5) from the given value, and divide by the range that should give 100% (also 0.5 in your example). Then multiply by 100 to convert to percentage.
Normalize it, and you're done:
// Assuming x is in the range (0,1)
x *= 2.0; // x is in the range (0,2)
x -= 1.0; // (-1,1)
x *= 100; // (-100,100)