what parameters does the function texture() takes? - opengl

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 (...).

Related

Using only part of a varying variable

Let's say I have a varying variable between any two GLSL shader stages (e.g. the vertex and fragment stage) declared as a vec4:
in/out/varying vec4 texCoord;
What happens if I only use part of that variable (say, through swizzling) in both shaders, i.e. I only write to a part of it in the vertex shader and only read from that same part in the fragment shader?
// vertex shader
texCoord.st = ...
// fragment shader
... = texture2D(..., texCoord.st);
Is that guartanteed (i.e. by specification) to always produce sane results? It seems reasonable that it does, however I'm not too well-versed in the intricacies of GLSL language-lawyering and don't know if that varying variable is interpreted as somehow "incomplete" by the compiler/linker because it isn't fully written to in the preceding stage. I'm sure the values of texCoord.pq will be undefined anyway, but does that affect the validity of texCoord.st too or does the whole varying system operate on a pure component level?
I haven't found anything to that effect in the GLSL specification on first glance and I would prefer answers based either on the actual specification or any other "official" guarantees, rather than statements that it should work on reasonable hardware (unless of course this case simply is unspecified or implementation-defined). I would also be interested in any possible changes of that throughout GLSL history, including all the way back to its appliance to deprecated builtin varying variables like gl_TexCoord[] in good old GLSL 1.10.
I'm trying to argue that your code will be fine, as per the specification. However, I'm not sure if you will find my reasoning 100% convincing, because I think that the spec seems somewhat imprecise about this. I'm going to refer to the OpenGL 4.5 Core Profile Specification and the OpenGL Shading language 4.50 specification.
Concerning input and output variables, the GLSL spec established the following in section 4.3.4
Shader input variables are declared with the storage qualifier in. They form the input interface between
previous stages of the OpenGL pipeline and the declaring shader. [...] Values from the previous pipeline stage are copied into input variables at the beginning of
shader execution.
and 4.3.6, respectively:
Shader output variables are declared with a storage qualifier using the storage qualifier out. They form
the output interface between the declaring shader and the subsequent stages of the OpenGL pipeline. [...]
During shader execution they will behave as normal
unqualified global variables. Their values are copied out to the subsequent pipeline stage on shader exit.
Only output variables that are read by the subsequent pipeline stage need to be written; it is allowed to
have superfluous declarations of output variables.
Section 5.8 "Assignments" establishes that
Reading a variable before writing (or initializing) it is legal, however the value is undefined.
Since the assignment of the .st vector will write to the sub-vector, we can establish that this variable will contain two intialized and two un-initialized components at the end of the shader invocation, and the whole vector will be copied to the output.
Section 11.1.2.1 of the GL spec states:
If the output variables are passed directly to the vertex processing
stages leading to rasterization, the values of all outputs are
expected to be interpolated across the primitive being rendered,
unless flatshaded. Otherwise the values of all outputs are collected
by the primitive assembly stage and passed on to the subsequent
pipeline stage once enough data for one primitive has been collected.
"The values of all outputs" are determined by the shader, and although some components have undefined values, they still have values, and there is no undefined or implementation-defined behavior here. The interpolation formulas for the line and polygon primitives (sections 14.5.1 and 14.6.1) also never mix between the components, so any defined component value will result in a defined value in the interpolated datum.
Section 11.1.2.1 also contains this statement about the vertex shader outputs:
When a program is linked, all components of any outputs written by a
vertex shader will count against this limit. A program whose vertex
shader writes more than the value of MAX_VERTEX_OUTPUT_COMPONENTS
components worth of outputs may fail to link, unless device-dependent
optimizations are able to make the program fit within available
hardware resources.
Note that this language implies that the full 4 components of a vec4 are counted against the limit as soon as a single component is written to.
On output variables, the specification says:
Their values are copied out to the subsequent pipeline stage on shader exit.
So the question boils down to two things:
What is the value of such an output variable?
That is easily answered. The section on swizzling makes it clear that writing to a swizzle mask will not modify the components that are not part of the swizzle mask. Since you did not write to those components, their values are undefined. So undefined values will be copied out to the subsequent pipeline stage.
Will interpolation of undefined values affect the interpolation of defined values?
No. Interpolation is a component-wise operation. The result of one component's interpolation cannot affect another's.
So this is fine.

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

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)

Use sampler without passing through value

I'm dealing with texture in fragment shader and I use a sampler2D to get the 2D texture but I do not pass through the value in OpenGL program. However, the value of that sampler2D is correct.
I feel really confused about this and any explanation about this?
The default value of a sampler variable is 0. From the GLSL 3.30 spec, section "4.3.5 Uniforms":
The link time initial value is either the value of the variable's initializer, if present, or 0 if no initializer is present. Sampler types cannot have initializers.
Since a value of 0 means that it's sampling from texture unit 0, it will work without ever setting the value as long as you bind your textures to unit 0. This is well defined behavior.
Since texture unit 0 is also the default until you call glActiveTexture() with a value other than GL_TEXTURE0, it's very common to always use unit 0 as long as shaders do not need more than one texture. Which means that often times, setting the sampler uniforms is redundant for simple applications.
I would still prefer to always set the values. If nothing else, it makes it clear to anybody reading your code that you really mean to sample from texture unit 0, and did not just forget to set the value.

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 does the 'iv' in glGetShaderiv() stand for?

What does the iv at the end of glGetShaderiv() stand for?
It describes the parameters returned, in this case a vector of ints. The same nomenclature is used for glTexParameteriv and glTexParameterfv for example, which updates a vector of ints or floats respectively.
OpenGL has some organized naming conventions regarding the routines they have in the libraries.
Prefixes
All routines have a gl before them. Similar thing you must have observed with glu and glut. Some vender libraries also have prefixes like NVidia guys have put up a NV_ prefix in the hardware feature flags.
Suffixes
Suffixes usually are an indicator to what kind of arguments does the method take.
Some specifying the context of the function. e.g. 1D, 2D or 3D
e.g. glTexCoord2D
Kind of value types is a function's argument taking. e.g. glTranslatef takes GLfloat arguments (observe that even the data types follow the same naming convention) and glTranslated take GLdouble.
The source of the vertices (usually when there are too many vertices and you store them in a single array) taking the method you have mentioned:
glGetShaderiv is a function, takes the parameters for shaders, where datatype is GLint and the source of data is a vector (v).
You can take such kind of conventions to easily identify that what method takes what kind of arguments.
It indicates you want to get a value that is an array of integers. The function reference can be found here, and as you can see, the return param is a GLint *. This is in contrast to functions such as glGetInternalFormati64v, which has a return param of GLint64 *. I believe, but can't locate at the moment, that there have been functions using the fv suffix to denote floats, and possibly others.