diff --git a/assets/Shaders/lib/lights.fs b/assets/Shaders/lib/lights.fs index b0ef0ae1..aafc2817 100644 --- a/assets/Shaders/lib/lights.fs +++ b/assets/Shaders/lib/lights.fs @@ -1,34 +1,37 @@ //uncomment if working on this library file: //#version 450 core +#extension GL_ARB_shading_language_include : require +#include "./material.fs" /** -Maximum number of point lights -*/ + * Maximum number of point lights + */ #define MAX_POINT_LIGHTS 512 /** -Maximum number of lights per cluster -*/ + * Maximum number of lights per cluster + */ #define MAX_LIGHTS_PER_CLUSTER 100 /** -Bind points for different SSBOs -*/ + * Bind points for different SSBOs + */ #define CLUSTER_SSBO_BIND_POINT 1 #define POINT_LIGHT_SSBO_BIND_POINT 2 #define DIRECT_LIGHT_SSBO_BIND_POINT 3 /** -The direct global light -*/ + * The direct global light + */ struct DirectLight { + vec3 ambientColor; vec3 direction; vec3 color; }; /** -A point light -*/ + * A point light + */ struct PointLight { vec4 position; vec4 color; @@ -39,8 +42,8 @@ struct PointLight { }; /** -A light cluster -*/ + * A light cluster + */ struct Cluster { vec4 minPoint; vec4 maxPoint; @@ -49,8 +52,8 @@ struct Cluster { }; /** -Cutoff for fragment alpha -*/ + * Cutoff for fragment alpha + */ #define FRAGMENT_ALPHA_CUTOFF 0.001 layout(std430, binding = CLUSTER_SSBO_BIND_POINT) restrict buffer clusterGridSSBO { @@ -70,34 +73,57 @@ layout(std430, binding = DIRECT_LIGHT_SSBO_BIND_POINT) restrict buffer dirLightS /** -Used for light cluster calculation -*/ + * Used for light cluster calculation + */ uniform float zNear; uniform float zFar; uniform uvec3 gridSize; uniform uvec2 screenDimensions; /** -The light depth map texture -*/ + * The light depth map texture + */ uniform sampler2D shadowMap; - +/** + * Finds the light cluster for this fragment + */ uint findCluster(vec3 viewspaceFragPos, float zNear, float zFar); + +/** + * Calculates the point light's value applied to this fragment + */ vec3 CalcPointLight(PointLight pointLight, vec3 normal, vec3 fragPos, vec3 viewDir); + +/** + * calculates the total light intensity on this fragment + */ float calcLightIntensityTotal(vec3 normal); + +/** + * Calculates the shadow applied to this fragment + */ float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal); +/** + * Gets the total light to apply to the fragment + */ +vec3 getTotalLight(Material mat, vec3 norm, vec3 viewDir); - +/** + * Calculates the ambient light applied to this fragment + */ float calcLightIntensityAmbient(){ //calculate average of ambient light - float avg = (directLight.color.x + directLight.color.y + directLight.color.z)/3.0; + float avg = (directLight.ambientColor.x + directLight.ambientColor.y + directLight.ambientColor.z)/3.0; return avg; } // +/** + * Calculates the direct light applied to this fragment + */ float calcLightIntensityDir(vec3 normal){ vec3 lightDir = normalize(-directLight.direction); // diffuse shading @@ -106,7 +132,28 @@ float calcLightIntensityDir(vec3 normal){ return diff; } -// +/** + * Calculates the direct light applied to this fragment + */ +vec3 calcLightIntensitySpec( + DirectLight directLight, + vec3 viewPos, + vec3 fragPos, + vec3 norm, + float shininess, + float specularVal +){ + vec3 viewDir = normalize(viewPos - fragPos); + vec3 reflectDir = reflect(-directLight.direction, norm); + float spec = pow(max(dot(viewDir, reflectDir), 0.0), shininess); + vec3 specular = directLight.color * (spec * specularVal); + + return specular; +} + +/** + * Calculates the total light intensity applied to this fragment + */ float calcLightIntensityTotal(vec3 normal){ //ambient intensity float ambientLightIntensity = calcLightIntensityAmbient(); @@ -129,6 +176,9 @@ vec3 getTotalLightColor(vec3 normal){ return totalLightColor; } +/** + * Calculates the point light applied to this fragment + */ vec3 CalcPointLight(PointLight pointLight, vec3 normal, vec3 fragPos, vec3 viewDir){ vec3 lightDir = normalize(pointLight.position.xyz - fragPos); // diffuse shading @@ -161,8 +211,8 @@ vec3 CalcPointLight(PointLight pointLight, vec3 normal, vec3 fragPos, vec3 viewD } /** -Finds the light cluster this fragment belongs to -*/ + * Finds the light cluster this fragment belongs to + */ uint findCluster(vec3 viewspaceFragPos, float zNear, float zFar){ uint zTile = uint((log(abs(viewspaceFragPos.z) / zNear) * gridSize.z) / log(zFar / zNear)); vec2 tileSize = screenDimensions / gridSize.xy; @@ -170,7 +220,9 @@ uint findCluster(vec3 viewspaceFragPos, float zNear, float zFar){ return tile.x + (tile.y * gridSize.x) + (tile.z * gridSize.x * gridSize.y); } - +/** + * Calculates the shadow applied to this fragment + */ float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal){ // perform perspective divide @@ -206,4 +258,45 @@ float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal){ // shadow = currentDepth; return clamp(1.0 - shadow, 0.0, 0.7); +} + +/** + * Gets the total light to apply to the fragment + */ +vec3 getTotalLight( + Material mat, + vec3 viewPos, + vec4 fragPosLightSpace, + vec3 fragPosView, + vec3 fragPos, + vec3 norm, + vec3 viewDir +){ + float specular = 1.0f; + + //grab light intensity + float ambientLightIntensity = calcLightIntensityAmbient(); + float directLightIntensity = calcLightIntensityDir(norm); + vec3 specularLightIntensity = calcLightIntensitySpec(directLight,viewPos,fragPos,norm,mat.shininess,specular); + + vec3 lightIntensity = vec3(calcLightIntensityTotal(norm)); + + //shadow + float shadow = ShadowCalculation(fragPosLightSpace, normalize(-directLight.direction), -norm); + + // + //point light calculations + vec3 lightAmount = vec3(0); + uint clusterIndex = findCluster(fragPosView, zNear, zFar); + uint pointLightCount = clusters[clusterIndex].count; + for(int i = 0; i < pointLightCount; i++){ + uint pointLightIndex = clusters[clusterIndex].lightIndices[i]; + PointLight pointLight = pointLight[pointLightIndex]; + lightIntensity = lightIntensity + CalcPointLight(pointLight, norm, fragPos, viewDir); + } + //error checking on light clusters + if(pointLightCount > MAX_LIGHTS_PER_CLUSTER){ + return vec3(1.0,0.0,0.0); + } + return lightIntensity; } \ No newline at end of file diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 0ef2eeb3..d2b1eadd 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1901,6 +1901,7 @@ Remove old uniforms from shaders and code to push uniforms Break out shader material into dedicated library file Materials read some properties from assimp data OpenGLState VAO caching +Ambient light sent in dedicated variable to shader diff --git a/src/main/java/electrosphere/renderer/light/LightManager.java b/src/main/java/electrosphere/renderer/light/LightManager.java index fab710e8..2b8a8c03 100644 --- a/src/main/java/electrosphere/renderer/light/LightManager.java +++ b/src/main/java/electrosphere/renderer/light/LightManager.java @@ -83,7 +83,7 @@ public class LightManager { /** * Size of the direct light buffer */ - static final int DIRECT_LIGHT_BUFFER_SIZE = 12 + 12; + static final int DIRECT_LIGHT_BUFFER_SIZE = 12 + 12 + 12; /** * Bind point for the cluster ssbo @@ -140,6 +140,7 @@ public class LightManager { * The direct light ssbo * struct DirectLight { + vec3 ambientColor; //12 bytes vec3 direction; //12 bytes vec3 color; //12 bytes }; @@ -151,6 +152,11 @@ public class LightManager { */ private DirectionalLight directionalLight; + /** + * Color of the ambient light + */ + private Vector3f ambientLightColor = new Vector3f(0.8f); + /** * Constructor */ @@ -270,6 +276,12 @@ public class LightManager { //push direct light ByteBuffer directLightBuffer = dirLightSSBO.getBuffer(); { + // + //ambient light color + directLightBuffer.putFloat(ambientLightColor.x); + directLightBuffer.putFloat(ambientLightColor.y); + directLightBuffer.putFloat(ambientLightColor.z); + // //direction directLightBuffer.putFloat(directionalLight.getDirection().x);