[英]OpenGL 3.3 shaders uniform variables not working
I've got two shaders programs (because I'm using deferred shading), each one with its Vertex and Fragment shader. 我有两个着色器程序(因为我正在使用延迟着色),每个程序都有其顶点和片段着色器。 My problem is that I can successfilly compile and link both of them (glGetProgramiv with GL_LINK_STATUS returns GL_TRUE for each one) but when I try to get the addresses of my second shader program's uniforms I can get only 3 of them, instead of 27 that are currently declared.
我的问题是我可以成功填充并链接它们(glGetProgramiv和GL_LINK_STATUS都为每个返回GL_TRUE),但是当我尝试获取第二个着色器程序的制服的地址时,我只能得到其中的3个,而不是27个当前声明。
I've checked with glGetProgramiv and GL_ACTIVE_UNIFORMS to check the number of uniforms for each shader program and for the first one it's right, but for the second it's wrong. 我已经使用glGetProgramiv和GL_ACTIVE_UNIFORMS进行了检查,以检查每个着色器程序的制服数量,第一个是正确的,但是第二个是错误的。
I've noticed that the only uniforms I can get from the secondo program are the first 3 of its vertex shader, and even if I add an uniform in that vertex shader, the number of readable uniforms is always 3. 我注意到,从secondo程序中可以获得的唯一制服是其顶点着色器的前3个,即使在该顶点着色器中添加了制服,可读的制服的数量也始终为3。
(I've added only my uniform's declaration because the shaders were too long.) (由于着色器太长,我只添加了我的制服的声明。)
This is the code for the first program vertex shader (working correctly) 这是第一个程序顶点着色器的代码(正常工作)
uniform struct Matrices
{
mat4 projectionMatrix;
mat4 modelMatrix;
mat4 viewMatrix;
mat4 normalMatrix;
} matrices;
layout (location = 0) in vec3 inPosition;
layout (location = 1) in vec2 inCoord;
layout (location = 2) in vec3 inNormal;
layout (location = 3) in vec3 inTangent;
This is the code for the first program fragment shader (working correctly) 这是第一个程序片段着色器的代码(正常工作)
uniform sampler2D gSampler;
uniform sampler2D gSamplerBump;
uniform vec4 vColor;
uniform float gMatSpecularIntensity;
uniform float gSpecularPower;
uniform float gRetroilluminato;
uniform int useTexture;
uniform int useTextureBump;
uniform int fondiTextureColore;
And these are the vertex and fragment shaders that are not working properly. 这些是顶点和片段着色器无法正常工作。
Vertex: 顶点:
uniform struct Matrici
{
mat4 projectionMatrix;
mat4 modelMatrix;
mat4 viewMatrix;
} matrici;
Fragment: 分段:
uniform struct MDLight
{
vec3 vColor;
vec3 vPosition;
vec3 vDirection;
float fAmbientIntensity;
float fStrength;
int bOn;
float fConeAngle;
float fConeCosine;
float fConstantAtt;
float fLinearAtt;
float fExpAtt;
float fAltezza;
float fLarghezza;
vec3 vUp;
vec3 vRight;
} gLuce;
uniform float gSpecularIntensity;
uniform float gSpecularPower;
uniform sampler2D gPositionMap;
uniform sampler2D gColorMap;
uniform sampler2D gNormalMap;
uniform vec3 gCameraPos;
uniform vec2 gScreenSize;
uniform int gLightType;
uniform int gUsaLuci;
Basically I can get only the addesses of projectionMatrix, modelMatrix and viewMatrix in the uniform struct "Matrici" of my second program vertex shader. 基本上,我只能在第二个程序顶点着色器的统一结构“ Matrici”中获得projectionMatrix,modelMatrix和viewMatrix的地址。 I've tried adding a value both inside the struct and outside but it doesen't read it.
我试过在结构体内部和外部都添加一个值,但它不会读取它。
Anyone with an idea? 有人有主意吗?
As @rems4e asked these are the complete shaders. 如@ rems4e所问,这些是完整的着色器。
Vertex shader for working program. 用于工作程序的顶点着色器。
#version 330
uniform struct Matrices
{
mat4 projectionMatrix;
mat4 modelMatrix;
mat4 viewMatrix;
mat4 normalMatrix;
} matrices;
layout (location = 0) in vec3 inPosition;
layout (location = 1) in vec2 inCoord;
layout (location = 2) in vec3 inNormal;
layout (location = 3) in vec3 inTangent;
smooth out vec2 texCoord;
smooth out vec3 vNormal;
smooth out vec3 vTangent;
smooth out vec3 vEyeSpacePos;
smooth out vec3 vWorldPos;
void main()
{
vec4 vEyeSpacePosVertex = matrices.viewMatrix*matrices.modelMatrix*vec4(inPosition, 1.0);
gl_Position = matrices.projectionMatrix*vEyeSpacePosVertex;
texCoord = inCoord;
vec4 vRes = matrices.normalMatrix*vec4(inNormal, 0.0);
vNormal = vRes.xyz;
vec4 vResTang = matrices.normalMatrix*vec4(inTangent, 0.0);
vTangent = vResTang.xyz;
vEyeSpacePos = vEyeSpacePosVertex.xyz;
vec4 vWorldPosVertex = matrices.modelMatrix*vec4(inPosition, 1.0);
vWorldPos = vWorldPosVertex.xyz;
}
Fragment shader for working program. 用于工作程序的片段着色器。
#version 330
smooth in vec2 texCoord;
smooth in vec3 vNormal;
smooth in vec3 vTangent;
smooth in vec3 vEyeSpacePos;
smooth in vec3 vWorldPos;
layout (location = 0) out vec4 WorldPosOut;
layout (location = 1) out vec4 DiffuseOut;
layout (location = 2) out vec4 NormalOut;
layout (location = 3) out vec4 FlagsOut;
uniform sampler2D gSampler;
uniform sampler2D gSamplerBump;
uniform vec4 vColor;
uniform float gMatSpecularIntensity;
uniform float gSpecularPower;
uniform float gRetroilluminato;
uniform int useTexture;
uniform int useTextureBump;
uniform int fondiTextureColore;
void main()
{
vec3 vNormalized = normalize(vNormal);
vec3 vTangente = normalize(vTangent);
vec4 vTexColor;
vec4 vMixedColor;
if(useTexture == 1)
{
vTexColor = texture2D(gSampler, texCoord);
if(fondiTextureColore == 1)
vMixedColor = vTexColor * vColor;
else
vMixedColor = vTexColor;
}
else
{
vMixedColor = vColor;
}
if(useTextureBump == 1)
{
vec3 vNormaleBump = texture(gSamplerBump, texCoord).xyz;
vNormaleBump = 2.0 * vNormaleBump - vec3(1.0, 1.0, 1.0);
vTangente = normalize(vTangente - dot(vTangente, vNormalized) * vNormalized);
vec3 vBitangente = cross(vTangente, vNormalized);
mat3 TBN = mat3(vTangente, vBitangente, vNormalized);
vec3 vNuovaNormale = TBN * vNormaleBump;
vNuovaNormale = normalize(vNuovaNormale);
vNormalized = vNuovaNormale;
}
WorldPosOut = vec4(vWorldPos, 1.0);
DiffuseOut = vMixedColor;
NormalOut = vec4(vNormalized, 1.0);
float v1 = 0.0;
float v2 = gMatSpecularIntensity;
float v3 = gSpecularPower;
float v4 = 1.0;
if(gRetroilluminato == 1)
v1 = 1.0;
FlagsOut = vec4(v1, v2, v3, v4);
}
Vertex shader for NOT working program. 顶点着色器不适用于程序。
#version 330
uniform struct Matrici
{
mat4 projectionMatrix;
mat4 modelMatrix;
mat4 viewMatrix;
} matrici;
layout (location = 0) in vec3 inPosition;
void main()
{
vec4 vEyeSpacePosVertex = matrici.viewMatrix * matrici.modelMatrix * vec4(inPosition, 1.0);
gl_Position = matrici.projectionMatrix * vEyeSpacePosVertex;
}
Fragment shader for NOT working program. 片段着色器不适用于程序。
#version 330
uniform struct MDLight
{
vec3 vColor;
vec3 vPosition;
vec3 vDirection;
float fAmbientIntensity;
float fStrength;
int bOn;
float fConeAngle;
float fConeCosine;
float fConstantAtt;
float fLinearAtt;
float fExpAtt;
float fAltezza;
float fLarghezza;
vec3 vUp;
vec3 vRight;
} gLuce;
uniform float gSpecularIntensity;
uniform float gSpecularPower;
uniform sampler2D gPositionMap;
uniform sampler2D gColorMap;
uniform sampler2D gNormalMap;
uniform vec3 gCameraPos;
uniform vec2 gScreenSize;
uniform int gLightType;
uniform int gUsaLuci;
vec3 projectOnPlane( vec3 point, vec3 planeCenter, vec3 planeNorm )
{
return point - dot( point - planeCenter, planeNorm ) * planeNorm;
}
vec3 linePlaneIntersect( vec3 lp, vec3 lv, vec3 pc, vec3 pn )
{
return lp + lv * ( dot( pn, pc - lp ) / dot( pn, lv ) );
}
bool isDavanti(vec3 p1, vec3 p2, vec3 n2)
{
vec3 p1p2 = normalize(p1 - p2);
float prod = dot(p1p2, n2);
if(prod >= 0.0)
return true;
else
return false;
}
vec4 getDirectionalLightColor(const MDLight dirLight, vec3 vNormale, int retroilluminato)
{
float fDiffuseIntensity = max(0.0, dot(vNormale, -dirLight.vDirection));
return vec4(dirLight.vColor * (dirLight.fAmbientIntensity + fDiffuseIntensity) * dirLight.fStrength, 1.0);
}
vec4 getPointLightColor(const MDLight ptLight, vec3 vWorldPos, vec3 vNormale, int retroilluminato)
{
if(ptLight.bOn == 0)
return vec4(0.0, 0.0, 0.0, 0.0);
vec3 vPosToLight = vWorldPos - ptLight.vPosition;
float fDist = length(vPosToLight);
vPosToLight = normalize(vPosToLight);
float fDiffuse;
if(retroilluminato == 1 && isDavanti(vWorldPos, ptLight.vPosition, vPosToLight))
fDiffuse = abs(dot(vNormale, -vPosToLight));
else
fDiffuse = max(0.0, dot(vNormale, -vPosToLight));
float fAttTotal = (1 + fDist * 0.0001 + 0.0000001 * fDist * fDist);
return vec4(ptLight.vColor, 1.0)*(ptLight.fAmbientIntensity + fDiffuse) / fAttTotal;
}
vec4 GetSpotLightColor(const MDLight spotLight, vec3 vWorldPos, vec3 vNormale, int retroilluminato)
{
if(spotLight.bOn == 0)
return vec4(0.0, 0.0, 0.0, 0.0);
vec3 vDir = vWorldPos-spotLight.vPosition;
vDir = normalize(vDir);
if(dot(vNormale, -vDir) <= 0.00 && (retroilluminato == 0))
return vec4(0.0, 0.0, 0.0, 0.0);
float fDistance = distance(vWorldPos, spotLight.vPosition);
float fCosine = dot(spotLight.vDirection, vDir);
float fDif = 1.0-spotLight.fConeCosine;
float fFactor = clamp((fCosine-spotLight.fConeCosine)/fDif, 0.0, 1.0);
float fAttTotal = (1 + fDistance * 0.0001 + 0.000001 * fDistance * fDistance);
if(fCosine > spotLight.fConeCosine)
return vec4(spotLight.vColor, 1.0)*(fFactor * spotLight.fAmbientIntensity) / fAttTotal;
return vec4(0.0, 0.0, 0.0, 0.0);
}
vec4 GetRectLightColor(const MDLight luce, vec3 vPosVert, vec3 vNormale, int retroilluminato)
{
if(luce.bOn == 0)
return vec4(0.0, 0.0, 0.0, 0.0);
vec3 direzioneLuce = normalize(luce.vDirection);
vec3 posizioneLuce = luce.vPosition;
vec3 normaleVertice = normalize(vNormale);
float w = luce.fLarghezza;
float h = luce.fAltezza;
vec3 proj = projectOnPlane(vPosVert, posizioneLuce, direzioneLuce);
vec3 dir = proj - posizioneLuce;
vec2 diagonal = vec2(dot( dir, luce.vRight), dot( dir, luce.vUp));
vec2 nearest2D = vec2(clamp(diagonal.x, -w, w), clamp(diagonal.y, -h, h));
vec3 nearestPointInside = posizioneLuce + (luce.vRight * nearest2D.x + luce.vUp * nearest2D.y);
vec3 lightDir = normalize(nearestPointInside - vPosVert);
float prodDirLmLD = dot(direzioneLuce, -lightDir);
float prodNVLD = dot(normaleVertice, lightDir);
float NdotL = 0.0;
float NdotL2 = 0.0;
if(retroilluminato == 1)
{
NdotL = abs(prodDirLmLD);
NdotL2 = abs(prodNVLD);
}
else
{
NdotL = max(prodDirLmLD, 0.0);
NdotL2 = max(prodNVLD, 0.0);
}
float prodottoDot = NdotL2 * NdotL;
if ( prodottoDot > 0.0 )
{
vec3 diffuse = vec3(sqrt(prodottoDot));
float dist = distance(vPosVert, nearestPointInside);
float attenuation = (1 + dist * 0.0001 + 0.000001 * dist * dist);
vec3 light = luce.fAmbientIntensity * luce.vColor;
return vec4(light * diffuse, 1.0) / attenuation;
}
else
{
return vec4(0.0, 0.0, 0.0, 0.0);
}
}
vec4 GetSpecularColor(vec3 vPosVertice, vec3 vPosCamera, vec3 vNormaleVertice, const MDLight luce)
{
vec4 vResult = vec4(0.0, 0.0, 0.0, 0.0);
vec3 direzioneLuce = luce.vDirection;
vec3 direzioneLuceVertice = vPosVertice - luce.vPosition;
if(gLightType == 1)
direzioneLuce = normalize(vPosVertice - luce.vPosition);
if(dot(-direzioneLuce, vNormaleVertice) <= 0.0 || dot(direzioneLuce, direzioneLuceVertice) <= 0.0)
return vResult;
vec3 vReflectedVector = normalize(reflect(direzioneLuce, vNormaleVertice));
vec3 vVertexToEyeVector = normalize(vPosCamera - vPosVertice);
float fSpecularFactor = dot(vVertexToEyeVector, vReflectedVector);
fSpecularFactor = pow(fSpecularFactor, gSpecularPower);
if (fSpecularFactor > 0)
vResult = vec4(luce.vColor, 1.0) * gSpecularIntensity * fSpecularFactor * luce.fAmbientIntensity;
return vResult;
}
vec4 GetMDLightColor(const MDLight ptLight, vec3 vWorldPos, vec3 vNormale, int retroilluminato)
{
if(gLightType == 0)
return getDirectionalLightColor(ptLight, vNormale, retroilluminato);
else if(gLightType == 1)
return getPointLightColor(ptLight, vWorldPos, vNormale, retroilluminato);
else if(gLightType == 2)
return GetSpotLightColor(ptLight, vWorldPos, vNormale, retroilluminato);
else if(gLightType == 3)
return GetRectLightColor(ptLight, vWorldPos, vNormale, retroilluminato);
}
vec2 CalcTexCoord()
{
return gl_FragCoord.xy / gScreenSize;
}
out vec4 FragColor;
void main()
{
vec2 TexCoord = CalcTexCoord();
vec4 Color = texture(gColorMap, TexCoord);
if(gUsaLuci == 1)
{
vec3 WorldPos = texture(gPositionMap, TexCoord).xyz;
vec3 Normal = texture(gNormalMap, TexCoord).xyz;
Normal = normalize(Normal);
int retroilluminato = 0;
vec4 coloreLuce = GetMDLightColor(gLuce, WorldPos, Normal, retroilluminato);
vec4 coloreRiflesso = GetSpecularColor(WorldPos, gCameraPos, Normal, gLuce);
}
else
{
FragColor = Color;
}
}
GL_ACTIVE_UNIFORMS
is mapped as its name indicates to the active uniforms, ie the ones that actually not optimized away by the shader compiler/linker. GL_ACTIVE_UNIFORMS
就像其名称所指示的那样映射到活动的制服,即,着色器编译器/链接器实际上并未对其进行优化的制服。 This happens when the uniform is not used by your program, or used in a way that won't affect the final rendering. 当您的程序不使用制服,或使用不会影响最终渲染的方式时,就会发生这种情况。 Your shader code is needed to see if the uniforms you can not get the index of are used or not, but I presume they are not.
需要您的着色器代码,以查看您是否无法使用无法获得索引的制服,但是我认为它们没有被使用。
I solved my problem following @rems4e hint. 我按照@ rems4e提示解决了我的问题。
In fact I thought I was using all my uniforms, in theory, but in practice I wasn't. 实际上,从理论上讲,我认为我正在使用我的所有制服,但实际上我没有。 In all of my functions I was passing a
MDLight
as parameter, which, actually, was gLuce
, the uniform I was trying to get the uniforms. 在我的所有函数中,我都传递了
MDLight
作为参数,实际上是gLuce
,我正在尝试获取制服。 Seems like that passing gLuce
as parameter for other functions, OpenGL thought I was actually not using gLuce
, deleting it from my active uniform list. 好像将
gLuce
作为其他函数的参数传递一样,OpenGL认为我实际上不是在使用gLuce
,而是从我的活动统一列表中删除了它。
So basically I just used gLuce
everywhere instead the parameter I was passing to the functions and it's now working. 因此,基本上我只是在
gLuce
地方都使用了gLuce
,而不是我传递给函数的参数,现在它可以正常工作了。
The same for all other uniforms I wasn't able to get. 我无法获得的所有其他制服都一样。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.