GLSL:如何做类似开关的语句 [英] GLSL: How to do switch-like statement

查看:86
本文介绍了GLSL:如何做类似开关的语句的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想基于传递到着色器中的数据动态调用缓动.所以用伪代码:

var easing = easings[easingId]
var value = easing(point)

我想知道在GLSL中实现此目标的最佳方法.我可以某种方式使用switch语句,或者可以将缓动放入数组中并像这样使用它们.也许有一种方法可以像上面的示例一样创建哈希表并使用它.

easingsArray = [
  cubicIn,
  cubicOut,
  ...
]

uniform easingId

main() {
  easing = easingsArray[easingId]
  value = easing(point)
}

那将是潜在的数组方法.另一种方法是switch语句.也许还有其他.想知道推荐的方法是这样做的.也许我可以以某种方式使用结构...

解决方案

如果您需要在GLSL中进行条件分支(在这种情况下,基于变量选择缓动函数),则需要使用if或switch语句. /p>

例如

if (easingId == 0) {
    result = cubicIn();
} else if (easingId == 1) {
    result = cubicOut();
}

switch (easingId) {
case 0:
    result = cubicIn();
    break;
case 1:
    result = cubicOut();
    break;
}

GLSL不支持函数指针,因此不幸的是,您正在考虑的那种动态分配解决方案(函数指针表等)将无法实现.

尽管您的问题明确地是关于将数据传递到着色器中的,但我也要指出,如果将控制分支的值以统一的方式传递到着色器中,则可以改为编译着色器的多个变体,然后从应用程序本身中动态选择合适的一个(即使用正确的缓动功能的选择).这样可以节省在着色器中分支的成本.

I would like to dynamically invoke an easing based on the data passed into the shader. So in pseudocode:

var easing = easings[easingId]
var value = easing(point)

I'm wondering the best way to accomplish this in GLSL. I could use a switch statement in some way, or could perhaps put the easings into an array and use them like that. Or maybe there is a way to create a hashtable and use it like the above example.

easingsArray = [
  cubicIn,
  cubicOut,
  ...
]

uniform easingId

main() {
  easing = easingsArray[easingId]
  value = easing(point)
}

That would be the potential array approach. Another approach is the switch statement. Maybe there are others. Wondering what the recommended way is of doing this. Maybe I could use a struct somehow...

解决方案

If you need conditional branching in GLSL (in your case for selecting an easing function based on a variable) you'll need to use if or switch statements.

For example

if (easingId == 0) {
    result = cubicIn();
} else if (easingId == 1) {
    result = cubicOut();
}

or

switch (easingId) {
case 0:
    result = cubicIn();
    break;
case 1:
    result = cubicOut();
    break;
}

GLSL has no support for function pointers, so the kind of dynamic dispatch solutions you are considering (tables of function pointers etc.) will unfortunately not be possible.

Whilst your question was explicitly about data being passed into the shader, I would also like to point out that if the value controlling the branch is being passed into the shader as a uniform, then you could instead compile multiple variants of your shader, and then dynamically select the right one (i.e. the one using the right easing function) from the application itself. This would save the cost of branching in the shader.

这篇关于GLSL:如何做类似开关的语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆