Volumetric rendering

This commit is contained in:
austin 2022-03-01 23:24:46 -05:00
parent 8b966838ef
commit 90aa9fb963
21 changed files with 745 additions and 488 deletions

View File

@ -1,165 +0,0 @@
#version 430 core
out vec4 FragColor;
struct Material {
sampler2D diffuse;
sampler2D specular;
float shininess;
};
struct DirLight {
vec3 direction;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
struct PointLight {
vec3 position;
float constant;
float linear;
float quadratic;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
struct SpotLight {
vec3 position;
vec3 direction;
float cutOff;
float outerCutOff;
float constant;
float linear;
float quadratic;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
#define NR_POINT_LIGHTS 4
in vec3 FragPos;
in vec3 Normal;
in vec2 TexCoords;
uniform int fragHasTexture;
uniform vec3 viewPos;
uniform DirLight dirLight;
uniform PointLight pointLights[NR_POINT_LIGHTS];
uniform SpotLight spotLight;
uniform Material material;
// function prototypes
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir);
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir);
vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir);
void main()
{
// properties
vec3 norm = normalize(Normal);
vec3 viewDir = normalize(viewPos - FragPos);
// == =====================================================
// Our lighting is set up in 3 phases: directional, point lights and an optional flashlight
// For each phase, a calculate function is defined that calculates the corresponding color
// per lamp. In the main() function we take all the calculated colors and sum them up for
// this fragment's final color.
// == =====================================================
// phase 1: directional lighting
vec3 result = CalcDirLight(dirLight, norm, viewDir);
// phase 2: point lights
//for(int i = 0; i < NR_POINT_LIGHTS; i++)
// result += CalcPointLight(pointLights[i], norm, FragPos, viewDir);
// phase 3: spot light
//result += CalcSpotLight(spotLight, norm, FragPos, viewDir);
FragColor = vec4(result, 1.0);
}
// calculates the color when using a directional light.
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir)
{
vec3 lightDir = normalize(-light.direction);
// 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 ambient = vec3(1.0,1.0,1.0);
vec3 diffuse = vec3(1.0,1.0,1.0);
vec3 specular = vec3(1.0,1.0,1.0);
if(fragHasTexture == 1){
ambient = light.ambient;// * vec3(texture(material.diffuse, TexCoords));
diffuse = light.diffuse * diff;// * vec3(texture(material.diffuse, TexCoords));
specular = light.specular * spec;// * vec3(texture(material.specular, TexCoords));
} else {
ambient = light.ambient;// * vec3(texture(material.diffuse, TexCoords));
diffuse = light.diffuse * diff;// * vec3(texture(material.diffuse, TexCoords));
specular = light.specular * spec;// * vec3(texture(material.specular, TexCoords));
}
//vec3 ambient = light.ambient;// * vec3(texture(material.diffuse, TexCoords));
//vec3 diffuse = light.diffuse * diff;// * vec3(texture(material.diffuse, TexCoords));
//vec3 specular = light.specular * spec;// * vec3(texture(material.specular, TexCoords));
return (ambient + diffuse);// + specular);
}
// calculates the color when using a point light.
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
{
vec3 lightDir = normalize(light.position - fragPos);
// 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);
// attenuation
float distance = length(light.position - fragPos);
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
// combine results
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
ambient *= attenuation;
diffuse *= attenuation;
specular *= attenuation;
return (ambient + diffuse + specular);
}
// calculates the color when using a spot light.
vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
{
vec3 lightDir = normalize(light.position - fragPos);
// 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);
// attenuation
float distance = length(light.position - fragPos);
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
// spotlight intensity
float theta = dot(lightDir, normalize(-light.direction));
float epsilon = light.cutOff - light.outerCutOff;
float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0);
// combine results
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
ambient *= attenuation * intensity;
diffuse *= attenuation * intensity;
specular *= attenuation * intensity;
return (ambient + diffuse + specular);
}

View File

@ -1,97 +0,0 @@
//Vertex Shader
#version 430 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec4 aWeights;
layout (location = 3) in vec4 aIndex;
layout (location = 4) in vec2 aText;
uniform mat4 transform;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
const int MAX_BONES = 100;
uniform mat4 bones[MAX_BONES];
uniform int hasBones;
uniform int numBones;
uniform int hasTexture;
out vec3 Normal;
out vec3 FragPos;
out vec2 TexCoords;
void main()
{
vec4 FinalVertex = vec4(aPos, 1.0);
vec4 FinalNormal = vec4(aNormal, 0.0);
if(hasBones == 1){
//mat4 BoneTransform;
//for(int i = 0; i < MAX_BONES; i++){
// if(i < numBones){
// BoneTransform += bones[i] * aWeights[i];
// }
//}
//vec4 FinalVertex = vec4(aPos, 1.0);
//vec4 FinalNormal = vec4(aNormal, 1.0);
//mat4 BoneTransform;
//BoneTransform = mat4(
// 1.0,0.0,0.0,0.0,
// 0.0,1.0,0.0,0.0,
// 0.0,0.0,1.0,0.0,
// 0.0,0.0,0.0,1.0);
//BoneTransform = BoneTransform * mat4(
// 1.0,0.0,0.0,0.0,
// 0.0,1.0,0.0,0.0,
// 0.0,0.0,2.0,0.0,
// 0.0,0.0,0.0,1.0);
//BoneTransform = BoneTransform * bones[aIndex[0]] * aWeights[0];
//BoneTransform += bones[aIndex[0]] * 1.0;
//BoneTransform += bones[aIndex[1]] * aWeights[1];
//BoneTransform += bones[aIndex[2]] * aWeights[2];
//BoneTransform += bones[aIndex[3]] * aWeights[3];
//FinalVertex = BoneTransform * FinalVertex;
vec4 inputVertex = FinalVertex;
vec4 inputNormal = FinalNormal;
//mat4 BoneTransform;
//BoneTransform = bones[int(aIndex[0])] * aWeights[0];
//BoneTransform += bones[int(aIndex[1])] * aWeights[1];
//BoneTransform += bones[int(aIndex[2])] * aWeights[2];
//BoneTransform += bones[int(aIndex[3])] * aWeights[3];
//FinalVertex = BoneTransform * inputVertex;
//FinalNormal = BoneTransform * inputNormal;
FinalVertex = (bones[int(aIndex[0])] * inputVertex) * aWeights[0];
FinalVertex = (bones[int(aIndex[1])] * inputVertex) * aWeights[1] + FinalVertex;
FinalVertex = (bones[int(aIndex[2])] * inputVertex) * aWeights[2] + FinalVertex;
FinalVertex = (bones[int(aIndex[3])] * inputVertex) * aWeights[3] + FinalVertex;
FinalNormal = (bones[int(aIndex[0])] * inputNormal) * aWeights[0];
FinalNormal = (bones[int(aIndex[1])] * inputNormal) * aWeights[1] + FinalNormal;
FinalNormal = (bones[int(aIndex[2])] * inputNormal) * aWeights[2] + FinalNormal;
FinalNormal = (bones[int(aIndex[3])] * inputNormal) * aWeights[3] + FinalNormal;
} else {
//gl_Position = projection * view * model * vec4(aPos, 1.0);
}
vec2 FinalTexture = vec2(1.0,1.0);
if(hasTexture == 1){
FinalTexture = aText;
}
TexCoords = FinalTexture;
FragPos = vec3(model * FinalVertex);
Normal = vec3(transpose(inverse(model)) * FinalNormal);
gl_Position = projection * view * model * FinalVertex;
}

View File

@ -0,0 +1,255 @@
/*
MIT License
Copyright (c) 2022 railgunSR
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
/*
THIS MAKES USE OF OPENSIMPLEX2, A NOISE ALGORITHM CREATED BY THE FINE FOLKS
OVER AT https://github.com/KdotJPG/OpenSimplex2
PLEASE GIVE THEM SOME LOVE.
THE FLAME FUNCTION IS ONE CREATED BY ME BLENDING A LOG2 INTO A EXPONENTIAL.
*/
//version
#version 330 core
//macros
#extension GL_ARB_explicit_uniform_location : enable
//output
out vec4 fragColor;
//input
in vec3 FragPos;
in vec3 Normal;
in vec2 TexCoord;
in vec4 projCoord;
//uniforms
uniform float time;
//layout uniforms
layout (location = 5) uniform sampler2D volumeDepthFrontface;
layout (location = 6) uniform sampler2D volumeDepthBackface;
//function declarations
vec4 openSimplex2_ImproveXY(vec3 X);
float flameTex(float x, float y);
/*
Main method
*/
void main(){
float timeS = time * 0.003;
// Normalized pixel coordinates (from 0 to 1)
// vec2 uv = vec2(TexCoord.x,TexCoord.y);
vec3 projCoordNorm = projCoord.xyz / projCoord.w / 2.0 + 0.5;
// vec2 finalProd = vec2((projCoord.x + 1.0)/2.0, (projCoord.y + 1.0)/2.0);
vec2 finalProd = projCoordNorm.xy;
// float closeDepth = texture(volumeDepthFrontface, projCoordNorm.xy).r;
// float farDepth = texture(volumeDepthBackface, projCoordNorm.xy).r;
float closeDepth = texture(volumeDepthFrontface, finalProd.xy).r;
float farDepth = texture(volumeDepthBackface, finalProd.xy).r;
// float closeDepth = texture(volumeDepthFrontface, uv).r;
// float farDepth = texture(volumeDepthBackface, uv).r;
float dist = farDepth - closeDepth;
float red = 0;
float green = 0;
float blue = 0;
// if(projCoordNorm.x > -0.4 && projCoordNorm.x < 0.6 && projCoordNorm.y > -0.4 && projCoordNorm.y < 0.1){
// dist = 0.1;
// green = 1;
// blue = closeDepth;
// }
// if(closeDepth != 1){
// blue = 1;
// }
// val = dist;
// red = projCoordNorm.x;
// green = projCoordNorm.y;
// blue = 0;
// if(mod(TexCoord.x,0.01) < 0.005){
// red = 1;
// }
// if(mod(TexCoord.y,0.01) < 0.005){
// green = 1;
// }
// if(dist != 0){
// red = 1;
// green = 1;
// blue = 1;
// }
red = dist;
green = dist;
blue = dist;
vec4 color = vec4(
red,
green,
blue,
1.0
);
// if(val < 0.3){
// discard;
// }
// Output to screen
fragColor = color;
}
//
//custom flame function
///
float flameTex(float x, float y){
//flip y
float t = 1.0 - y;
//calculate vertical component
float verticalFlameValue = pow(log(t+1.0),1.4) - step(0.5,t) * (pow((2.0 * (t - 0.5)),3.0) / pow(log(2.0),1.4));
//calculate dist along horizontal from vertical component
float dist = abs(x-0.5);
//want to fade to nothing at dist >= vertical flame value
//use exponent to get there
//clamp range with min
float v = max(2.0 * (verticalFlameValue - dist),0.0);
//apply exponent to get value
float rVal = pow(v,1.4);
return rVal;
}
//////////////// K.jpg's Re-oriented 4-Point BCC Noise (OpenSimplex2) ////////////////
////////////////////// Output: vec4(dF/dx, dF/dy, dF/dz, value) //////////////////////
// Inspired by Stefan Gustavson's noise
vec4 permute(vec4 t) {
return t * (t * 34.0 + 133.0);
}
// Gradient set is a normalized expanded rhombic dodecahedron
vec3 grad(float hash) {
// Random vertex of a cube, +/- 1 each
vec3 cube = mod(floor(hash / vec3(1.0, 2.0, 4.0)), 2.0) * 2.0 - 1.0;
// Random edge of the three edges connected to that vertex
// Also a cuboctahedral vertex
// And corresponds to the face of its dual, the rhombic dodecahedron
vec3 cuboct = cube;
cuboct[int(hash / 16.0)] = 0.0;
// In a funky way, pick one of the four points on the rhombic face
float type = mod(floor(hash / 8.0), 2.0);
vec3 rhomb = (1.0 - type) * cube + type * (cuboct + cross(cube, cuboct));
// Expand it so that the new edges are the same length
// as the existing ones
vec3 grad = cuboct * 1.22474487139 + rhomb;
// To make all gradients the same length, we only need to shorten the
// second type of vector. We also put in the whole noise scale constant.
// The compiler should reduce it into the existing floats. I think.
grad *= (1.0 - 0.042942436724648037 * type) * 32.80201376986577;
return grad;
}
// BCC lattice split up into 2 cube lattices
vec4 openSimplex2Base(vec3 X) {
// First half-lattice, closest edge
vec3 v1 = round(X);
vec3 d1 = X - v1;
vec3 score1 = abs(d1);
vec3 dir1 = step(max(score1.yzx, score1.zxy), score1);
vec3 v2 = v1 + dir1 * sign(d1);
vec3 d2 = X - v2;
// Second half-lattice, closest edge
vec3 X2 = X + 144.5;
vec3 v3 = round(X2);
vec3 d3 = X2 - v3;
vec3 score2 = abs(d3);
vec3 dir2 = step(max(score2.yzx, score2.zxy), score2);
vec3 v4 = v3 + dir2 * sign(d3);
vec3 d4 = X2 - v4;
// Gradient hashes for the four points, two from each half-lattice
vec4 hashes = permute(mod(vec4(v1.x, v2.x, v3.x, v4.x), 289.0));
hashes = permute(mod(hashes + vec4(v1.y, v2.y, v3.y, v4.y), 289.0));
hashes = mod(permute(mod(hashes + vec4(v1.z, v2.z, v3.z, v4.z), 289.0)), 48.0);
// Gradient extrapolations & kernel function
vec4 a = max(0.5 - vec4(dot(d1, d1), dot(d2, d2), dot(d3, d3), dot(d4, d4)), 0.0);
vec4 aa = a * a; vec4 aaaa = aa * aa;
vec3 g1 = grad(hashes.x); vec3 g2 = grad(hashes.y);
vec3 g3 = grad(hashes.z); vec3 g4 = grad(hashes.w);
vec4 extrapolations = vec4(dot(d1, g1), dot(d2, g2), dot(d3, g3), dot(d4, g4));
// Derivatives of the noise
vec3 derivative = -8.0 * mat4x3(d1, d2, d3, d4) * (aa * a * extrapolations)
+ mat4x3(g1, g2, g3, g4) * aaaa;
// Return it all as a vec4
return vec4(derivative, dot(aaaa, extrapolations));
}
// Use this if you don't want Z to look different from X and Y
vec4 openSimplex2_Conventional(vec3 X) {
// Rotate around the main diagonal. Not a skew transform.
vec4 result = openSimplex2Base(dot(X, vec3(2.0/3.0)) - X);
return vec4(dot(result.xyz, vec3(2.0/3.0)) - result.xyz, result.w);
}
// Use this if you want to show X and Y in a plane, then use Z for time, vertical, etc.
vec4 openSimplex2_ImproveXY(vec3 X) {
// Rotate so Z points down the main diagonal. Not a skew transform.
mat3 orthonormalMap = mat3(
0.788675134594813, -0.211324865405187, -0.577350269189626,
-0.211324865405187, 0.788675134594813, -0.577350269189626,
0.577350269189626, 0.577350269189626, 0.577350269189626);
vec4 result = openSimplex2Base(orthonormalMap * X);
return vec4(result.xyz * orthonormalMap, result.w);
}
//////////////////////////////// End noise code ////////////////////////////////

View File

@ -0,0 +1,43 @@
//Vertex Shader
#version 330 core
//input buffers
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 4) in vec2 aTex;
//coordinate space transformation matrices
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform float time;
//output buffers
out vec3 FragPos;
out vec3 Normal;
out vec2 TexCoord;
out vec4 projCoord;
void main() {
//normalize posiiton and normal
vec4 FinalVertex = vec4(aPos, 1.0);
vec4 FinalNormal = vec4(aNormal, 1.0);
//push frag, normal, and texture positions to fragment shader
FragPos = vec3(model * FinalVertex);
Normal = mat3(transpose(inverse(model))) * aNormal;
TexCoord = aTex;
projCoord = projection * view * model * FinalVertex;
//set final position with opengl space
gl_Position = projection * view * model * FinalVertex;
}

View File

@ -1,13 +0,0 @@
//Fragment Shader
#version 330 core
out vec4 FragColor;
uniform vec3 objectColor;
uniform vec3 lightColor;
void main()
{
FragColor = vec4(1.0);
}

View File

@ -1,68 +0,0 @@
//Vertex Shader
#version 430 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec4 aWeights;
layout (location = 3) in ivec4 aIndex;
uniform mat4 transform;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
const int MAX_BONES = 100;
uniform mat4 bones[MAX_BONES];
uniform int hasBones;
uniform int numBones;
out vec3 Normal;
out vec3 FragPos;
out vec2 TexCoords;
void main()
{
if(hasBones == 1){
//mat4 BoneTransform;
//for(int i = 0; i < MAX_BONES; i++){
// if(i < numBones){
// BoneTransform += bones[i] * aWeights[i];
// }
//}
mat4 BoneTransform;
BoneTransform = mat4(
1.0,0.0,0.0,0.0,
0.0,1.0,0.0,0.0,
0.0,0.0,1.0,0.0,
0.0,0.0,0.0,1.0);
//BoneTransform = BoneTransform * mat4(
// 1.0,0.0,0.0,0.0,
// 0.0,1.0,0.0,0.0,
// 0.0,0.0,2.0,0.0,
// 0.0,0.0,0.0,1.0);
BoneTransform = BoneTransform * bones[aIndex[0]] * aWeights[0];
BoneTransform += BoneTransform * bones[aIndex[1]] * aWeights[1];
BoneTransform += BoneTransform * bones[aIndex[2]] * aWeights[2];
BoneTransform += BoneTransform * bones[aIndex[3]] * aWeights[3];
//BoneTransform += bones[aIndex[0]] * 1.0;
//BoneTransform += bones[aIndex[1]] * aWeights[1];
//BoneTransform += bones[aIndex[2]] * aWeights[2];
//BoneTransform += bones[aIndex[3]] * aWeights[3];
gl_Position = projection * view * model * BoneTransform * vec4(aPos, 1.0);
} else {
gl_Position = projection * view * model * vec4(aPos, 1.0);
}
FragPos = vec3(model * vec4(aPos, 1.0));
Normal = vec3(vec4(aNormal, 1.0));
TexCoords = vec2(0.5, 0.5);
}

View File

@ -1,61 +0,0 @@
//Vertex Shader
#version 330 core
layout (location = 0) in vec3 aPos;
//layout (location = 1) in vec3 aColor;
//layout (location = 1) in vec2 aTexCoord;
//layout (location = 2) in vec3 aNormal;
//out vec3 ourColor;
//uniform vec3 offset;
uniform mat4 transform;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
//out vec3 ourPos;
//out vec2 TexCoord;
//out vec3 FragPos;
//out vec3 Normal;
void main()
{
//gl_Position = vec4(aPos, 1.0);
gl_Position = projection * view * model * vec4(aPos, 1.0);
//ourColor = aColor;
//FragPos = vec3(model * vec4(aPos, 1.0));
//TexCoord = aTexCoord;
//Normal = mat3(transpose(inverse(model))) * aNormal;
}
//Fragment Shader
#version 330 core
out vec4 FragColor;
//in vec3 ourColor;
//in vec2 TexCoord;
//uniform sampler2D ourTexture1;
//uniform sampler2D ourTexture2;
//in vec3 Normal;
//uniform vec3 lightPos;
//in vec3 FragPos;
void main()
{
//vec3 lightColor = vec3(1.0, 1.0, 1.0);
//vec3 norm = normalize(Normal);
//vec3 lightDir = normalize(lightPos - FragPos);
//float diff = max(dot(Normal, lightDir), 0.0);
//vec3 diffuse = diff * lightColor;
//vec3 result = diffuse * objectColor;
//FragColor = mix(texture(ourTexture1, TexCoord), texture(ourTexture2, TexCoord), 0.2);// - (vec4(diffuse, 1.0)*0.2);// * vec4(ourColor, 1.0);
FragColor = vec4(0.5, 0.5, 0.5, 1.0);
}

View File

@ -1,34 +0,0 @@
//Fragment Shader
#version 330 core
in vec3 FragPos;
in vec3 Normal;
uniform vec3 objectColor;
uniform vec3 lightColor;
uniform vec3 lightPos;
uniform vec3 viewPos;
out vec4 FragColor;
void main()
{
//Diffuse calculations..
vec3 norm = normalize(Normal);
vec3 lightDir = normalize(lightPos - FragPos);
float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = diff * lightColor;
//Ambient Light
float ambientStrength = 0.5;
vec3 ambient = ambientStrength * lightColor;
//Specular calculations..
float specularStrength = 0.5;
vec3 viewDir = normalize(viewPos - FragPos);
vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
vec3 specular = specularStrength * spec * lightColor;
//result color
vec3 result = (ambient + diffuse + specular) * objectColor;
//push output color
FragColor = vec4(result, 1.0);
}

View File

@ -0,0 +1,37 @@
#version 330 core
uniform float linearCoef;
uniform float quadCoef;
uniform float near;
uniform float far;
float LinearizeDepth(float depth);
void main(){
// float coord = gl_FragCoord.x;
// if(coord != 1){
// gl_FragDepth = 0;
// } else {
// gl_FragDepth = 1;
// }
float depthRaw = gl_FragCoord.z;
// if(depthRaw != 1){
// depthRaw = 0;
// }
float finalValue = LinearizeDepth(depthRaw) / sqrt(far);//min(depthRaw * linearCoef + depthRaw * depthRaw * quadCoef,1);
gl_FragDepth = finalValue;
}
//
//Util
//
float LinearizeDepth(float depth){
float z = depth * 2.0 - 1.0; // back to NDC
return (2.0 * near * far) / (far + near - z * (far - near));
}

View File

@ -0,0 +1,40 @@
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 2) in vec4 aWeights;
layout (location = 3) in vec4 aIndex;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
//bone related variables
const int MAX_WEIGHTS = 4;
const int MAX_BONES = 100;
uniform mat4 bones[MAX_BONES];
uniform int numBones;
uniform int hasBones;
void main()
{
//calculate bone transform
mat4 BoneTransform = (bones[int(aIndex[0])] * aWeights[0]);
BoneTransform = BoneTransform + (bones[int(aIndex[1])] * aWeights[1]);
BoneTransform = BoneTransform + (bones[int(aIndex[2])] * aWeights[2]);
BoneTransform = BoneTransform + (bones[int(aIndex[3])] * aWeights[3]);
//apply bone transform to position vectors
vec4 FinalVertex = BoneTransform * vec4(aPos, 1.0);
//make sure the W component is 1.0
FinalVertex = vec4(FinalVertex.xyz, 1.0);
//have to account for if dont have bones
if(hasBones == 0){
FinalVertex = vec4(aPos, 1.0);
}
gl_Position = projection * view * model * FinalVertex;
}

View File

@ -24,6 +24,7 @@ import electrosphere.menu.WindowStrings;
import electrosphere.menu.WindowUtils;
import electrosphere.menu.MenuCallbacks;
import electrosphere.menu.MenuGenerators;
import electrosphere.renderer.RenderingEngine;
import electrosphere.renderer.ui.DrawableElement;
import electrosphere.renderer.ui.Element;
import electrosphere.renderer.ui.Window;
@ -765,10 +766,12 @@ public class ControlHandler {
void setInGameDebugControls(){
mainGameDebugControlList.add(controls.get(DATA_STRING_INPUT_CODE_DEBUG_SPAWN_ITEM));
controls.get(DATA_STRING_INPUT_CODE_DEBUG_SPAWN_ITEM).setOnPress(new ControlMethod(){public void execute(){
Entity bow = ItemUtils.spawnBasicItem("shorts1");
EntityUtils.getPosition(bow).set(1, 5, 2);
CollisionObjUtils.positionCharacter(bow, new Vector3f(1, 5, 2));
RenderingEngine.incrementOutputFramebuffer();
// Entity bow = ItemUtils.spawnBasicItem("shorts1");
// EntityUtils.getPosition(bow).set(1, 5, 2);
// CollisionObjUtils.positionCharacter(bow, new Vector3f(1, 5, 2));
}});
// RenderingEngine.incrementOutputFramebuffer();
}
void setMenuNavigationControls(){

View File

@ -3,6 +3,7 @@ package electrosphere.engine;
import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.controls.ControlHandler;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.ApplyRotationTree;
import electrosphere.game.collision.CollisionEngine;
@ -40,10 +41,13 @@ import electrosphere.menu.WindowUtils;
import electrosphere.net.NetUtils;
import electrosphere.net.client.ClientNetworking;
import electrosphere.net.server.Server;
import electrosphere.renderer.Mesh;
import electrosphere.renderer.Model;
import electrosphere.renderer.RenderUtils;
import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.actor.ActorTextureMask;
import electrosphere.renderer.actor.ActorUtils;
import electrosphere.renderer.texture.Texture;
import electrosphere.engine.assetmanager.AssetDataStrings;
import electrosphere.game.client.targeting.crosshair.Crosshair;
import electrosphere.game.server.ai.creature.OpportunisticAttacker;
@ -55,6 +59,8 @@ import electrosphere.renderer.ui.DrawableElement;
import electrosphere.renderer.ui.WidgetUtils;
import electrosphere.renderer.ui.Window;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
@ -679,36 +685,28 @@ public class LoadingThread extends Thread {
Actor fireActor = EntityUtils.getActor(fire);
fireActor.maskShader("particleBillboard", "Shaders/flame1/flame.vs", "Shaders/flame1/flame.fs");
Globals.assetManager.addShaderToQueue("Shaders/flame1/flame.vs", "Shaders/flame1/flame.fs");
//corner flame 1
fire = ParticleUtils.spawnStaticBillboardParticle();
EntityUtils.getPosition(fire).set(new Vector3f(1.05f,0.1f,0.95f));
EntityUtils.getScale(fire).set(0.4f);
fireActor = EntityUtils.getActor(fire);
fireActor.maskShader("particleBillboard", "Shaders/flame1/flame.vs", "Shaders/flame1/flame.fs");
//corner flame 2
fire = ParticleUtils.spawnStaticBillboardParticle();
EntityUtils.getPosition(fire).set(new Vector3f(1.05f,0.1f,1.05f));
EntityUtils.getScale(fire).set(0.4f);
fireActor = EntityUtils.getActor(fire);
fireActor.maskShader("particleBillboard", "Shaders/flame1/flame.vs", "Shaders/flame1/flame.fs");
//corner flame 3
fire = ParticleUtils.spawnStaticBillboardParticle();
EntityUtils.getPosition(fire).set(new Vector3f(0.95f,0.1f,0.95f));
EntityUtils.getScale(fire).set(0.4f);
fireActor = EntityUtils.getActor(fire);
fireActor.maskShader("particleBillboard", "Shaders/flame1/flame.vs", "Shaders/flame1/flame.fs");
//corner flame 4
fire = ParticleUtils.spawnStaticBillboardParticle();
EntityUtils.getPosition(fire).set(new Vector3f(0.95f,0.1f,1.05f));
EntityUtils.getScale(fire).set(0.4f);
fireActor = EntityUtils.getActor(fire);
fireActor.maskShader("particleBillboard", "Shaders/flame1/flame.vs", "Shaders/flame1/flame.fs");
//campfire
Entity campfire = EntityUtils.spawnDrawableEntity("Models/campfire1.fbx");
EntityUtils.getPosition(campfire).set(1,0,1);
EntityUtils.getRotation(campfire).rotationX(-(float)Math.PI/2.0f);
Entity cube = EntityUtils.spawnDrawableEntity("Models/unitcube.fbx");
//shader mask
EntityUtils.getActor(cube).maskShader("Cube", "Shaders/flame2/flame.vs", "Shaders/flame2/flame.fs");
Globals.assetManager.addShaderToQueue("Shaders/flame2/flame.vs", "Shaders/flame2/flame.fs");
//texture mask
List<Texture> textureList = new LinkedList<Texture>();
textureList.add(Globals.renderingEngine.getVolumeFrontfaceTexture());
textureList.add(Globals.renderingEngine.getVolumeBackfaceTexture());
List<String> uniformList = new LinkedList<String>();
uniformList.add("volumeDepthFrontface");
uniformList.add("volumeDepthBackface");
ActorTextureMask textureMask = new ActorTextureMask("Cube",textureList,uniformList);
EntityUtils.getActor(cube).addTextureMask(textureMask);
//set draw volumetric
cube.putData(EntityDataStrings.DRAW_VOLUMETRIC, true);
// goblin = CreatureUtils.spawnBasicCreature("Goblin");
// CollisionObjUtils.positionCharacter(goblin, new Vector3f(3, 0, 4));
// EntityUtils.getScale(goblin).set(0.005f);

View File

@ -17,6 +17,7 @@ public class EntityDataStrings {
public static final String DATA_STRING_ACTOR = "actor";
public static final String DATA_STRING_DRAW = "drawFlag";
public static final String DRAW_CAST_SHADOW = "castShadow";
public static final String DRAW_VOLUMETRIC = "drawVolumetric";
/*

View File

@ -15,8 +15,13 @@ import electrosphere.renderer.Model;
import electrosphere.renderer.ModelUtils;
import electrosphere.renderer.RenderUtils;
import electrosphere.renderer.ShaderProgram;
import electrosphere.renderer.actor.ActorTextureMask;
import electrosphere.renderer.texture.Texture;
import electrosphere.util.Utilities;
import java.util.LinkedList;
import java.util.List;
import org.joml.Quaternionf;
import org.joml.Vector3f;
@ -96,13 +101,19 @@ public class DrawCell {
}
Model terrainModel = RenderUtils.createMinimizedTerrainModelPrecomputedShader(heightmap, texturemap, program, stride);
Mesh terrainMesh = terrainModel.meshes.get(0);
terrainMesh.useTextureList = true;
terrainMesh.textureList.add(groundTextureOne);
terrainMesh.textureList.add(groundTextureTwo);
terrainMesh.textureList.add(groundTextureThree);
terrainMesh.textureList.add(groundTextureFour);
List<Texture> textureList = new LinkedList<Texture>();
textureList.add(groundTextureOne);
textureList.add(groundTextureTwo);
textureList.add(groundTextureThree);
textureList.add(groundTextureFour);
List<String> uniformList = new LinkedList<String>();
uniformList.add("groundTextures[0]");
uniformList.add("groundTextures[1]");
uniformList.add("groundTextures[2]");
uniformList.add("groundTextures[3]");
String terrainModelPath = Globals.assetManager.registerModel(terrainModel);
modelEntity = EntityUtils.spawnDrawableEntity(terrainModelPath);
EntityUtils.getActor(modelEntity).addTextureMask(new ActorTextureMask("terrain",textureList,uniformList));
modelEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
modelEntity.putData(EntityDataStrings.DRAW_CAST_SHADOW, true);
LoggerInterface.loggerRenderer.INFO("New cell @ " + cellX * dynamicInterpolationRatio + "," + cellY * dynamicInterpolationRatio);

View File

@ -4,6 +4,7 @@ import electrosphere.entity.types.camera.CameraEntityUtils;
import electrosphere.logger.LoggerInterface;
import electrosphere.main.Globals;
import electrosphere.main.Main;
import electrosphere.renderer.actor.ActorTextureMask;
import electrosphere.renderer.light.LightManager;
import electrosphere.renderer.texture.Texture;
import java.nio.FloatBuffer;
@ -81,9 +82,7 @@ public class Mesh {
boolean hasBones = true;
public boolean hasTextureCoords = true;
public List<Texture> textureList = new ArrayList<Texture>();
public boolean useTextureList;
public String textureListArrayUniformName;
public ActorTextureMask textureMask;
public float vertexMinX;
public float vertexMaxX;
@ -609,10 +608,8 @@ public class Mesh {
glEnableVertexAttribArray(attribIndex);
}
public void setTextureList(List<Texture> textureList, String uniformName){
this.textureList = textureList;
useTextureList = true;
textureListArrayUniformName = uniformName;
public void setTextureMask(ActorTextureMask textureMask){
this.textureMask = textureMask;
}
public void setMaterial(Material input){
@ -774,7 +771,7 @@ public class Mesh {
}
}
if(useMaterial && !useTextureList){
if(useMaterial && textureMask == null){
if(material == null){
Globals.materialDefault.apply_material(0,1);
GL20.glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "hasTransparency"), 0);
@ -796,18 +793,18 @@ public class Mesh {
if(useTextureList){
if(textureMask != null){
int i = 0;
// glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "groundTextures"), 5);
// for(int j = 1; j < 15; j++){
// textureList.get(0).bind(j);
// }
for(Texture texture : textureList){
for(Texture texture : textureMask.getTextures()){
// System.out.println(texture.getPath() + " => groundTextures[" + i + "]" + "=>" + (i));
if(texture != null){
texture.bind(5+i);
}
glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "groundTextures[" + i + "]"),5+i);
glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, textureMask.getUniformNames().get(i)),5+i);
i++;
}
// for(int j = i; j < 10; j++){

View File

@ -3,6 +3,7 @@ package electrosphere.renderer;
import electrosphere.renderer.actor.ActorAnimationMask;
import electrosphere.renderer.actor.ActorMeshMask;
import electrosphere.renderer.actor.ActorShaderMask;
import electrosphere.renderer.actor.ActorTextureMask;
import electrosphere.renderer.anim.AnimChannel;
import electrosphere.renderer.anim.Animation;
import electrosphere.renderer.anim.AnimNode;
@ -61,6 +62,7 @@ public class Model {
AnimNode root_anim_node;
ActorMeshMask meshMask;
Map<String,ActorShaderMask> shaderMask = new HashMap<String,ActorShaderMask>();
Map<String,ActorTextureMask> textureMap = null;
public static Model createModelFromAiscene(AIScene s){
Model rVal = new Model();
@ -203,10 +205,19 @@ public class Model {
while(mesh_Iterator.hasNext()){
Mesh currentMesh = mesh_Iterator.next();
if(!meshMask.isBlockedMesh(currentMesh.nodeID)){
//set shader
ShaderProgram original = currentMesh.shader;
ShaderProgram shader = getCorrectShader(shaderMask, currentMesh, currentMesh.shader);
currentMesh.shader = shader;
//set texture mask
if(this.textureMap != null && textureMap.containsKey(currentMesh.nodeID)){
currentMesh.setTextureMask(textureMap.get(currentMesh.nodeID));
}
//draw
currentMesh.complexDraw(setShader, bufferStandardUniforms, bufferNonStandardUniforms, useMaterial, useShadowMap, setBones, useLight);
//reset texture mask
currentMesh.setTextureMask(null);
//reset shader
currentMesh.shader = original;
}
}
@ -483,4 +494,8 @@ public class Model {
public void setMeshMask(ActorMeshMask meshMask){
this.meshMask = meshMask;
}
public void setTextureMask(Map<String,ActorTextureMask> textureMask){
this.textureMap = textureMask;
}
}

View File

@ -57,6 +57,9 @@ import static org.lwjgl.glfw.GLFW.glfwWindowHint;
import org.lwjgl.glfw.GLFWWindowSizeCallbackI;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import static org.lwjgl.opengl.GL11.GL_BLEND;
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
@ -112,6 +115,17 @@ public class RenderingEngine {
static ShaderProgram lightDepthShaderProgram;
static Framebuffer lightDepthBuffer;
static Matrix4f nearVolumeProjectionMatrix = new Matrix4f();
static Matrix4f midVolumeProjectionMatrix = new Matrix4f();
static Matrix4f farVolumeProjectionMatrix = new Matrix4f();
static ShaderProgram volumeDepthShaderProgram;
static Framebuffer volumeDepthBackfaceFramebuffer;
static Texture volumeDepthBackfaceTexture;
static Framebuffer volumeDepthFrontfaceFramebuffer;
static Texture volumeDepthFrontfaceTexture;
static float volumeDepthLinearCoef = 0.1f;
static float volumeDepthQuadCoef = 0.01f;
// public static boolean renderHitboxes = false;
// public static boolean renderPhysics = false;
@ -121,6 +135,8 @@ public class RenderingEngine {
static float currentViewPlanarAngle;
ShaderProgram activeProgram;
static int outputFramebuffer = 0;
public void createOpenglContext(){
@ -210,13 +226,28 @@ public class RenderingEngine {
screenFramebuffer = FramebufferUtils.generateScreensizeTextureFramebuffer();
glBindFramebuffer(GL_FRAMEBUFFER, GL_DEFAULT_FRAMEBUFFER);
glBindRenderbuffer(GL_RENDERBUFFER, GL_DEFAULT_RENDERBUFFER);
//
//create light depth framebuffer/shader for shadowmapping
//
lightDepthShaderProgram = ShaderProgram.loadSpecificShader("/Shaders/lightDepth/lightDepth.vs", "/Shaders/lightDepth/lightDepth.fs");
Globals.depthMapShaderProgramLoc = lightDepthShaderProgram.shaderProgram;
lightDepthBuffer = FramebufferUtils.generateDepthBuffer();
Globals.shadowMapTextureLoc = lightDepthBuffer.getTexturePointer();
// glEnable(GL_CULL_FACE); // enabled for shadow mapping
//
//create volume depth framebuffer/shader for volumetric rendering
//
volumeDepthShaderProgram = ShaderProgram.loadSpecificShader("/Shaders/volumeBuffer/volumetric.vs", "/Shaders/volumeBuffer/volumetric.fs");
volumeDepthBackfaceTexture = FramebufferUtils.generateDepthBufferTexture(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
volumeDepthBackfaceFramebuffer = FramebufferUtils.generateDepthBuffer(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, volumeDepthBackfaceTexture);
volumeDepthFrontfaceTexture = FramebufferUtils.generateDepthBufferTexture(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
volumeDepthFrontfaceFramebuffer = FramebufferUtils.generateDepthBuffer(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, volumeDepthFrontfaceTexture);
//projection matrices
nearVolumeProjectionMatrix.setPerspective((float)(Globals.verticalFOV * Math.PI /180.0f), (float)Globals.WINDOW_WIDTH / (float)Globals.WINDOW_HEIGHT, 0.1f, 100);
// midVolumeProjectionMatrix.setPerspective((float)(Globals.verticalFOV * Math.PI /180.0f), (float)Globals.WINDOW_WIDTH / (float)Globals.WINDOW_HEIGHT, 0.01f, 7);
// farVolumeProjectionMatrix.setPerspective((float)(Globals.verticalFOV * Math.PI /180.0f), (float)Globals.WINDOW_WIDTH / (float)Globals.WINDOW_HEIGHT, 0.1f, 50);
//instantiate light manager
@ -302,17 +333,26 @@ public class RenderingEngine {
if(Globals.RENDER_FLAG_RENDER_SHADOW_MAP){
renderShadowMapContent();
}
/*
render volume buffer
*/
if(Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT){
updateVolumeBuffer();
}
/*
Update light buffer
*/
lightManager.updateData();
/*
Render content to the game framebuffer
*/
if(Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT){
renderGameContent();
renderDebugContent();
}
@ -500,6 +540,13 @@ public class RenderingEngine {
}
}
// glBindVertexArray(0);
}
static void renderDebugContent(){
Matrix4f modelTransformMatrix = new Matrix4f();
if(Globals.userSettings.graphicsDebugDrawCollisionSpheres()){
for(Entity currentHitbox : Globals.hitboxManager.getAllHitboxes()){
if((boolean)currentHitbox.getData(EntityDataStrings.DATA_STRING_DRAW)){
@ -645,10 +692,6 @@ public class RenderingEngine {
}
}
}
// glBindVertexArray(0);
}
static void renderScreenFramebuffer(){
@ -681,8 +724,15 @@ public class RenderingEngine {
Globals.renderingEngine.setActiveShader(screenTextureShaders);
glBindVertexArray(screenTextureVAO);
//aaa
glBindTexture(GL_TEXTURE_2D, screenFramebuffer.getTexturePointer());
// glBindTexture(GL_TEXTURE_2D, lightDepthBuffer.getTexturePointer());
if(outputFramebuffer == 0){
glBindTexture(GL_TEXTURE_2D, screenFramebuffer.getTexturePointer());
} else if(outputFramebuffer == 1){
glBindTexture(GL_TEXTURE_2D, lightDepthBuffer.getTexturePointer());
} else if(outputFramebuffer == 2){
glBindTexture(GL_TEXTURE_2D, volumeDepthBackfaceTexture.getTexturePointer());
} else if(outputFramebuffer == 3){
glBindTexture(GL_TEXTURE_2D, volumeDepthFrontfaceTexture.getTexturePointer());
}
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
}
@ -709,6 +759,140 @@ public class RenderingEngine {
// uiActor.drawUI();
// }
}
static void updateVolumeBuffer(){
Matrix4f modelTransformMatrix = new Matrix4f();
//set the viewport to shadow map size
glViewport(0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
glEnable(GL_DEPTH_TEST);
//stop rendering front faces
GL15.glEnable(GL15.GL_CULL_FACE);
GL15.glCullFace(GL15.GL_FRONT);
Globals.renderingEngine.setActiveShader(volumeDepthShaderProgram);
volumeDepthBackfaceFramebuffer.bind();
glClear(GL_DEPTH_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);
// glBindTexture(GL_TEXTURE_2D, woodTexture);
// renderScene(simpleDepthShader);
glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "view"), false, Globals.viewMatrix.get(new float[16]));
// glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "projection"), false, Globals.projectionMatrix.get(new float[16]));
GL20.glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "linearCoef"), volumeDepthLinearCoef);
GL20.glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "quadCoef"), volumeDepthQuadCoef);
GL20.glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "near"), 0.1f);
GL20.glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "far"), 100f);
// glCullFace(GL_FRONT);
//
// D R A W A L L E N T I T I E S
//
Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera);
for(Entity currentEntity : Globals.entityManager.getDrawable()){
Vector3d position = EntityUtils.getPosition(currentEntity);
if(
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
drawPoint(cameraPos,new Vector3f((float)position.x,(float)position.y,(float)position.z)) &&
currentEntity.getDataKeys().contains(EntityDataStrings.DRAW_VOLUMETRIC)
){
//fetch actor
Actor currentActor = EntityUtils.getActor(currentEntity);
//calculate camera-modified vector3f
Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
//set projection matrix
// if(cameraModifiedPosition.length() > 2f){
// glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "projection"), false, farVolumeProjectionMatrix.get(new float[16]));
// } else if(cameraModifiedPosition.length() > 0.5f){
// glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "projection"), false, midVolumeProjectionMatrix.get(new float[16]));
// } else {
glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "projection"), false, nearVolumeProjectionMatrix.get(new float[16]));
// }
// glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "projection"), false, Globals.projectionMatrix.get(new float[16]));
//calculate and apply model transform
modelTransformMatrix = modelTransformMatrix.identity();
modelTransformMatrix.translate(cameraModifiedPosition);
modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity));
modelTransformMatrix.scale(EntityUtils.getScale(currentEntity));
currentActor.applyModelMatrix(modelTransformMatrix);
//draw
// if(!currentEntity.getDataKeys().contains(EntityDataStrings.TERRAIN_IS_TERRAIN) && !currentEntity.getDataKeys().contains(EntityDataStrings.DATA_STRING_CREATURE_IS_CREATURE)){
currentActor.drawForDepthBuffer();
// System.out.println(currentActor.modelPath);
// }
}
}
//stop rendering front faces
GL15.glEnable(GL15.GL_CULL_FACE);
GL15.glCullFace(GL15.GL_BACK);
Globals.renderingEngine.setActiveShader(volumeDepthShaderProgram);
volumeDepthFrontfaceFramebuffer.bind();
glClear(GL_DEPTH_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);
// glBindTexture(GL_TEXTURE_2D, woodTexture);
// renderScene(simpleDepthShader);
// glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "view"), false, Globals.viewMatrix.get(new float[16]));
// glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "projection"), false, Globals.projectionMatrix.get(new float[16]));
// GL20.glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "linearCoef"), volumeDepthLinearCoef);
// GL20.glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "quadCoef"), volumeDepthQuadCoef);
// glCullFace(GL_FRONT);
//
// D R A W A L L E N T I T I E S
//
for(Entity currentEntity : Globals.entityManager.getDrawable()){
Vector3d position = EntityUtils.getPosition(currentEntity);
if(
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
drawPoint(cameraPos,new Vector3f((float)position.x,(float)position.y,(float)position.z)) &&
currentEntity.getDataKeys().contains(EntityDataStrings.DRAW_VOLUMETRIC)
){
//fetch actor
Actor currentActor = EntityUtils.getActor(currentEntity);
//calculate camera-modified vector3f
Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
//calculate and apply model transform
modelTransformMatrix = modelTransformMatrix.identity();
modelTransformMatrix.translate(cameraModifiedPosition);
modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity));
modelTransformMatrix.scale(EntityUtils.getScale(currentEntity));
currentActor.applyModelMatrix(modelTransformMatrix);
//draw
// if(!currentEntity.getDataKeys().contains(EntityDataStrings.TERRAIN_IS_TERRAIN) && !currentEntity.getDataKeys().contains(EntityDataStrings.DATA_STRING_CREATURE_IS_CREATURE)){
currentActor.drawForDepthBuffer();
// System.out.println(currentActor.modelPath);
// }
}
}
GL15.glCullFace(GL15.GL_BACK);
//now cull back faces
//reset texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 0);
//bind default framebuffer
glBindFramebuffer(GL_FRAMEBUFFER,0);
//resume culling backface
GL15.glDisable(GL15.GL_CULL_FACE);
}
static void renderBlackBackground(){
//render full screen quad
@ -768,8 +952,23 @@ public class RenderingEngine {
// System.out.println(tLeft.get() + " " + tTop.get() + " " + tRight.get() + " " + tBottom.get());
}
public Texture getVolumeBackfaceTexture(){
return volumeDepthBackfaceTexture;
}
public Texture getVolumeFrontfaceTexture(){
return volumeDepthFrontfaceTexture;
}
public LightManager getLightManager(){
return lightManager;
}
public static void incrementOutputFramebuffer(){
outputFramebuffer++;
if(outputFramebuffer > 3){
outputFramebuffer = 0;
}
}
}

View File

@ -5,8 +5,10 @@ import electrosphere.renderer.Bone;
import electrosphere.renderer.Model;
import electrosphere.renderer.texture.Texture;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import org.joml.AxisAngle4f;
@ -26,6 +28,7 @@ public class Actor {
PriorityQueue<ActorAnimationMask> animationQueue = new PriorityQueue<ActorAnimationMask>();
ActorMeshMask meshMask = new ActorMeshMask();
List<ActorShaderMask> shaderMasks = new LinkedList<ActorShaderMask>();
Map<String,ActorTextureMask> textureMap = null;
public Actor(String modelPath){
this.modelPath = modelPath;
@ -183,6 +186,7 @@ public class Actor {
applyAnimationMasks(model);
meshMask.processMeshMaskQueue();
model.setMeshMask(meshMask);
model.setTextureMask(textureMap);
// if(!meshMask.isEmpty()){
// }
// if(animation != null){
@ -210,6 +214,7 @@ public class Actor {
model.draw(true, true, false, true, true, true, true);
}
model.getShaderMask().clear();
model.setTextureMask(null);
}
}
@ -328,5 +333,12 @@ public class Actor {
throw new UnsupportedOperationException("Not implemented yet");
}
public void addTextureMask(ActorTextureMask textureMask){
if(textureMap == null){
textureMap = new HashMap<String,ActorTextureMask>();
}
textureMap.put(textureMask.getMeshName(),textureMask);
}
}

View File

@ -0,0 +1,31 @@
package electrosphere.renderer.actor;
import java.util.List;
import electrosphere.renderer.texture.Texture;
public class ActorTextureMask {
String meshName;
List<Texture> textures;
List<String> uniformNames;
public ActorTextureMask(String meshName, List<Texture> textures, List<String> uniformNames){
this.meshName = meshName;
this.textures = textures;
this.uniformNames = uniformNames;
}
public String getMeshName(){
return meshName;
}
public List<Texture> getTextures(){
return textures;
}
public List<String> getUniformNames(){
return uniformNames;
}
}

View File

@ -2,6 +2,8 @@ package electrosphere.renderer.framebuffer;
import electrosphere.logger.LoggerInterface;
import electrosphere.main.Globals;
import electrosphere.renderer.texture.Texture;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -157,4 +159,48 @@ public class FramebufferUtils {
}
return buffer;
}
public static Texture generateDepthBufferTexture(int width, int height){
int texturePtr = glGenTextures();
glBindTexture(GL_TEXTURE_2D,texturePtr);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT , NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
float borderColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
Texture texture = new Texture(texturePtr);
return texture;
}
public static Framebuffer generateDepthBuffer(int width, int height, Texture texture){
Framebuffer buffer = new Framebuffer();
buffer.bind();
//texture
buffer.setTexturePointer(texture.getTexturePointer());
//bind texture to fbo
int mipMapLevel = 0;
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texture.getTexturePointer(), mipMapLevel);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
//check make sure compiled
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){
System.out.println("Framebuffer is not complete!");
}
return buffer;
}
}

View File

@ -30,9 +30,16 @@ public class Texture {
int height;
boolean hasTransparency;
String path = "";
public Texture(){
}
public Texture(int pointer){
this.texturePointer = pointer;
}
public Texture(String path){
this.path = path;
//generate the texture object on gpu