clustered lighting implementation
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
This commit is contained in:
parent
5eeb281e0b
commit
dc52e375e3
@ -1,37 +1,66 @@
|
|||||||
#version 330 core
|
#version 450 core
|
||||||
|
|
||||||
//FragmentShader.fs
|
//FragmentShader.fs
|
||||||
|
|
||||||
#define NR_POINT_LIGHTS 10
|
/**
|
||||||
|
Maximum number of point lights
|
||||||
|
*/
|
||||||
|
#define MAX_POINT_LIGHTS 512
|
||||||
|
|
||||||
|
/**
|
||||||
|
Maximum number of lights per cluster
|
||||||
|
*/
|
||||||
|
#define MAX_LIGHTS_PER_CLUSTER 100
|
||||||
|
|
||||||
|
/**
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
struct DirectLight {
|
||||||
|
vec3 direction;
|
||||||
|
vec3 color;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
A point light
|
||||||
|
*/
|
||||||
|
struct PointLight {
|
||||||
|
vec4 position;
|
||||||
|
vec4 color;
|
||||||
|
float constant;
|
||||||
|
float linear;
|
||||||
|
float quadratic;
|
||||||
|
float radius;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
A light cluster
|
||||||
|
*/
|
||||||
|
struct Cluster {
|
||||||
|
vec4 minPoint;
|
||||||
|
vec4 maxPoint;
|
||||||
|
uint count;
|
||||||
|
uint lightIndices[MAX_LIGHTS_PER_CLUSTER];
|
||||||
|
};
|
||||||
|
|
||||||
out vec4 FragColor;
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
layout(std430, binding = CLUSTER_SSBO_BIND_POINT) restrict buffer clusterGridSSBO {
|
||||||
|
Cluster clusters[];
|
||||||
|
};
|
||||||
|
|
||||||
layout (std140) uniform Lights {
|
layout(std430, binding = POINT_LIGHT_SSBO_BIND_POINT) restrict buffer pointLightSSBO {
|
||||||
// this is how many because we have to align
|
PointLight pointLight[];
|
||||||
// bytes it SHOULD in multiples of 16, this
|
};
|
||||||
// take it where it ACTUALLY is
|
|
||||||
//
|
|
||||||
//refer: https://learnopengl.com/Advanced-OpenGL/Advanced-GLSL
|
|
||||||
//
|
|
||||||
// base alignment aligned offset
|
|
||||||
//direct light
|
|
||||||
vec3 dLDirection; // 16 0
|
|
||||||
vec3 dLAmbient; // 16 16
|
|
||||||
vec3 dLDiffuse; // 16 32
|
|
||||||
vec3 dLSpecular; // 16 48
|
|
||||||
|
|
||||||
//point light
|
|
||||||
vec3 pLposition[NR_POINT_LIGHTS]; // 16*10 64
|
|
||||||
float pLconstant[NR_POINT_LIGHTS]; // 16*10 224
|
|
||||||
float pLlinear[NR_POINT_LIGHTS]; // 16*10 384
|
|
||||||
float pLquadratic[NR_POINT_LIGHTS]; // 16*10 544
|
|
||||||
vec3 pLambient[NR_POINT_LIGHTS]; // 16*10 704
|
|
||||||
vec3 pLdiffuse[NR_POINT_LIGHTS]; // 16*10 864
|
|
||||||
vec3 pLspecular[NR_POINT_LIGHTS]; // 16*10 1024
|
|
||||||
|
|
||||||
//for a total size of 1184
|
|
||||||
|
|
||||||
|
layout(std430, binding = DIRECT_LIGHT_SSBO_BIND_POINT) restrict buffer dirLightSSBO {
|
||||||
|
DirectLight directLight;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Material {
|
struct Material {
|
||||||
@ -41,6 +70,7 @@ struct Material {
|
|||||||
};
|
};
|
||||||
|
|
||||||
in vec3 FragPos;
|
in vec3 FragPos;
|
||||||
|
in vec3 ViewFragPos;
|
||||||
in vec3 Normal;
|
in vec3 Normal;
|
||||||
in vec2 TexCoord;
|
in vec2 TexCoord;
|
||||||
in vec4 FragPosLightSpace;
|
in vec4 FragPosLightSpace;
|
||||||
@ -60,11 +90,18 @@ uniform int hasTransparency;
|
|||||||
//light depth map
|
//light depth map
|
||||||
uniform sampler2D shadowMap;
|
uniform sampler2D shadowMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Used for light cluster calculation
|
||||||
|
*/
|
||||||
|
uniform float zNear;
|
||||||
|
uniform float zFar;
|
||||||
|
uniform uvec3 gridSize;
|
||||||
|
uniform uvec2 screenDimensions;
|
||||||
|
|
||||||
|
|
||||||
// function prototypes
|
// function prototypes
|
||||||
// vec3 CalcDirLight(vec3 normal, vec3 viewDir);
|
uint findCluster(vec3 viewspaceFragPos, float zNear, float zFar);
|
||||||
// vec3 CalcPointLight(int i, vec3 normal, vec3 fragPos, vec3 viewDir);
|
vec3 CalcPointLight(PointLight pointLight, vec3 normal, vec3 fragPos, vec3 viewDir);
|
||||||
// vec3 CalcSpotLight(vec3 normal, vec3 fragPos, vec3 viewDir);
|
|
||||||
float calcLightIntensityTotal(vec3 normal);
|
float calcLightIntensityTotal(vec3 normal);
|
||||||
float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal);
|
float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal);
|
||||||
|
|
||||||
@ -76,54 +113,47 @@ void main(){
|
|||||||
vec3 viewDir = normalize(viewPos - FragPos);
|
vec3 viewDir = normalize(viewPos - FragPos);
|
||||||
|
|
||||||
//grab light intensity
|
//grab light intensity
|
||||||
float lightIntensity = calcLightIntensityTotal(norm);
|
vec3 lightIntensity = vec3(calcLightIntensityTotal(norm));
|
||||||
|
|
||||||
//get color of base texture
|
//get color of base texture
|
||||||
vec3 textureColor = texture(material.diffuse, TexCoord).rgb;
|
vec3 textureColor = texture(material.diffuse, TexCoord).rgb;
|
||||||
|
|
||||||
//shadow
|
//shadow
|
||||||
float shadow = ShadowCalculation(FragPosLightSpace, normalize(-dLDirection), norm);
|
float shadow = ShadowCalculation(FragPosLightSpace, normalize(-directLight.direction), norm);
|
||||||
|
|
||||||
|
//
|
||||||
|
//point light calculations
|
||||||
|
vec3 lightAmount = vec3(0);
|
||||||
|
uint clusterIndex = findCluster(ViewFragPos, 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){
|
||||||
|
FragColor = vec4(1.0f,0,0,1.0f);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//calculate final color
|
//calculate final color
|
||||||
vec3 finalColor = textureColor * lightIntensity * max(shadow,0.4);
|
vec3 finalColor = textureColor * lightIntensity * max(shadow,0.4);
|
||||||
// vec3 lightAmount = CalcDirLight(norm, viewDir);
|
|
||||||
// for(int i = 0; i < NR_POINT_LIGHTS; i++){
|
|
||||||
// lightAmount += CalcPointLight(i, norm, FragPos, viewDir);
|
|
||||||
// }
|
|
||||||
|
|
||||||
//this final calculation is for transparency
|
//this final calculation is for transparency
|
||||||
FragColor = vec4(finalColor, texture(material.diffuse, TexCoord).a);//texture(ourTexture, TexCoord);//vec4(result, 1.0);
|
FragColor = vec4(finalColor, texture(material.diffuse, TexCoord).a);//texture(ourTexture, TexCoord);//vec4(result, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculates the color when using a directional light.
|
|
||||||
// vec3 CalcDirLight(vec3 normal, vec3 viewDir){
|
|
||||||
// vec3 lightDir = normalize(-dLDirection);
|
|
||||||
// // diffuse shading
|
|
||||||
// float diff = max(dot(normal, lightDir), 0.0);
|
|
||||||
// // specular shading
|
|
||||||
// // vec3 reflectDir = reflect(-lightDir, normal);
|
|
||||||
// // float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
|
|
||||||
// // combine results
|
|
||||||
// vec3 texColor = texture(material.diffuse, TexCoord).rgb;
|
|
||||||
// vec3 diffuse = dLDiffuse * diff;
|
|
||||||
// //vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoord).rgb);
|
|
||||||
|
|
||||||
|
|
||||||
// float shadow = ShadowCalculation(FragPosLightSpace, lightDir, normal);
|
|
||||||
|
|
||||||
// return ( dLAmbient + (1.0-shadow) * diffuse ) * texColor;// + specular);
|
|
||||||
// }
|
|
||||||
|
|
||||||
//
|
//
|
||||||
float calcLightIntensityAmbient(){
|
float calcLightIntensityAmbient(){
|
||||||
//calculate average of ambient light
|
//calculate average of ambient light
|
||||||
float avg = (dLAmbient.x + dLAmbient.y + dLAmbient.z)/3.0;
|
float avg = (directLight.color.x + directLight.color.y + directLight.color.z)/3.0;
|
||||||
return avg;
|
return avg;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
float calcLightIntensityDir(vec3 normal){
|
float calcLightIntensityDir(vec3 normal){
|
||||||
vec3 lightDir = normalize(-dLDirection);
|
vec3 lightDir = normalize(-directLight.direction);
|
||||||
// diffuse shading
|
// diffuse shading
|
||||||
float diff = max(dot(normal, lightDir), 0.0);
|
float diff = max(dot(normal, lightDir), 0.0);
|
||||||
|
|
||||||
@ -146,63 +176,53 @@ float calcLightIntensityTotal(vec3 normal){
|
|||||||
//
|
//
|
||||||
vec3 getTotalLightColor(vec3 normal){
|
vec3 getTotalLightColor(vec3 normal){
|
||||||
//get the direct light color adjusted for intensity
|
//get the direct light color adjusted for intensity
|
||||||
vec3 diffuseLightColor = dLDiffuse * calcLightIntensityDir(normal);
|
vec3 diffuseLightColor = directLight.color * calcLightIntensityDir(normal);
|
||||||
|
|
||||||
//sum light colors
|
//sum light colors
|
||||||
vec3 totalLightColor = diffuseLightColor;
|
vec3 totalLightColor = diffuseLightColor;
|
||||||
return totalLightColor;
|
return totalLightColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 CalcPointLight(int i, vec3 normal, vec3 fragPos, vec3 viewDir){
|
vec3 CalcPointLight(PointLight pointLight, vec3 normal, vec3 fragPos, vec3 viewDir){
|
||||||
vec3 lightDir = normalize(pLposition[i] - fragPos);
|
vec3 lightDir = normalize(pointLight.position.xyz - fragPos);
|
||||||
// diffuse shading
|
// diffuse shading
|
||||||
float diff = max(dot(normal, lightDir), 0.0);
|
float diff = max(dot(normal, lightDir), 0.0);
|
||||||
// specular shading
|
// specular shading
|
||||||
// vec3 reflectDir = reflect(-lightDir, normal);
|
// vec3 reflectDir = reflect(-lightDir, normal);
|
||||||
// float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
|
// float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
|
||||||
// attenuation
|
// attenuation
|
||||||
float distance = length(pLposition[i] - fragPos);
|
float distance = length(pointLight.position.xyz - fragPos);
|
||||||
float attenuation = 1.0 / (pLconstant[i] + pLlinear[i] * distance + pLquadratic[i] * (distance * distance));
|
float attenuation = 1.0 / (pointLight.constant + pointLight.linear * distance + pointLight.quadratic * (distance * distance));
|
||||||
|
if(distance > pointLight.radius){
|
||||||
|
attenuation = 0;
|
||||||
|
}
|
||||||
// combine results
|
// combine results
|
||||||
vec3 ambient = pLambient[i];// * vec4(texture(material.diffuse, TexCoord)).xyz;
|
vec3 ambient = pointLight.color.xyz;// * vec4(texture(material.diffuse, TexCoord)).xyz;
|
||||||
vec3 diffuse = pLdiffuse[i] * diff;// * vec4(texture(material.diffuse, TexCoord)).xyz;
|
vec3 diffuse = pointLight.color.xyz * diff;// * vec4(texture(material.diffuse, TexCoord)).xyz;
|
||||||
// vec3 specular = pLspecular[i] * spec;// * vec4(texture(material.specular, TexCoord)).xyz;
|
// vec3 specular = pLspecular[i] * spec;// * vec4(texture(material.specular, TexCoord)).xyz;
|
||||||
ambient *= attenuation;
|
ambient = ambient * attenuation;
|
||||||
diffuse *= attenuation;
|
diffuse = diffuse * attenuation;
|
||||||
// specular *= attenuation;
|
// specular *= attenuation;
|
||||||
vec3 specular = vec3(0,0,0);
|
vec3 specular = vec3(0,0,0);
|
||||||
|
|
||||||
vec3 finalValue = (ambient + diffuse + specular);
|
vec3 finalValue = vec3(0);
|
||||||
finalValue = vec3(max(finalValue.x,0),max(finalValue.y,0),max(finalValue.z,0));
|
if(distance < pointLight.radius){
|
||||||
|
finalValue = (ambient + diffuse + specular);
|
||||||
|
finalValue = vec3(max(finalValue.x,0),max(finalValue.y,0),max(finalValue.z,0));
|
||||||
|
}
|
||||||
|
|
||||||
return finalValue;
|
return finalValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// // calculates the color when using a point light.
|
/**
|
||||||
// vec3 CalcPointLight(int i, vec3 normal, vec3 fragPos, vec3 viewDir){
|
Finds the light cluster this fragment belongs to
|
||||||
// vec3 lightDir = normalize(pLposition[i] - fragPos);
|
*/
|
||||||
// // diffuse shading
|
uint findCluster(vec3 viewspaceFragPos, float zNear, float zFar){
|
||||||
// float diff = max(dot(normal, lightDir), 0.0);
|
uint zTile = uint((log(abs(viewspaceFragPos.z) / zNear) * gridSize.z) / log(zFar / zNear));
|
||||||
// // specular shading
|
vec2 tileSize = screenDimensions / gridSize.xy;
|
||||||
// // vec3 reflectDir = reflect(-lightDir, normal);
|
uvec3 tile = uvec3(gl_FragCoord.xy / tileSize, zTile);
|
||||||
// // float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
|
return tile.x + (tile.y * gridSize.x) + (tile.z * gridSize.x * gridSize.y);
|
||||||
// // attenuation
|
}
|
||||||
// float distance = length(pLposition[i] - fragPos);
|
|
||||||
// float attenuation = 1.0 / (pLconstant[i] + pLlinear[i] * distance + pLquadratic[i] * (distance * distance));
|
|
||||||
// // combine results
|
|
||||||
// vec3 ambient = pLambient[i];// * vec4(texture(material.diffuse, TexCoord)).xyz;
|
|
||||||
// vec3 diffuse = pLdiffuse[i] * diff;// * vec4(texture(material.diffuse, TexCoord)).xyz;
|
|
||||||
// // vec3 specular = pLspecular[i] * spec;// * vec4(texture(material.specular, TexCoord)).xyz;
|
|
||||||
// ambient *= attenuation;
|
|
||||||
// diffuse *= attenuation;
|
|
||||||
// // specular *= attenuation;
|
|
||||||
// vec3 specular = vec3(0,0,0);
|
|
||||||
|
|
||||||
// vec3 finalValue = (ambient + diffuse + specular);
|
|
||||||
// finalValue = vec3(max(finalValue.x,0),max(finalValue.y,0),max(finalValue.z,0));
|
|
||||||
|
|
||||||
// return finalValue;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal){
|
float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal){
|
||||||
|
|||||||
@ -30,6 +30,7 @@ uniform int numBones;
|
|||||||
//output buffers
|
//output buffers
|
||||||
out vec3 Normal;
|
out vec3 Normal;
|
||||||
out vec3 FragPos;
|
out vec3 FragPos;
|
||||||
|
out vec3 ViewFragPos;
|
||||||
out vec2 TexCoord;
|
out vec2 TexCoord;
|
||||||
out vec4 FragPosLightSpace;
|
out vec4 FragPosLightSpace;
|
||||||
|
|
||||||
@ -59,6 +60,7 @@ void main() {
|
|||||||
|
|
||||||
//push frag, normal, and texture positions to fragment shader
|
//push frag, normal, and texture positions to fragment shader
|
||||||
FragPos = vec3(model * FinalVertex);
|
FragPos = vec3(model * FinalVertex);
|
||||||
|
ViewFragPos = vec3(view * model * FinalVertex);
|
||||||
Normal = mat3(transpose(inverse(model))) * FinalNormal.xyz;
|
Normal = mat3(transpose(inverse(model))) * FinalNormal.xyz;
|
||||||
TexCoord = aTex;
|
TexCoord = aTex;
|
||||||
|
|
||||||
|
|||||||
97
assets/Shaders/core/light/cluster.comp
Normal file
97
assets/Shaders/core/light/cluster.comp
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
#version 450 core
|
||||||
|
|
||||||
|
/**
|
||||||
|
Maximum number of lights per cluster
|
||||||
|
*/
|
||||||
|
#define MAX_LIGHTS_PER_CLUSTER 100
|
||||||
|
|
||||||
|
/**
|
||||||
|
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
|
||||||
|
|
||||||
|
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
||||||
|
|
||||||
|
struct Cluster {
|
||||||
|
vec4 minPoint;
|
||||||
|
vec4 maxPoint;
|
||||||
|
uint count;
|
||||||
|
uint lightIndices[MAX_LIGHTS_PER_CLUSTER];
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(std430, binding = CLUSTER_SSBO_BIND_POINT) restrict buffer clusterSSBO {
|
||||||
|
Cluster clusters[];
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform float zNear;
|
||||||
|
uniform float zFar;
|
||||||
|
|
||||||
|
uniform mat4 inverseProjection;
|
||||||
|
uniform uvec3 gridSize;
|
||||||
|
uniform uvec2 screenDimensions;
|
||||||
|
|
||||||
|
vec3 screenToView(vec2 screenCoord);
|
||||||
|
vec3 lineIntersectionWithZPlane(vec3 startPoint, vec3 endPoint, float zDistance);
|
||||||
|
|
||||||
|
/*
|
||||||
|
context: glViewport is referred to as the "screen"
|
||||||
|
clusters are built based on a 2d screen-space grid and depth slices.
|
||||||
|
Later when shading, it is easy to figure what cluster a fragment is in based on
|
||||||
|
gl_FragCoord.xy and the fragment's z depth from camera
|
||||||
|
*/
|
||||||
|
void main() {
|
||||||
|
uint tileIndex = gl_WorkGroupID.x + (gl_WorkGroupID.y * gridSize.x) +
|
||||||
|
(gl_WorkGroupID.z * gridSize.x * gridSize.y);
|
||||||
|
vec2 tileSize = screenDimensions / gridSize.xy;
|
||||||
|
|
||||||
|
// tile in screen-space
|
||||||
|
vec2 minTile_screenspace = gl_WorkGroupID.xy * tileSize;
|
||||||
|
vec2 maxTile_screenspace = (gl_WorkGroupID.xy + 1) * tileSize;
|
||||||
|
|
||||||
|
// convert tile to view space sitting on the near plane
|
||||||
|
vec3 minTile = screenToView(minTile_screenspace);
|
||||||
|
vec3 maxTile = screenToView(maxTile_screenspace);
|
||||||
|
|
||||||
|
float planeNear =
|
||||||
|
zNear * pow(zFar / zNear, gl_WorkGroupID.z / float(gridSize.z));
|
||||||
|
float planeFar =
|
||||||
|
zNear * pow(zFar / zNear, (gl_WorkGroupID.z + 1) / float(gridSize.z));
|
||||||
|
|
||||||
|
// the line goes from the eye position in view space (0, 0, 0)
|
||||||
|
// through the min/max points of a tile to intersect with a given cluster's near-far planes
|
||||||
|
vec3 minPointNear =
|
||||||
|
lineIntersectionWithZPlane(vec3(0, 0, 0), minTile, planeNear);
|
||||||
|
vec3 minPointFar =
|
||||||
|
lineIntersectionWithZPlane(vec3(0, 0, 0), minTile, planeFar);
|
||||||
|
vec3 maxPointNear =
|
||||||
|
lineIntersectionWithZPlane(vec3(0, 0, 0), maxTile, planeNear);
|
||||||
|
vec3 maxPointFar =
|
||||||
|
lineIntersectionWithZPlane(vec3(0, 0, 0), maxTile, planeFar);
|
||||||
|
|
||||||
|
clusters[tileIndex].minPoint = vec4(min(minPointNear, minPointFar), 0.0);
|
||||||
|
clusters[tileIndex].maxPoint = vec4(max(maxPointNear, maxPointFar), 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the intersection point of an infinite line and a
|
||||||
|
// plane perpendicular to the Z-axis
|
||||||
|
vec3 lineIntersectionWithZPlane(vec3 startPoint, vec3 endPoint, float zDistance) {
|
||||||
|
vec3 direction = endPoint - startPoint;
|
||||||
|
vec3 normal = vec3(0.0, 0.0, -1.0); // plane normal
|
||||||
|
|
||||||
|
// skip check if the line is parallel to the plane.
|
||||||
|
|
||||||
|
float t = (zDistance - dot(normal, startPoint)) / dot(normal, direction);
|
||||||
|
return startPoint + t * direction; // the parametric form of the line equation
|
||||||
|
}
|
||||||
|
vec3 screenToView(vec2 screenCoord) {
|
||||||
|
// normalize screenCoord to [-1, 1] and
|
||||||
|
// set the NDC depth of the coordinate to be on the near plane. This is -1 by
|
||||||
|
// default in OpenGL
|
||||||
|
vec4 ndc = vec4(screenCoord / screenDimensions * 2.0 - 1.0, -1.0, 1.0);
|
||||||
|
|
||||||
|
vec4 viewCoord = inverseProjection * ndc;
|
||||||
|
viewCoord /= viewCoord.w;
|
||||||
|
return viewCoord.xyz;
|
||||||
|
}
|
||||||
87
assets/Shaders/core/light/cull.comp
Normal file
87
assets/Shaders/core/light/cull.comp
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#version 450 core
|
||||||
|
|
||||||
|
/**
|
||||||
|
Maximum number of lights per cluster
|
||||||
|
*/
|
||||||
|
#define MAX_LIGHTS_PER_CLUSTER 100
|
||||||
|
|
||||||
|
/**
|
||||||
|
The number of "threads" to run
|
||||||
|
*/
|
||||||
|
#define CULL_LOCAL_SIZE 128
|
||||||
|
|
||||||
|
/**
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
layout(local_size_x = CULL_LOCAL_SIZE, local_size_y = 1, local_size_z = 1) in;
|
||||||
|
|
||||||
|
struct PointLight {
|
||||||
|
vec4 position;
|
||||||
|
vec4 color;
|
||||||
|
float constant;
|
||||||
|
float linear;
|
||||||
|
float quadratic;
|
||||||
|
float radius;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Cluster {
|
||||||
|
vec4 minPoint;
|
||||||
|
vec4 maxPoint;
|
||||||
|
uint count;
|
||||||
|
uint lightIndices[MAX_LIGHTS_PER_CLUSTER];
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(std430, binding = CLUSTER_SSBO_BIND_POINT) restrict buffer clusterSSBO {
|
||||||
|
Cluster clusters[];
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(std430, binding = POINT_LIGHT_SSBO_BIND_POINT) restrict buffer lightSSBO {
|
||||||
|
PointLight pointLight[];
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform mat4 viewMatrix;
|
||||||
|
|
||||||
|
bool testSphereAABB(uint i, Cluster c);
|
||||||
|
|
||||||
|
// each invocation of main() is a thread processing a cluster
|
||||||
|
void main() {
|
||||||
|
uint lightCount = pointLight.length();
|
||||||
|
uint index = gl_WorkGroupID.x * CULL_LOCAL_SIZE + gl_LocalInvocationID.x;
|
||||||
|
Cluster cluster = clusters[index];
|
||||||
|
|
||||||
|
// we need to reset count because culling runs every frame.
|
||||||
|
// otherwise it would accumulate.
|
||||||
|
cluster.count = 0;
|
||||||
|
|
||||||
|
for (uint i = 0; i < lightCount; ++i){
|
||||||
|
if (testSphereAABB(i, cluster) && cluster.count < 100){
|
||||||
|
cluster.lightIndices[cluster.count] = i;
|
||||||
|
cluster.count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clusters[index] = cluster;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sphereAABBIntersection(vec3 center, float radius, vec3 aabbMin, vec3 aabbMax) {
|
||||||
|
// closest point on the AABB to the sphere center
|
||||||
|
vec3 closestPoint = clamp(center, aabbMin, aabbMax);
|
||||||
|
// squared distance between the sphere center and closest point
|
||||||
|
float distanceSquared = dot(closestPoint - center, closestPoint - center);
|
||||||
|
return distanceSquared <= radius * radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this just unpacks data for sphereAABBIntersection
|
||||||
|
bool testSphereAABB(uint i, Cluster cluster) {
|
||||||
|
vec3 center = vec3(viewMatrix * pointLight[i].position);
|
||||||
|
float radius = pointLight[i].radius;
|
||||||
|
|
||||||
|
vec3 aabbMin = cluster.minPoint.xyz;
|
||||||
|
vec3 aabbMax = cluster.maxPoint.xyz;
|
||||||
|
|
||||||
|
return sphereAABBIntersection(center, radius, aabbMin, aabbMax);
|
||||||
|
}
|
||||||
@ -1,36 +1,67 @@
|
|||||||
#version 400 core
|
#version 450 core
|
||||||
|
|
||||||
|
/**
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Maximum number of point lights
|
||||||
|
*/
|
||||||
|
#define MAX_POINT_LIGHTS 512
|
||||||
|
|
||||||
|
/**
|
||||||
|
Maximum number of lights per cluster
|
||||||
|
*/
|
||||||
|
#define MAX_LIGHTS_PER_CLUSTER 100
|
||||||
|
|
||||||
|
/**
|
||||||
|
The direct global light
|
||||||
|
*/
|
||||||
|
struct DirectLight {
|
||||||
|
vec3 direction;
|
||||||
|
vec3 color;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
A point light
|
||||||
|
*/
|
||||||
|
struct PointLight {
|
||||||
|
vec4 position;
|
||||||
|
vec4 color;
|
||||||
|
float constant;
|
||||||
|
float linear;
|
||||||
|
float quadratic;
|
||||||
|
float radius;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
A light cluster
|
||||||
|
*/
|
||||||
|
struct Cluster {
|
||||||
|
vec4 minPoint;
|
||||||
|
vec4 maxPoint;
|
||||||
|
uint count;
|
||||||
|
uint lightIndices[MAX_LIGHTS_PER_CLUSTER];
|
||||||
|
};
|
||||||
|
|
||||||
#define NR_POINT_LIGHTS 10
|
|
||||||
|
|
||||||
layout (location = 0) out vec4 accum;
|
layout (location = 0) out vec4 accum;
|
||||||
layout (location = 1) out float reveal;
|
layout (location = 1) out float reveal;
|
||||||
|
|
||||||
|
layout(std430, binding = CLUSTER_SSBO_BIND_POINT) restrict buffer clusterGridSSBO {
|
||||||
|
Cluster clusters[];
|
||||||
|
};
|
||||||
|
|
||||||
layout (std140) uniform Lights {
|
layout(std430, binding = POINT_LIGHT_SSBO_BIND_POINT) restrict buffer pointLightSSBO {
|
||||||
// this is how many because we have to align
|
PointLight pointLight[];
|
||||||
// bytes it SHOULD in multiples of 16, this
|
};
|
||||||
// take it where it ACTUALLY is
|
|
||||||
//
|
|
||||||
//refer: https://learnopengl.com/Advanced-OpenGL/Advanced-GLSL
|
|
||||||
//
|
|
||||||
// base alignment aligned offset
|
|
||||||
//direct light
|
|
||||||
vec3 dLDirection; // 16 0
|
|
||||||
vec3 dLAmbient; // 16 16
|
|
||||||
vec3 dLDiffuse; // 16 32
|
|
||||||
vec3 dLSpecular; // 16 48
|
|
||||||
|
|
||||||
//point light
|
|
||||||
vec3 pLposition[NR_POINT_LIGHTS]; // 16*10 64
|
|
||||||
float pLconstant[NR_POINT_LIGHTS]; // 16*10 224
|
|
||||||
float pLlinear[NR_POINT_LIGHTS]; // 16*10 384
|
|
||||||
float pLquadratic[NR_POINT_LIGHTS]; // 16*10 544
|
|
||||||
vec3 pLambient[NR_POINT_LIGHTS]; // 16*10 704
|
|
||||||
vec3 pLdiffuse[NR_POINT_LIGHTS]; // 16*10 864
|
|
||||||
vec3 pLspecular[NR_POINT_LIGHTS]; // 16*10 1024
|
|
||||||
|
|
||||||
//for a total size of 1184
|
|
||||||
|
|
||||||
|
layout(std430, binding = DIRECT_LIGHT_SSBO_BIND_POINT) restrict buffer dirLightSSBO {
|
||||||
|
DirectLight directLight;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Material {
|
struct Material {
|
||||||
@ -42,6 +73,7 @@ struct Material {
|
|||||||
|
|
||||||
//inputs
|
//inputs
|
||||||
in vec3 FragPos;
|
in vec3 FragPos;
|
||||||
|
in vec3 ViewFragPos;
|
||||||
in vec3 Normal;
|
in vec3 Normal;
|
||||||
in vec2 TexCoord;
|
in vec2 TexCoord;
|
||||||
in vec4 FragPosLightSpace;
|
in vec4 FragPosLightSpace;
|
||||||
@ -58,9 +90,20 @@ uniform Material material;
|
|||||||
//light depth map
|
//light depth map
|
||||||
uniform sampler2D shadowMap;
|
uniform sampler2D shadowMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Used for light cluster calculation
|
||||||
|
*/
|
||||||
|
uniform float zNear;
|
||||||
|
uniform float zFar;
|
||||||
|
uniform uvec3 gridSize;
|
||||||
|
uniform uvec2 screenDimensions;
|
||||||
|
uniform mat4 view;
|
||||||
|
|
||||||
|
|
||||||
//function prototypes
|
//function prototypes
|
||||||
float calcLightIntensityTotal(vec3 normal);
|
float calcLightIntensityTotal(vec3 normal);
|
||||||
|
uint findCluster(vec3 FragPos, float zNear, float zFar);
|
||||||
|
vec3 CalcPointLight(PointLight pointLight, vec3 normal, vec3 fragPos, vec3 viewDir);
|
||||||
float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal);
|
float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal);
|
||||||
float linearizeDepth(float d,float zNear,float zFar);
|
float linearizeDepth(float d,float zNear,float zFar);
|
||||||
float weightCalcOrigin(float finalAlpha, float zLoc, float linearizedLoc);
|
float weightCalcOrigin(float finalAlpha, float zLoc, float linearizedLoc);
|
||||||
@ -74,17 +117,33 @@ void main(){
|
|||||||
vec3 viewDir = normalize(viewPos - FragPos);
|
vec3 viewDir = normalize(viewPos - FragPos);
|
||||||
|
|
||||||
//grab light intensity
|
//grab light intensity
|
||||||
float lightIntensity = calcLightIntensityTotal(norm);
|
vec3 lightIntensity = vec3(calcLightIntensityTotal(norm));
|
||||||
|
|
||||||
//get color of base texture
|
//get color of base texture
|
||||||
vec4 textureColor = texture(material.diffuse, TexCoord);
|
vec4 textureColor = texture(material.diffuse, TexCoord);
|
||||||
vec3 textureRGB = textureColor.rgb;
|
vec3 textureRGB = textureColor.rgb;
|
||||||
|
|
||||||
//shadow
|
//shadow
|
||||||
float shadow = ShadowCalculation(FragPosLightSpace, normalize(-dLDirection), norm);
|
float shadow = ShadowCalculation(FragPosLightSpace, normalize(-directLight.direction), norm);
|
||||||
vec3 shadowModifiedColor = textureRGB * lightIntensity * max(shadow, 0.4);
|
|
||||||
|
//
|
||||||
|
//point light calculations
|
||||||
|
uint clusterIndex = findCluster(ViewFragPos, 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){
|
||||||
|
accum = vec4(1.0f,0.0f,0.0f,1);
|
||||||
|
reveal = textureColor.a;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//calculate final color
|
//calculate final color
|
||||||
|
vec3 shadowModifiedColor = textureRGB * lightIntensity * max(shadow, 0.4);
|
||||||
vec4 finalColor = vec4(shadowModifiedColor,textureColor.a);
|
vec4 finalColor = vec4(shadowModifiedColor,textureColor.a);
|
||||||
|
|
||||||
//calculate weight function
|
//calculate weight function
|
||||||
@ -127,13 +186,13 @@ float linearizeDepth(float d,float zNear,float zFar){
|
|||||||
|
|
||||||
float calcLightIntensityAmbient(){
|
float calcLightIntensityAmbient(){
|
||||||
//calculate average of ambient light
|
//calculate average of ambient light
|
||||||
float avg = (dLAmbient.x + dLAmbient.y + dLAmbient.z)/3.0;
|
float avg = (directLight.color.x + directLight.color.y + directLight.color.z)/3.0;
|
||||||
return avg;
|
return avg;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
float calcLightIntensityDir(vec3 normal){
|
float calcLightIntensityDir(vec3 normal){
|
||||||
vec3 lightDir = normalize(-dLDirection);
|
vec3 lightDir = normalize(-directLight.direction);
|
||||||
// diffuse shading
|
// diffuse shading
|
||||||
float diff = max(dot(normal, lightDir), 0.0);
|
float diff = max(dot(normal, lightDir), 0.0);
|
||||||
|
|
||||||
@ -156,38 +215,55 @@ float calcLightIntensityTotal(vec3 normal){
|
|||||||
//
|
//
|
||||||
vec3 getTotalLightColor(vec3 normal){
|
vec3 getTotalLightColor(vec3 normal){
|
||||||
//get the direct light color adjusted for intensity
|
//get the direct light color adjusted for intensity
|
||||||
vec3 diffuseLightColor = dLDiffuse * calcLightIntensityDir(normal);
|
vec3 diffuseLightColor = directLight.color * calcLightIntensityDir(normal);
|
||||||
|
|
||||||
//sum light colors
|
//sum light colors
|
||||||
vec3 totalLightColor = diffuseLightColor;
|
vec3 totalLightColor = diffuseLightColor;
|
||||||
return totalLightColor;
|
return totalLightColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 CalcPointLight(int i, vec3 normal, vec3 fragPos, vec3 viewDir){
|
|
||||||
vec3 lightDir = normalize(pLposition[i] - fragPos);
|
vec3 CalcPointLight(PointLight pointLight, vec3 normal, vec3 fragPos, vec3 viewDir){
|
||||||
|
vec3 lightDir = normalize(pointLight.position.xyz - fragPos);
|
||||||
// diffuse shading
|
// diffuse shading
|
||||||
float diff = max(dot(normal, lightDir), 0.0);
|
float diff = max(dot(normal, lightDir), 0.0);
|
||||||
// specular shading
|
// specular shading
|
||||||
// vec3 reflectDir = reflect(-lightDir, normal);
|
// vec3 reflectDir = reflect(-lightDir, normal);
|
||||||
// float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
|
// float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
|
||||||
// attenuation
|
// attenuation
|
||||||
float distance = length(pLposition[i] - fragPos);
|
float distance = length(pointLight.position.xyz - fragPos);
|
||||||
float attenuation = 1.0 / (pLconstant[i] + pLlinear[i] * distance + pLquadratic[i] * (distance * distance));
|
float attenuation = 1.0 / (pointLight.constant + pointLight.linear * distance + pointLight.quadratic * (distance * distance));
|
||||||
|
if(distance > pointLight.radius){
|
||||||
|
attenuation = 0;
|
||||||
|
}
|
||||||
// combine results
|
// combine results
|
||||||
vec3 ambient = pLambient[i];// * vec4(texture(material.diffuse, TexCoord)).xyz;
|
vec3 ambient = pointLight.color.xyz;// * vec4(texture(material.diffuse, TexCoord)).xyz;
|
||||||
vec3 diffuse = pLdiffuse[i] * diff;// * vec4(texture(material.diffuse, TexCoord)).xyz;
|
vec3 diffuse = pointLight.color.xyz * diff;// * vec4(texture(material.diffuse, TexCoord)).xyz;
|
||||||
// vec3 specular = pLspecular[i] * spec;// * vec4(texture(material.specular, TexCoord)).xyz;
|
// vec3 specular = pLspecular[i] * spec;// * vec4(texture(material.specular, TexCoord)).xyz;
|
||||||
ambient *= attenuation;
|
ambient = ambient * attenuation;
|
||||||
diffuse *= attenuation;
|
diffuse = diffuse * attenuation;
|
||||||
// specular *= attenuation;
|
// specular *= attenuation;
|
||||||
vec3 specular = vec3(0,0,0);
|
vec3 specular = vec3(0,0,0);
|
||||||
|
|
||||||
vec3 finalValue = (ambient + diffuse + specular);
|
vec3 finalValue = vec3(0);
|
||||||
finalValue = vec3(max(finalValue.x,0),max(finalValue.y,0),max(finalValue.z,0));
|
if(distance < pointLight.radius){
|
||||||
|
finalValue = (ambient + diffuse + specular);
|
||||||
|
finalValue = vec3(max(finalValue.x,0),max(finalValue.y,0),max(finalValue.z,0));
|
||||||
|
}
|
||||||
|
|
||||||
return finalValue;
|
return finalValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
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;
|
||||||
|
uvec3 tile = uvec3(gl_FragCoord.xy / tileSize, zTile);
|
||||||
|
return tile.x + (tile.y * gridSize.x) + (tile.z * gridSize.x * gridSize.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -30,6 +30,7 @@ uniform int numBones;
|
|||||||
//output buffers
|
//output buffers
|
||||||
out vec3 Normal;
|
out vec3 Normal;
|
||||||
out vec3 FragPos;
|
out vec3 FragPos;
|
||||||
|
out vec3 ViewFragPos;
|
||||||
out vec2 TexCoord;
|
out vec2 TexCoord;
|
||||||
out vec4 FragPosLightSpace;
|
out vec4 FragPosLightSpace;
|
||||||
|
|
||||||
@ -59,6 +60,7 @@ void main() {
|
|||||||
|
|
||||||
//push frag, normal, and texture positions to fragment shader
|
//push frag, normal, and texture positions to fragment shader
|
||||||
FragPos = vec3(model * FinalVertex);
|
FragPos = vec3(model * FinalVertex);
|
||||||
|
ViewFragPos = vec3(view * model * FinalVertex);
|
||||||
Normal = mat3(transpose(inverse(model))) * FinalNormal.xyz;
|
Normal = mat3(transpose(inverse(model))) * FinalNormal.xyz;
|
||||||
TexCoord = aTex;
|
TexCoord = aTex;
|
||||||
|
|
||||||
|
|||||||
@ -1,37 +1,68 @@
|
|||||||
#version 330 core
|
#version 450 core
|
||||||
|
|
||||||
//foliage.fs
|
//foliage.fs
|
||||||
|
|
||||||
#define NR_POINT_LIGHTS 10
|
/**
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Maximum number of point lights
|
||||||
|
*/
|
||||||
|
#define MAX_POINT_LIGHTS 512
|
||||||
|
|
||||||
|
/**
|
||||||
|
Maximum number of lights per cluster
|
||||||
|
*/
|
||||||
|
#define MAX_LIGHTS_PER_CLUSTER 100
|
||||||
|
|
||||||
|
/**
|
||||||
|
The direct global light
|
||||||
|
*/
|
||||||
|
struct DirectLight {
|
||||||
|
vec3 direction;
|
||||||
|
vec3 color;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
A point light
|
||||||
|
*/
|
||||||
|
struct PointLight {
|
||||||
|
vec4 position;
|
||||||
|
vec4 color;
|
||||||
|
float constant;
|
||||||
|
float linear;
|
||||||
|
float quadratic;
|
||||||
|
float radius;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
A light cluster
|
||||||
|
*/
|
||||||
|
struct Cluster {
|
||||||
|
vec4 minPoint;
|
||||||
|
vec4 maxPoint;
|
||||||
|
uint count;
|
||||||
|
uint lightIndices[MAX_LIGHTS_PER_CLUSTER];
|
||||||
|
};
|
||||||
|
|
||||||
out vec4 FragColor;
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
|
||||||
layout (std140) uniform Lights {
|
layout(std430, binding = CLUSTER_SSBO_BIND_POINT) restrict buffer clusterGridSSBO {
|
||||||
// this is how many because we have to align
|
Cluster clusters[];
|
||||||
// bytes it SHOULD in multiples of 16, this
|
};
|
||||||
// take it where it ACTUALLY is
|
|
||||||
//
|
|
||||||
//refer: https://learnopengl.com/Advanced-OpenGL/Advanced-GLSL
|
|
||||||
//
|
|
||||||
// base alignment aligned offset
|
|
||||||
//direct light
|
|
||||||
vec3 dLDirection; // 16 0
|
|
||||||
vec3 dLAmbient; // 16 16
|
|
||||||
vec3 dLDiffuse; // 16 32
|
|
||||||
vec3 dLSpecular; // 16 48
|
|
||||||
|
|
||||||
//point light
|
layout(std430, binding = POINT_LIGHT_SSBO_BIND_POINT) restrict buffer pointLightSSBO {
|
||||||
vec3 pLposition[NR_POINT_LIGHTS]; // 16*10 64
|
PointLight pointLight[];
|
||||||
float pLconstant[NR_POINT_LIGHTS]; // 16*10 224
|
};
|
||||||
float pLlinear[NR_POINT_LIGHTS]; // 16*10 384
|
|
||||||
float pLquadratic[NR_POINT_LIGHTS]; // 16*10 544
|
|
||||||
vec3 pLambient[NR_POINT_LIGHTS]; // 16*10 704
|
|
||||||
vec3 pLdiffuse[NR_POINT_LIGHTS]; // 16*10 864
|
|
||||||
vec3 pLspecular[NR_POINT_LIGHTS]; // 16*10 1024
|
|
||||||
|
|
||||||
//for a total size of 1184
|
|
||||||
|
|
||||||
|
layout(std430, binding = DIRECT_LIGHT_SSBO_BIND_POINT) restrict buffer dirLightSSBO {
|
||||||
|
DirectLight directLight;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Material {
|
struct Material {
|
||||||
@ -41,6 +72,7 @@ struct Material {
|
|||||||
};
|
};
|
||||||
|
|
||||||
in vec3 FragPos;
|
in vec3 FragPos;
|
||||||
|
in vec3 ViewFragPos;
|
||||||
in vec3 Normal;
|
in vec3 Normal;
|
||||||
in vec2 TexCoord;
|
in vec2 TexCoord;
|
||||||
in vec4 FragPosLightSpace;
|
in vec4 FragPosLightSpace;
|
||||||
@ -62,11 +94,19 @@ uniform int hasTransparency;
|
|||||||
//light depth map
|
//light depth map
|
||||||
uniform sampler2D shadowMap;
|
uniform sampler2D shadowMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Used for light cluster calculation
|
||||||
|
*/
|
||||||
|
uniform float zNear;
|
||||||
|
uniform float zFar;
|
||||||
|
uniform uvec3 gridSize;
|
||||||
|
uniform uvec2 screenDimensions;
|
||||||
|
uniform mat4 view;
|
||||||
|
|
||||||
|
|
||||||
// function prototypes
|
// function prototypes
|
||||||
// vec3 CalcDirLight(vec3 normal, vec3 viewDir);
|
uint findCluster(vec3 FragPos, float zNear, float zFar);
|
||||||
// vec3 CalcPointLight(int i, vec3 normal, vec3 fragPos, vec3 viewDir);
|
vec3 CalcPointLight(PointLight pointLight, vec3 normal, vec3 fragPos, vec3 viewDir);
|
||||||
// vec3 CalcSpotLight(vec3 normal, vec3 fragPos, vec3 viewDir);
|
|
||||||
float calcLightIntensityTotal(vec3 normal);
|
float calcLightIntensityTotal(vec3 normal);
|
||||||
float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal);
|
float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal);
|
||||||
float easeIn(float interpolator);
|
float easeIn(float interpolator);
|
||||||
@ -90,7 +130,7 @@ void main(){
|
|||||||
vec3 viewDir = normalize(viewPos - FragPos);
|
vec3 viewDir = normalize(viewPos - FragPos);
|
||||||
|
|
||||||
//grab light intensity
|
//grab light intensity
|
||||||
float lightIntensity = calcLightIntensityTotal(norm);
|
vec3 lightIntensity = vec3(calcLightIntensityTotal(norm));
|
||||||
|
|
||||||
//get color of base texture
|
//get color of base texture
|
||||||
// vec3 textureColor = vec3((norm.x + 1) / 2.0, norm.y, 1.0 - (norm.x + 1) / 2.0);
|
// vec3 textureColor = vec3((norm.x + 1) / 2.0, norm.y, 1.0 - (norm.x + 1) / 2.0);
|
||||||
@ -98,7 +138,22 @@ void main(){
|
|||||||
// vec3 textureColor = vec3(0.17647,0.4,0.09411);//texture(material.diffuse, TexCoord).rgb;
|
// vec3 textureColor = vec3(0.17647,0.4,0.09411);//texture(material.diffuse, TexCoord).rgb;
|
||||||
|
|
||||||
//shadow
|
//shadow
|
||||||
float shadow = ShadowCalculation(FragPosLightSpace, normalize(-dLDirection), norm);
|
float shadow = ShadowCalculation(FragPosLightSpace, normalize(-directLight.direction), norm);
|
||||||
|
|
||||||
|
//
|
||||||
|
//point light calculations
|
||||||
|
uint clusterIndex = findCluster(ViewFragPos, 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){
|
||||||
|
FragColor = vec4(1.0f,0.0f,0.0f,1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//calculate final color
|
//calculate final color
|
||||||
vec3 finalColor = textureColor * lightIntensity;// * max(shadow,0.4);
|
vec3 finalColor = textureColor * lightIntensity;// * max(shadow,0.4);
|
||||||
@ -133,13 +188,13 @@ void main(){
|
|||||||
//
|
//
|
||||||
float calcLightIntensityAmbient(){
|
float calcLightIntensityAmbient(){
|
||||||
//calculate average of ambient light
|
//calculate average of ambient light
|
||||||
float avg = (dLAmbient.x + dLAmbient.y + dLAmbient.z)/3.0;
|
float avg = (directLight.color.x + directLight.color.y + directLight.color.z)/3.0;
|
||||||
return avg;
|
return avg;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
float calcLightIntensityDir(vec3 normal){
|
float calcLightIntensityDir(vec3 normal){
|
||||||
vec3 lightDir = normalize(-dLDirection);
|
vec3 lightDir = normalize(-directLight.direction);
|
||||||
// diffuse shading
|
// diffuse shading
|
||||||
float diff = max(dot(normal, lightDir), 0.0);
|
float diff = max(dot(normal, lightDir), 0.0);
|
||||||
|
|
||||||
@ -162,64 +217,53 @@ float calcLightIntensityTotal(vec3 normal){
|
|||||||
//
|
//
|
||||||
vec3 getTotalLightColor(vec3 normal){
|
vec3 getTotalLightColor(vec3 normal){
|
||||||
//get the direct light color adjusted for intensity
|
//get the direct light color adjusted for intensity
|
||||||
vec3 diffuseLightColor = dLDiffuse * calcLightIntensityDir(normal);
|
vec3 diffuseLightColor = directLight.color * calcLightIntensityDir(normal);
|
||||||
|
|
||||||
//sum light colors
|
//sum light colors
|
||||||
vec3 totalLightColor = diffuseLightColor;
|
vec3 totalLightColor = diffuseLightColor;
|
||||||
return totalLightColor;
|
return totalLightColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 CalcPointLight(int i, vec3 normal, vec3 fragPos, vec3 viewDir){
|
vec3 CalcPointLight(PointLight pointLight, vec3 normal, vec3 fragPos, vec3 viewDir){
|
||||||
vec3 lightDir = normalize(pLposition[i] - fragPos);
|
vec3 lightDir = normalize(pointLight.position.xyz - fragPos);
|
||||||
// diffuse shading
|
// diffuse shading
|
||||||
float diff = max(dot(normal, lightDir), 0.0);
|
float diff = max(dot(normal, lightDir), 0.0);
|
||||||
// specular shading
|
// specular shading
|
||||||
// vec3 reflectDir = reflect(-lightDir, normal);
|
// vec3 reflectDir = reflect(-lightDir, normal);
|
||||||
// float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
|
// float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
|
||||||
// attenuation
|
// attenuation
|
||||||
float distance = length(pLposition[i] - fragPos);
|
float distance = length(pointLight.position.xyz - fragPos);
|
||||||
float attenuation = 1.0 / (pLconstant[i] + pLlinear[i] * distance + pLquadratic[i] * (distance * distance));
|
float attenuation = 1.0 / (pointLight.constant + pointLight.linear * distance + pointLight.quadratic * (distance * distance));
|
||||||
|
if(distance > pointLight.radius){
|
||||||
|
attenuation = 0;
|
||||||
|
}
|
||||||
// combine results
|
// combine results
|
||||||
vec3 ambient = pLambient[i];// * vec4(texture(material.diffuse, TexCoord)).xyz;
|
vec3 ambient = pointLight.color.xyz;// * vec4(texture(material.diffuse, TexCoord)).xyz;
|
||||||
vec3 diffuse = pLdiffuse[i] * diff;// * vec4(texture(material.diffuse, TexCoord)).xyz;
|
vec3 diffuse = pointLight.color.xyz * diff;// * vec4(texture(material.diffuse, TexCoord)).xyz;
|
||||||
// vec3 specular = pLspecular[i] * spec;// * vec4(texture(material.specular, TexCoord)).xyz;
|
// vec3 specular = pLspecular[i] * spec;// * vec4(texture(material.specular, TexCoord)).xyz;
|
||||||
ambient *= attenuation;
|
ambient = ambient * attenuation;
|
||||||
diffuse *= attenuation;
|
diffuse = diffuse * attenuation;
|
||||||
// specular *= attenuation;
|
// specular *= attenuation;
|
||||||
vec3 specular = vec3(0,0,0);
|
vec3 specular = vec3(0,0,0);
|
||||||
|
|
||||||
vec3 finalValue = (ambient + diffuse + specular);
|
vec3 finalValue = vec3(0);
|
||||||
finalValue = vec3(max(finalValue.x,0),max(finalValue.y,0),max(finalValue.z,0));
|
if(distance < pointLight.radius){
|
||||||
|
finalValue = (ambient + diffuse + specular);
|
||||||
|
finalValue = vec3(max(finalValue.x,0),max(finalValue.y,0),max(finalValue.z,0));
|
||||||
|
}
|
||||||
|
|
||||||
return finalValue;
|
return finalValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// // calculates the color when using a point light.
|
/**
|
||||||
// vec3 CalcPointLight(int i, vec3 normal, vec3 fragPos, vec3 viewDir){
|
Finds the light cluster this fragment belongs to
|
||||||
// vec3 lightDir = normalize(pLposition[i] - fragPos);
|
*/
|
||||||
// // diffuse shading
|
uint findCluster(vec3 viewspaceFragPos, float zNear, float zFar){
|
||||||
// float diff = max(dot(normal, lightDir), 0.0);
|
uint zTile = uint((log(abs(viewspaceFragPos.z) / zNear) * gridSize.z) / log(zFar / zNear));
|
||||||
// // specular shading
|
vec2 tileSize = screenDimensions / gridSize.xy;
|
||||||
// // vec3 reflectDir = reflect(-lightDir, normal);
|
uvec3 tile = uvec3(gl_FragCoord.xy / tileSize, zTile);
|
||||||
// // float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
|
return tile.x + (tile.y * gridSize.x) + (tile.z * gridSize.x * gridSize.y);
|
||||||
// // attenuation
|
}
|
||||||
// float distance = length(pLposition[i] - fragPos);
|
|
||||||
// float attenuation = 1.0 / (pLconstant[i] + pLlinear[i] * distance + pLquadratic[i] * (distance * distance));
|
|
||||||
// // combine results
|
|
||||||
// vec3 ambient = pLambient[i];// * vec4(texture(material.diffuse, TexCoord)).xyz;
|
|
||||||
// vec3 diffuse = pLdiffuse[i] * diff;// * vec4(texture(material.diffuse, TexCoord)).xyz;
|
|
||||||
// // vec3 specular = pLspecular[i] * spec;// * vec4(texture(material.specular, TexCoord)).xyz;
|
|
||||||
// ambient *= attenuation;
|
|
||||||
// diffuse *= attenuation;
|
|
||||||
// // specular *= attenuation;
|
|
||||||
// vec3 specular = vec3(0,0,0);
|
|
||||||
|
|
||||||
// vec3 finalValue = (ambient + diffuse + specular);
|
|
||||||
// finalValue = vec3(max(finalValue.x,0),max(finalValue.y,0),max(finalValue.z,0));
|
|
||||||
|
|
||||||
// return finalValue;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal){
|
float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal){
|
||||||
|
|
||||||
|
|||||||
@ -40,6 +40,7 @@ uniform float time;
|
|||||||
//output buffers
|
//output buffers
|
||||||
out vec3 Normal;
|
out vec3 Normal;
|
||||||
out vec3 FragPos;
|
out vec3 FragPos;
|
||||||
|
out vec3 ViewFragPos;
|
||||||
out vec2 TexCoord;
|
out vec2 TexCoord;
|
||||||
out vec4 FragPosLightSpace;
|
out vec4 FragPosLightSpace;
|
||||||
out vec3 normalRot1;
|
out vec3 normalRot1;
|
||||||
@ -156,6 +157,7 @@ void main() {
|
|||||||
//push frag, normal, and texture positions to fragment shader
|
//push frag, normal, and texture positions to fragment shader
|
||||||
//
|
//
|
||||||
FragPos = vec3(FinalVertex);
|
FragPos = vec3(FinalVertex);
|
||||||
|
ViewFragPos = vec3(view * model * FinalVertex);
|
||||||
Normal = vec3(FinalNormal);
|
Normal = vec3(FinalNormal);
|
||||||
TexCoord = aTex;
|
TexCoord = aTex;
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
#version 330 core
|
#version 450 core
|
||||||
|
|
||||||
//texture defines
|
//texture defines
|
||||||
#define ATLAS_ELEMENT_DIM 256.0
|
#define ATLAS_ELEMENT_DIM 256.0
|
||||||
@ -8,37 +8,67 @@
|
|||||||
#define ATLAS_NORMALIZED_ELEMENT_WIDTH_FULL 0.03125 //used to properly shift from texture to texture in the atlas
|
#define ATLAS_NORMALIZED_ELEMENT_WIDTH_FULL 0.03125 //used to properly shift from texture to texture in the atlas
|
||||||
|
|
||||||
|
|
||||||
#define NR_POINT_LIGHTS 10
|
/**
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Maximum number of point lights
|
||||||
|
*/
|
||||||
|
#define MAX_POINT_LIGHTS 512
|
||||||
|
|
||||||
|
/**
|
||||||
|
Maximum number of lights per cluster
|
||||||
|
*/
|
||||||
|
#define MAX_LIGHTS_PER_CLUSTER 100
|
||||||
|
|
||||||
|
/**
|
||||||
|
The direct global light
|
||||||
|
*/
|
||||||
|
struct DirectLight {
|
||||||
|
vec3 direction;
|
||||||
|
vec3 color;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
A point light
|
||||||
|
*/
|
||||||
|
struct PointLight {
|
||||||
|
vec4 position;
|
||||||
|
vec4 color;
|
||||||
|
float constant;
|
||||||
|
float linear;
|
||||||
|
float quadratic;
|
||||||
|
float radius;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
A light cluster
|
||||||
|
*/
|
||||||
|
struct Cluster {
|
||||||
|
vec4 minPoint;
|
||||||
|
vec4 maxPoint;
|
||||||
|
uint count;
|
||||||
|
uint lightIndices[MAX_LIGHTS_PER_CLUSTER];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
out vec4 FragColor;
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
layout(std430, binding = CLUSTER_SSBO_BIND_POINT) restrict buffer clusterGridSSBO {
|
||||||
|
Cluster clusters[];
|
||||||
|
};
|
||||||
|
|
||||||
layout (std140) uniform Lights {
|
layout(std430, binding = POINT_LIGHT_SSBO_BIND_POINT) restrict buffer pointLightSSBO {
|
||||||
// this is how many because we have to align
|
PointLight pointLight[];
|
||||||
// bytes it SHOULD in multiples of 16, this
|
};
|
||||||
// take it where it ACTUALLY is
|
|
||||||
//
|
|
||||||
//refer: https://learnopengl.com/Advanced-OpenGL/Advanced-GLSL
|
|
||||||
//
|
|
||||||
// base alignment aligned offset
|
|
||||||
//direct light
|
|
||||||
vec3 dLDirection; // 16 0
|
|
||||||
vec3 dLAmbient; // 16 16
|
|
||||||
vec3 dLDiffuse; // 16 32
|
|
||||||
vec3 dLSpecular; // 16 48
|
|
||||||
|
|
||||||
//point light
|
|
||||||
vec3 pLposition[NR_POINT_LIGHTS]; // 16*10 64
|
|
||||||
float pLconstant[NR_POINT_LIGHTS]; // 16*10 224
|
|
||||||
float pLlinear[NR_POINT_LIGHTS]; // 16*10 384
|
|
||||||
float pLquadratic[NR_POINT_LIGHTS]; // 16*10 544
|
|
||||||
vec3 pLambient[NR_POINT_LIGHTS]; // 16*10 704
|
|
||||||
vec3 pLdiffuse[NR_POINT_LIGHTS]; // 16*10 864
|
|
||||||
vec3 pLspecular[NR_POINT_LIGHTS]; // 16*10 1024
|
|
||||||
|
|
||||||
//for a total size of 1184
|
|
||||||
|
|
||||||
|
layout(std430, binding = DIRECT_LIGHT_SSBO_BIND_POINT) restrict buffer dirLightSSBO {
|
||||||
|
DirectLight directLight;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Material {
|
struct Material {
|
||||||
@ -48,6 +78,7 @@ struct Material {
|
|||||||
};
|
};
|
||||||
|
|
||||||
in vec3 FragPos;
|
in vec3 FragPos;
|
||||||
|
in vec3 ViewFragPos;
|
||||||
in vec3 Normal;
|
in vec3 Normal;
|
||||||
in vec2 texPlane1;
|
in vec2 texPlane1;
|
||||||
in vec2 texPlane2;
|
in vec2 texPlane2;
|
||||||
@ -71,11 +102,19 @@ uniform int hasTransparency;
|
|||||||
//light depth map
|
//light depth map
|
||||||
uniform sampler2D shadowMap;
|
uniform sampler2D shadowMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Used for light cluster calculation
|
||||||
|
*/
|
||||||
|
uniform float zNear;
|
||||||
|
uniform float zFar;
|
||||||
|
uniform uvec3 gridSize;
|
||||||
|
uniform uvec2 screenDimensions;
|
||||||
|
uniform mat4 view;
|
||||||
|
|
||||||
|
|
||||||
// function prototypes
|
// function prototypes
|
||||||
// vec3 CalcDirLight(vec3 normal, vec3 viewDir);
|
uint findCluster(vec3 FragPos, float zNear, float zFar);
|
||||||
// vec3 CalcPointLight(int i, vec3 normal, vec3 fragPos, vec3 viewDir);
|
vec3 CalcPointLight(PointLight pointLight, vec3 normal, vec3 fragPos, vec3 viewDir);
|
||||||
// vec3 CalcSpotLight(vec3 normal, vec3 fragPos, vec3 viewDir);
|
|
||||||
float calcLightIntensityTotal(vec3 normal);
|
float calcLightIntensityTotal(vec3 normal);
|
||||||
float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal);
|
float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal);
|
||||||
vec3 getColor(vec2 texPlane1, vec2 texPlane2, vec2 texPlane3, vec3 normal, vec3 samplerIndexVec, vec3 samplerRatioVec, Material material);
|
vec3 getColor(vec2 texPlane1, vec2 texPlane2, vec2 texPlane3, vec3 normal, vec3 samplerIndexVec, vec3 samplerRatioVec, Material material);
|
||||||
@ -85,20 +124,31 @@ void main(){
|
|||||||
vec3 viewDir = normalize(viewPos - FragPos);
|
vec3 viewDir = normalize(viewPos - FragPos);
|
||||||
|
|
||||||
//grab light intensity
|
//grab light intensity
|
||||||
float lightIntensity = calcLightIntensityTotal(norm);
|
vec3 lightIntensity = vec3(calcLightIntensityTotal(norm));
|
||||||
|
|
||||||
//get color of base texture
|
//get color of base texture
|
||||||
vec3 textureColor = getColor(texPlane1, texPlane2, texPlane3, norm, samplerIndexVec, samplerRatioVec, material);
|
vec3 textureColor = getColor(texPlane1, texPlane2, texPlane3, norm, samplerIndexVec, samplerRatioVec, material);
|
||||||
|
|
||||||
//shadow
|
//shadow
|
||||||
float shadow = ShadowCalculation(FragPosLightSpace, normalize(-dLDirection), norm);
|
float shadow = ShadowCalculation(FragPosLightSpace, normalize(-directLight.direction), norm);
|
||||||
|
|
||||||
|
//
|
||||||
|
//point light calculations
|
||||||
|
uint clusterIndex = findCluster(ViewFragPos, 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){
|
||||||
|
FragColor = vec4(1.0f,0.0f,0.0f,1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//calculate final color
|
//calculate final color
|
||||||
vec3 finalColor = textureColor * lightIntensity * max(shadow,0.4);
|
vec3 finalColor = textureColor * lightIntensity * max(shadow,0.4);
|
||||||
// vec3 lightAmount = CalcDirLight(norm, viewDir);
|
|
||||||
// for(int i = 0; i < NR_POINT_LIGHTS; i++){
|
|
||||||
// lightAmount += CalcPointLight(i, norm, FragPos, viewDir);
|
|
||||||
// }
|
|
||||||
|
|
||||||
//this final calculation is for transparency
|
//this final calculation is for transparency
|
||||||
FragColor = vec4(finalColor, 1);
|
FragColor = vec4(finalColor, 1);
|
||||||
@ -188,13 +238,13 @@ vec3 getColor(vec2 texPlane1, vec2 texPlane2, vec2 texPlane3, vec3 normal, vec3
|
|||||||
//
|
//
|
||||||
float calcLightIntensityAmbient(){
|
float calcLightIntensityAmbient(){
|
||||||
//calculate average of ambient light
|
//calculate average of ambient light
|
||||||
float avg = (dLAmbient.x + dLAmbient.y + dLAmbient.z)/3.0;
|
float avg = (directLight.color.x + directLight.color.y + directLight.color.z)/3.0;
|
||||||
return avg;
|
return avg;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
float calcLightIntensityDir(vec3 normal){
|
float calcLightIntensityDir(vec3 normal){
|
||||||
vec3 lightDir = normalize(-dLDirection);
|
vec3 lightDir = normalize(-directLight.direction);
|
||||||
// diffuse shading
|
// diffuse shading
|
||||||
float diff = max(dot(normal, lightDir), 0.0);
|
float diff = max(dot(normal, lightDir), 0.0);
|
||||||
|
|
||||||
@ -217,37 +267,54 @@ float calcLightIntensityTotal(vec3 normal){
|
|||||||
//
|
//
|
||||||
vec3 getTotalLightColor(vec3 normal){
|
vec3 getTotalLightColor(vec3 normal){
|
||||||
//get the direct light color adjusted for intensity
|
//get the direct light color adjusted for intensity
|
||||||
vec3 diffuseLightColor = dLDiffuse * calcLightIntensityDir(normal);
|
vec3 diffuseLightColor = directLight.color * calcLightIntensityDir(normal);
|
||||||
|
|
||||||
//sum light colors
|
//sum light colors
|
||||||
vec3 totalLightColor = diffuseLightColor;
|
vec3 totalLightColor = diffuseLightColor;
|
||||||
return totalLightColor;
|
return totalLightColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 CalcPointLight(int i, vec3 normal, vec3 fragPos, vec3 viewDir){
|
vec3 CalcPointLight(PointLight pointLight, vec3 normal, vec3 fragPos, vec3 viewDir){
|
||||||
vec3 lightDir = normalize(pLposition[i] - fragPos);
|
vec3 lightDir = normalize(pointLight.position.xyz - fragPos);
|
||||||
// diffuse shading
|
// diffuse shading
|
||||||
float diff = max(dot(normal, lightDir), 0.0);
|
float diff = max(dot(normal, lightDir), 0.0);
|
||||||
// specular shading
|
// specular shading
|
||||||
// vec3 reflectDir = reflect(-lightDir, normal);
|
// vec3 reflectDir = reflect(-lightDir, normal);
|
||||||
// float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
|
// float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
|
||||||
// attenuation
|
// attenuation
|
||||||
float distance = length(pLposition[i] - fragPos);
|
float distance = length(pointLight.position.xyz - fragPos);
|
||||||
float attenuation = 1.0 / (pLconstant[i] + pLlinear[i] * distance + pLquadratic[i] * (distance * distance));
|
float attenuation = 1.0 / (pointLight.constant + pointLight.linear * distance + pointLight.quadratic * (distance * distance));
|
||||||
|
if(distance > pointLight.radius){
|
||||||
|
attenuation = 0;
|
||||||
|
}
|
||||||
// combine results
|
// combine results
|
||||||
vec3 ambient = pLambient[i];
|
vec3 ambient = pointLight.color.xyz;// * vec4(texture(material.diffuse, TexCoord)).xyz;
|
||||||
vec3 diffuse = pLdiffuse[i] * diff;
|
vec3 diffuse = pointLight.color.xyz * diff;// * vec4(texture(material.diffuse, TexCoord)).xyz;
|
||||||
ambient *= attenuation;
|
// vec3 specular = pLspecular[i] * spec;// * vec4(texture(material.specular, TexCoord)).xyz;
|
||||||
diffuse *= attenuation;
|
ambient = ambient * attenuation;
|
||||||
|
diffuse = diffuse * attenuation;
|
||||||
// specular *= attenuation;
|
// specular *= attenuation;
|
||||||
vec3 specular = vec3(0,0,0);
|
vec3 specular = vec3(0,0,0);
|
||||||
|
|
||||||
vec3 finalValue = (ambient + diffuse + specular);
|
vec3 finalValue = vec3(0);
|
||||||
finalValue = vec3(max(finalValue.x,0),max(finalValue.y,0),max(finalValue.z,0));
|
if(distance < pointLight.radius){
|
||||||
|
finalValue = (ambient + diffuse + specular);
|
||||||
|
finalValue = vec3(max(finalValue.x,0),max(finalValue.y,0),max(finalValue.z,0));
|
||||||
|
}
|
||||||
|
|
||||||
return finalValue;
|
return finalValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
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;
|
||||||
|
uvec3 tile = uvec3(gl_FragCoord.xy / tileSize, zTile);
|
||||||
|
return tile.x + (tile.y * gridSize.x) + (tile.z * gridSize.x * gridSize.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal){
|
float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal){
|
||||||
|
|
||||||
|
|||||||
@ -26,6 +26,7 @@ uniform mat4 lightSpaceMatrix;
|
|||||||
//output buffers
|
//output buffers
|
||||||
out vec3 Normal;
|
out vec3 Normal;
|
||||||
out vec3 FragPos;
|
out vec3 FragPos;
|
||||||
|
out vec3 ViewFragPos;
|
||||||
out vec2 texPlane1;
|
out vec2 texPlane1;
|
||||||
out vec2 texPlane2;
|
out vec2 texPlane2;
|
||||||
out vec2 texPlane3;
|
out vec2 texPlane3;
|
||||||
@ -44,6 +45,7 @@ void main() {
|
|||||||
|
|
||||||
//push frag, normal, and texture positions to fragment shader
|
//push frag, normal, and texture positions to fragment shader
|
||||||
FragPos = vec3(model * FinalVertex);
|
FragPos = vec3(model * FinalVertex);
|
||||||
|
ViewFragPos = vec3(view * model * FinalVertex);
|
||||||
Normal = mat3(transpose(inverse(model))) * aNormal;
|
Normal = mat3(transpose(inverse(model))) * aNormal;
|
||||||
|
|
||||||
//reference https://catlikecoding.com/unity/tutorials/advanced-rendering/triplanar-mapping/
|
//reference https://catlikecoding.com/unity/tutorials/advanced-rendering/triplanar-mapping/
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
#maven.buildNumber.plugin properties file
|
#maven.buildNumber.plugin properties file
|
||||||
#Mon Sep 16 19:58:57 EDT 2024
|
#Wed Sep 18 20:37:06 EDT 2024
|
||||||
buildNumber=333
|
buildNumber=338
|
||||||
|
|||||||
@ -5,13 +5,21 @@ Design notes for the chemistry system
|
|||||||
|
|
||||||
Ideas for the chemistry system:
|
Ideas for the chemistry system:
|
||||||
- fire
|
- fire
|
||||||
|
- Torch
|
||||||
|
- Fire Arrow
|
||||||
- water
|
- water
|
||||||
|
- bucket
|
||||||
- electricity
|
- electricity
|
||||||
|
- lightning arrow
|
||||||
- ice
|
- ice
|
||||||
|
- ice chunk/block
|
||||||
|
- light
|
||||||
|
- Glittering chunk
|
||||||
|
- Wind/fans
|
||||||
|
- Placeable fan
|
||||||
- gravity
|
- gravity
|
||||||
- stabilization
|
- stabilization
|
||||||
- metal parts / conductivity
|
- metal parts / conductivity
|
||||||
- light
|
|
||||||
- mirrors
|
- mirrors
|
||||||
- plants burning
|
- plants burning
|
||||||
- plants growing really fast
|
- plants growing really fast
|
||||||
@ -20,6 +28,5 @@ Ideas for the chemistry system:
|
|||||||
- spinning mechanisms and gears
|
- spinning mechanisms and gears
|
||||||
- weighing things down and measuring scales w/ weight
|
- weighing things down and measuring scales w/ weight
|
||||||
- trampolines
|
- trampolines
|
||||||
- Wind/fans
|
|
||||||
- Weight
|
- Weight
|
||||||
- Music
|
- Music
|
||||||
@ -37,6 +37,8 @@
|
|||||||
- Spawn player in a town with a quest to complete a nearby dungeon
|
- Spawn player in a town with a quest to complete a nearby dungeon
|
||||||
|
|
||||||
+ bug fixes
|
+ bug fixes
|
||||||
|
Fix light cluster mapping for foliage shader
|
||||||
|
Fix ui elements not storing default discrete world size on level editor menu
|
||||||
Fix skeleton right strafe
|
Fix skeleton right strafe
|
||||||
Fix block tree preventing initiating an attack
|
Fix block tree preventing initiating an attack
|
||||||
Fix return to title menu synchronization bug
|
Fix return to title menu synchronization bug
|
||||||
|
|||||||
@ -801,6 +801,11 @@ Migrate documentation
|
|||||||
Netcode generator qol fixes
|
Netcode generator qol fixes
|
||||||
Combat Stances Component
|
Combat Stances Component
|
||||||
Remove geometry shader support
|
Remove geometry shader support
|
||||||
|
Work on clustered lighting
|
||||||
|
|
||||||
|
(09/19/2024)
|
||||||
|
Cluster lighting completed
|
||||||
|
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
@ -836,11 +841,15 @@ Code Generation
|
|||||||
|
|
||||||
Rearchitecting
|
Rearchitecting
|
||||||
- Main render is a ui element (that we can have multiple of)
|
- Main render is a ui element (that we can have multiple of)
|
||||||
|
- Shader handling updates to allow for library based shader compilation
|
||||||
|
- Also allow injecting consts from the engine itself (ie max lights is dynamically injected, that way never have to worry about .glsl and .java not aligning)
|
||||||
|
|
||||||
Code cleanup
|
Code cleanup
|
||||||
- Rename "BehaviorTree" to be "Component" (what it actually is)
|
- Rename "BehaviorTree" to be "Component" (what it actually is)
|
||||||
- Refactor ground movement components
|
- Refactor ground movement components
|
||||||
- Refactor menu clases to be under electrosphere.client package
|
- Refactor menu clases to be under electrosphere.client package
|
||||||
|
- Rename "ShaderProgram" to "VisualShader"
|
||||||
|
- Have ComputeShader and VisualShader use same static method for uploading uniforms
|
||||||
|
|
||||||
Goof off today requirements:
|
Goof off today requirements:
|
||||||
Transvoxel implementation
|
Transvoxel implementation
|
||||||
|
|||||||
@ -232,6 +232,24 @@ public class CameraEntityUtils {
|
|||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the near clip of the camera
|
||||||
|
* @param camera The camera
|
||||||
|
* @return The near clip
|
||||||
|
*/
|
||||||
|
public static float getNearClip(Entity camera){
|
||||||
|
return Globals.nearClip;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the far clip of the camera
|
||||||
|
* @param camera The camera
|
||||||
|
* @return The far clip
|
||||||
|
*/
|
||||||
|
public static float getFarClip(Entity camera){
|
||||||
|
return Globals.userSettings.getGraphicsViewDistance();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the rotation quaternion from a camera entity
|
* Gets the rotation quaternion from a camera entity
|
||||||
* @param entity The entity
|
* @param entity The entity
|
||||||
|
|||||||
@ -250,6 +250,7 @@ public class Globals {
|
|||||||
|
|
||||||
public static float verticalFOV = 90;
|
public static float verticalFOV = 90;
|
||||||
public static float aspectRatio = 2.0f;
|
public static float aspectRatio = 2.0f;
|
||||||
|
public static float nearClip = 0.001f;
|
||||||
|
|
||||||
//matrices for drawing models
|
//matrices for drawing models
|
||||||
public static Matrix4f viewMatrix = new Matrix4f();
|
public static Matrix4f viewMatrix = new Matrix4f();
|
||||||
@ -651,6 +652,10 @@ public class Globals {
|
|||||||
assetManager.addShaderToQueue("Shaders/ui/debug/windowBorder/windowBound.vs", "Shaders/ui/debug/windowBorder/windowBound.fs");
|
assetManager.addShaderToQueue("Shaders/ui/debug/windowBorder/windowBound.vs", "Shaders/ui/debug/windowBorder/windowBound.fs");
|
||||||
assetManager.addShaderToQueue("Shaders/ui/debug/windowContentBorder/windowContentBound.vs", "Shaders/ui/debug/windowContentBorder/windowContentBound.fs");
|
assetManager.addShaderToQueue("Shaders/ui/debug/windowContentBorder/windowContentBound.vs", "Shaders/ui/debug/windowContentBorder/windowContentBound.fs");
|
||||||
|
|
||||||
|
//compute shaders
|
||||||
|
assetManager.addComputeShaderToQueue(AssetDataStrings.COMPUTE_LIGHT_CLUSTER);
|
||||||
|
assetManager.addComputeShaderToQueue(AssetDataStrings.COMPUTE_LIGHT_CULL);
|
||||||
|
|
||||||
//as these assets are required for the renderer to work, we go ahead and
|
//as these assets are required for the renderer to work, we go ahead and
|
||||||
//load them into memory now. The loading time penalty is worth it I think.
|
//load them into memory now. The loading time penalty is worth it I think.
|
||||||
Globals.assetManager.loadAssetsInQueue();
|
Globals.assetManager.loadAssetsInQueue();
|
||||||
|
|||||||
@ -45,4 +45,10 @@ public class AssetDataStrings {
|
|||||||
public static final String UI_SFX_ITEM_GRAB = "Audio/ui/items/inventoryGrabItem.ogg";
|
public static final String UI_SFX_ITEM_GRAB = "Audio/ui/items/inventoryGrabItem.ogg";
|
||||||
public static final String UI_SFX_ITEM_RELEASE = "Audio/ui/items/inventorySlotItem.ogg";
|
public static final String UI_SFX_ITEM_RELEASE = "Audio/ui/items/inventorySlotItem.ogg";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute shaders
|
||||||
|
*/
|
||||||
|
public static final String COMPUTE_LIGHT_CLUSTER = "Shaders/core/light/cluster.comp";
|
||||||
|
public static final String COMPUTE_LIGHT_CULL = "Shaders/core/light/cull.comp";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import electrosphere.renderer.buffer.HomogenousUniformBuffer;
|
|||||||
import electrosphere.renderer.loading.ModelLoader;
|
import electrosphere.renderer.loading.ModelLoader;
|
||||||
import electrosphere.renderer.model.Mesh;
|
import electrosphere.renderer.model.Mesh;
|
||||||
import electrosphere.renderer.model.Model;
|
import electrosphere.renderer.model.Model;
|
||||||
|
import electrosphere.renderer.shader.ComputeShader;
|
||||||
import electrosphere.renderer.shader.ShaderProgram;
|
import electrosphere.renderer.shader.ShaderProgram;
|
||||||
import electrosphere.renderer.texture.Texture;
|
import electrosphere.renderer.texture.Texture;
|
||||||
import electrosphere.renderer.texture.TextureMap;
|
import electrosphere.renderer.texture.TextureMap;
|
||||||
@ -20,6 +21,7 @@ import electrosphere.server.poseactor.PoseModel;
|
|||||||
import electrosphere.util.FileUtils;
|
import electrosphere.util.FileUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@ -51,6 +53,12 @@ public class AssetManager {
|
|||||||
Map<String,ShaderProgram> shadersLoadedIntoMemory = new ConcurrentHashMap<String,ShaderProgram>();
|
Map<String,ShaderProgram> shadersLoadedIntoMemory = new ConcurrentHashMap<String,ShaderProgram>();
|
||||||
List<ActorShaderMask> shadersInQueue = new CopyOnWriteArrayList<ActorShaderMask>();
|
List<ActorShaderMask> shadersInQueue = new CopyOnWriteArrayList<ActorShaderMask>();
|
||||||
|
|
||||||
|
//
|
||||||
|
//Compute shader related
|
||||||
|
//
|
||||||
|
Map<String,ComputeShader> computeShadersLoadedIntoMemory = new ConcurrentHashMap<String,ComputeShader>();
|
||||||
|
List<String> computeShadersInQueue = new CopyOnWriteArrayList<String>();
|
||||||
|
|
||||||
Map<String,DBody> physicsMeshesLoadedIntoMemory = new ConcurrentHashMap<String,DBody>();
|
Map<String,DBody> physicsMeshesLoadedIntoMemory = new ConcurrentHashMap<String,DBody>();
|
||||||
List<PhysicsMeshQueueItem> physicsMeshesToLoad = new CopyOnWriteArrayList<PhysicsMeshQueueItem>();
|
List<PhysicsMeshQueueItem> physicsMeshesToLoad = new CopyOnWriteArrayList<PhysicsMeshQueueItem>();
|
||||||
|
|
||||||
@ -126,6 +134,20 @@ public class AssetManager {
|
|||||||
ShaderProgram.loadSpecificShader(currentShader.getVertexShaderPath(),currentShader.getFragmentShaderPath())
|
ShaderProgram.loadSpecificShader(currentShader.getVertexShaderPath(),currentShader.getFragmentShaderPath())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
//compute shaders
|
||||||
|
LoggerInterface.loggerEngine.DEBUG_LOOP("AssetManager - Load compute shaders");
|
||||||
|
for(String computePath : computeShadersInQueue){
|
||||||
|
computeShadersInQueue.remove(computePath);
|
||||||
|
String key = getComputeShaderKey(computePath);
|
||||||
|
try {
|
||||||
|
computeShadersLoadedIntoMemory.put(
|
||||||
|
key,
|
||||||
|
ComputeShader.create(FileUtils.getAssetFileAsString(computePath))
|
||||||
|
);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
//pose models
|
//pose models
|
||||||
LoggerInterface.loggerEngine.DEBUG_LOOP("AssetManager - Load pose models");
|
LoggerInterface.loggerEngine.DEBUG_LOOP("AssetManager - Load pose models");
|
||||||
for(String currentPath: poseModelsInQueue){
|
for(String currentPath: poseModelsInQueue){
|
||||||
@ -416,6 +438,40 @@ public class AssetManager {
|
|||||||
shadersLoadedIntoMemory.clear();
|
shadersLoadedIntoMemory.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//SHADERS
|
||||||
|
//
|
||||||
|
/**
|
||||||
|
* Adds a compute shader to the queue to be loaded
|
||||||
|
* @param computePath The path to the source code for the shader
|
||||||
|
*/
|
||||||
|
public void addComputeShaderToQueue(String computePath){
|
||||||
|
computeShadersInQueue.add(getComputeShaderKey(computePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a compute shader
|
||||||
|
* @param computePath The path to the source code for the compute shader
|
||||||
|
* @return The compute shader if it exists, null otherwise
|
||||||
|
*/
|
||||||
|
public ComputeShader fetchComputeShader(String computePath){
|
||||||
|
String key = getComputeShaderKey(computePath);
|
||||||
|
ComputeShader rVal = null;
|
||||||
|
if(computeShadersLoadedIntoMemory.containsKey(key)){
|
||||||
|
rVal = computeShadersLoadedIntoMemory.get(key);
|
||||||
|
}
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the key for a compute shader
|
||||||
|
* @param computePath The path to the shader source
|
||||||
|
* @return The key
|
||||||
|
*/
|
||||||
|
static String getComputeShaderKey(String computePath){
|
||||||
|
return computePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import org.lwjgl.opengl.GL45;
|
|||||||
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.logger.LoggerInterface;
|
import electrosphere.logger.LoggerInterface;
|
||||||
|
import electrosphere.renderer.buffer.OpenGLBuffer;
|
||||||
import electrosphere.renderer.buffer.UniformBlockBinding;
|
import electrosphere.renderer.buffer.UniformBlockBinding;
|
||||||
import electrosphere.renderer.shader.Shader;
|
import electrosphere.renderer.shader.Shader;
|
||||||
import electrosphere.renderer.shader.ShaderProgram;
|
import electrosphere.renderer.shader.ShaderProgram;
|
||||||
@ -122,7 +123,7 @@ public class OpenGLState {
|
|||||||
* @return The viewport's dimensions
|
* @return The viewport's dimensions
|
||||||
*/
|
*/
|
||||||
public Vector2i getViewport(){
|
public Vector2i getViewport(){
|
||||||
return viewport;
|
return new Vector2i(viewport);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -333,13 +334,13 @@ public class OpenGLState {
|
|||||||
if(currentBuffer == null || currentBuffer != buffer){
|
if(currentBuffer == null || currentBuffer != buffer){
|
||||||
//does not already contain index, should bind
|
//does not already contain index, should bind
|
||||||
this.indexBlockMap.put(index,buffer);
|
this.indexBlockMap.put(index,buffer);
|
||||||
GL45.glBindBufferBase(index, index, buffer.getId());
|
GL45.glBindBufferBase(OpenGLBuffer.getTypeInt(buffer), index, buffer.getId());
|
||||||
Globals.renderingEngine.checkError();
|
Globals.renderingEngine.checkError();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//does not already contain index, should bind
|
//does not already contain index, should bind
|
||||||
this.indexBlockMap.put(index,buffer);
|
this.indexBlockMap.put(index,buffer);
|
||||||
GL45.glBindBufferBase(index, index, buffer.getId());
|
GL45.glBindBufferBase(OpenGLBuffer.getTypeInt(buffer), index, buffer.getId());
|
||||||
Globals.renderingEngine.checkError();
|
Globals.renderingEngine.checkError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -348,10 +349,10 @@ public class OpenGLState {
|
|||||||
* Unbinds a buffer from a given uniform buffer block index
|
* Unbinds a buffer from a given uniform buffer block index
|
||||||
* @param index the index
|
* @param index the index
|
||||||
*/
|
*/
|
||||||
public void glUnbindBufferBase(int index){
|
public void glUnbindBufferBase(int index, UniformBlockBinding buffer){
|
||||||
if(this.indexBlockMap.containsKey(index)){
|
if(this.indexBlockMap.containsKey(index)){
|
||||||
this.indexBlockMap.remove(index);
|
this.indexBlockMap.remove(index);
|
||||||
GL45.glBindBufferBase(index, index, UniformBlockBinding.UNBIND_ADDRESS);
|
GL45.glBindBufferBase(OpenGLBuffer.getTypeInt(buffer), index, UniformBlockBinding.UNBIND_ADDRESS);
|
||||||
Globals.renderingEngine.checkError();
|
Globals.renderingEngine.checkError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -415,7 +415,7 @@ public class RenderingEngine {
|
|||||||
|
|
||||||
|
|
||||||
//instantiate light manager
|
//instantiate light manager
|
||||||
lightManager = new LightManager();
|
lightManager = LightManager.create();
|
||||||
|
|
||||||
//
|
//
|
||||||
//Fog
|
//Fog
|
||||||
@ -452,8 +452,7 @@ public class RenderingEngine {
|
|||||||
verticalFOV = (float)(Globals.verticalFOV * Math.PI /180.0f);
|
verticalFOV = (float)(Globals.verticalFOV * Math.PI /180.0f);
|
||||||
//set local aspect ratio and global aspect ratio at the same time
|
//set local aspect ratio and global aspect ratio at the same time
|
||||||
aspectRatio = Globals.aspectRatio = Globals.WINDOW_WIDTH / (float)Globals.WINDOW_HEIGHT;
|
aspectRatio = Globals.aspectRatio = Globals.WINDOW_WIDTH / (float)Globals.WINDOW_HEIGHT;
|
||||||
float nearClip = 0.001f;
|
Globals.projectionMatrix.setPerspective(verticalFOV, Globals.aspectRatio, Globals.nearClip, Globals.userSettings.getGraphicsViewDistance());
|
||||||
Globals.projectionMatrix.setPerspective(verticalFOV, Globals.aspectRatio, nearClip, Globals.userSettings.getGraphicsViewDistance());
|
|
||||||
Globals.viewMatrix.translation(new Vector3f(0.0f,0.0f,-3.0f));
|
Globals.viewMatrix.translation(new Vector3f(0.0f,0.0f,-3.0f));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -489,7 +488,7 @@ public class RenderingEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Update light buffer
|
//Update light buffer
|
||||||
lightManager.updateData();
|
lightManager.update(renderPipelineState,openGLState,Globals.playerCamera);
|
||||||
checkError();
|
checkError();
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -223,7 +223,7 @@ public class StridedInstanceData implements InstanceData {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void upload(OpenGLState openGLState, RenderPipelineState renderPipelineState){
|
public void upload(OpenGLState openGLState, RenderPipelineState renderPipelineState){
|
||||||
this.buffer.upload();
|
this.buffer.upload(openGLState);
|
||||||
openGLState.glBindBufferBase(0, buffer);
|
openGLState.glBindBufferBase(0, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,9 +4,9 @@ import java.nio.ByteBuffer;
|
|||||||
|
|
||||||
import org.lwjgl.BufferUtils;
|
import org.lwjgl.BufferUtils;
|
||||||
import org.lwjgl.opengl.GL45;
|
import org.lwjgl.opengl.GL45;
|
||||||
import org.lwjgl.system.MemoryUtil;
|
|
||||||
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
|
import electrosphere.renderer.OpenGLState;
|
||||||
import electrosphere.renderer.buffer.BufferEnums.BufferAccess;
|
import electrosphere.renderer.buffer.BufferEnums.BufferAccess;
|
||||||
import electrosphere.renderer.buffer.BufferEnums.BufferUsage;
|
import electrosphere.renderer.buffer.BufferEnums.BufferUsage;
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ public class ShaderStorageBuffer implements UniformBlockBinding {
|
|||||||
Globals.renderingEngine.checkError();
|
Globals.renderingEngine.checkError();
|
||||||
GL45.glBindBuffer(GL45.GL_SHADER_STORAGE_BUFFER, id);
|
GL45.glBindBuffer(GL45.GL_SHADER_STORAGE_BUFFER, id);
|
||||||
Globals.renderingEngine.checkError();
|
Globals.renderingEngine.checkError();
|
||||||
GL45.glBufferData(GL45.GL_SHADER_STORAGE_BUFFER, MemoryUtil.NULL, BufferEnums.getBufferUsage(usage, access));
|
GL45.glBufferData(GL45.GL_SHADER_STORAGE_BUFFER, buffer, BufferEnums.getBufferUsage(usage, access));
|
||||||
Globals.renderingEngine.checkError();
|
Globals.renderingEngine.checkError();
|
||||||
GL45.glBindBuffer(GL45.GL_SHADER_STORAGE_BUFFER,id);
|
GL45.glBindBuffer(GL45.GL_SHADER_STORAGE_BUFFER,id);
|
||||||
Globals.renderingEngine.checkError();
|
Globals.renderingEngine.checkError();
|
||||||
@ -51,19 +51,21 @@ public class ShaderStorageBuffer implements UniformBlockBinding {
|
|||||||
/**
|
/**
|
||||||
* Uploads the java side buffer to opengl
|
* Uploads the java side buffer to opengl
|
||||||
*/
|
*/
|
||||||
public void upload(){
|
public void upload(OpenGLState openGLState){
|
||||||
long offset = 0;
|
long offset = 0;
|
||||||
//bind
|
if(buffer.limit() > buffer.position()){
|
||||||
GL45.glBindBuffer(GL45.GL_SHADER_STORAGE_BUFFER,id);
|
//bind
|
||||||
Globals.renderingEngine.checkError();
|
openGLState.glBindBufferBase(0, this);
|
||||||
|
Globals.renderingEngine.checkError();
|
||||||
|
|
||||||
//upload
|
//upload
|
||||||
GL45.glBufferSubData(GL45.GL_SHADER_STORAGE_BUFFER, offset, buffer);
|
GL45.glBufferSubData(OpenGLBuffer.getTypeInt(this), offset, buffer);
|
||||||
Globals.renderingEngine.checkError();
|
Globals.renderingEngine.checkError();
|
||||||
|
|
||||||
//unbind
|
//unbind
|
||||||
GL45.glBindBuffer(GL45.GL_SHADER_STORAGE_BUFFER,UNBIND_ADDRESS);
|
openGLState.glUnbindBufferBase(0, this);
|
||||||
Globals.renderingEngine.checkError();
|
Globals.renderingEngine.checkError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -10,64 +10,34 @@ public class DirectionalLight {
|
|||||||
//the direction of the light as a uniform vector
|
//the direction of the light as a uniform vector
|
||||||
Vector3f direction;
|
Vector3f direction;
|
||||||
|
|
||||||
//the ambient color
|
//the color
|
||||||
Vector3f ambient;
|
Vector3f color;
|
||||||
//the diffuse color
|
|
||||||
Vector3f diffuse;
|
|
||||||
//the specular color
|
|
||||||
Vector3f specular;
|
|
||||||
|
|
||||||
public void setDirection(Vector3f direction) {
|
public void setDirection(Vector3f direction) {
|
||||||
this.direction = direction;
|
this.direction = direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAmbient(Vector3f ambient) {
|
public void setColor(Vector3f color) {
|
||||||
this.ambient = ambient;
|
this.color = color;
|
||||||
}
|
|
||||||
|
|
||||||
public void setDiffuse(Vector3f diffuse) {
|
|
||||||
this.diffuse = diffuse;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSpecular(Vector3f specular) {
|
|
||||||
this.specular = specular;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3f getDirection() {
|
public Vector3f getDirection() {
|
||||||
return direction;
|
return direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3f getAmbient() {
|
public Vector3f getColor() {
|
||||||
return ambient;
|
return color;
|
||||||
}
|
|
||||||
|
|
||||||
public Vector3f getDiffuse() {
|
|
||||||
return diffuse;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector3f getSpecular() {
|
|
||||||
return specular;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DirectionalLight(Vector3f direction){
|
public DirectionalLight(Vector3f direction){
|
||||||
this.direction = direction;
|
this.direction = direction;
|
||||||
ambient = new Vector3f(0.05f, 0.05f, 0.05f);
|
color = new Vector3f(1.0f);
|
||||||
diffuse = new Vector3f(0.4f, 0.4f, 0.4f);
|
|
||||||
specular = new Vector3f(0.5f, 0.5f, 0.5f);
|
|
||||||
this.direction.normalize();
|
this.direction.normalize();
|
||||||
ambient.normalize();
|
|
||||||
diffuse.normalize();
|
|
||||||
specular.normalize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DirectionalLight(Vector3f direction, Vector3f color){
|
public DirectionalLight(Vector3f direction, Vector3f color){
|
||||||
this.direction = direction;
|
this.direction = direction;
|
||||||
ambient = new Vector3f( color.x * 0.05f, color.y * 0.05f, color.z * 0.05f);
|
this.color = new Vector3f(color);
|
||||||
diffuse = new Vector3f( color.x * 0.4f, color.y * 0.4f, color.z * 0.4f);
|
|
||||||
specular = new Vector3f(color.x * 0.5f, color.y * 0.5f, color.z * 0.5f);
|
|
||||||
this.direction.normalize();
|
this.direction.normalize();
|
||||||
ambient.normalize();
|
|
||||||
diffuse.normalize();
|
|
||||||
specular.normalize();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,300 +1,339 @@
|
|||||||
package electrosphere.renderer.light;
|
package electrosphere.renderer.light;
|
||||||
|
|
||||||
import static org.lwjgl.opengl.GL15.*;
|
|
||||||
import static org.lwjgl.opengl.GL31.GL_UNIFORM_BUFFER;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import org.joml.Matrix4d;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
import org.lwjgl.BufferUtils;
|
import org.joml.Vector3i;
|
||||||
import org.lwjgl.opengl.GL30;
|
|
||||||
import org.lwjgl.opengl.GL31;
|
|
||||||
|
|
||||||
import electrosphere.client.entity.camera.CameraEntityUtils;
|
import electrosphere.client.entity.camera.CameraEntityUtils;
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
|
import electrosphere.engine.assetmanager.AssetDataStrings;
|
||||||
|
import electrosphere.entity.Entity;
|
||||||
|
import electrosphere.entity.EntityCreationUtils;
|
||||||
import electrosphere.logger.LoggerInterface;
|
import electrosphere.logger.LoggerInterface;
|
||||||
import electrosphere.renderer.OpenGLState;
|
import electrosphere.renderer.OpenGLState;
|
||||||
import electrosphere.renderer.RenderingEngine;
|
import electrosphere.renderer.RenderPipelineState;
|
||||||
import electrosphere.renderer.shader.ShaderProgram;
|
import electrosphere.renderer.buffer.ShaderStorageBuffer;
|
||||||
|
import electrosphere.renderer.buffer.BufferEnums.BufferAccess;
|
||||||
|
import electrosphere.renderer.buffer.BufferEnums.BufferUsage;
|
||||||
|
import electrosphere.renderer.shader.ComputeShader;
|
||||||
|
import electrosphere.renderer.shader.MemoryBarrier;
|
||||||
|
import electrosphere.renderer.shader.MemoryBarrier.Barrier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages the light sources in the engine
|
* Manages the light sources in the engine
|
||||||
*/
|
*/
|
||||||
public class LightManager {
|
public class LightManager {
|
||||||
|
|
||||||
final static int BIND_POINT = 1;
|
/**
|
||||||
final static int POINT_LIGHT_COUNT = 10;
|
* Maximum number of lights per cluster
|
||||||
final static int BUFFER_SIZE = 1184;
|
*/
|
||||||
int uboIndex;
|
static final int MAX_LIGHTS_PER_CLUSTER = 100;
|
||||||
ByteBuffer dataBuffer;
|
|
||||||
|
|
||||||
//sun position (For shadow maps)
|
/**
|
||||||
Vector3f sunPosition = new Vector3f(0.2f,-1.0f,0.3f);
|
* Size of the light cluster structure
|
||||||
|
*/
|
||||||
|
static final int CLUSTER_STRUCT_SIZE = 16 + 16 + 4 + (4 * MAX_LIGHTS_PER_CLUSTER);
|
||||||
|
|
||||||
//lights
|
/**
|
||||||
DirectionalLight directionalLight;
|
* The width of the light cluster grid's x dimension
|
||||||
PointLight[] pointLights;
|
*/
|
||||||
|
public static final int LIGHT_CLUSTER_WIDTH_X = 12;
|
||||||
|
/**
|
||||||
|
* The width of the light cluster grid's y dimension
|
||||||
|
*/
|
||||||
|
public static final int LIGHT_CLUSTER_WIDTH_Y = 12;
|
||||||
|
/**
|
||||||
|
* The width of the light cluster grid's z dimension
|
||||||
|
*/
|
||||||
|
public static final int LIGHT_CLUSTER_WIDTH_Z = 24;
|
||||||
|
|
||||||
public LightManager(){
|
/**
|
||||||
|
* The size of a single point light struct
|
||||||
|
*/
|
||||||
|
static final int POINT_LIGHT_STRUCT_SIZE = 16 + 16 + 4 + 4 + 4 + 4;
|
||||||
|
|
||||||
//create data buffer
|
/**
|
||||||
dataBuffer = BufferUtils.createByteBuffer(BUFFER_SIZE);
|
* The maximum number of point lights
|
||||||
|
*/
|
||||||
|
static final int MAX_POINT_LIGHTS = 2048;
|
||||||
|
|
||||||
uboIndex = glGenBuffers();
|
/**
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, uboIndex);
|
* The size of the point light buffer
|
||||||
glBufferData(GL_UNIFORM_BUFFER, BUFFER_SIZE, GL_DYNAMIC_DRAW); // allocate 152 bytes of memory
|
*/
|
||||||
//set range to full size
|
static final int POINT_LIGHT_BUFFER_SIZE = POINT_LIGHT_STRUCT_SIZE * MAX_POINT_LIGHTS;
|
||||||
int offset = 0;
|
|
||||||
GL30.glBindBufferRange(GL_UNIFORM_BUFFER, BIND_POINT, uboIndex, offset, BUFFER_SIZE);
|
|
||||||
//unbind
|
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
|
||||||
|
|
||||||
//create directional light
|
/**
|
||||||
directionalLight = new DirectionalLight(new Vector3f(1,-1,0).normalize());
|
* The number of "threads" to run for light culling
|
||||||
directionalLight.setAmbient(new Vector3f(0.6f,0.6f,0.6f));
|
*/
|
||||||
directionalLight.setDiffuse(new Vector3f(0.3f,0.3f,0.3f));
|
static final int CULL_LOCAL_SIZE = 128;
|
||||||
directionalLight.setDirection(sunPosition);
|
|
||||||
directionalLight.setSpecular(new Vector3f(0.0f,0.0f,0.0f));
|
|
||||||
|
|
||||||
pointLights = new PointLight[POINT_LIGHT_COUNT];
|
/**
|
||||||
for(int i = 0; i < POINT_LIGHT_COUNT; i++){
|
* The number of work groups to dispatch for the light culling phase
|
||||||
pointLights[i] = new PointLight(new Vector3f(0,0,0),new Vector3f(0,0,0));
|
* !!note!! DISPATCH_LOCAL_COUNT * CULL_LOCAL_SIZE must equal (LIGHT_CLUSTER_WIDTH_X * LIGHT_CLUSTER_WIDTH_Y * LIGHT_CLUSTER_WIDTH_Z)
|
||||||
|
*/
|
||||||
|
static final int DISPATCH_LOCAL_COUNT = 27;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Size of the direct light buffer
|
||||||
|
*/
|
||||||
|
static final int DIRECT_LIGHT_BUFFER_SIZE = 12 + 12;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bind point for the cluster ssbo
|
||||||
|
*/
|
||||||
|
public static final int CLUSTER_SSBO_BIND_POINT = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bind point for the point light ssbo
|
||||||
|
*/
|
||||||
|
public static final int POINT_LIGHT_SSBO_BIND_POINT = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bind point for the direct light ssbo
|
||||||
|
*/
|
||||||
|
public static final int DIRECT_LIGHT_SSBO_BIND_POINT = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The cluster grid ssbo
|
||||||
|
Light cluster struct:
|
||||||
|
{
|
||||||
|
vec4 minPoint; //16 bytes
|
||||||
|
vec4 maxPoint; //16 bytes
|
||||||
|
unsigned int count; //4 bytes
|
||||||
|
unsigned int lightIndices[MAX_LIGHTS_PER_CLUSTER]; //assuming MAX_LIGHTS_PER_CLUSTER is 100, 400 bytes
|
||||||
|
}
|
||||||
|
Totals to 436 bytes
|
||||||
|
*/
|
||||||
|
ShaderStorageBuffer clusterGridSSBO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The map of all entities to point lights
|
||||||
|
*/
|
||||||
|
Map<Entity,PointLight> entityPointLightMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The buffer of all point light data
|
||||||
|
|
||||||
|
Point light struct:
|
||||||
|
{
|
||||||
|
vec4 position; //16 bytes
|
||||||
|
vec4 color; //16 bytes
|
||||||
|
float constant; //4 bytes
|
||||||
|
float linear; // 4 bytes
|
||||||
|
float quadratic; // 4 bytes
|
||||||
|
float radius; //4 bytes
|
||||||
}
|
}
|
||||||
|
|
||||||
pointLights[0].setAmbient(new Vector3f(0.924500f, 0.369800f, 0.092450f));
|
|
||||||
pointLights[0].setConstant(1.0f);
|
|
||||||
pointLights[0].setDiffuse(new Vector3f(0.924500f, 0.369800f, 0.092450f));
|
|
||||||
pointLights[0].setLinear(0.7f);
|
|
||||||
pointLights[0].setPosition(new Vector3f(1.0f,0.05f,1.0f));
|
|
||||||
pointLights[0].setQuadratic(1.8f);
|
|
||||||
pointLights[0].setSpecular(new Vector3f(0.0f,0.0f,0.0f));
|
|
||||||
|
|
||||||
// pointLights[0].setAmbient(new Vector3f(0.924500f, 0.369800f, 0.092450f));
|
*/
|
||||||
// pointLights[0].setConstant(1.0f);
|
ShaderStorageBuffer pointLightSSBO;
|
||||||
// pointLights[0].setDiffuse(new Vector3f(0.924500f, 0.369800f, 0.092450f));
|
|
||||||
// pointLights[0].setLinear(0.09f);
|
|
||||||
// pointLights[0].setPosition(new Vector3f(1.0f,0.05f,1.0f));
|
|
||||||
// pointLights[0].setQuadratic(0.032f);
|
|
||||||
// pointLights[0].setSpecular(new Vector3f(0.0f,0.0f,0.0f));
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The direct light ssbo
|
||||||
|
*
|
||||||
|
struct DirectLight {
|
||||||
|
vec3 direction; //12 bytes
|
||||||
|
vec3 color; //12 bytes
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
ShaderStorageBuffer dirLightSSBO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The directional light
|
||||||
|
*/
|
||||||
|
DirectionalLight directionalLight;
|
||||||
|
|
||||||
|
/**
|
||||||
/*
|
* Constructor
|
||||||
Vector3f lightLoc = new Vector3f(0.2f,-1.0f,0.3f);
|
*/
|
||||||
float temp[] = new float[3];
|
private LightManager(){
|
||||||
temp[0] = lightLoc.x;
|
|
||||||
temp[1] = lightLoc.y;
|
|
||||||
temp[2] = lightLoc.z;
|
|
||||||
glUniform3fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "dirLight.direction"), temp);
|
|
||||||
|
|
||||||
temp[0] = 0.4f;
|
|
||||||
temp[1] = 0.4f;
|
|
||||||
temp[2] = 0.4f;
|
|
||||||
glUniform3fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "dirLight.ambient"), temp);
|
|
||||||
|
|
||||||
temp[0] = 0.3f;
|
|
||||||
temp[1] = 0.3f;
|
|
||||||
temp[2] = 0.3f;
|
|
||||||
glUniform3fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "dirLight.diffuse"), temp);
|
|
||||||
|
|
||||||
temp[0] = 0.1f;
|
|
||||||
temp[1] = 0.1f;
|
|
||||||
temp[2] = 0.1f;
|
|
||||||
glUniform3fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "dirLight.specular"), temp);
|
|
||||||
|
|
||||||
temp[0] = 32f;
|
|
||||||
*/
|
|
||||||
|
|
||||||
//glBufferData(GL_UNIFORM_BUFFER, <my_data>, GL_STATIC_DRAW);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// HIGHER ORDER OBJECT MANIPULATION
|
|
||||||
//
|
|
||||||
//
|
|
||||||
|
|
||||||
public void setPointLight(PointLight light, int index){
|
|
||||||
pointLights[index] = light;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the directional light for this light manager
|
* Creates a light manager
|
||||||
* @return the directional light
|
* @return The light manager
|
||||||
|
*/
|
||||||
|
public static LightManager create(){
|
||||||
|
LightManager rVal = new LightManager();
|
||||||
|
|
||||||
|
//
|
||||||
|
//create the cluster ssbo
|
||||||
|
rVal.clusterGridSSBO = new ShaderStorageBuffer(
|
||||||
|
CLUSTER_STRUCT_SIZE * LIGHT_CLUSTER_WIDTH_X * LIGHT_CLUSTER_WIDTH_Y * LIGHT_CLUSTER_WIDTH_Z,
|
||||||
|
BufferUsage.STATIC,
|
||||||
|
BufferAccess.COPY
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
//create pointlight structures
|
||||||
|
rVal.entityPointLightMap = new HashMap<Entity,PointLight>();
|
||||||
|
rVal.pointLightSSBO = new ShaderStorageBuffer(POINT_LIGHT_BUFFER_SIZE, BufferUsage.DYNAMIC, BufferAccess.DRAW);
|
||||||
|
|
||||||
|
//create a shit ton of point lights
|
||||||
|
Random rand = new Random(0);
|
||||||
|
for(int i = 0; i < 500; i++){
|
||||||
|
PointLight newLight = new PointLight(new Vector3f(rand.nextFloat(32),rand.nextFloat(),rand.nextFloat(32)));
|
||||||
|
newLight.setRadius(1);
|
||||||
|
newLight.setColor(new Vector3f(rand.nextFloat(),rand.nextFloat(),rand.nextFloat()).normalize());
|
||||||
|
rVal.entityPointLightMap.put(EntityCreationUtils.createClientSpatialEntity(),newLight);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//create direct light ssbo
|
||||||
|
rVal.dirLightSSBO = new ShaderStorageBuffer(DIRECT_LIGHT_BUFFER_SIZE, BufferUsage.DYNAMIC, BufferAccess.DRAW);
|
||||||
|
rVal.directionalLight = new DirectionalLight(new Vector3f(0,-1,0));
|
||||||
|
rVal.directionalLight.setColor(new Vector3f(0.5f));
|
||||||
|
|
||||||
|
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the light culling clusters based on a camera
|
||||||
|
* @param renderPipelineState The render pipeline state
|
||||||
|
* @param openGLState The opengl state
|
||||||
|
* @param camera The camera
|
||||||
|
*/
|
||||||
|
private void computeLightCulling(RenderPipelineState renderPipelineState, OpenGLState openGLState, Entity camera){
|
||||||
|
|
||||||
|
openGLState.glViewport(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
|
||||||
|
|
||||||
|
//
|
||||||
|
//Build AABBs
|
||||||
|
ComputeShader clusterComp = Globals.assetManager.fetchComputeShader(AssetDataStrings.COMPUTE_LIGHT_CLUSTER);
|
||||||
|
if(clusterComp != null){
|
||||||
|
openGLState.setActiveShader(renderPipelineState, clusterComp);
|
||||||
|
clusterComp.setUniform(openGLState, "zNear", CameraEntityUtils.getNearClip(camera));
|
||||||
|
clusterComp.setUniform(openGLState, "zFar", CameraEntityUtils.getFarClip(camera));
|
||||||
|
clusterComp.setUniform(openGLState, "inverseProjection", new Matrix4d(Globals.projectionMatrix).invert());
|
||||||
|
clusterComp.setUniform(openGLState, "gridSize", new Vector3i(LIGHT_CLUSTER_WIDTH_X,LIGHT_CLUSTER_WIDTH_Y,LIGHT_CLUSTER_WIDTH_Z));
|
||||||
|
clusterComp.setUniform(openGLState, "screenDimensions", openGLState.getViewport());
|
||||||
|
|
||||||
|
clusterComp.dispatch(LIGHT_CLUSTER_WIDTH_X,LIGHT_CLUSTER_WIDTH_Y,LIGHT_CLUSTER_WIDTH_Z);
|
||||||
|
MemoryBarrier.glMemoryBarrier(Barrier.GL_SHADER_STORAGE_BARRIER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//cull lights
|
||||||
|
ComputeShader lightCull = Globals.assetManager.fetchComputeShader(AssetDataStrings.COMPUTE_LIGHT_CULL);
|
||||||
|
openGLState.setActiveShader(renderPipelineState, lightCull);
|
||||||
|
lightCull.setUniform(openGLState, "viewMatrix", Globals.viewMatrix);
|
||||||
|
|
||||||
|
int dispatchLocal = (LIGHT_CLUSTER_WIDTH_X * LIGHT_CLUSTER_WIDTH_Y * LIGHT_CLUSTER_WIDTH_Z) / CULL_LOCAL_SIZE;
|
||||||
|
lightCull.dispatch(dispatchLocal, ComputeShader.DEFAULT_LOCAL_SIZE, ComputeShader.DEFAULT_LOCAL_SIZE);
|
||||||
|
MemoryBarrier.glMemoryBarrier(Barrier.GL_SHADER_STORAGE_BARRIER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pushes latest data to buffers
|
||||||
|
*/
|
||||||
|
private void pushToBuffers(RenderPipelineState renderPipelineState, OpenGLState openGLState, Entity camera){
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
//push point lights
|
||||||
|
ByteBuffer pointLightBuffer = pointLightSSBO.getBuffer();
|
||||||
|
for(PointLight light : this.entityPointLightMap.values()){
|
||||||
|
if(i >= MAX_POINT_LIGHTS){
|
||||||
|
LoggerInterface.loggerRenderer.WARNING("CLOSE TO MAXIMUM NUMBER OF POINT LIGHTS!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
//position
|
||||||
|
Vector3f modifiedCameraPos = new Vector3f(light.getPosition()).sub(CameraEntityUtils.getCameraCenter(camera));
|
||||||
|
pointLightBuffer.putFloat(modifiedCameraPos.x);
|
||||||
|
pointLightBuffer.putFloat(modifiedCameraPos.y);
|
||||||
|
pointLightBuffer.putFloat(modifiedCameraPos.z);
|
||||||
|
pointLightBuffer.putFloat(1);
|
||||||
|
|
||||||
|
//
|
||||||
|
//color
|
||||||
|
pointLightBuffer.putFloat(light.getColor().x);
|
||||||
|
pointLightBuffer.putFloat(light.getColor().y);
|
||||||
|
pointLightBuffer.putFloat(light.getColor().z);
|
||||||
|
pointLightBuffer.putFloat(1);
|
||||||
|
|
||||||
|
//
|
||||||
|
//const
|
||||||
|
pointLightBuffer.putFloat(light.getConstant());
|
||||||
|
pointLightBuffer.putFloat(light.getLinear());
|
||||||
|
pointLightBuffer.putFloat(light.getQuadratic());
|
||||||
|
pointLightBuffer.putFloat(light.getRadius());
|
||||||
|
}
|
||||||
|
pointLightBuffer.flip();
|
||||||
|
pointLightSSBO.upload(openGLState);
|
||||||
|
|
||||||
|
//
|
||||||
|
//push direct light
|
||||||
|
ByteBuffer directLightBuffer = dirLightSSBO.getBuffer();
|
||||||
|
{
|
||||||
|
//
|
||||||
|
//direction
|
||||||
|
directLightBuffer.putFloat(directionalLight.getDirection().x);
|
||||||
|
directLightBuffer.putFloat(directionalLight.getDirection().y);
|
||||||
|
directLightBuffer.putFloat(directionalLight.getDirection().z);
|
||||||
|
|
||||||
|
//
|
||||||
|
//color
|
||||||
|
directLightBuffer.putFloat(directionalLight.getColor().x);
|
||||||
|
directLightBuffer.putFloat(directionalLight.getColor().y);
|
||||||
|
directLightBuffer.putFloat(directionalLight.getColor().z);
|
||||||
|
}
|
||||||
|
directLightBuffer.flip();
|
||||||
|
dirLightSSBO.upload(openGLState);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the light manager
|
||||||
|
* @param renderPipelineState The rendering state
|
||||||
|
* @param openGLState The opengl state
|
||||||
|
* @param camera The camera
|
||||||
|
*/
|
||||||
|
public void update(RenderPipelineState renderPipelineState, OpenGLState openGLState, Entity camera){
|
||||||
|
if(camera != null){
|
||||||
|
this.pushToBuffers(renderPipelineState, openGLState, camera);
|
||||||
|
this.computeLightCulling(renderPipelineState, openGLState, camera);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the cluster grid ssbo
|
||||||
|
* @return The cluster grid ssbo
|
||||||
|
*/
|
||||||
|
public ShaderStorageBuffer getClusterGridSSBO(){
|
||||||
|
return this.clusterGridSSBO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the point light ssbo
|
||||||
|
* @return The point light ssbo
|
||||||
|
*/
|
||||||
|
public ShaderStorageBuffer getPointLightSSBO(){
|
||||||
|
return this.pointLightSSBO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the direct light ssbo
|
||||||
|
* @return The direct light ssbo
|
||||||
|
*/
|
||||||
|
public ShaderStorageBuffer getDirectLightSSBO(){
|
||||||
|
return this.dirLightSSBO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the directional light
|
||||||
|
* @return The directional light
|
||||||
*/
|
*/
|
||||||
public DirectionalLight getDirectionalLight(){
|
public DirectionalLight getDirectionalLight(){
|
||||||
return this.directionalLight;
|
return directionalLight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// BUFFER MANAGEMENT
|
|
||||||
//
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call in each mesh / per each shader
|
|
||||||
* @param shaderIndex
|
|
||||||
*/
|
|
||||||
public void bindBuffer(OpenGLState openGLState){
|
|
||||||
//get position of lights object in shader
|
|
||||||
int bufferIndex = GL31.glGetUniformBlockIndex(openGLState.getActiveShader().getId(), "Lights");
|
|
||||||
int glErrorCode = Globals.renderingEngine.getError();
|
|
||||||
if(glErrorCode != 0){
|
|
||||||
LoggerInterface.loggerRenderer.DEBUG_LOOP(RenderingEngine.getErrorInEnglish(glErrorCode));
|
|
||||||
}
|
|
||||||
if(bufferIndex == ShaderProgram.INVALID_UNIFORM_NAME){
|
|
||||||
LoggerInterface.loggerRenderer.INFO("Tried to buffer light manager to shader that does not have it active.");
|
|
||||||
} else {
|
|
||||||
//bind that position to the slot '2'
|
|
||||||
GL31.glUniformBlockBinding(openGLState.getActiveShader().getId(), bufferIndex, BIND_POINT);
|
|
||||||
Globals.renderingEngine.checkError();
|
|
||||||
//bind our buffer to slot '2' as well
|
|
||||||
GL31.glBindBufferBase(GL_UNIFORM_BUFFER, BIND_POINT, uboIndex);
|
|
||||||
Globals.renderingEngine.checkError();
|
|
||||||
}
|
|
||||||
//alternatively if want to use range, do glBindBufferRange(GL_UNIFORM_BUFFER, 2, uboExampleBlock, 0, 152);
|
|
||||||
// Globals.renderingEngine.checkError();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call once per render loop to set buffer values
|
|
||||||
*/
|
|
||||||
public void updateData(){
|
|
||||||
putDataInBuffer();
|
|
||||||
bufferData();
|
|
||||||
}
|
|
||||||
|
|
||||||
void bufferData(){
|
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, uboIndex);
|
|
||||||
// int offset = 0;
|
|
||||||
glBufferData(GL_UNIFORM_BUFFER, dataBuffer, GL_DYNAMIC_DRAW);
|
|
||||||
// glBufferSubData(GL_UNIFORM_BUFFER, offset, dataBuffer);
|
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void putDataInBuffer(){
|
|
||||||
//implicitly flips
|
|
||||||
dataBuffer.clear();
|
|
||||||
|
|
||||||
//direct light
|
|
||||||
//vec3 dirLightDirection
|
|
||||||
dataBuffer.putFloat(directionalLight.direction.x);
|
|
||||||
dataBuffer.putFloat(directionalLight.direction.y);
|
|
||||||
dataBuffer.putFloat(directionalLight.direction.z);
|
|
||||||
dataBuffer.putFloat(0);
|
|
||||||
//vec3 dirLightAmbient
|
|
||||||
dataBuffer.putFloat(directionalLight.ambient.x);
|
|
||||||
dataBuffer.putFloat(directionalLight.ambient.y);
|
|
||||||
dataBuffer.putFloat(directionalLight.ambient.z);
|
|
||||||
dataBuffer.putFloat(0);
|
|
||||||
//vec3 dirLightDiffuse
|
|
||||||
dataBuffer.putFloat(directionalLight.diffuse.x);
|
|
||||||
dataBuffer.putFloat(directionalLight.diffuse.y);
|
|
||||||
dataBuffer.putFloat(directionalLight.diffuse.z);
|
|
||||||
dataBuffer.putFloat(0);
|
|
||||||
//vec3 dirLightSpecular
|
|
||||||
dataBuffer.putFloat(directionalLight.specular.x);
|
|
||||||
dataBuffer.putFloat(directionalLight.specular.y);
|
|
||||||
dataBuffer.putFloat(directionalLight.specular.z);
|
|
||||||
dataBuffer.putFloat(0);
|
|
||||||
|
|
||||||
//point light
|
|
||||||
//vec3 position[10]
|
|
||||||
//dont sub cam
|
|
||||||
// for(int i = 0; i < POINT_LIGHT_COUNT; i++){
|
|
||||||
// PointLight light = pointLights[i];
|
|
||||||
// dataBuffer.putFloat(light.position.x);
|
|
||||||
// dataBuffer.putFloat(light.position.y);
|
|
||||||
// dataBuffer.putFloat(light.position.z);
|
|
||||||
// dataBuffer.putFloat(0);
|
|
||||||
// }
|
|
||||||
//do sub cam
|
|
||||||
if(Globals.playerCamera != null){
|
|
||||||
Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera);
|
|
||||||
for(int i = 0; i < POINT_LIGHT_COUNT; i++){
|
|
||||||
PointLight light = pointLights[i];
|
|
||||||
dataBuffer.putFloat(light.position.x - cameraPos.x);
|
|
||||||
dataBuffer.putFloat(light.position.y - cameraPos.y);
|
|
||||||
dataBuffer.putFloat(light.position.z - cameraPos.z);
|
|
||||||
dataBuffer.putFloat(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//float constant[10]
|
|
||||||
for(int i = 0; i < POINT_LIGHT_COUNT; i++){
|
|
||||||
PointLight light = pointLights[i];
|
|
||||||
dataBuffer.putFloat(light.constant);
|
|
||||||
dataBuffer.putFloat(0);
|
|
||||||
dataBuffer.putFloat(0);
|
|
||||||
dataBuffer.putFloat(0);
|
|
||||||
}
|
|
||||||
//float linear[10]
|
|
||||||
for(int i = 0; i < POINT_LIGHT_COUNT; i++){
|
|
||||||
PointLight light = pointLights[i];
|
|
||||||
dataBuffer.putFloat(light.linear);
|
|
||||||
dataBuffer.putFloat(0);
|
|
||||||
dataBuffer.putFloat(0);
|
|
||||||
dataBuffer.putFloat(0);
|
|
||||||
}
|
|
||||||
//float quadratic[10]
|
|
||||||
for(int i = 0; i < POINT_LIGHT_COUNT; i++){
|
|
||||||
PointLight light = pointLights[i];
|
|
||||||
dataBuffer.putFloat(light.quadratic);
|
|
||||||
dataBuffer.putFloat(0);
|
|
||||||
dataBuffer.putFloat(0);
|
|
||||||
dataBuffer.putFloat(0);
|
|
||||||
}
|
|
||||||
//vec3 ambient[10]
|
|
||||||
for(int i = 0; i < POINT_LIGHT_COUNT; i++){
|
|
||||||
PointLight light = pointLights[i];
|
|
||||||
dataBuffer.putFloat(light.ambient.x);
|
|
||||||
dataBuffer.putFloat(light.ambient.y);
|
|
||||||
dataBuffer.putFloat(light.ambient.z);
|
|
||||||
dataBuffer.putFloat(0);
|
|
||||||
}
|
|
||||||
//vec3 diffuse[10]
|
|
||||||
for(int i = 0; i < POINT_LIGHT_COUNT; i++){
|
|
||||||
PointLight light = pointLights[i];
|
|
||||||
dataBuffer.putFloat(light.diffuse.x);
|
|
||||||
dataBuffer.putFloat(light.diffuse.y);
|
|
||||||
dataBuffer.putFloat(light.diffuse.z);
|
|
||||||
dataBuffer.putFloat(0);
|
|
||||||
}
|
|
||||||
//vec3 specular[10]
|
|
||||||
for(int i = 0; i < POINT_LIGHT_COUNT; i++){
|
|
||||||
PointLight light = pointLights[i];
|
|
||||||
dataBuffer.putFloat(light.specular.x);
|
|
||||||
dataBuffer.putFloat(light.specular.y);
|
|
||||||
dataBuffer.putFloat(light.specular.z);
|
|
||||||
dataBuffer.putFloat(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(dataBuffer.position() > 0){
|
|
||||||
dataBuffer.flip();
|
|
||||||
}
|
|
||||||
|
|
||||||
// dataBuffer.position(0);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -10,9 +10,8 @@ public class PointLight {
|
|||||||
float constant;
|
float constant;
|
||||||
float linear;
|
float linear;
|
||||||
float quadratic;
|
float quadratic;
|
||||||
Vector3f ambient;
|
float radius;
|
||||||
Vector3f diffuse;
|
Vector3f color;
|
||||||
Vector3f specular;
|
|
||||||
|
|
||||||
public void setPosition(Vector3f position) {
|
public void setPosition(Vector3f position) {
|
||||||
this.position = position;
|
this.position = position;
|
||||||
@ -30,16 +29,12 @@ public class PointLight {
|
|||||||
this.quadratic = quadratic;
|
this.quadratic = quadratic;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAmbient(Vector3f ambient) {
|
public void setRadius(float radius){
|
||||||
this.ambient = ambient;
|
this.radius = radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDiffuse(Vector3f diffuse) {
|
public void setColor(Vector3f color){
|
||||||
this.diffuse = diffuse;
|
this.color = color;
|
||||||
}
|
|
||||||
|
|
||||||
public void setSpecular(Vector3f specular) {
|
|
||||||
this.specular = specular;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3f getPosition() {
|
public Vector3f getPosition() {
|
||||||
@ -58,43 +53,29 @@ public class PointLight {
|
|||||||
return quadratic;
|
return quadratic;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3f getAmbient() {
|
public Vector3f getColor(){
|
||||||
return ambient;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3f getDiffuse() {
|
public float getRadius(){
|
||||||
return diffuse;
|
return radius;
|
||||||
}
|
|
||||||
|
|
||||||
public Vector3f getSpecular() {
|
|
||||||
return specular;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public PointLight(Vector3f position){
|
public PointLight(Vector3f position){
|
||||||
this.position = position;
|
this.position = position;
|
||||||
|
radius = 1;
|
||||||
constant = 1.0f;
|
constant = 1.0f;
|
||||||
linear = 0.01f;
|
linear = 0.7f;
|
||||||
quadratic = 0.01f;
|
quadratic = 1.8f;
|
||||||
ambient = new Vector3f(0.05f, 0.05f, 0.05f);
|
color = new Vector3f(1.0f);
|
||||||
diffuse = new Vector3f(0.8f, 0.8f, 0.8f);
|
|
||||||
specular = new Vector3f(1.0f, 1.0f, 1.0f);
|
|
||||||
this.position.normalize();
|
|
||||||
ambient.normalize();
|
|
||||||
diffuse.normalize();
|
|
||||||
specular.normalize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public PointLight(Vector3f position, Vector3f color){
|
public PointLight(Vector3f position, Vector3f color){
|
||||||
this.position = position;
|
this.position = position;
|
||||||
|
radius = 1;
|
||||||
constant = 1.0f;
|
constant = 1.0f;
|
||||||
linear = 0.01f;
|
linear = 0.7f;
|
||||||
quadratic = 0.01f;
|
quadratic = 1.8f;
|
||||||
ambient = new Vector3f(color.x * 0.05f, color.y * 0.05f, color.z * 0.05f);
|
this.color = color;
|
||||||
diffuse = new Vector3f(color.x * 0.8f, color.y * 0.8f, color.z * 0.8f);
|
|
||||||
specular = new Vector3f(color.x, color.y, color.z);
|
|
||||||
this.position.normalize();
|
|
||||||
ambient.normalize();
|
|
||||||
diffuse.normalize();
|
|
||||||
specular.normalize();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -21,6 +21,7 @@ import org.joml.Matrix4d;
|
|||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
import org.joml.Sphered;
|
import org.joml.Sphered;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
import org.joml.Vector3i;
|
||||||
import org.lwjgl.BufferUtils;
|
import org.lwjgl.BufferUtils;
|
||||||
import org.lwjgl.opengl.GL11;
|
import org.lwjgl.opengl.GL11;
|
||||||
import org.lwjgl.opengl.GL15;
|
import org.lwjgl.opengl.GL15;
|
||||||
@ -354,7 +355,16 @@ public class Mesh {
|
|||||||
//don't buffer as the light manager hasn't initialized
|
//don't buffer as the light manager hasn't initialized
|
||||||
} else {
|
} else {
|
||||||
LightManager lightManager = Globals.renderingEngine.getLightManager();
|
LightManager lightManager = Globals.renderingEngine.getLightManager();
|
||||||
lightManager.bindBuffer(openGLState);
|
openGLState.glBindBufferBase(LightManager.CLUSTER_SSBO_BIND_POINT, lightManager.getClusterGridSSBO());
|
||||||
|
openGLState.glBindBufferBase(LightManager.POINT_LIGHT_SSBO_BIND_POINT, lightManager.getPointLightSSBO());
|
||||||
|
openGLState.glBindBufferBase(LightManager.DIRECT_LIGHT_SSBO_BIND_POINT, lightManager.getDirectLightSSBO());
|
||||||
|
|
||||||
|
//set uniforms required
|
||||||
|
openGLState.getActiveShader().setUniform(openGLState, "zNear", CameraEntityUtils.getNearClip(Globals.playerCamera));
|
||||||
|
openGLState.getActiveShader().setUniform(openGLState, "zFar", CameraEntityUtils.getFarClip(Globals.playerCamera));
|
||||||
|
openGLState.getActiveShader().setUniform(openGLState, "gridSize", new Vector3i(LightManager.LIGHT_CLUSTER_WIDTH_X,LightManager.LIGHT_CLUSTER_WIDTH_Y,LightManager.LIGHT_CLUSTER_WIDTH_Z));
|
||||||
|
openGLState.getActiveShader().setUniform(openGLState, "screenDimensions", openGLState.getViewport());
|
||||||
|
|
||||||
}
|
}
|
||||||
Globals.renderingEngine.checkError();
|
Globals.renderingEngine.checkError();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,11 @@ import java.util.Map;
|
|||||||
|
|
||||||
import org.joml.Matrix4d;
|
import org.joml.Matrix4d;
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
|
import org.joml.Vector2d;
|
||||||
|
import org.joml.Vector2i;
|
||||||
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
import org.joml.Vector3i;
|
||||||
import org.lwjgl.BufferUtils;
|
import org.lwjgl.BufferUtils;
|
||||||
import org.lwjgl.opengl.GL40;
|
import org.lwjgl.opengl.GL40;
|
||||||
import org.lwjgl.opengl.GL45;
|
import org.lwjgl.opengl.GL45;
|
||||||
@ -21,6 +25,11 @@ import electrosphere.renderer.RenderingEngine;
|
|||||||
*/
|
*/
|
||||||
public class ComputeShader implements Shader {
|
public class ComputeShader implements Shader {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default local size
|
||||||
|
*/
|
||||||
|
public static final int DEFAULT_LOCAL_SIZE = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The id for the shader
|
* The id for the shader
|
||||||
*/
|
*/
|
||||||
@ -86,14 +95,7 @@ public class ComputeShader implements Shader {
|
|||||||
*/
|
*/
|
||||||
public void dispatch(int x, int y, int z){
|
public void dispatch(int x, int y, int z){
|
||||||
GL45.glDispatchCompute(x, y, z);
|
GL45.glDispatchCompute(x, y, z);
|
||||||
}
|
Globals.renderingEngine.checkError();
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the memory barrier value
|
|
||||||
* @param value The value
|
|
||||||
*/
|
|
||||||
public void memoryBarier(int value){
|
|
||||||
GL45.glMemoryBarrier(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -164,7 +166,39 @@ public class ComputeShader implements Shader {
|
|||||||
Vector3f currentUniform = (Vector3f)value;
|
Vector3f currentUniform = (Vector3f)value;
|
||||||
GL40.glUniform3fv(uniformLocation, currentUniform.get(BufferUtils.createFloatBuffer(3)));
|
GL40.glUniform3fv(uniformLocation, currentUniform.get(BufferUtils.createFloatBuffer(3)));
|
||||||
Globals.renderingEngine.checkError();
|
Globals.renderingEngine.checkError();
|
||||||
uniformMap.put(uniformLocation,new Vector3f(currentUniform)); //create new matrix4f to break pointer-matching with equals on cache check
|
uniformMap.put(uniformLocation,new Vector3f(currentUniform)); //create new vector3f to break pointer-matching with equals on cache check
|
||||||
|
|
||||||
|
//
|
||||||
|
//vector3d
|
||||||
|
} else if(value instanceof Vector3d){
|
||||||
|
Vector3d currentUniform = (Vector3d)value;
|
||||||
|
GL40.glUniform3dv(uniformLocation, currentUniform.get(BufferUtils.createDoubleBuffer(3)));
|
||||||
|
Globals.renderingEngine.checkError();
|
||||||
|
uniformMap.put(uniformLocation,new Vector3d(currentUniform)); //create new vector3d to break pointer-matching with equals on cache check
|
||||||
|
|
||||||
|
//
|
||||||
|
//vector2d
|
||||||
|
} else if(value instanceof Vector2d){
|
||||||
|
Vector2d currentUniform = (Vector2d)value;
|
||||||
|
GL40.glUniform2dv(uniformLocation, currentUniform.get(BufferUtils.createDoubleBuffer(2)));
|
||||||
|
Globals.renderingEngine.checkError();
|
||||||
|
uniformMap.put(uniformLocation,new Vector2d(currentUniform)); //create new vector2d to break pointer-matching with equals on cache check
|
||||||
|
|
||||||
|
//
|
||||||
|
//Vector3i
|
||||||
|
} else if(value instanceof Vector3i){
|
||||||
|
Vector3i currentUniform = (Vector3i)value;
|
||||||
|
GL40.glUniform3uiv(uniformLocation, currentUniform.get(BufferUtils.createIntBuffer(3)));
|
||||||
|
Globals.renderingEngine.checkError();
|
||||||
|
uniformMap.put(uniformLocation,new Vector3i(currentUniform)); //create new vector2d to break pointer-matching with equals on cache check
|
||||||
|
|
||||||
|
//
|
||||||
|
//Vector2i
|
||||||
|
} else if(value instanceof Vector2i){
|
||||||
|
Vector2i currentUniform = (Vector2i)value;
|
||||||
|
GL40.glUniform2uiv(uniformLocation, currentUniform.get(BufferUtils.createIntBuffer(2)));
|
||||||
|
Globals.renderingEngine.checkError();
|
||||||
|
uniformMap.put(uniformLocation,new Vector2i(currentUniform)); //create new vector2d to break pointer-matching with equals on cache check
|
||||||
|
|
||||||
//
|
//
|
||||||
//integer
|
//integer
|
||||||
|
|||||||
@ -2,6 +2,8 @@ package electrosphere.renderer.shader;
|
|||||||
|
|
||||||
import org.lwjgl.opengl.GL45;
|
import org.lwjgl.opengl.GL45;
|
||||||
|
|
||||||
|
import electrosphere.engine.Globals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Memory barrier operations
|
* Memory barrier operations
|
||||||
*/
|
*/
|
||||||
@ -152,7 +154,9 @@ public class MemoryBarrier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the memory barrier
|
* Sets the memory barrier.
|
||||||
|
* Essentially halts CPU execution until the given barrier is cleared.
|
||||||
|
* IE, if GL_SHADER_STORAGE_BARRIER_BIT is passed, the CPU will wait until the SSBO values are fully set before continuing execution.
|
||||||
* @param barrier The barrier to set
|
* @param barrier The barrier to set
|
||||||
*/
|
*/
|
||||||
public static void glMemoryBarrier(Barrier barrier){
|
public static void glMemoryBarrier(Barrier barrier){
|
||||||
@ -205,6 +209,7 @@ public class MemoryBarrier {
|
|||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
GL45.glMemoryBarrier(barrierVal);
|
GL45.glMemoryBarrier(barrierVal);
|
||||||
|
Globals.renderingEngine.checkError();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,7 +29,11 @@ import javax.management.RuntimeErrorException;
|
|||||||
|
|
||||||
import org.joml.Matrix4d;
|
import org.joml.Matrix4d;
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
|
import org.joml.Vector2d;
|
||||||
|
import org.joml.Vector2i;
|
||||||
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
import org.joml.Vector3i;
|
||||||
import org.lwjgl.BufferUtils;
|
import org.lwjgl.BufferUtils;
|
||||||
import org.lwjgl.opengl.GL20;
|
import org.lwjgl.opengl.GL20;
|
||||||
import org.lwjgl.opengl.GL40;
|
import org.lwjgl.opengl.GL40;
|
||||||
@ -704,6 +708,38 @@ public class ShaderProgram implements Shader {
|
|||||||
Globals.renderingEngine.checkError();
|
Globals.renderingEngine.checkError();
|
||||||
uniformMap.put(uniformLocation,new Vector3f(currentUniform)); //create new matrix4f to break pointer-matching with equals on cache check
|
uniformMap.put(uniformLocation,new Vector3f(currentUniform)); //create new matrix4f to break pointer-matching with equals on cache check
|
||||||
|
|
||||||
|
//
|
||||||
|
//vector3d
|
||||||
|
} else if(value instanceof Vector3d){
|
||||||
|
Vector3d currentUniform = (Vector3d)value;
|
||||||
|
GL40.glUniform3dv(uniformLocation, currentUniform.get(BufferUtils.createDoubleBuffer(3)));
|
||||||
|
Globals.renderingEngine.checkError();
|
||||||
|
uniformMap.put(uniformLocation,new Vector3d(currentUniform)); //create new vector3d to break pointer-matching with equals on cache check
|
||||||
|
|
||||||
|
//
|
||||||
|
//vector2d
|
||||||
|
} else if(value instanceof Vector2d){
|
||||||
|
Vector2d currentUniform = (Vector2d)value;
|
||||||
|
GL40.glUniform2dv(uniformLocation, currentUniform.get(BufferUtils.createDoubleBuffer(2)));
|
||||||
|
Globals.renderingEngine.checkError();
|
||||||
|
uniformMap.put(uniformLocation,new Vector2d(currentUniform)); //create new vector2d to break pointer-matching with equals on cache check
|
||||||
|
|
||||||
|
//
|
||||||
|
//Vector3i
|
||||||
|
} else if(value instanceof Vector3i){
|
||||||
|
Vector3i currentUniform = (Vector3i)value;
|
||||||
|
GL40.glUniform3uiv(uniformLocation, currentUniform.get(BufferUtils.createIntBuffer(3)));
|
||||||
|
Globals.renderingEngine.checkError();
|
||||||
|
uniformMap.put(uniformLocation,new Vector3i(currentUniform)); //create new vector2d to break pointer-matching with equals on cache check
|
||||||
|
|
||||||
|
//
|
||||||
|
//Vector2i
|
||||||
|
} else if(value instanceof Vector2i){
|
||||||
|
Vector2i currentUniform = (Vector2i)value;
|
||||||
|
GL40.glUniform2uiv(uniformLocation, currentUniform.get(BufferUtils.createIntBuffer(2)));
|
||||||
|
Globals.renderingEngine.checkError();
|
||||||
|
uniformMap.put(uniformLocation,new Vector2i(currentUniform)); //create new vector2d to break pointer-matching with equals on cache check
|
||||||
|
|
||||||
//
|
//
|
||||||
//integer
|
//integer
|
||||||
} else if(value instanceof Integer){
|
} else if(value instanceof Integer){
|
||||||
|
|||||||
@ -48,7 +48,7 @@ public class ShaderStorageBufferTests extends RenderingTestTemplate {
|
|||||||
public void test_upload_NoThrow(){
|
public void test_upload_NoThrow(){
|
||||||
assertDoesNotThrow(() -> {
|
assertDoesNotThrow(() -> {
|
||||||
ShaderStorageBuffer buffer = new ShaderStorageBuffer(10, BufferUsage.STATIC, BufferAccess.READ);
|
ShaderStorageBuffer buffer = new ShaderStorageBuffer(10, BufferUsage.STATIC, BufferAccess.READ);
|
||||||
buffer.upload();
|
buffer.upload(Globals.renderingEngine.getOpenGLState());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user