kku*_*llo 1 opengl shader glsl
我想通过
out float texture_contribs[16]
Run Code Online (Sandbox Code Playgroud)
使用glsl 3.3从顶点着色器到frament着色器
但是,无论顶点着色器中的值如何,frament着色器中的值始终为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];
}
}
Run Code Online (Sandbox Code Playgroud)
这是片段着色器代码:
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);
}
Run Code Online (Sandbox Code Playgroud)
我尝试将数组拆分为单个变量并单独传递它们的值,它们的值仍然在片段着色器中消失.
const int gl_MaxVertexAttribs = 16; // Minimum: 16 Vertex Attribute Slots
Run Code Online (Sandbox Code Playgroud)
GLuint max_vtx_attribs;
glGetIntegerv (GL_MAX_VERTEX_ATTRIBS, &max_vtx_attribs);
Run Code Online (Sandbox Code Playgroud)
AMD是我所知道的唯一提供超过16个属性的供应商(它们在一些驱动程序/硬件组合上提供29-32).Intel,Apple,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个属性槽来存储所有每个顶点数据.如果将此16元素数组替换float为4元素数组vec4或单个数组mat4,则只需使用4个属性插槽即可存储相同数量的数据.
4(in_position,in_colour,in_coord,in_normal)+ 4(texture_contributions)= 8
这也极大地简化了顶点指针的设置,因为你只需要8个而不是20个.
| 归档时间: |
|
| 查看次数: |
3012 次 |
| 最近记录: |