Multiple subroutine types defined in the same fragment shader does not work correctly using GLSL Shaders

喜夏-厌秋 提交于 2019-12-06 09:20:14

glUniformSubroutines sets all of the subroutines for a shader stage, not just one of them.

See, when OpenGL links your program, it takes all of the subroutine uniforms and builds an array out of them. Each uniform has an index into this array. If you want to figure out what the index for a particular subroutine uniform in the array is, you need to call glGetSubroutineIndex. Alternatively, assuming you have 4.3/ARB_explicit_uniform_locations (which admittedly AMD is rather slow on), you can just set this directly with the layout(location = #) layout qualifier. That way, you don't have to query it.

Once you know what index each subroutine uniform refers to, you can then set all of the subroutine uniforms for a stage with a single call to glUniformSubroutines. You build up a short array, where each index in the array contains the index of the subroutine function you want to use.


But I want to choose just 2 subroutines each time among the four subroutines.

You may have 4 subroutines, but you only have two subroutine uniform variables. These uniforms represent the user setting the particular function in the shader to be called.

Furthermore, both of the uniforms use different types, so they cannot select from among the 4 subroutines. Each subroutine uniform can only select from among the specific subroutines used by that particular type. This is defined when you declare the subroutine function with subroutine(SubroutineType). Each type has its own set of functions which it could be used with. So each uniform can only select from among those specific functions set in the subroutine type declared for that uniform.

So you can't choose among 4 subroutines; each uniform can only choose among the functions you set for each subroutine type. Each uniform can only pick between the two functions you declared the subroutine type with.

If I have just a single call of glUniformSubroutinesuiv how can I select them ?

By passing it an array. There's a reason why the third parameter is a pointer, and why the second parameter is the number of entries in the array.

Your fragment shader has two subroutine uniform values. Therefore, there are 2 elements in the array, each one of which represents the subroutine index for a particular subroutine uniform. You select them both by creating an array, setting both subroutine indexes into it, and passing that array to the function.

I think there is a conflict between the two uniform subroutines.

No, the problem (besides the array issue noted earlier) is that you're not using the other subroutine. While subroutine uniforms are different from regular uniforms in most respects, they are like regular uniforms in this way. If you don't use them, the driver can optimize them (and anything they rely on) away.

Your fragment shader probably doesn't use TexturedShading anywhere. And since there's no other subroutine uniform that declares a TexturedShadingType uniform, the compiler realizes that those two functions are never used as subroutines. So it optimizes them out. Therefore, the indices you get for them are GL_INVALID_INDEX.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!