I currently get a very uninformative compilation error when trying to compile a shader. It's automatically generated and contains a bit of unnecessary stuff, so bare with me .
#version 430
subroutine vec3 CalculateBump(in vec3 tangent, in vec3 binormal, in vec3 normal, in vec2 uv, in sampler2D normalMap);
subroutine float CalculateDepth(in vec3 viewSpacePosition);
subroutine vec4 CalculateEmissive(in vec4 emissiveColor, in float emissiveIntensity);
subroutine vec4 CalculateSpecular(in vec3 specularColor, in float specularIntensity, in vec3 environmentColor, in float roughness);
subroutine vec3 CalculateEnvironment(in vec3 specularColor, in samplerCube environmentMap, in vec3 viewSpaceNormal, in vec3 viewSpacePos, in vec4 eyePos, in mat4x4 invView, in float roughness);
subroutine vec4 CalculateColor(in vec4 albedoColor, in vec3 environmentColor, in float saturation, in vec4 color, in float roughness, in float alphaBlend);
subroutine (CalculateBump) vec3
NormalMapFunctor(vec3 tangent, vec3 binormal, vec3 normal, vec2 uv, sampler2D normalMap)
{
mat3 tangentViewMatrix = mat3(normalize(tangent.xyz), normalize(binormal.xyz), normalize(normal.xyz));
vec3 tNormal = vec3(0,0,0);
tNormal.xy = (texture(normalMap, uv).ag * 2.0f) - 1.0f;
tNormal.z = clamp(sqrt(1.0f - dot(tNormal.xy, tNormal.xy)), 0, 1) ;
return tangentViewMatrix * tNormal;
}
subroutine (CalculateDepth) float
ViewSpaceDepthFunctor(vec3 viewSpacePosition)
{
return length(viewSpacePosition);
}
subroutine (CalculateEmissive) vec4
IntensityEmissiveFunctor(vec4 color, float intensity)
{
return color * intensity;
}
subroutine (CalculateSpecular) vec4
NonReflectiveSpecularFunctor(vec3 specularColor, float specularIntensity, vec3 environmentColor, float roughness)
{
return vec4(specularColor * specularIntensity, roughness);
}
subroutine (CalculateSpecular) vec4
ReflectiveSpecularFunctor(vec3 specularColor, float specularIntensity, vec3 environmentColor, float roughness)
{
return vec4(specularColor * specularIntensity * environmentColor, roughness);
}
subroutine (CalculateEnvironment) vec3
EnvironmentPBR(vec3 specularColor, samplerCube environmentMap, vec3 viewSpaceNormal, vec3 viewSpacePos, vec4 eyePos, mat4x4 invView, float roughness)
{
vec3 worldViewVec = normalize(eyePos.xyz - (invView * vec4(viewSpacePos, 1)).xyz);
vec3 reflectVec = reflect(-worldViewVec, (invView * vec4(viewSpaceNormal, 0)).xyz);
float x = dot(viewSpaceNormal, normalize(viewSpacePos.xyz));
vec3 rim = specularColor + (1 - specularColor) * (pow((1 - x), 5) / (4 - 3 * roughness));
vec3 envColor = textureLod(environmentMap, reflectVec, (1 - roughness) * 9).rgb * clamp(rim, 0, 1) ;
return envColor;
}
subroutine (CalculateEnvironment) vec3
NoEnvironment(vec3 specularColor, samplerCube environmentMap, vec3 viewSpaceNormal, vec3 viewSpacePos, vec4 eyePos, mat4x4 invView, float roughness)
{
return vec3(0);
}
subroutine (CalculateColor) vec4
SimpleColor(vec4 albedoColor, vec3 environmentColor, float saturation, vec4 color, float roughness, float alphaBlend)
{
return albedoColor;
}
subroutine (CalculateColor) vec4
SimpleColorMultiply(vec4 albedoColor, vec3 environmentColor, float saturation, vec4 color, float roughness, float alphaBlend)
{
return albedoColor * color;
}
subroutine (CalculateColor) vec4
AlphaColor(vec4 albedoColor, vec3 environmentColor, float saturation, vec4 color, float roughness, float alphaBlend)
{
return albedoColor * alphaBlend;
}
subroutine (CalculateColor) vec4
AlphaColorMultiply(vec4 albedoColor, vec3 environmentColor, float saturation, vec4 color, float roughness, float alphaBlend)
{
return albedoColor * color * alphaBlend;
}
subroutine (CalculateColor) vec4
EnvironmentMapColor(vec4 albedoColor, vec3 environmentColor, float saturation, vec4 color, float roughness, float alphaBlend)
{
vec4 result = albedoColor;
result.rgb = result.rgb * mix (vec3(1), environmentColor, roughness);
return result;
}
uniform mat4x4 JointPalette[128];
uniform sampler2D JointInstanceTexture;
uniform mat4x4 ModelArray[128];
uniform vec4 LightPositionsArray[16];
uniform mat4x4 LightProjTransformArray[16];
uniform vec4 LightColorArray[16];
uniform vec4 LightProjMapOffsetArray[16];
uniform vec4 LightShadowMapOffsetArray[16];
uniform vec4 LightShadowSizeArray[16];
uniform float LightInvRangeArray[16];
uniform int LightTypeArray[16];
uniform bool LightCastsShadowsArray[16];
uniform sampler2D LightShadowTexture;
uniform vec4 GlobalBackLightColor;
uniform vec4 GlobalLightColor;
uniform vec4 GlobalAmbientLightColor;
uniform vec4 GlobalLightDir;
uniform float GlobalBackLightOffset;
uniform mat4x4 Model;
uniform mat4x4 InvModel;
uniform mat4x4 EmitterTransform;
uniform vec4 OcclusionConstants;
uniform vec4 TextureRatio;
uniform vec4 MatDiffuse;
uniform float MatEmissiveIntensity;
uniform float MatSpecularIntensity;
uniform float AlphaSensitivity;
uniform float AlphaBlendFactor;
uniform float LightMapIntensity;
uniform float FresnelPower;
uniform float FresnelStrength;
uniform int ObjectId;
uniform float TessellationFactor;
uniform float MaxDistance;
uniform float MinDistance;
uniform float HeightScale;
uniform float SceneScale;
uniform vec2 AnimationDirection;
uniform float AnimationAngle;
uniform float Time;
uniform float Random;
uniform float AnimationLinearSpeed;
uniform float AnimationAngularSpeed;
uniform int NumXTiles;
uniform int NumYTiles;
uniform float WindWaveSize;
uniform float WindSpeed;
uniform vec4 WindDirection;
uniform float WindIntensity;
uniform float WindForce;
uniform mat4x4 ViewMatrixArray[6];
uniform sampler2D DiffuseMap;
uniform sampler2D DisplacementMap;
uniform sampler2D SpecularMap;
uniform sampler2D EmissiveMap;
uniform sampler2D NormalMap;
uniform sampler2D RoughnessMap;
uniform samplerCube EnvironmentMap;
subroutine uniform CalculateBump calculateBump;
subroutine uniform CalculateDepth calculateDepth;
subroutine uniform CalculateEmissive calculateEmissive;
subroutine uniform CalculateSpecular calculateSpecular;
subroutine uniform CalculateEnvironment calculateEnvironment;
subroutine uniform CalculateColor calculateColor;
layout(shared) uniform PerFrame
{
mat4x4 View;
mat4x4 InvView;
mat4x4 ViewProjection;
mat4x4 Projection;
mat4x4 InvProjection;
mat4x4 InvViewProjection;
vec4 EyePos;
vec4 FocalLength;
};
const float depthScale = float(100.000000);
const float MiddleGrey = float(1.100000);
const float MaxLuminance = float(16.000000);
const float MinLuminance = float(0.300000);
const float RimIntensity = float(0.900000);
const float RimPower = float(2.000000);
const float ShadowConstant = float(100.000000);
layout(location = 0) in vec3 ViewSpacePos;
layout(location = 1) in vec3 Tangent;
layout(location = 2) in vec3 Normal;
layout(location = 3) in vec3 Binormal;
layout(location = 4) in vec2 UV;
layout(location = 5) in vec4 Color;
layout(location = 0) out vec4 Albedo;
layout(location = 1) out vec4 Normals;
layout(location = 2) out float Depth;
layout(location = 3) out vec4 Specular;
layout(location = 4) out vec4 Emissive;
layout(location = 5) out vec4 Unshaded;
void
main()
{
#line 836 44
vec4 diffColor = texture(DiffuseMap, UV);
vec4 emsvColor = texture(EmissiveMap, UV);
vec4 specColor = texture(SpecularMap, UV);
float roughness = texture(RoughnessMap, UV).r;
vec3 bumpNormal = calculateBump(Tangent, Binormal, Normal, UV, NormalMap);
Normals = PackViewSpaceNormal(bumpNormal);
vec3 environment = calculateEnvironment(specColor.rgb, EnvironmentMap, bumpNormal, ViewSpacePos, EyePos, InvView, roughness);
Emissive = EncodeHDR(calculateEmissive(emsvColor, MatEmissiveIntensity));
Specular = calculateSpecular(specColor.rgb, MatSpecularIntensity, environment, roughness);
Depth = calculateDepth(ViewSpacePos);
Albedo = calculateColor(diffColor, environment, 1, Color, roughness, AlphaBlendFactor);
Unshaded = vec4(0,0,0,1);
}
It's being compiled as a fragment shader. The compilation error I get is:
'Fragment shader failed to compile with the following errors:'
And that's it, it doesn't list what the actual problem is. This seems only to occur when I attempt to call subroutines, since the same subroutine type definition and implementations are included in other files and they compile just fine.
I'm currently using a HD 7970 on Windows 7.
I at least figured out why it failed to compile, and it was because the 'saturation' variable wasn't being used in any subroutine. So I guess it goes optimized away, and I can only assume the signature changed to not contain the unused variable. The weird thing is why I never received this in the form of a compilation error.
It also seems to be some kind of graphical bug caused by the subroutines. This is the image generated when the above shader managed to compile:
Notice the edges not being shaded? It shouldn't be like that. The cube should be as it is when no subroutines are used at all, like this:
This is produced when no subroutines are used, however the implementation is identical apart from the fact that instead of calling functions I simply run the code inline. Also note that this is only using subroutines within the fragment shader.