Does GLSL's mix() clamp the third parameter? - opengl

Does GLSL's mix() clamp the third parameter to the [0, 1] range before using it to interpolate before the other two?
I could write a shader to test this, but: I don't want to just test my particular implementation of GLSL, and also it'd be nice to have an answer to this available online for a reference.

My reading of the GLSL spec is that no clamping is done:
Returns the linear blend of x and y, i.e., x⋅(1 − a) + y⋅a
(https://www.opengl.org/registry/doc/GLSLangSpec.4.40.pdf)

Related

GLSL: Data Distortion

I'm using OpenGL 3.3 GLSL 1.5 compatibility. I'm getting a strange problem with my vertex data. I'm trying to pass an index value to the fragment shader, but the value seems to change based on my camera position.
This should be simple : I pass a GLfloat through the vertex shader to the fragment shader. I then convert this value to an unsigned integer. The value is correct the majority of the time, except for the edges of the fragment. No matter what I do the same distortion appears. Why is does my camera position change this value? Even in the ridiculous example below, tI erratically equals something other than 1.0;
uint i;
if (tI == 1.0) i = 1;
else i = 0;
vec4 color = texture2D(tex[i], t) ;
If I send integer data instead of float data I get the exact same problem. It does not seem to matter what I enter as vertex Data. The value I enter into the data is not consistent across the fragment. The distortion even looks the exact same each time.
What you are doing here is invalid in OpenGL/GLSL 3.30.
Let me quote the GLSL 3.30 specification, section 4.1.7 "Samplers" (emphasis mine):
Samplers aggregated into arrays within a shader (using square brackets
[ ]) can only be indexed with integral constant expressions (see
section 4.3.3 “Constant Expressions”).
Using a varying as index to a texture does not represent a constant expression as defined by the spec.
Beginning with GL 4.0, this was somewhat relaxed. The GLSL 4.00 specification states now the following (still my emphasis):
Samplers aggregated into arrays within a shader (using square brackets
[ ]) can only be indexed with a dynamically uniform integral
expression, otherwise results are undefined.
With dynamically uniform being defined as follows:
A fragment-shader expression is dynamically uniform if all fragments
evaluating it get the same resulting value. When loops are involved,
this refers to the expression's value for the same loop iteration.
When functions are involved, this refers to calls from the same call
point.
So now this is a bit tricky. If all fragment shader invocations actaully get the same value for that varying, it would be allowed, I guess. But it is unclear that your code guarantees that. You should also take into account that the fragment might be even sampled outside of the primitive.
However, you should never check floats for equality. There will be numerical issues. I don't know what exactly you are trying to achieve here, but you might use some simple rounding behavior, or use an integer varying. You also should disable the interpolation of the value in any case using the flat qualifier (which is required for the integer case anyway), which should greatly improve the changes of that construct to become dynamically uniform.

what parameters does the function texture() takes?

float texture(gsampler2DArrayShadow sampler, vec4 P, [float bias]);
Look at this function in OpenGL ES (shader lang). I do not understand the difference between gsampler2DArrayShadow and sampler2DArrayShadow. Can you explain this? I read that 'g' can mean nothing or i or u. But what then is this type?
Also, Does '[float bias]' mean that we have 2 functions: with this parameter and without?
Anytime you see a variable type in GLSL prefixed with g in a function prototype, that is a shorthand convention that means there is an overload for every type of data. A function that accepts gvec, for instance, means it has an overload for ivec, uvec, vec, dvec, bvec and so on.
Desktop GLSL has support for integer samplers in addition to fixed-/floating-point so you will see a lot of functions defined using gsampler... instead of sampler..., that means the function has isampler... and usampler... overloads in addition to the more traditional variety.
As for [float bias], that is used to control mipmap LOD bias. When you do not supply a value to that parameter, GL computes the bias itself.
Interestingly because of the way mipmap LODs are computed, only the fragment shader variety of the texture lookups support automatic mipmap selection (it has to do with the per-fragment derivative calculation). To use mipmapping in the vertex shader, you have to explicitly select the LOD with textureLod (...) or supply your own partial derivative using textureGrad (...).

Alglib: solving A * x = b in a least squares sense

I have a somewhat complicated algorithm that requires the fitting of a quadric to a set of points. This quadric is given by its parametrization (u, v, f(u,v)), where f(u,v) = au^2+bv^2+cuv+du+ev+f.
The coefficients of the f(u,v) function need to be found since I have a set of exactly 6 constraints this function should obey. The problem is that this set of constraints, although yielding a problem like A*x = b, is not completely well behaved to guarantee a unique solution.
Thus, to cut it short, I'd like to use alglib's facilities to somehow either determine A's pseudoinverse or directly find the best fit for the x vector.
Apart from computing the SVD, is there a more direct algorithm implemented in this library that can solve a system in a least squares sense (again, apart from the SVD or from using the naive inv(transpose(A)*A)*transpose(A)*b formula for general least squares problems where A is not a square matrix?
Found the answer through some careful documentation browsing:
rmatrixsolvels( A, noRows, noCols, b, singularValueThreshold, info, solverReport, x)
The documentation states the the singular value threshold is a clamping threshold that sets any singular value from the SVD decomposition S matrix to 0 if that value is below it. Thus it should be a scalar between 0 and 1.
Hopefully, it will help someone else too.

GLSL equivalent of HLSL clip()?

The HLSL clip() function is described here.
I intend to use this for alpha cutoff, in OpenGL. Would the equivalent in GLSL simply be
if (gl_FragColor.a < cutoff)
{
discard;
}
Or is there some more efficient equivalent?
OpenGL has no such function. And it doesn't need one.
Or is there some more efficient equivalent?
The question assumes that this conditional statement is less efficient than calling HLSL's clip function. It's very possible that it's more efficient (though even then, it's a total micro-optimization). clip checks if the value is less than 0, and if it is, discards the fragment. But you're not testing against zero; you're testing against cutoff, which probably isn't 0. So, you must call clip like this (using GLSL-style): clip(gl_FragColor.a - cutoff)
If clip is not directly support by the hardware, then your call is equivalent to if(gl_FragColor.a - cutoff < 0) discard;. That's a math operation and a conditional test. That's slower than just a conditional test. And if it's not... the driver will almost certainly rearrange your code to do the conditional test that way.
The only way the conditional would be slower than clip is if the hardware had specific support for clip and that the driver is too stupid to turn if(gl_FragColor.a < cutoff) discard; into clip(gl_FragColor.a - cutoff). If the driver is that stupid, if it lacks that basic pinhole optimization, then you've got bigger performance problems than this to deal with.
In short: don't worry about it.

GLSL vectors questions

In OpenGL GLSL syntax, is there any difference between the components of a vector?
I mean, for a given vec3, the xyzw, rgba and stpq, have any real differences between them or is just a helper?
So if I set a color value into a vec3, I assume that though for making it clear to read I would use the rgba, xyzw would give the same values, right?
Actually, I am not certain how it is implemented, but I think it might be some sort of a union, in which case writing to one and reading from the other is not guaranteed to work.
EDIT: The above comment holds for unions in general (C/C++), however the case in GLSL might be different. The link: http://www.opengl.org/wiki/GLSL_Types#Swizzling states that:
"You can use xyzw, rgba (for colors), or stpq (for texture coordinates). These three sets have no actual difference; they're just syntactic sugar."
So as #tito mentioned in the comment, it is just syntatic sugar, and can be mixed. (although not mixed in a single call, for instance xyga is not valid)
I think it is just a helper so
vec.xyzw = vec.rgba = vec.stpq
and so on. You can use which ever set you want you just can not mix the set like
vec3 pos;
pos.xgb = vec3(1,1,1); // not valid do to mixing the sets
From Kronos.org - Data Type (GLSL):
You can use xyzw, rgba (for colors), or stpq (for texture coordinates). These three sets have no actual difference; they're just syntactic sugar. https://www.khronos.org/opengl/wiki/Data_Type_(GLSL)#Vectors
It is one of the many convenient features offered by GLSL to make vectors manipulation more flexible, like Swizzling.