我试图通过
out float texture_contribs[16]
使用glsl 3.3从顶点着色器到框架着色器
但是,无论顶点着色器中的值如何,帧着色器中的值始终为0.0。
这是我的顶点着色器代码:
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
uniform mat4 normalMatrix;
layout(location = 0) in vec4 in_position;
layout(location = 1) in vec4 in_colour;
layout(location = 2) in vec2 in_coord;
layout(location = 3) in vec3 in_normal;
layout(location = 4) in float texture_contributions[16];
out vec2 texcoord;
out vec4 pass_colour;
out float texture_contribs[16];
smooth out vec3 vNormal;
void main()
{
gl_Position = projectionMatrix * viewMatrix * modelMatrix * in_position;
texcoord = in_coord;
vec4 vRes = normalMatrix*vec4(in_normal, 0.0);
vNormal = vRes.xyz;
pass_colour = in_colour;
for (int i = 0; i < 16; i++)
{
texture_contribs[i] = texture_contributions[i];
}
}
这是片段着色器代码:
uniform sampler2D texture[16];
in vec2 texcoord;
in vec4 pass_colour;
in float texture_contribs[16];
smooth in vec3 vNormal;
out vec4 out_colour;
struct SimpleDirectionalLight
{
vec3 vColor;
vec3 vDirection;
float fAmbientIntensity;
};
uniform SimpleDirectionalLight sunLight;
void main()
{
vec4 vTexColor = texture2D(texture[2], texcoord) * texture_contribs[2] + texture2D(texture[3], texcoord) * texture_contribs[3];
if(vTexColor.a < 0.1)
discard;
float fDiffuseIntensity = max(0.0, dot(normalize(vNormal), -sunLight.vDirection));
out_colour = vTexColor*pass_colour*vec4(sunLight.vColor*(sunLight.fAmbientIntensity+fDiffuseIntensity), 1.0);
}
我尝试将数组拆分为单独的变量,然后分别传递它们,它们的值仍在片段着色器中消失。
const int gl_MaxVertexAttribs = 16; // Minimum: 16 Vertex Attribute Slots
GLuint max_vtx_attribs;
glGetIntegerv (GL_MAX_VERTEX_ATTRIBS, &max_vtx_attribs);
我是唯一知道AMD的厂商,它提供的属性至少超过16种(至少在某些驱动程序/硬件组合中为29-32)。英特尔,苹果,NVIDIA和Mesa都给您16。如果要编写可移植的代码,则应尝试定位的顶点属性不超过16个。否则,您必须为不同的供应商编写不同的代码路径,这很无聊。
实际应用中并不需要每个顶点属性多于16个,而通常依赖于更适合于存储大量数据的东西,例如纹理/着色器存储缓冲区对象。
的OpenGL 3.3核心配置文件规格- 2.7顶点规范-第26
顶点着色器(请参阅第2.11节)访问包含4个组件的通用顶点属性的数组。该数组的第一个插槽编号为0,并且数组的大小由与实现相关的常量指定
GL_MAX_VERTEX_ATTRIBS
。
GLSL 3.3中的每个顶点属性位置都可以存储单个vec4
,大于vec4
(例如 mat4
)的数据类型将跨越多个位置。小于的数据类型会vec4
占用整个位置,这是您的着色器开始出现问题的地方。您已经声明了一个由16个元素组成的标量数组,每个标量都具有从4开始的自己的顺序位置。这意味着阵列占据位置4 - 19,但大部分的实现没有20点的位置来伸手。
的OpenGL 3.3核心配置文件规格- 2.11.3顶点属性-第55
如果编译器和链接器确定在执行着色器时可以访问该属性,则将其视为通用属性变量。在顶点着色器中声明但从未使用过的属性变量将不会计入限制。如果编译器和链接器无法做出确定的决定,则将属性视为活动的。如果活动顶点属性的数量超过,则程序对象将无法链接
GL_MAX_VERTEX_ATTRIBS
。
第一4个顶点属性(0 - 3)是激活的,如可通过您的标量阵列创建的16。您的GLSL程序(应该)在任何不提供至少20个顶点属性的实现上均无法链接。如果不是,则您有一个不兼容的实现。
您实际上并不需要消耗16个属性槽来存储所有每个顶点数据。如果float
用的4元素数组vec4
或single替换此16元素数组mat4
,则仅使用4个属性槽就可以存储相同数量的数据。
4(in_position
,in_colour
,in_coord
,in_normal
)+ 4(texture_contributions
)= 8
这也大大简化了顶点指针的设置,因为您只需要8个而不是20个即可。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句