uniform keyword in HLSL - directx

it seems that in HLSL i can but dont have to provide the uniform keyword for variables which come from the application. right?
why is that so?

In HLSL global variables are considered uniform by default.
It's also settled that a variable coming out of the vertex shader stage for example is varying (HLSL doesn't need this keyword at all!).
Note that GLSL keywords uniform/varying are inherited from RSL
(RenderMan shading language).

Related

What is the correct usage of sampler lod_options (MSL) in Metal shader?

I'm trying to learn MSL through the Metal Shading Language Specification, and saw that you can set LOD options when sampling a texture by specifying the options in the sample function. This is one of the examples given in the spec:
Tv sample(sampler s, float2 coord, lod_options options, int2 offset = int2(0)) const
lod_options include bias, level, gradient2d, etc.
I've looked all over but cannot find the usage syntax for this. Are these named arguments? Is lod_options a struct? For example, if I want to specify the LOD level, what is the correct way to do it? I know these options can also be specified in the sampler object itself, but if I want to do it here, what would be the right syntax to do so?
There is no lod_options type as such; you can think of it as a placeholder for one of the bias, level, gradient2d, etc. types. Each of these types is a different struct, which allows the Metal standard library to have an overloaded variant of the sample function for each such option.
To specify, for example, the mipmap level to sample, you'd provide a parameter of level type:
float4 color = myTexture.sample(mySampler, coords, level(1));

How and when to choose highp, lowp and mediump in the Vertex and Fragment shader?

What's the best practice for them? Is there any performance difference?
What's the best practice for them?
For the most part these only matter on mobile. The spec says an implementation can always use a higher precision so on desktop both the vertex shader and fragment shader run in highp always. (I know of no desktop GPUs for which this is not true)
From the spec section 4.5.2
4.5.2 Precision Qualifiers
...
Precision qualifiers declare a minimum range and precision that the underlying implementation must use
when storing these variables. Implementations may use greater range and precision than requested, but
not less.
For Mobile and Tablets then there are several answers. There is no best. It's up to you
use the lowest precision you can that still does what you need it to do.
use highp and ignore the perf issues and the old phones where it doesn't work
use mediump and ignore the bugs (See below)
check if the user's device supports highp, if not use different shaders with less features.
WebGL defaults to vertex shaders use highp and fragment shaders don't have a default an you have to specify one. Further, highp in the fragment shader is an optional feature and some mobile GPUs don't support it. I don't know what percent that is in 2019. AFAIK most or maybe even all phones shipping in 2019 support highp but older phones (2011, 2012, 2013) don't.]
From the spec:
The vertex language requires any uses of lowp, mediump and highp to compile and link without error.
The fragment language requires any uses of lowp and mediump to compile without error. Support for
highp is optional.
Examples of places you generally need highp. Phong shaded point lights usually need highp. So for example you might use only directional lights on a system that doesn't support highp OR you might use only directional lights on mobile for performance.
Is there any performance difference?
Yes but as it says above an implemenation is free to use a higher precision. So if you use mediump on a desktop GPU you won't see any perf difference since it's really using highp always. On mobile you will see a perf diff, at least in 2019. You may also see where your shaders really needed highp.
Here is a phong shader set to use mediump. On desktop since mediump is actually highp it works
On Mobile where mediump is actually mediump it breaks
An example where mediump would be fine, at least in the fragment shader, is most 2D games.

How can a shader read a vertex information?

I have lately learned a shader.
Speeking of this as I know simply,
First, Make a buffer that saves vertices information.
Then make a shader file and compile.
Finally, Set a shader and Draw.
But studying code, I guess that there is no direct connection between
a shader and buffer has vertices. So I wonder How can a shader read a vertex information? Just does a shader read a existent buffer?
I am not sure that my intend will be well delivered.
Because I can't speak English well. I hope you guys understand me.
You are not mentioned about the InputLayout, to render it is necessary to define in the context:
Vertex buffer,
Index buffer (optional),
Input layout (how the data will be distributed in the Vertex Shader parameters, sizes, types, "offset for each stride"),
VS and PS

equivalent to Open GL precision attributes (lowp, mediump, highp) in iOS Metal

In OpenGL ES it is possible to set precision to uniforms and attributes using lopw/mediump/highp. Is there something like this in Metal?
The metal shading language supports the half data type (see section 2.1 of the spec). It's defined there as:
A 16-bit floating-point. The half data type must conform to the IEEE 754 binary16 storage format.
This makes it pretty much equivalent to mediump.
There isn't really an equivalent to lowp in metal. However, that's no real loss because I believe that metal capable iOS GPUs don't benefit from lowp anyway and just do any lowp operations at mediump.

How to pass non interpolated data OpenGL ES (GLSL)

I'm trying to pass simple FLOAT value from vertex to fragment shader. How can I pass it "as is" without interpolation?
On desktop I could use flat varying to disable interpolation, is there something similar in openGL es or the only way is through texture?
GLSL ES does currently not support the flat keyword, so the only way is to use the same float value in all the triangle vertices.
The same answer was given here:
In opengl es 2, is there a way to prevent interpolation of varyings
GLSL ES 2.0 does not support the flat interpolation qualifier, just as it does not support integral vertex shader output variables.
Compare OpenGL ES 2.0 Specification and OpenGL ES 3.0. Specification.

Resources