From 5b236ab09a9dcd2987628d4cb82c96b90e04c35f Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 19 Mar 2017 20:31:04 +0100 Subject: [PATCH] Add test shader --- examples/bin/Shaders/PhongLighting/core.frag | 488 +++++++++++++++++++ examples/bin/Shaders/PhongLighting/core.vert | 148 ++++++ 2 files changed, 636 insertions(+) create mode 100644 examples/bin/Shaders/PhongLighting/core.frag create mode 100644 examples/bin/Shaders/PhongLighting/core.vert diff --git a/examples/bin/Shaders/PhongLighting/core.frag b/examples/bin/Shaders/PhongLighting/core.frag new file mode 100644 index 000000000..f95d0eb04 --- /dev/null +++ b/examples/bin/Shaders/PhongLighting/core.frag @@ -0,0 +1,488 @@ +#if EARLY_FRAGMENT_TESTS && !ALPHA_TEST +layout(early_fragment_tests) in; +#endif + +// HACK UNTIL PROPER FIX +#if GLSL_VERSION < 400 + #undef SHADOW_MAPPING + #define SHADOW_MAPPING 0 +#endif +// HACK + +#define LIGHT_DIRECTIONAL 0 +#define LIGHT_POINT 1 +#define LIGHT_SPOT 2 + +/********************Entrant********************/ +in vec4 vColor; +in vec4 vLightSpacePos[3]; +in mat3 vLightToWorld; +in vec3 vNormal; +in vec2 vTexCoord; +in vec3 vViewDir; +in vec3 vWorldPos; + +/********************Sortant********************/ +out vec4 RenderTarget0; +out vec4 RenderTarget1; +out vec4 RenderTarget2; + +/********************Uniformes********************/ +struct Light +{ + int type; + vec4 color; + vec2 factors; + + vec4 parameters1; + vec4 parameters2; + vec2 parameters3; + bool shadowMapping; +}; + +// Lumières +uniform Light Lights[3]; +uniform samplerCube PointLightShadowMap[3]; +uniform sampler2D DirectionalSpotLightShadowMap[3]; + +// Matériau +uniform sampler2D MaterialAlphaMap; +uniform float MaterialAlphaThreshold; +uniform vec4 MaterialAmbient; +uniform vec4 MaterialDiffuse; +uniform sampler2D MaterialDiffuseMap; +uniform sampler2D MaterialEmissiveMap; +uniform sampler2D MaterialHeightMap; +uniform sampler2D MaterialNormalMap; +uniform float MaterialShininess; +uniform vec4 MaterialSpecular; +uniform sampler2D MaterialSpecularMap; + +// Autres +uniform float ParallaxBias = -0.03; +uniform float ParallaxScale = 0.02; +uniform vec2 InvTargetSize; +uniform vec3 EyePosition; +uniform samplerCube ReflectionMap; +uniform vec4 SceneAmbient; + +uniform mat4 WorldMatrix; + +uniform sampler2D TextureOverlay; + +/********************Fonctions********************/ + +#define kPI 3.1415926536 + +vec4 EncodeNormal(in vec3 normal) +{ + //return vec4(normal*0.5 + 0.5, 0.0); + return vec4(vec2(atan(normal.y, normal.x)/kPI, normal.z), 0.0, 0.0); +} + +float VectorToDepthValue(vec3 vec, float zNear, float zFar) +{ + vec3 absVec = abs(vec); + float localZ = max(absVec.x, max(absVec.y, absVec.z)); + + float normZ = ((zFar + zNear) * localZ - (2.0*zFar*zNear)) / ((zFar - zNear)*localZ); + return (normZ + 1.0) * 0.5; +} + +#if SHADOW_MAPPING +float CalculateDirectionalShadowFactor(int lightIndex) +{ + vec4 lightSpacePos = vLightSpacePos[lightIndex]; + return (texture(DirectionalSpotLightShadowMap[lightIndex], lightSpacePos.xy).x >= (lightSpacePos.z - 0.0005)) ? 1.0 : 0.0; +} + +float CalculatePointShadowFactor(int lightIndex, vec3 lightToWorld, float zNear, float zFar) +{ + return (texture(PointLightShadowMap[lightIndex], vec3(lightToWorld.x, -lightToWorld.y, -lightToWorld.z)).x >= VectorToDepthValue(lightToWorld, zNear, zFar)) ? 1.0 : 0.0; +} + +float CalculateSpotShadowFactor(int lightIndex, float lambert) +{ + vec4 lightSpacePos = vLightSpacePos[lightIndex]; + +#if 0 + float visibility = 1.0; + float bias = 0.005 * tan(acos(NoL)); + bias = clamp(bias, MinAllowedBias, MaxAllowedBias); + + float x,y; + for (y = -1.0; y <= 1.0; y+= 1.0) + for (x = -1.0; x <= 1.0; x+= 1.0) + visibility += (textureProj(DirectionalSpotLightShadowMap[lightIndex], lightSpacePos.xyw + vec3(x/1024.0 * lightSpacePos.w, y/1024.0 * lightSpacePos.w, 0.0)).x >= (lightSpacePos.z - 0.0005)/lightSpacePos.w) ? 1.0 : 0.0; + + visibility /= 9.0; + + return visibility; +#else + float bias = 0.005 * tan(acos(lambert)); + + return (textureProj(DirectionalSpotLightShadowMap[lightIndex], lightSpacePos.xyw).x >= (lightSpacePos.z - bias)/lightSpacePos.w) ? 1.0 : 0.0; +#endif +} +#endif + +void main() +{ + vec4 diffuseColor = MaterialDiffuse * vColor; + +#if AUTO_TEXCOORDS + vec2 texCoord = gl_FragCoord.xy * InvTargetSize; +#else + vec2 texCoord = vTexCoord; +#endif + +#if PARALLAX_MAPPING + float height = texture(MaterialHeightMap, texCoord).r; + float v = height*ParallaxScale + ParallaxBias; + + vec3 viewDir = normalize(vViewDir); + texCoord += v * viewDir.xy; +#endif + +#if DIFFUSE_MAPPING + diffuseColor *= texture(MaterialDiffuseMap, texCoord); +#endif + +#if FLAG_TEXTUREOVERLAY + diffuseColor *= texture(TextureOverlay, texCoord); +#endif + +#if FLAG_DEFERRED + #if ALPHA_TEST + // Inutile de faire de l'alpha-mapping sans alpha-test en Deferred (l'alpha n'est pas sauvegardé dans le G-Buffer) + #if ALPHA_MAPPING + diffuseColor.a *= texture(MaterialAlphaMap, texCoord).r; + #endif + + if (diffuseColor.a < MaterialAlphaThreshold) + discard; + #endif // ALPHA_TEST + + #if NORMAL_MAPPING + vec3 normal = normalize(vLightToWorld * (2.0 * vec3(texture(MaterialNormalMap, texCoord)) - 1.0)); + #else + vec3 normal = normalize(vNormal); + #endif // NORMAL_MAPPING + + vec3 specularColor = MaterialSpecular.rgb; + #if SPECULAR_MAPPING + specularColor *= texture(MaterialSpecularMap, texCoord).rgb; + #endif + + /* + Texture0: Diffuse Color + Specular + Texture1: Normal + Specular + Texture2: Encoded depth + Shininess + */ + RenderTarget0 = vec4(diffuseColor.rgb, dot(specularColor, vec3(0.3, 0.59, 0.11))); + RenderTarget1 = vec4(EncodeNormal(normal)); + RenderTarget2 = vec4(0.0, 0.0, 0.0, (MaterialShininess == 0.0) ? 0.0 : max(log2(MaterialShininess), 0.1)/10.5); // http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf +#else // FLAG_DEFERRED + #if ALPHA_MAPPING + diffuseColor.a *= texture(MaterialAlphaMap, texCoord).r; + #endif + + #if ALPHA_TEST + if (diffuseColor.a < MaterialAlphaThreshold) + discard; + #endif + + vec3 lightAmbient = vec3(0.0); + vec3 lightDiffuse = vec3(0.0); + vec3 lightSpecular = vec3(0.0); + + #if NORMAL_MAPPING + vec3 normal = normalize(vLightToWorld * (2.0 * vec3(texture(MaterialNormalMap, texCoord)) - 1.0)); + #else + vec3 normal = normalize(vNormal); + #endif + + if (MaterialShininess > 0.0) + { + vec3 eyeVec = normalize(EyePosition - vWorldPos); + + for (int i = 0; i < 3; ++i) + { + vec4 lightColor = Lights[i].color; + float lightAmbientFactor = Lights[i].factors.x; + float lightDiffuseFactor = Lights[i].factors.y; + + switch (Lights[i].type) + { + case LIGHT_DIRECTIONAL: + { + vec3 lightDir = -Lights[i].parameters1.xyz; + + // Ambient + lightAmbient += lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); + + float att = 1.0; + + float lambert = max(dot(normal, lightDir), 0.0); + + #if SHADOW_MAPPING + if (Lights[i].shadowMapping) + { + float shadowFactor = CalculateDirectionalShadowFactor(i); + if (shadowFactor == 0.0) + break; + + att *= shadowFactor; + } + #endif + + // Diffuse + lightDiffuse += att * lambert * lightColor.rgb * lightDiffuseFactor; + + // Specular + vec3 reflection = reflect(-lightDir, normal); + float specularFactor = max(dot(reflection, eyeVec), 0.0); + specularFactor = pow(specularFactor, MaterialShininess); + + lightSpecular += att * specularFactor * lightColor.rgb; + break; + } + + case LIGHT_POINT: + { + vec3 lightPos = Lights[i].parameters1.xyz; + float lightAttenuation = Lights[i].parameters1.w; + float lightInvRadius = Lights[i].parameters2.w; + + vec3 worldToLight = lightPos - vWorldPos; + float lightDirLength = length(worldToLight); + vec3 lightDir = worldToLight / lightDirLength; // Normalisation + + float att = max(lightAttenuation - lightInvRadius * lightDirLength, 0.0); + + // Ambient + lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); + + #if SHADOW_MAPPING + if (Lights[i].shadowMapping) + { + float shadowFactor = CalculatePointShadowFactor(i, vWorldPos - lightPos, 0.1, 50.0); + if (shadowFactor == 0.0) + break; + + att *= shadowFactor; + } + #endif + + // Diffuse + float lambert = max(dot(normal, lightDir), 0.0); + + lightDiffuse += att * lambert * lightColor.rgb * lightDiffuseFactor; + + // Specular + vec3 reflection = reflect(-lightDir, normal); + float specularFactor = max(dot(reflection, eyeVec), 0.0); + specularFactor = pow(specularFactor, MaterialShininess); + + lightSpecular += att * specularFactor * lightColor.rgb; + break; + } + + case LIGHT_SPOT: + { + vec3 lightPos = Lights[i].parameters1.xyz; + vec3 lightDir = Lights[i].parameters2.xyz; + float lightAttenuation = Lights[i].parameters1.w; + float lightInvRadius = Lights[i].parameters2.w; + float lightInnerAngle = Lights[i].parameters3.x; + float lightOuterAngle = Lights[i].parameters3.y; + + vec3 worldToLight = lightPos - vWorldPos; + float lightDistance = length(worldToLight); + worldToLight /= lightDistance; // Normalisation + + float att = max(lightAttenuation - lightInvRadius * lightDistance, 0.0); + + // Ambient + lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); + + float lambert = max(dot(normal, worldToLight), 0.0); + + #if SHADOW_MAPPING + if (Lights[i].shadowMapping) + { + float shadowFactor = CalculateSpotShadowFactor(i, lambert); + if (shadowFactor == 0.0) + break; + + att *= shadowFactor; + } + #endif + + // Modification de l'atténuation pour gérer le spot + float curAngle = dot(lightDir, -worldToLight); + float innerMinusOuterAngle = lightInnerAngle - lightOuterAngle; + att *= max((curAngle - lightOuterAngle) / innerMinusOuterAngle, 0.0); + + // Diffuse + lightDiffuse += att * lambert * lightColor.rgb * lightDiffuseFactor; + + // Specular + vec3 reflection = reflect(-worldToLight, normal); + float specularFactor = max(dot(reflection, eyeVec), 0.0); + specularFactor = pow(specularFactor, MaterialShininess); + + lightSpecular += att * specularFactor * lightColor.rgb; + break; + } + + default: + break; + } + } + } + else + { + for (int i = 0; i < 3; ++i) + { + vec4 lightColor = Lights[i].color; + float lightAmbientFactor = Lights[i].factors.x; + float lightDiffuseFactor = Lights[i].factors.y; + + switch (Lights[i].type) + { + case LIGHT_DIRECTIONAL: + { + vec3 lightDir = -Lights[i].parameters1.xyz; + + // Ambient + lightAmbient += lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); + + float att = 1.0; + + #if SHADOW_MAPPING + if (Lights[i].shadowMapping) + { + float shadowFactor = CalculateDirectionalShadowFactor(i); + if (shadowFactor == 0.0) + break; + + att *= shadowFactor; + } + #endif + + // Diffuse + float lambert = max(dot(normal, lightDir), 0.0); + + lightDiffuse += att * lambert * lightColor.rgb * lightDiffuseFactor; + break; + } + + case LIGHT_POINT: + { + vec3 lightPos = Lights[i].parameters1.xyz; + float lightAttenuation = Lights[i].parameters1.w; + float lightInvRadius = Lights[i].parameters2.w; + + vec3 worldToLight = lightPos - vWorldPos; + float lightDirLength = length(worldToLight); + vec3 lightDir = worldToLight / lightDirLength; // Normalisation + + float att = max(lightAttenuation - lightInvRadius * lightDirLength, 0.0); + + // Ambient + lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); + + #if SHADOW_MAPPING + if (Lights[i].shadowMapping) + { + float shadowFactor = CalculatePointShadowFactor(i, vWorldPos - lightPos, 0.1, 50.0); + if (shadowFactor == 0.0) + break; + + att *= shadowFactor; + } + #endif + + // Diffuse + float lambert = max(dot(normal, lightDir), 0.0); + + lightDiffuse += att * lambert * lightColor.rgb * lightDiffuseFactor; + break; + } + + case LIGHT_SPOT: + { + vec3 lightPos = Lights[i].parameters1.xyz; + vec3 lightDir = Lights[i].parameters2.xyz; + float lightAttenuation = Lights[i].parameters1.w; + float lightInvRadius = Lights[i].parameters2.w; + float lightInnerAngle = Lights[i].parameters3.x; + float lightOuterAngle = Lights[i].parameters3.y; + + vec3 worldToLight = lightPos - vWorldPos; + float lightDistance = length(worldToLight); + worldToLight /= lightDistance; // Normalisation + + float att = max(lightAttenuation - lightInvRadius * lightDistance, 0.0); + + // Ambient + lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); + + float lambert = max(dot(normal, worldToLight), 0.0); + + #if SHADOW_MAPPING + if (Lights[i].shadowMapping) + { + float shadowFactor = CalculateSpotShadowFactor(i, lambert); + if (shadowFactor == 0.0) + break; + + att *= shadowFactor; + } + #endif + + // Modification de l'atténuation pour gérer le spot + float curAngle = dot(lightDir, -worldToLight); + float innerMinusOuterAngle = lightInnerAngle - lightOuterAngle; + att *= max((curAngle - lightOuterAngle) / innerMinusOuterAngle, 0.0); + + // Diffuse + lightDiffuse += att * lambert * lightColor.rgb * lightDiffuseFactor; + } + + default: + break; + } + } + } + + lightSpecular *= MaterialSpecular.rgb; + #if SPECULAR_MAPPING + lightSpecular *= texture(MaterialSpecularMap, texCoord).rgb; // Utiliser l'alpha de MaterialSpecular n'aurait aucun sens + #endif + + vec3 lightColor = (lightAmbient + lightDiffuse + lightSpecular); + + #if REFLECTION_MAPPING + vec3 eyeVec = normalize(vWorldPos - EyePosition); + + vec3 reflected = normalize(reflect(eyeVec, normal)); + //reflected = vec3(inverse(WorldMatrix) * vec4(reflected, 0.0)); + + lightColor *= texture(ReflectionMap, reflected).rgb; + #endif + + vec4 fragmentColor = vec4(lightColor, 1.0) * diffuseColor; + + #if EMISSIVE_MAPPING + float lightIntensity = dot(lightColor, vec3(0.3, 0.59, 0.11)); + + vec3 emissionColor = MaterialDiffuse.rgb * texture(MaterialEmissiveMap, texCoord).rgb; + RenderTarget0 = vec4(mix(fragmentColor.rgb, emissionColor, clamp(1.0 - 3.0*lightIntensity, 0.0, 1.0)), fragmentColor.a); + #else + RenderTarget0 = fragmentColor; + #endif // EMISSIVE_MAPPING +#endif // FLAG_DEFERRED +} + diff --git a/examples/bin/Shaders/PhongLighting/core.vert b/examples/bin/Shaders/PhongLighting/core.vert new file mode 100644 index 000000000..8943c5935 --- /dev/null +++ b/examples/bin/Shaders/PhongLighting/core.vert @@ -0,0 +1,148 @@ +/********************Entrant********************/ +#if FLAG_BILLBOARD +in vec3 InstanceData0; // center +in vec4 InstanceData1; // size | sin cos +in vec4 InstanceData2; // color +#else +in mat4 InstanceData0; +#endif + +in vec4 VertexColor; +in vec3 VertexPosition; +in vec3 VertexNormal; +in vec3 VertexTangent; +in vec2 VertexTexCoord; +in vec4 VertexUserdata0; + +/********************Sortant********************/ +out vec4 vColor; +out vec4 vLightSpacePos[3]; +out mat3 vLightToWorld; +out vec3 vNormal; +out vec2 vTexCoord; +out vec3 vViewDir; +out vec3 vWorldPos; + +/********************Uniformes********************/ +uniform vec3 EyePosition; +uniform mat4 InvViewMatrix; +uniform mat4 LightViewProjMatrix[3]; +uniform float VertexDepth; +uniform mat4 ViewMatrix; +uniform mat4 ViewProjMatrix; +uniform mat4 WorldMatrix; +uniform mat4 WorldViewProjMatrix; + +/********************Fonctions********************/ +void main() +{ +#if FLAG_VERTEXCOLOR + vec4 color = VertexColor; +#else + vec4 color = vec4(1.0); +#endif + + vec2 texCoords; + +#if FLAG_BILLBOARD + #if FLAG_INSTANCING + vec3 billboardCenter = InstanceData0; + vec2 billboardSize = InstanceData1.xy; + vec2 billboardSinCos = InstanceData1.zw; + vec4 billboardColor = InstanceData2; + + vec2 rotatedPosition; + rotatedPosition.x = VertexPosition.x*billboardSinCos.y - VertexPosition.y*billboardSinCos.x; + rotatedPosition.y = VertexPosition.y*billboardSinCos.y + VertexPosition.x*billboardSinCos.x; + rotatedPosition *= billboardSize; + + vec3 cameraRight = vec3(ViewMatrix[0][0], ViewMatrix[1][0], ViewMatrix[2][0]); + vec3 cameraUp = vec3(ViewMatrix[0][1], ViewMatrix[1][1], ViewMatrix[2][1]); + vec3 vertexPos = billboardCenter + cameraRight*rotatedPosition.x + cameraUp*rotatedPosition.y; + + gl_Position = ViewProjMatrix * vec4(vertexPos, 1.0); + color = billboardColor; + texCoords = VertexPosition.xy + 0.5; + #else + vec2 billboardCorner = VertexTexCoord - 0.5; + vec2 billboardSize = VertexUserdata0.xy; + vec2 billboardSinCos = VertexUserdata0.zw; + + vec2 rotatedPosition; + rotatedPosition.x = billboardCorner.x*billboardSinCos.y - billboardCorner.y*billboardSinCos.x; + rotatedPosition.y = billboardCorner.y*billboardSinCos.y + billboardCorner.x*billboardSinCos.x; + rotatedPosition *= billboardSize; + + vec3 cameraRight = vec3(ViewMatrix[0][0], ViewMatrix[1][0], ViewMatrix[2][0]); + vec3 cameraUp = vec3(ViewMatrix[0][1], ViewMatrix[1][1], ViewMatrix[2][1]); + vec3 vertexPos = VertexPosition + cameraRight*rotatedPosition.x + cameraUp*rotatedPosition.y; + + gl_Position = ViewProjMatrix * vec4(vertexPos, 1.0); + texCoords = VertexTexCoord; + #endif + texCoords.y = 1.0 - texCoords.y; +#else + #if FLAG_INSTANCING + #if TRANSFORM + gl_Position = ViewProjMatrix * InstanceData0 * vec4(VertexPosition, 1.0); + #else + #if UNIFORM_VERTEX_DEPTH + gl_Position = InstanceData0 * vec4(VertexPosition.xy, VertexDepth, 1.0); + #else + gl_Position = InstanceData0 * vec4(VertexPosition, 1.0); + #endif + #endif + #else + #if TRANSFORM + gl_Position = WorldViewProjMatrix * vec4(VertexPosition, 1.0); + #else + #if UNIFORM_VERTEX_DEPTH + gl_Position = vec4(VertexPosition.xy, VertexDepth, 1.0); + #else + gl_Position = vec4(VertexPosition, 1.0); + #endif + #endif + #endif + + texCoords = VertexTexCoord; +#endif + + vColor = color; + +#if FLAG_INSTANCING + mat3 rotationMatrix = mat3(InstanceData0); +#else + mat3 rotationMatrix = mat3(WorldMatrix); +#endif + +#if COMPUTE_TBNMATRIX + vec3 binormal = cross(VertexNormal, VertexTangent); + vLightToWorld[0] = normalize(rotationMatrix * VertexTangent); + vLightToWorld[1] = normalize(rotationMatrix * binormal); + vLightToWorld[2] = normalize(rotationMatrix * VertexNormal); +#else + vNormal = normalize(rotationMatrix * VertexNormal); +#endif + +#if SHADOW_MAPPING + for (int i = 0; i < 3; ++i) + vLightSpacePos[i] = LightViewProjMatrix[i] * WorldMatrix * vec4(VertexPosition, 1.0); +#endif + +#if TEXTURE_MAPPING + vTexCoord = VertexTexCoord; +#endif + +#if PARALLAX_MAPPING + vViewDir = EyePosition - VertexPosition; + vViewDir *= vLightToWorld; +#endif + +#if !FLAG_DEFERRED + #if FLAG_INSTANCING + vWorldPos = vec3(InstanceData0 * vec4(VertexPosition, 1.0)); + #else + vWorldPos = vec3(WorldMatrix * vec4(VertexPosition, 1.0)); + #endif +#endif +}