GLSL sampler2D结构 [英] GLSL sampler2D in struct

查看:1108
本文介绍了GLSL sampler2D结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在GLSL中,当我尝试将带有sampler2D属性的统一结构传递给向前声明的函数时,似乎存在着色器的链接错误.如果我删除前向声明并将函数移到main之上,则该代码有效.这是非法代码吗?

In GLSL there seems to be linking error of shaders when I try to pass a uniform struct with a sampler2D attribute to a function which is forward declared. The code works if I remove forward declaration and move the function above main. Is this illegal code?

#version 330 core

in vec2 texcoords;
out vec4 color;

struct Material{
    sampler2D tex; // Sampler inside a struct
}; 

uniform Material material;

// Forward Declaration
vec4 add(Material m);

void main() {
    color = add(material);
}

// Function Definition
vec4 add(Material m) {
    return vec4(texture(m.tex, texcoords));
}

// C++
glUniform1f(glGetUniformLocation(shader, "material.tex"), 0);
glBindTexture(GL_TEXTURE_2D, texture);

因此,经过一番搜索后,看来似乎是AMD驱动程序中的错误.我个人使用了很老的 ATI Mobility Radeon HD 4670 ,但是它仍然运行OpenGL 3.3.在AMD的论坛上,我找到了 类似帖子 ,因此有趣的是,这在AMD的图形卡上有多大.因为如果您在Intel或NVidia上进行开发,那么如何知道着色器无法在某些AMD显卡上编译?我们应该保持安全,不要在带有采样器的结构上使用原型,或者甚至不将采样器完全放入结构中吗?...还应该注意, WebGL 甚至不允许在内部使用采样器结构.

So after a bit of searching it appears to be a bug in AMD's driver. I personally use ATI Mobility Radeon HD 4670 which is pretty old, but it still runs OpenGL 3.3. On AMD's forums I found a similar post, and so it would be interesting to know how big this is on AMD's graphic cards. Because if you're developing on Intel or NVidia, then how are you to know your shaders won't compile on some AMD's graphic cards? Should we stay safe and not use prototypes on structs with samplers, or even go as far as not putting samplers in struct completely?... It's also worth noting that WebGL doesn't even allow for samplers inside structs.

错误消息:

Vertex shader(s) failed to link, fragment shader(s) failed to link.
unexpected error.
unexpected error.

推荐答案

这实际上不起作用,因为您无法实例化包含不透明数据类型(采样器,图像,原子计数器)的结构.可以使用具有不透明类型的结构作为统一结构,这是可以接受的,但是您不能通过传递Material的实例来实现函数add (...).

This actually is not supposed to work because you cannot instantiate a struct that contains an opaque data type (sampler, image, atomic counter). It is acceptable to have a struct with an opaque type as a uniform, but you cannot implement the function add (...) by passing an instance of Material.

不透明类型的变量只能以两种方式之一声明.它们可以在全局范围内声明为统一变量.这样的变量可以是不透明类型的数组. 它们可以声明为结构的成员但是,如果是这样,则结构只能用于声明统一变量 >(或声明本身是统一变量的struct/array的成员).它们不能直接或间接成为缓冲区支持的接口块或输入/输出变量的一部分.

Variables of opaque types can only be declared in one of two ways. They can be declared at global scope, as a uniform​ variables. Such variables can be arrays of the opaque type. They can be declared as members of a struct, but if so, then the struct can only be used to declare a uniform​ variable (or to declare a member of a struct/array that itself a uniform variable). They cannot be part of a buffer-backed interface block or an input/output variable, either directly or indirectly.


您的代码更改 应该 可以在OpenGL的所有兼容实现中使用:


This change to your code should work across all compliant implementations of OpenGL:

// Must be in, because you cannot assign values to an opaque type.
vec4 add (in sampler2D tex) {
  return vec4(texture(tex, texcoords));
}

这也将起作用,因为它使用material.tex制服中的采样器:

This would also work, since it uses the sampler in the material.tex uniform:

vec4 add (void) {
  return vec4(texture(material.tex, texcoords));
}

这篇关于GLSL sampler2D结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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