clip distance activation specified by shader

One thing that is a touch… aggravating is that which clip distances are active is specified by C-code; My suggestion is relatively simple: a little jazz in shader code that overrides GL state in choosing if clipping for each clip distance is on or off, something like this:



//specifies that GL_CLIP_DISTANCE0+I is active for this shader regardless of GL state
layout( clip_distance, I, true) 

//specifies that GL_CLIP_DISTANCE0+I is inactive for this shader regardless of GL state
layout( clip_distance, I, false) 



As for which shader this value is observed: the shader just before rasterization (so if Geometry shader is present, then Geometry otherwise if tessellation evaluation, then that one, otherwise vertex shader).

Is there a reason why a shader would specifically need to deactivate a clip distance? The point of having the shader set this stuff at all is so that the OpenGL code won’t have to set it. So if the shader is setting these values, the OpenGL code shouldn’t be setting them.

It makes much more sense to do this: if the shader enables any clip distances from the shader, then the OpenGL state is completely ignored. There’s no reason to have some half-state, where some values come from GL and some from the shader.

Also, the grammar of that command doesn’t fit with layout qualifiers. You have to qualify something; layout qualifiers are qualifiers after all. Given that it covers an output variable, it should qualify out.

I would much rather simplify it like this: you set an output qualifier switch like this:

layout(shader_clip) out;

Upon seeing this, the program will then (if the shader stage is applicable, as you defined) override all enables. How? Well, in order to write to gl_ClipDistance, you must redeclare it with an explicit size. Therefore, we can simply assume that all of them are enabled (and similarly all others are disabled). If you resize gl_ClipDistance to 4, then rendering will proceed as if GL_CLIP_DISTANCE0-3 will be enabled and all others were not.

Yes, it doesn’t let you punch holes in your array, so that certain indices are followed and others aren’t. However, your shader is now in control of the enables and disables. Unless your fragment shader is reading from its gl_ClipDistance (and I have no idea why it should), there’s really no reason to put holes in the array. If you have only 3 clip planes, then you redeclare gl_ClipDistance with 3 indices. Setting the above layout qualifier switch ensures that all three will be enabled.

This is simply easier to use and reason about.

Is there a reason why a shader would specifically need to deactivate a clip distance?

For example if it does not write to gl_ClipDistance.

In an ideal world, weather or not clipping is active would depend on the active GL program, but enabling/disabling clip distance is already GL state so that cat is out of the bag.

I agree with you that using layout keyword the way I suggested is dumb; it might be that just doing your suggestion of using layout to declare the size of the gl_ClipDistance array is enough with the understanding that a size of 0 means all are disabled.

Unless your fragment shader is reading from its gl_ClipDistance (and I have no idea why it should),

I can imagine using clip distance as a cheese muffin way to get a scaled distance to the boundary of primitive and then scaling it to screen space with dFdx/dFdx/fwidth to perform some anti-alias logick; but in all honesty I am not too shuffed about this since one know what fragment shader one is using so one can adapt it to know what gl_ClipDistance values are valid and worth using anyways.

For example if it does not write to gl_ClipDistance.

In an ideal world, weather or not clipping is active would depend on the active GL program, but enabling/disabling clip distance is already GL state so that cat is out of the bag.

If the user enables clip distances and they aren’t written to, you get undefined behavior currently. The spec is therefore perfectly free to define that behavior as explicitly acting as if those clip distances were not enabled. All existing code that relied upon the undefined behavior would be potentially broken. But it already was.

So if you don’t redeclare gl_ClipDistance, it could simply act as if all clip distances were disabled. There’s really no reason not to.

If for some reason this isn’t palatable, the use of the shader_clip could simply turn it on. So if you use that flag and never redeclare gl_ClipDistance (it’s not legal to set an array to 0 size), then all of them are disabled.

If the user enables clip distances and they aren’t written to, you get undefined behavior currently. The spec is therefore perfectly free to define that behavior as explicitly acting as if those clip distances were not enabled. All existing code that relied upon the undefined behavior would be potentially broken. But it already was.

True.

So if you don’t redeclare gl_ClipDistance, it could simply act as if all clip distances were disabled. There’s really no reason not to.

Um, I don’t follow how this would be ok with current shaders: if a shader now writes to gl_ClipDistance it has an effect dependent on GL state, but this idea indicates of someone did not redeclare them, then they are not in effect??

There are 2 jazzes:

[ul]
[li]Make clipping active from shader. The idea of (re)declaring gl_ClipDistance does this job perfectly; it allows one to also specify how many of them have an effect by the size of the array[/li][li]Disable clipping from a shader; allow to redeclare gl_ClipDistance as size 0 would do the trick, but would require that gl_ClipDistance would then need to be made “special built in array” that could be size 0… but failing to (re)declare gl_ClipDistance would then just mean that the current GL state determines it.[/li][/ul]
I like the idea of (re)declaring gl_ClipDistance, I don’t like the idea of -2- command/declarations affecting this (the shader_clip thing to say clipping off and the (re)declaration of gl_ClipDistance, with or without the shader_clip thing, determining which ones are active). Much better IMO to say “hey gl_ClipDistance is a built in array that can be be declared with size 0, indicating no clipping and writes to gl_ClipDistance are then errors”

Um, I don’t follow how this would be ok with current shaders: if a shader now writes to gl_ClipDistance it has an effect dependent on GL state, but this idea indicates of someone did not redeclare them, then they are not in effect?

I was going to talk about how you have to redeclare gl_ClipDistance in order to write to it, but then I found out that that’s not true.

Even so, that simply changes how you define this. If a program computes the size of gl_ClipDistance usage (based on either redeclaring it or writing to some components of it) as zero, then the program will implicitly disable all clip planes.

This is OK with current shaders because if a program doesn’t write to any gl_ClipDistances, then their values are undefined. So if the user enabled any of the clipping planes, rendering would be undefined. So all this is doing is replacing undefined behavior with defined behavior.

The issue with that approach is that is starts to walk the line “if this is written to…” which may or may not be determinable when a GLSL program is linked. Going further, in order for current shaders to work as is, a mechanism is needed to for a shader to choose between the 3 options:
[ul]
[li]use GL state[/li][li]clip distance is ON and what range of indices are ON[/li][li]clip distance is OFF[/li][/ul]

this is why I am for the idea of re declaring gl_ClipDistance. If it is not (re)declared, then GL state determines behavior (the case I am worried about is a shader that writes to gl_ClipDistance but is used also when clip distance of various indices is disabled). If gl_ClipDistance is (re)declared, then that declaration, by its size, determines which are active including allowing size 0 to say one are…

Or just some other syntax, I don’t really care at this point what the syntax will be, but have to specify
[ul]
[li]clip distance(s) on and which (or how many)[/li][li]clip distance(s) all off [strictly speaking a subcase of above][/li][li]GL state [implied by lack of new syntax being present][/li][/ul]

The issue with that approach is that is starts to walk the line “if this is written to…” which may or may not be determinable when a GLSL program is linked.

But that issue already exists. From the spec:

So the issue already exists and has been resolved. At link time, the compiler knows the size of that array.

Going further, in order for current shaders to work as is, a mechanism is needed to for a shader to choose between the 3 options:

I really only see 2 options. Either you’re using the GL state, or you’re not. If you’re not using GL state, then you’re using whatever clip planes are specified by the shader (under the rules already established for that, per the above).