Hello,
I want to use an array of arrays (vec4[3][1]) as vertex output and fragment input. If the array has the form vec4 a[2][1]my program works but if the first index is larger than 2, my program shows only the clear color.
The array has no effect on the rest of the shaders, other than an identity matrix multiplication to avoid that that array gets optimized out. The full fragment and vertex shaders:
vert:
#version 450
#define MAX_NUM_LIGHTS 10
#define NUM_CASCADES 2
in layout(location = 0) vec4 vertPosition_ModelSpace;
in layout(location = 1) vec3 vertNormal_ModelSpace;
in layout(location = 2) vec3 vertTangent_ModelSpace;
in layout(location = 3) vec2 textureCoordinate;
uniform mat4 modelToWorld;
uniform mat4 worldToProjection;
uniform mat4 worldToLight[NUM_CASCADES][MAX_NUM_LIGHTS];
uniform vec3 cameraPosition_WorldSpace;
uniform vec3 lightPosition_WorldSpace[MAX_NUM_LIGHTS];
uniform int numLights;
out VsOut
{
vec3 fragPosition_TangentSpace;
vec2 textureCoordinate;
vec3 cameraPosition_TangentSpace;
vec3 lightPosition_TangentSpace[MAX_NUM_LIGHTS];
vec4 v[3][1];
vec4 fragPosition_LightSpace[NUM_CASCADES][MAX_NUM_LIGHTS];
} vsOut;
void main()
{
vsOut.v[0][0] = vec4(1.0);
vec3 vertNormal_WorldSpace = normalize(vec3(modelToWorld * vec4(vertNormal_ModelSpace, 0.0)));
vec3 vertTangent_WorldSpace = normalize(vec3(modelToWorld * vec4(vertTangent_ModelSpace, 0.0)));
vec3 vertBiTangent_WorldSpace = normalize(cross(vertNormal_WorldSpace, vertTangent_WorldSpace));
mat3 worldToTangentSpace = transpose(mat3(
vertTangent_WorldSpace,
vertBiTangent_WorldSpace,
vertNormal_WorldSpace
));
vec3 vertPosition_WorldSpace = vec3(modelToWorld * vertPosition_ModelSpace);
gl_Position = worldToProjection * vec4(vertPosition_WorldSpace, 1.0);
vsOut.fragPosition_TangentSpace = worldToTangentSpace * vertPosition_WorldSpace;
vsOut.cameraPosition_TangentSpace = worldToTangentSpace * cameraPosition_WorldSpace;
for(int i = 0; i < numLights; i++)
{
vsOut.lightPosition_TangentSpace[i] = worldToTangentSpace * lightPosition_WorldSpace[i];
for(int cascadeIndex = 0; cascadeIndex<NUM_CASCADES; cascadeIndex++)
{
vsOut.fragPosition_LightSpace[cascadeIndex][i] = worldToLight[cascadeIndex][i] * vec4(vertPosition_WorldSpace, 1.0);
}
}
vsOut.textureCoordinate = textureCoordinate;
}
frag:
#version 450
#define MAX_NUM_LIGHTS 10
#define NUM_CASCADES 2
in VsOut
{
vec3 fragPosition_TangentSpace;
vec2 textureCoordinate;
vec3 cameraPosition_TangentSpace;
vec3 lightPosition_TangentSpace[MAX_NUM_LIGHTS];
vec4 v[3][1];
vec4 fragPosition_LightSpace[NUM_CASCADES][MAX_NUM_LIGHTS];
} vsOut;
layout(location = 0) out vec4 outColor;
uniform float lightPower[MAX_NUM_LIGHTS];
uniform vec3 lightColor[MAX_NUM_LIGHTS];
uniform int numLights;
uniform vec3 ambientColor;
uniform vec3 diffuseColor;
uniform vec3 specularColor;
uniform float transparency;
uniform float shininess;
uniform sampler2D diffuseTexture;
uniform sampler2D normalMap;
uniform sampler2D depthMap[NUM_CASCADES][MAX_NUM_LIGHTS];
uniform float cascadeDistances[NUM_CASCADES];
float shadowCalculation(int lightIndex, int cascadeIndex)
{
vec3 projCoords = vsOut.fragPosition_LightSpace[cascadeIndex][lightIndex].xyz / vsOut.fragPosition_LightSpace[cascadeIndex][lightIndex].w;
projCoords = projCoords * 0.5 + 0.5;
float currentDepth = projCoords.z;
float shadow = 0.0;
vec2 texelSize = 1.0 / textureSize(depthMap[cascadeIndex][lightIndex], 0);
float bias = 0.0;
for(int x = -1; x <= 1; ++x)
{
for(int y = -1; y <= 1; ++y)
{
float pcfDepth = texture(depthMap[cascadeIndex][lightIndex], projCoords.xy + vec2(x, y) * texelSize).r;
shadow += currentDepth - bias > pcfDepth ? 1.0 : 0.0;
}
}
shadow /= 9.0;
return clamp(shadow, 0.0, 1.0);
}
float calculateLocalLightPower(float lightDistance, float lightPower)
{
return clamp(lightPower/pow(lightDistance, 2.0), 0.0, 1.0);
}
vec3 ambientLight(vec3 ambientColor)
{
return ambientColor * vec3(0.0, 0.0, 0.0);
}
vec3 diffuseLight(
vec3 diffuseColor,
vec3 toLight[MAX_NUM_LIGHTS],
vec3 lightColor[MAX_NUM_LIGHTS],
float localLightPower[MAX_NUM_LIGHTS],
vec3 normal
)
{
vec3 diffuseLight = vec3(0.0, 0.0, 0.0);
for(int i = 0; i < numLights; i++)
{
diffuseLight +=
lightColor[i] * clamp(dot(toLight[i], normal), 0.0, 1.0) * localLightPower[i];
}
return diffuseColor * clamp(diffuseLight, 0.0, 1.0);
}
vec3 specularLight(
vec3 specularColor,
vec3 toLight[MAX_NUM_LIGHTS],
vec3 lightColor[MAX_NUM_LIGHTS],
float localLightPower[MAX_NUM_LIGHTS],
vec3 toCamera,
vec3 normal
)
{
vec3 specularLight = vec3(0.0, 0.0, 0.0);
for(int i = 0; i < numLights; i++)
{
vec3 halfDir = normalize(toLight[i] + toCamera);
float specAngle = clamp(dot(halfDir, normal), 0.0, 1.0);
specularLight += lightColor[i] * pow(specAngle, shininess) * localLightPower[i];
}
return specularColor * specularLight;
}
void main()
{
vec4 diffuseTextureColor = texture2D(diffuseTexture, vsOut.textureCoordinate);
vec3 fragNormal_TangentSpace = normalize(texture2D(normalMap, vsOut.textureCoordinate).rgb * 2.0 - vec3(1.0, 1.0, 1.0));
int cascadeIndex;
float currentCascadeDistance = distance(vsOut.fragPosition_TangentSpace, vsOut.cameraPosition_TangentSpace);
for(int i = 0; i<NUM_CASCADES; i++)
{
cascadeIndex = i;
if(currentCascadeDistance<cascadeDistances[i])
{
break;
}
}
vec3 toLight_TangentSpace[MAX_NUM_LIGHTS];
float localLightPower[MAX_NUM_LIGHTS];
for(int i = 0; i < numLights; i++)
{
toLight_TangentSpace[i] = normalize(vsOut.lightPosition_TangentSpace[i] - vsOut.fragPosition_TangentSpace);
float lightDistance = distance(vsOut.lightPosition_TangentSpace[i], vsOut.fragPosition_TangentSpace);
localLightPower[i] =
calculateLocalLightPower(lightDistance, lightPower[i])*(1.0 - shadowCalculation(i, cascadeIndex));
}
vec3 toCamera = normalize(vsOut.cameraPosition_TangentSpace - vsOut.fragPosition_TangentSpace);
vec3 ambientLight = ambientLight(ambientColor);
vec3 diffuseLight = diffuseLight(diffuseColor, toLight_TangentSpace, lightColor, localLightPower, fragNormal_TangentSpace);
vec3 specularLight = specularLight(specularColor, toLight_TangentSpace, lightColor, localLightPower, toCamera, fragNormal_TangentSpace);
vec3 finalLight = clamp(ambientLight +
(diffuseLight + specularLight)
, 0.0, 1.0);
outColor = diffuseTextureColor * vec4(finalLight, transparency)*vsOut.v[0][0];
}
As they are these shaders do not work as I intended, they work when vec4 v[3][1] gets replaced with vec4 v[2][1].
I am sorry that i can’t provide a minimal example but it would be too much of a headache to rewrite the renderer.
system information:
KAOS Linux, Intel Open Source Technology Center, 4.5 (Core Profile) Mesa 17.3.9, Mesa DRI Intel(R) UHD Graphics 620 (Kabylake GT2)
using C++, glew, glfw