HDR, Bloom and SSR

This commit is contained in:
Halbear 2026-09-04 00:23:48 +01:00
parent 577836a03f
commit 04befce27d
44 changed files with 1377 additions and 269 deletions

2
.gitignore vendored
View file

@ -87,3 +87,5 @@ fabric.properties
/resources/models/bistrohd/ /resources/models/bistrohd/
/resources/models/Cafe/ /resources/models/Cafe/
/resources/models/Forest/ /resources/models/Forest/
/resources/models/tree/
/resources/models/woman/

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1,61 @@
#version 450
layout(location = 0) out vec4 FragColor;
layout(location = 0) in vec2 TexCoords;
layout(set = 0, binding = 0) uniform sampler2D image;
layout(set = 0, binding = 1) uniform sampler2D bloomImage;
layout(set = 1 , binding = 0) uniform PassConfig{
int ApplyToFinalImage;
int horizontal;
float GAMMA_CONST;
float Exposure;
float blur_radius;
vec3 padding;
} config;
const float weight[5] = float[] (0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216);
vec3 safeBloomSample(vec2 uv)
{
vec3 value = texture(bloomImage, uv).rgb;
return clamp(value, vec3(0.0), vec3(8.0));
}
void main()
{
if(config.ApplyToFinalImage != 0){
vec3 bloomColour = safeBloomSample(TexCoords);
vec3 hdrColour = texture(image, TexCoords).rgb;
hdrColour += bloomColour;
vec3 result = vec3(1.0) - exp(-hdrColour * config.Exposure);
result = pow(result, vec3(1.0 / config.GAMMA_CONST));
FragColor = vec4(result, 1.0);
return;
}
float blurRadius = config.blur_radius;
vec2 tex_offset = blurRadius / vec2(textureSize(bloomImage, 0));
vec3 result = safeBloomSample(TexCoords) * weight[0];
if(config.horizontal != 0)
{
for(int i = 1; i < 5; ++i)
{
result += safeBloomSample(TexCoords + vec2(tex_offset.x * i, 0.0)) * weight[i];
result += safeBloomSample(TexCoords - vec2(tex_offset.x * i, 0.0)) * weight[i];
}
}
else
{
for(int i = 1; i < 5; ++i)
{
result += safeBloomSample(TexCoords + vec2(0.0, tex_offset.y * i)) * weight[i];
result += safeBloomSample(TexCoords - vec2(0.0, tex_offset.y * i)) * weight[i];
}
}
FragColor = vec4(result, 1.0);
}

View file

@ -26,7 +26,8 @@ layout(set = 0, binding = 3) uniform sampler2D pbrSampler;
layout(set = 0, binding = 4) uniform sampler2D emissiveSampler; layout(set = 0, binding = 4) uniform sampler2D emissiveSampler;
layout(set = 0, binding = 5) uniform sampler2D TranslucencySampler; layout(set = 0, binding = 5) uniform sampler2D TranslucencySampler;
layout(set = 0, binding = 6) uniform sampler2D OpacitySampler; layout(set = 0, binding = 6) uniform sampler2D OpacitySampler;
layout(set = 0, binding = 7) uniform sampler2D ssaoBlur; layout(set = 0, binding = 7) uniform sampler2D ViewPos;
layout(set = 0, binding = 8) uniform sampler2D ssaoBlur;
layout(scalar, set = 1, binding = 0) readonly buffer Lights { layout(scalar, set = 1, binding = 0) readonly buffer Lights {
Light lights[]; Light lights[];
@ -128,17 +129,18 @@ vec3 calculateDirectionalLight(Light light, vec3 V, vec3 N, vec3 F0, vec3 albedo
void main() { void main() {
vec3 albedo = texture(albedoSampler, inTextCoord).rgb; vec3 albedo = texture(albedoSampler, inTextCoord).rgb;
vec3 normal = texture(normalsSampler, inTextCoord).rgb; vec4 normalW = texture(normalsSampler, inTextCoord);
vec3 normal = normalW.rgb;
vec3 viewPos = texture(ViewPos, inTextCoord).rgb;
vec3 worldPos = texture(posSampler, inTextCoord).rgb; vec3 worldPos = texture(posSampler, inTextCoord).rgb;
vec3 pbr = texture(pbrSampler, inTextCoord).rgb; vec4 pbr = texture(pbrSampler, inTextCoord);
vec3 emissive = texture(emissiveSampler, inTextCoord).rgb; vec3 emissive = texture(emissiveSampler, inTextCoord).rgb;
vec3 translucency = texture(TranslucencySampler, inTextCoord).rgb; vec3 translucency = texture(TranslucencySampler, inTextCoord).rgb;
float emissiveness = emissive.r; float emissiveness = emissive.r;
// outFragColor = vec4(vec3(texture(ssaoBlur, inTextCoord).r), 1);
// return;
float ssao = texture(ssaoBlur, inTextCoord).r; float ssao = texture(ssaoBlur, inTextCoord).r;
outFragColor = vec4(vec3(normalW.a/2.0,normalW.a/2.0,normalW.a/2.0), 1);
return;
float roughness = pbr.g; float roughness = pbr.g;
float metallic = pbr.b; float metallic = pbr.b;

View file

@ -30,8 +30,9 @@ layout(set = 0, binding = 3) uniform sampler2D pbrSampler;
layout(set = 0, binding = 4) uniform sampler2D emissiveSampler; layout(set = 0, binding = 4) uniform sampler2D emissiveSampler;
layout(set = 0, binding = 5) uniform sampler2D TranslucencySampler; layout(set = 0, binding = 5) uniform sampler2D TranslucencySampler;
layout(set = 0, binding = 6) uniform sampler2D OpacitySampler; layout(set = 0, binding = 6) uniform sampler2D OpacitySampler;
layout(set = 0, binding = 7) uniform sampler2D ssaoBlur; layout(set = 0, binding = 7) uniform sampler2D viewPos;
layout(set = 0, binding = 8) uniform sampler2DArray shadowSampler; layout(set = 0, binding = 8) uniform sampler2D ssaoBlur;
layout(set = 0, binding = 9) uniform sampler2DArray shadowSampler;
layout(scalar, set = 1, binding = 0) readonly buffer Lights { layout(scalar, set = 1, binding = 0) readonly buffer Lights {
@ -62,12 +63,12 @@ float chebyshevUpperBound(vec2 moments, float t) {
float p_max = variance / (variance + d * d); float p_max = variance / (variance + d * d);
// Reduce light bleeding // Reduce light bleeding
p_max = smoothstep(0.2, 1.0, p_max); p_max = smoothstep(0.5, 1.0, p_max);
return p_max; return p_max;
} }
float calcVisibility(vec4 worldPosition, uint cascadeIndex, float ShadowBias) { float calcVisibility(vec4 worldPosition, uint cascadeIndex, float ShadowBias, vec2 texelSize) {
vec4 shadowMapPosition = shadows.cascadeshadows[cascadeIndex].projViewMatrix * worldPosition; vec4 shadowMapPosition = shadows.cascadeshadows[cascadeIndex].projViewMatrix * worldPosition;
shadowMapPosition.xyz /= shadowMapPosition.w; shadowMapPosition.xyz /= shadowMapPosition.w;
@ -87,19 +88,18 @@ float calcVisibility(vec4 worldPosition, uint cascadeIndex, float ShadowBias) {
float shadow = 0.0; float shadow = 0.0;
vec2 texelSize = 1.0 / textureSize(shadowSampler, 0).rg;
for(int x = -1; x <= 1; ++x) for(int x = -1; x <= 1; ++x)
{ {
for(int y = -1; y <= 1; ++y) for(int y = -1; y <= 1; ++y)
{ {
vec2 moments = texture(shadowSampler, vec3((uv + vec2(x, y) * texelSize), cascadeIndex)).rg; vec2 moments = texture(shadowSampler, vec3((uv + vec2(x, y) * texelSize), cascadeIndex)).rg;
float visibility = chebyshevUpperBound(moments, depth); float visibility = chebyshevUpperBound(moments, depth);
shadow += depth - ShadowBias > visibility ? 1.0 : 0.0; shadow += visibility;
} }
} }
shadow /= 9.0; shadow /= 9.0;
return 1 - shadow; return shadow;
} }
float distributionGGX(vec3 N, vec3 H, float roughness) { float distributionGGX(vec3 N, vec3 H, float roughness) {
@ -193,13 +193,17 @@ vec3 calculateDirectionalLight(Light light, vec3 V, vec3 N, vec3 F0, vec3 albedo
void main() { void main() {
vec3 albedo = texture(albedoSampler, inTextCoord).rgb; vec3 albedo = texture(albedoSampler, inTextCoord).rgb;
vec3 normal = texture(normalsSampler, inTextCoord).rgb; vec4 normalW = texture(normalsSampler, inTextCoord);
vec3 normal = normalW.rgb;
vec4 worldPosW = texture(posSampler, inTextCoord); vec4 worldPosW = texture(posSampler, inTextCoord);
vec3 worldPos = worldPosW.xyz; vec3 worldPos = worldPosW.xyz;
vec3 pbr = texture(pbrSampler, inTextCoord).rgb; vec4 pbrW = texture(pbrSampler, inTextCoord);
vec3 pbr = pbrW.rgb;
vec3 emissive = texture(emissiveSampler, inTextCoord).rgb; vec3 emissive = texture(emissiveSampler, inTextCoord).rgb;
vec3 Opacity = texture(OpacitySampler, inTextCoord).rgb; vec3 Opacity = texture(OpacitySampler, inTextCoord).rgb;
vec3 translucency = texture(TranslucencySampler, inTextCoord).rgb; vec3 translucency = texture(TranslucencySampler, inTextCoord).rgb;
float Reflectivity = pbrW.a;
float Refractivity = normalW.a;
float emissiveness = emissive.r; float emissiveness = emissive.r;
float translucencyf = translucency.r; float translucencyf = translucency.r;
@ -231,7 +235,10 @@ void main() {
cascadeIndex = i + 1; cascadeIndex = i + 1;
} }
} }
float shadow = calcVisibility(vec4(worldPos, 1), cascadeIndex,ShadowBias);
vec2 texelSizeShadow = 1.0 / textureSize(shadowSampler, 0).rg;
float shadow = calcVisibility(vec4(worldPos, 1), cascadeIndex,ShadowBias, texelSizeShadow);
vec3 Lo = vec3(0.0); vec3 Lo = vec3(0.0);
for (uint i = 0; i < sceneInfo.numLights; i++) { for (uint i = 0; i < sceneInfo.numLights; i++) {
@ -242,7 +249,7 @@ void main() {
Lo += calculatePointLight(light, worldPos, V, N, F0, albedo, metallic, roughness); Lo += calculatePointLight(light, worldPos, V, N, F0, albedo, metallic, roughness);
} }
} }
vec3 ambient = sceneInfo.ambientLightColor * albedo * sceneInfo.ambientLightIntensity * vec3(ssao,ssao,ssao);; vec3 ambient = sceneInfo.ambientLightColor * albedo * sceneInfo.ambientLightIntensity * vec3(ssao,ssao,ssao);
if(emissive.x > 0 || emissive.y > 0 || emissive.z > 0) ambient = emissive; if(emissive.x > 0 || emissive.y > 0 || emissive.z > 0) ambient = emissive;
outFragColor = vec4(Lo + ambient, 1.0f); outFragColor = vec4(Lo + ambient, 1.0f);
outFragColor = vec4(outFragColor.xyz/2 + (outFragColor.xyz/2) * vec3(ssao,ssao,ssao),1); outFragColor = vec4(outFragColor.xyz/2 + (outFragColor.xyz/2) * vec3(ssao,ssao,ssao),1);

View file

@ -9,6 +9,7 @@ const float REDUCE_MUL = 1.0/32.0;
layout(location = 0) in vec2 inTextCoord; layout(location = 0) in vec2 inTextCoord;
layout(location = 0) out vec4 outFragColor; layout(location = 0) out vec4 outFragColor;
layout(location = 1) out vec4 outBloomColour;
layout(set = 0, binding = 0) uniform sampler2DMS inputTexture; layout(set = 0, binding = 0) uniform sampler2DMS inputTexture;
@ -19,7 +20,12 @@ layout(set = 1, binding = 0) uniform ScreenSize{
vec4 gamma(vec4 color){ vec4 gamma(vec4 color){
return color = vec4(pow(color.rgb,vec3(GAMMA_CONST)),color.a); return color = vec4(pow(color.rgb,vec3(GAMMA_CONST)),color.a);
} }
vec3 HDR(float Gamma, float Exposure, sampler2D Texture, vec2 TexCoords){
vec3 hdrColor = texture(Texture, TexCoords).rgb;
vec3 mapped = vec3(1.0) - exp(-hdrColor * Exposure);
mapped = pow(mapped, vec3(1.0 / Gamma));
return mapped;
}
vec4 msaa(int sampleCount, sampler2DMS textureIn,vec2 TextCoord){ vec4 msaa(int sampleCount, sampler2DMS textureIn,vec2 TextCoord){
ivec2 pixelCoords = ivec2(TextCoord * textureSize(textureIn)); ivec2 pixelCoords = ivec2(TextCoord * textureSize(textureIn));
vec4 colorSum = vec4(0.0); vec4 colorSum = vec4(0.0);
@ -34,6 +40,8 @@ vec4 msaa(int sampleCount, sampler2DMS textureIn,vec2 TextCoord){
void main(){ void main(){
ivec2 pixelCoords = ivec2(inTextCoord * textureSize(inputTexture)); ivec2 pixelCoords = ivec2(inTextCoord * textureSize(inputTexture));
outFragColor = texelFetch(inputTexture, pixelCoords, 0);
if(USE_AA == 0){ if(USE_AA == 0){
outFragColor = texelFetch(inputTexture,pixelCoords,0); outFragColor = texelFetch(inputTexture,pixelCoords,0);
} }
@ -49,5 +57,16 @@ void main(){
if(USE_AA == 4){ if(USE_AA == 4){
outFragColor = msaa(8,inputTexture,inTextCoord); outFragColor = msaa(8,inputTexture,inTextCoord);
} }
outFragColor = gamma(outFragColor);
vec3 color = outFragColor.rgb;
float brightness = dot(color, vec3(0.2126, 0.7152, 0.0722));
float threshold = 1.0;
float softKnee = 0.5;
float contribution = max(brightness - threshold, 0.0);
contribution = contribution / max(contribution + softKnee, 0.0001);
outBloomColour = vec4(color * contribution, 1.0);
} }

View file

@ -2,13 +2,15 @@
layout(constant_id = 0) const int USE_AA = 0; layout(constant_id = 0) const int USE_AA = 0;
const float GAMMA_CONST = 0.8545; const float GAMMA_CONST = 0.4545;
const float Exposure = 2.0;
const float SPAN_MAX = 8.0; const float SPAN_MAX = 8.0;
const float REDUCE_MIN = 1.0/128.0; const float REDUCE_MIN = 1.0/128.0;
const float REDUCE_MUL = 1.0/32.0; const float REDUCE_MUL = 1.0/32.0;
layout(location = 0) in vec2 inTextCoord; layout(location = 0) in vec2 inTextCoord;
layout(location = 0) out vec4 outFragColor; layout(location = 0) out vec4 outFragColor;
layout(location = 1) out vec4 outBloomColour;
layout(set = 0, binding = 0) uniform sampler2D inputTexture; layout(set = 0, binding = 0) uniform sampler2D inputTexture;
@ -20,6 +22,13 @@ vec4 gamma(vec4 color){
return color = vec4(pow(color.rgb,vec3(GAMMA_CONST)),color.a); return color = vec4(pow(color.rgb,vec3(GAMMA_CONST)),color.a);
} }
vec3 HDR(float Gamma, float Exposure, sampler2D Texture, vec2 TexCoords){
vec3 hdrColor = texture(Texture, TexCoords).rgb;
vec3 mapped = vec3(1.0) - exp(-hdrColor * Exposure);
mapped = pow(mapped, vec3(1.0 / Gamma));
return mapped;
}
// Sourced from: https://mini.gmshaders.com/p/gm-shaders-mini-fxaa // Sourced from: https://mini.gmshaders.com/p/gm-shaders-mini-fxaa
vec4 fxaa(sampler2D tex, vec2 uv) { vec4 fxaa(sampler2D tex, vec2 uv) {
vec2 u_texel = 1.0 / screenSize.size; vec2 u_texel = 1.0 / screenSize.size;
@ -74,17 +83,32 @@ void main(){
if(USE_AA == 1){ if(USE_AA == 1){
outFragColor = fxaa(inputTexture, inTextCoord); outFragColor = fxaa(inputTexture, inTextCoord);
outFragColor = gamma(outFragColor);
return;
} }
if(USE_AA == 2){ else if(USE_AA == 2){
outFragColor = texture(inputTexture, inTextCoord);
} }
if(USE_AA == 3){ else if(USE_AA == 3){
outFragColor = texture(inputTexture, inTextCoord);
} }
if(USE_AA == 4){ else if(USE_AA == 4){
outFragColor = texture(inputTexture, inTextCoord);
} }
outFragColor = gamma(texture(inputTexture,inTextCoord)); else {
outFragColor = texture(inputTexture, inTextCoord);
}
vec3 color = outFragColor.rgb;
float brightness = dot(color, vec3(0.2126, 0.7152, 0.0722));
float threshold = 1.0;
float softKnee = 0.5;
float contribution = max(brightness - threshold, 0.0);
contribution = contribution / max(contribution + softKnee, 0.0001);
outBloomColour = vec4(color * contribution, 1.0);
} }

View file

@ -7,8 +7,10 @@ layout(location = 1) in vec3 inNormal;
layout(location = 2) in vec3 inTangent; layout(location = 2) in vec3 inTangent;
layout(location = 3) in vec3 inBitangent; layout(location = 3) in vec3 inBitangent;
layout(location = 4) in vec2 inTextCoords; layout(location = 4) in vec2 inTextCoords;
layout(location = 5) in mat4 viewMatrix;
layout(location = 0) out vec4 outAlbedo; layout(location = 0) out vec4 outAlbedo;
layout(location = 1) out vec4 outViewPos;
struct Material { struct Material {
vec4 diffuseColor; //16 vec4 diffuseColor; //16
@ -29,6 +31,10 @@ struct Material {
uint hasOpacityMap; //88 uint hasOpacityMap; //88
uint OpacityMapIdx; //92 uint OpacityMapIdx; //92
float OpacityFactor; //96 float OpacityFactor; //96
float reflectiveness; //100
float refractiveness; //104
float Padding1; //108
float Padding2; //112
}; };
layout(set = 2, binding = 0) readonly buffer MaterialUniform{ layout(set = 2, binding = 0) readonly buffer MaterialUniform{
@ -37,6 +43,7 @@ layout(set = 2, binding = 0) readonly buffer MaterialUniform{
layout(set = 3, binding = 0) uniform sampler2D textSampler[MAX_TEXTURES]; layout(set = 3, binding = 0) uniform sampler2D textSampler[MAX_TEXTURES];
layout(push_constant) uniform pc{ layout(push_constant) uniform pc{
layout(offset = 64) uint materialIdx; layout(offset = 64) uint materialIdx;
} push_constants; } push_constants;
@ -44,13 +51,15 @@ layout(push_constant) uniform pc{
void main() void main()
{ {
Material material = matUniform.materials[inMaterialIdx]; vec4 viewPos = vec4(viewMatrix * inPos);
outViewPos = viewPos;
Material material = matUniform.materials[push_constants.materialIdx];
int textureIndex = int(material.textureIdx); int textureIndex = int(material.textureIdx);
if (textureIndex >= MAX_TEXTURES){ if (textureIndex >= MAX_TEXTURES){
outAlbedo = vec4(0.0,0.0,1.0,1.0); outAlbedo = vec4(0.0,0.0,1.0,1.0);
return; return;
} }
Material material = matUniform.materials[push_constants.materialIdx];
if(material.hasTexture == 1){ if(material.hasTexture == 1){
vec4 texColor = texture(textSampler[material.textureIdx],inTextCoords); vec4 texColor = texture(textSampler[material.textureIdx],inTextCoords);
outAlbedo = texColor; outAlbedo = texColor;

View file

@ -8,6 +8,7 @@ layout(location = 1) in vec3 inNormal;
layout(location = 2) in vec3 inTangent; layout(location = 2) in vec3 inTangent;
layout(location = 3) in vec3 inBitangent; layout(location = 3) in vec3 inBitangent;
layout(location = 4) in vec2 inTextCoords; layout(location = 4) in vec2 inTextCoords;
layout(location = 5) in mat4 viewMatrix;
layout(location = 1) out vec4 outAlbedo ; layout(location = 1) out vec4 outAlbedo ;
layout(location = 0) out vec4 outPos; layout(location = 0) out vec4 outPos;
@ -16,6 +17,7 @@ layout(location = 3) out vec4 outPBR;
layout(location = 4) out vec4 outEmissive; layout(location = 4) out vec4 outEmissive;
layout(location = 5) out vec4 outTranslucency; layout(location = 5) out vec4 outTranslucency;
layout(location = 6) out vec4 outOpacity; layout(location = 6) out vec4 outOpacity;
layout(location = 7) out vec4 outViewPos;
struct Material { struct Material {
vec4 diffuseColor; //16 vec4 diffuseColor; //16
@ -36,6 +38,10 @@ struct Material {
uint hasOpacityMap; //88 uint hasOpacityMap; //88
uint OpacityMapIdx; //92 uint OpacityMapIdx; //92
float OpacityFactor; //96 float OpacityFactor; //96
float reflectiveness; //100
float refractiveness; //104
float Padding1; //108
float Padding2; //112
}; };
layout(set = 2, binding = 0) readonly buffer MaterialUniform { layout(set = 2, binding = 0) readonly buffer MaterialUniform {
Material materials[]; Material materials[];
@ -62,6 +68,9 @@ void main()
{ {
outPos = inPos; outPos = inPos;
vec4 viewPos = vec4(viewMatrix * vec4(inPos.xyz, 1.0));
outViewPos = viewPos;
Material material = matUniform.materials[push_constants.materialIdx]; Material material = matUniform.materials[push_constants.materialIdx];
int textureIndex = int(material.textureIdx); int textureIndex = int(material.textureIdx);
if (textureIndex >= MAX_TEXTURES){ if (textureIndex >= MAX_TEXTURES){
@ -95,7 +104,7 @@ void main()
mat3 TBN = mat3(inTangent, inBitangent, inNormal); mat3 TBN = mat3(inTangent, inBitangent, inNormal);
vec3 newNormal = calcNormal(material, inNormal, inTextCoords, TBN); vec3 newNormal = calcNormal(material, inNormal, inTextCoords, TBN);
outNormal = vec4(newNormal, 1.0f);
float ao = 0.5f; float ao = 0.5f;
float roughnessFactor = 0.0f; float roughnessFactor = 0.0f;
@ -121,6 +130,9 @@ void main()
} }
outTranslucency = Translucency; outTranslucency = Translucency;
outPBR = vec4(ao, roughnessFactor, metallicFactor, 1.0f); float Refractiveness = material.refractiveness;
float Reflectiveness = material.reflectiveness;
outNormal = vec4(newNormal, Refractiveness);
outPBR = vec4(ao, roughnessFactor, metallicFactor, Reflectiveness);
} }

View file

@ -8,8 +8,10 @@ layout(location = 1) in vec3 inNormal;
layout(location = 2) in vec3 inTangent; layout(location = 2) in vec3 inTangent;
layout(location = 3) in vec3 inBitangent; layout(location = 3) in vec3 inBitangent;
layout(location = 4) in vec2 inTextCoords; layout(location = 4) in vec2 inTextCoords;
layout(location = 5) in mat4 viewMatrix;
layout(location = 0) out vec4 outAlbedo; layout(location = 0) out vec4 outAlbedo;
layout(location = 1) out vec4 outViewPos;
struct Material { struct Material {
vec4 diffuseColor; //16 vec4 diffuseColor; //16
@ -30,6 +32,10 @@ struct Material {
uint hasOpacityMap; //88 uint hasOpacityMap; //88
uint OpacityMapIdx; //92 uint OpacityMapIdx; //92
float OpacityFactor; //96 float OpacityFactor; //96
float reflectiveness; //100
float refractiveness; //104
float Padding1; //108
float Padding2; //112
}; };
layout(set = 2, binding = 0) readonly buffer MaterialUniform{ layout(set = 2, binding = 0) readonly buffer MaterialUniform{
@ -44,6 +50,9 @@ layout(push_constant) uniform pc{
void main() void main()
{ {
vec4 viewPos = vec4(viewMatrix * inPos);
outViewPos = viewPos;
Material material = matUniform.materials[push_constants.materialIdx]; Material material = matUniform.materials[push_constants.materialIdx];
int textureIndex = int(material.textureIdx); int textureIndex = int(material.textureIdx);
if (textureIndex >= MAX_TEXTURES){ if (textureIndex >= MAX_TEXTURES){

View file

@ -7,6 +7,7 @@ layout(location = 1) in vec3 inNormal;
layout(location = 2) in vec3 inTangent; layout(location = 2) in vec3 inTangent;
layout(location = 3) in vec3 inBitangent; layout(location = 3) in vec3 inBitangent;
layout(location = 4) in vec2 inTextCoords; layout(location = 4) in vec2 inTextCoords;
layout(location = 5) in mat4 viewMatrix;
layout(location = 1) out vec4 outAlbedo ; layout(location = 1) out vec4 outAlbedo ;
layout(location = 0) out vec4 outPos; layout(location = 0) out vec4 outPos;
@ -15,6 +16,7 @@ layout(location = 3) out vec4 outPBR;
layout(location = 4) out vec4 outEmissive; layout(location = 4) out vec4 outEmissive;
layout(location = 5) out vec4 outTranslucency; layout(location = 5) out vec4 outTranslucency;
layout(location = 6) out vec4 outOpacity; layout(location = 6) out vec4 outOpacity;
layout(location = 7) out vec4 outViewPos;
const float bayerMatrix[16] = float[]( const float bayerMatrix[16] = float[](
0.0 / 16.0, 8.0 / 16.0, 2.0 / 16.0, 10.0 / 16.0, 0.0 / 16.0, 8.0 / 16.0, 2.0 / 16.0, 10.0 / 16.0,
@ -42,6 +44,10 @@ struct Material {
uint hasOpacityMap; //88 uint hasOpacityMap; //88
uint OpacityMapIdx; //92 uint OpacityMapIdx; //92
float OpacityFactor; //96 float OpacityFactor; //96
float reflectiveness; //100
float refractiveness; //104
float Padding1; //108
float Padding2; //112
}; };
layout(set = 2, binding = 0) readonly buffer MaterialUniform { layout(set = 2, binding = 0) readonly buffer MaterialUniform {
Material materials[]; Material materials[];
@ -68,6 +74,9 @@ void main()
{ {
outPos = inPos; outPos = inPos;
vec4 viewPos = vec4(viewMatrix * vec4(inPos.xyz, 1.0));
outViewPos = viewPos;
Material material = matUniform.materials[push_constants.materialIdx]; Material material = matUniform.materials[push_constants.materialIdx];
int textureIndex = int(material.textureIdx); int textureIndex = int(material.textureIdx);
if (textureIndex >= MAX_TEXTURES){ if (textureIndex >= MAX_TEXTURES){
@ -84,11 +93,6 @@ void main()
} else { } else {
outAlbedo = material.diffuseColor; outAlbedo = material.diffuseColor;
} }
/*int Intensity = 4;
int x = int(gl_FragCoord.x) % Intensity;
int y = int(gl_FragCoord.y) % Intensity;
float threshold = bayerMatrix[y * Intensity + x];
if(outAlbedo.a < threshold || outAlbedo.a < 0.05f) discard;*/
vec4 Opacity = vec4(outAlbedo.a,outAlbedo.a,outAlbedo.a,1); vec4 Opacity = vec4(outAlbedo.a,outAlbedo.a,outAlbedo.a,1);
if(material.OpacityFactor != 1) Opacity = vec4(material.OpacityFactor, material.OpacityFactor, material.OpacityFactor, 1); if(material.OpacityFactor != 1) Opacity = vec4(material.OpacityFactor, material.OpacityFactor, material.OpacityFactor, 1);
@ -102,12 +106,11 @@ void main()
outAlbedo = vec4(outAlbedo.rgb, opacityf); outAlbedo = vec4(outAlbedo.rgb, opacityf);
if(outAlbedo.a < 0.75) discard; if(outAlbedo.a < 0.9) discard;
mat3 TBN = mat3(inTangent, inBitangent, inNormal); mat3 TBN = mat3(inTangent, inBitangent, inNormal);
vec3 newNormal = calcNormal(material, inNormal, inTextCoords, TBN); vec3 newNormal = calcNormal(material, inNormal, inTextCoords, TBN);
outNormal = vec4(newNormal, outAlbedo.a);
float ao = 0.5f; float ao = 0.5f;
float roughnessFactor = 0.0f; float roughnessFactor = 0.0f;
@ -133,6 +136,9 @@ void main()
} }
outTranslucency = Translucency; outTranslucency = Translucency;
outPBR = vec4(ao, roughnessFactor, metallicFactor, outAlbedo.a); float Refractiveness = material.refractiveness;
float Reflectiveness = material.reflectiveness;
outNormal = vec4(newNormal, Refractiveness);
outPBR = vec4(ao, roughnessFactor, metallicFactor, Reflectiveness);
} }

View file

@ -7,8 +7,10 @@ layout(location = 1) in vec3 inNormal;
layout(location = 2) in vec3 inTangent; layout(location = 2) in vec3 inTangent;
layout(location = 3) in vec3 inBitangent; layout(location = 3) in vec3 inBitangent;
layout(location = 4) in vec2 inTextCoords; layout(location = 4) in vec2 inTextCoords;
layout(location = 5) in mat4 viewMatrix;
layout(location = 0) out vec4 outAlbedo; layout(location = 0) out vec4 outAlbedo;
layout(location = 1) out vec4 outViewPos;
struct Material { struct Material {
vec4 diffuseColor; //16 vec4 diffuseColor; //16
@ -29,6 +31,10 @@ struct Material {
uint hasOpacityMap; //88 uint hasOpacityMap; //88
uint OpacityMapIdx; //92 uint OpacityMapIdx; //92
float OpacityFactor; //96 float OpacityFactor; //96
float reflectiveness; //100
float refractiveness; //104
float Padding1; //108
float Padding2; //112
}; };
layout(set = 2, binding = 0) readonly buffer MaterialUniform{ layout(set = 2, binding = 0) readonly buffer MaterialUniform{
Material materials[]; Material materials[];
@ -42,6 +48,10 @@ layout(push_constant) uniform pc{
void main() void main()
{ {
vec4 viewPos = vec4(viewMatrix * inPos);
outViewPos = viewPos;
Material material = matUniform.materials[push_constants.materialIdx]; Material material = matUniform.materials[push_constants.materialIdx];
int textureIndex = int(material.textureIdx); int textureIndex = int(material.textureIdx);
if (textureIndex >= MAX_TEXTURES){ if (textureIndex >= MAX_TEXTURES){

View file

@ -7,6 +7,7 @@ layout(location = 1) in vec3 inNormal;
layout(location = 2) in vec3 inTangent; layout(location = 2) in vec3 inTangent;
layout(location = 3) in vec3 inBitangent; layout(location = 3) in vec3 inBitangent;
layout(location = 4) in vec2 inTextCoords; layout(location = 4) in vec2 inTextCoords;
layout(location = 5) in mat4 viewMatrix;
layout(location = 1) out vec4 outAlbedo ; layout(location = 1) out vec4 outAlbedo ;
layout(location = 0) out vec4 outPos; layout(location = 0) out vec4 outPos;
@ -15,6 +16,7 @@ layout(location = 3) out vec4 outPBR;
layout(location = 4) out vec4 outEmissive; layout(location = 4) out vec4 outEmissive;
layout(location = 5) out vec4 outTranslucency; layout(location = 5) out vec4 outTranslucency;
layout(location = 6) out vec4 outOpacity; layout(location = 6) out vec4 outOpacity;
layout(location = 7) out vec4 outViewPos;
const float bayerMatrix[16] = float[]( const float bayerMatrix[16] = float[](
0.0 / 16.0, 8.0 / 16.0, 2.0 / 16.0, 10.0 / 16.0, 0.0 / 16.0, 8.0 / 16.0, 2.0 / 16.0, 10.0 / 16.0,
@ -43,6 +45,10 @@ struct Material {
uint hasOpacityMap; //88 uint hasOpacityMap; //88
uint OpacityMapIdx; //92 uint OpacityMapIdx; //92
float OpacityFactor; //96 float OpacityFactor; //96
float reflectiveness; //100
float refractiveness; //104
float Padding1; //108
float Padding2; //112
}; };
layout(set = 2, binding = 0) readonly buffer MaterialUniform { layout(set = 2, binding = 0) readonly buffer MaterialUniform {
@ -69,6 +75,10 @@ layout(push_constant) uniform pc {
void main() void main()
{ {
outPos = inPos; outPos = inPos;
vec4 viewPos = vec4(viewMatrix * vec4(inPos.xyz, 1.0));
outViewPos = viewPos;
Material material = matUniform.materials[push_constants.materialIdx]; Material material = matUniform.materials[push_constants.materialIdx];
int textureIndex = int(material.textureIdx); int textureIndex = int(material.textureIdx);
if (textureIndex >= MAX_TEXTURES){ if (textureIndex >= MAX_TEXTURES){
@ -98,11 +108,11 @@ void main()
outAlbedo = vec4(outAlbedo.rgb, opacityf); outAlbedo = vec4(outAlbedo.rgb, opacityf);
if(outAlbedo.a >= 0.75 || outAlbedo.a < 0.05f) discard; if(outAlbedo.a >= 0.9 || outAlbedo.a <= 0.1) discard;
mat3 TBN = mat3(inTangent, inBitangent, inNormal); mat3 TBN = mat3(inTangent, inBitangent, inNormal);
vec3 newNormal = calcNormal(material, inNormal, inTextCoords, TBN); vec3 newNormal = calcNormal(material, inNormal, inTextCoords, TBN);
outNormal = vec4(newNormal, outAlbedo.a);
float ao = 0.5f; float ao = 0.5f;
float roughnessFactor = 0.0f; float roughnessFactor = 0.0f;
@ -128,6 +138,9 @@ void main()
} }
outTranslucency = Translucency; outTranslucency = Translucency;
outPBR = vec4(ao, roughnessFactor, metallicFactor, outAlbedo.a); float Refractiveness = material.refractiveness;
float Reflectiveness = material.reflectiveness;
outNormal = vec4(newNormal, Refractiveness);
outPBR = vec4(ao, roughnessFactor, metallicFactor, Reflectiveness);
} }

View file

@ -11,7 +11,7 @@ layout(location = 1) out vec3 outNormal;
layout(location = 2) out vec3 outTangent; layout(location = 2) out vec3 outTangent;
layout(location = 3) out vec3 outBitangent; layout(location = 3) out vec3 outBitangent;
layout(location = 4) out vec2 outTextCoords; layout(location = 4) out vec2 outTextCoords;
layout(location = 5) out mat4 viewMatrix;
layout(set = 0, binding = 0) uniform ProjUniform{ layout(set = 0, binding = 0) uniform ProjUniform{
mat4 matrix; mat4 matrix;
@ -27,6 +27,7 @@ layout(push_constant) uniform pc{
void main() void main()
{ {
viewMatrix = viewUniform.matrix;
vec4 worldPos = push_constants.modelMatrix * vec4(inPos,1); vec4 worldPos = push_constants.modelMatrix * vec4(inPos,1);
gl_Position = projUniform.matrix * viewUniform.matrix * push_constants.modelMatrix * vec4(inPos,1); gl_Position = projUniform.matrix * viewUniform.matrix * push_constants.modelMatrix * vec4(inPos,1);
mat3 mNormal = transpose(inverse(mat3(push_constants.modelMatrix))); mat3 mNormal = transpose(inverse(mat3(push_constants.modelMatrix)));

View file

@ -0,0 +1,128 @@
#version 450
layout(location = 0) in vec2 fragTexCoord;
layout(location = 0) out vec4 outColor;
layout(set = 0, binding = 0) uniform sampler2D albedoSampler;
layout(set = 0, binding = 1) uniform sampler2D worldPosSampler;
layout(set = 0, binding = 2) uniform sampler2D normalSampler;
layout(set = 0, binding = 3) uniform sampler2D pbrSampler;
layout(set = 1, binding = 0) uniform CameraProperties {
mat4 projection;
mat4 invProjection;
mat4 view;
mat4 invView;
float ssrStepSize;
float ssrMaxDistance;
int maxSteps;
int padding;
vec4 cameraWorldPos;
} ubo;
const float THICKNESS = 0.35;
const float MIN_REFLECTION = 0.01;
float edgeFade(vec2 uv) {
vec2 fade = smoothstep(vec2(0.0), vec2(0.08), uv) *
smoothstep(vec2(0.0), vec2(0.08), vec2(1.0) - uv);
return fade.x * fade.y;
}
void main() {
vec4 sceneColor = texture(albedoSampler, fragTexCoord);
vec4 posSample = texture(worldPosSampler, fragTexCoord);
vec4 normalSample = texture(normalSampler, fragTexCoord);
vec4 pbrSample = texture(pbrSampler, fragTexCoord);
if (posSample.a == 0.0 || length(posSample.xyz) == 0.0 || length(normalSample.xyz) < 0.001) {
outColor = sceneColor;
return;
}
vec3 worldPos = posSample.xyz;
vec3 worldNormal = normalize(normalSample.xyz);
float roughness = clamp(pbrSample.g, 0.0, 1.0);
float metallic = clamp(pbrSample.b, 0.0, 1.0);
float reflectiveness = clamp(pbrSample.a, 0.0, 1.0);
float refractiveness = clamp(normalSample.a, 0.0, 2.0);
vec3 viewDirToCamera = normalize(ubo.cameraWorldPos.xyz - worldPos);
float NoV = clamp(dot(worldNormal, viewDirToCamera), 0.0, 1.0);
float fresnel = pow(1.0 - NoV, 5.0);
float materialReflection = reflectiveness + refractiveness - 1;
materialReflection *= mix(0.75, 1.0, metallic);
materialReflection *= smoothstep(0.7, 0.05, roughness);
materialReflection *= mix(0.45, 1.0, fresnel);
if (materialReflection <= MIN_REFLECTION) {
outColor = sceneColor;
return;
}
vec3 viewDir = normalize(worldPos - ubo.cameraWorldPos.xyz);
vec3 reflectDir = normalize(reflect(viewDir, worldNormal));
if (dot(reflectDir, worldNormal) <= 0.0) {
outColor = sceneColor;
return;
}
int steps = clamp(ubo.maxSteps, 1, 128);
float stepSize = max(ubo.ssrStepSize, 0.01);
float maxDistance = max(ubo.ssrMaxDistance, stepSize);
vec3 rayPos = worldPos;
vec2 hitUV = vec2(0.0);
bool hitFound = false;
for (int i = 0; i < steps; i++) {
rayPos += reflectDir * stepSize;
if (distance(rayPos, worldPos) > maxDistance) {
break;
}
vec4 clip = ubo.projection * ubo.view * vec4(rayPos, 1.0);
if (clip.w <= 0.0) {
break;
}
vec2 uv = clip.xy / clip.w;
uv = uv * 0.5 + 0.5;
uv.y = 1.0 - uv.y;
if (uv.x <= 0.0 || uv.x >= 1.0 || uv.y <= 0.0 || uv.y >= 1.0) {
break;
}
vec4 surfaceWorld = texture(worldPosSampler, uv);
if (surfaceWorld.a == 0.0 || length(surfaceWorld.xyz) == 0.0) {
continue;
}
float rayViewZ = abs((ubo.view * vec4(rayPos, 1.0)).z);
float surfaceViewZ = abs((ubo.view * vec4(surfaceWorld.xyz, 1.0)).z);
float depthDelta = rayViewZ - surfaceViewZ;
if (depthDelta >= 0.0 && depthDelta < THICKNESS) {
hitUV = uv;
hitFound = true;
break;
}
}
if (!hitFound) {
outColor = sceneColor;
return;
}
vec3 reflectedColor = texture(albedoSampler, hitUV).rgb;
float fade = edgeFade(hitUV);
float weight = clamp(materialReflection * fade, 0.0, 0.85);
outColor = vec4(mix(sceneColor.rgb, reflectedColor, weight), sceneColor.a);
}

View file

@ -27,6 +27,10 @@ struct Material {
uint hasOpacityMap; //88 uint hasOpacityMap; //88
uint OpacityMapIdx; //92 uint OpacityMapIdx; //92
float OpacityFactor; //96 float OpacityFactor; //96
float reflectiveness; //100
float refractiveness; //104
float Padding1; //108
float Padding2; //112
}; };
layout(set = 1, binding = 0) uniform sampler2D textSampler[MAX_TEXTURES]; layout(set = 1, binding = 0) uniform sampler2D textSampler[MAX_TEXTURES];
layout(set = 2, binding = 0) readonly buffer MaterialUniform { layout(set = 2, binding = 0) readonly buffer MaterialUniform {
@ -35,7 +39,21 @@ layout(set = 2, binding = 0) readonly buffer MaterialUniform {
void main() void main()
{ {
Material material = matUniform.materials[inMaterialIdx]; Material material = matUniform.materials[inMaterialIdx];
float Refractiveness = material.refractiveness;
float Reflectiveness = material.reflectiveness;
float Translucency = material.translucencyFactor;
float Opacity = material.OpacityFactor;
if(material.hasTranslucencyMap > 0){
vec4 translucencyMap = texture(textSampler[material.translucencyMapIdx], inTextCoords);
Translucency = (translucencyMap.x + translucencyMap.y + translucencyMap.z)/3.0;
}
if(material.hasOpacityMap > 0){
vec4 opacityMap = texture(textSampler[material.OpacityMapIdx], inTextCoords);
Opacity = (opacityMap.x + opacityMap.y + opacityMap.z)/3.0;
}
int textureIndex = int(material.textureIdx); int textureIndex = int(material.textureIdx);
if (textureIndex >= MAX_TEXTURES){ if (textureIndex >= MAX_TEXTURES){
outFragColor = vec2(0.0,0.0); outFragColor = vec2(0.0,0.0);
@ -47,7 +65,7 @@ void main()
} else { } else {
albedo = material.diffuseColor; albedo = material.diffuseColor;
} }
if (albedo.a < 0.5) { if (albedo.a < 0.5 || Translucency > 0.5 || Opacity < 0.5) {
discard; discard;
} }
@ -55,7 +73,6 @@ void main()
float moment1 = depth; float moment1 = depth;
float moment2 = depth * depth; float moment2 = depth * depth;
// Adjust moments to avoid light bleeding
float dx = dFdx(depth); float dx = dFdx(depth);
float dy = dFdy(depth); float dy = dFdy(depth);
moment2 += 0.25 * (dx * dx + dy * dy); moment2 += 0.25 * (dx * dx + dy * dy);

View file

@ -7,5 +7,5 @@ layout(location = 1) out vec4 outColor;
layout(set = 2, binding = 0) uniform samplerCube skyboxSampler; layout(set = 2, binding = 0) uniform samplerCube skyboxSampler;
void main() { void main() {
outColor = texture(skyboxSampler, outTexCoords) * vec4(0.0,0.05,0.1,1); outColor = texture(skyboxSampler, outTexCoords);// * vec4(3,1.0,0.65,1);
} }

View file

@ -4,18 +4,42 @@ layout(location = 0) in vec2 inTextCoord;
layout(location = 0) out float outAO; layout(location = 0) out float outAO;
layout(set = 0, binding = 0) uniform sampler2D ssaoSampler; layout(set = 0, binding = 0) uniform sampler2D ssaoSampler;
layout(set = 0, binding = 1) uniform sampler2D viewPosSampler;
void main() { void main() {
vec2 texelSize = 2.0 / vec2(textureSize(ssaoSampler, 0));
vec2 texelSize = 1.0 / vec2(textureSize(ssaoSampler, 0)); float centerAO = texture(ssaoSampler, inTextCoord).r;
float result = 0.0; float centerDepth = texture(viewPosSampler, inTextCoord).z;
for (int x = -2; x <= 2; x++) { float totalAO = centerAO;
for (int y = -2; y <= 2; y++) { float totalWeight = 1.0;
vec2 offset = vec2(float(x), float(y)) * texelSize;
result += texture(ssaoSampler, vec2(inTextCoord.x,inTextCoord.y) + offset).r; float weights[4] = float[](0.227027, 0.1216216, 0.054054, 0.016216);
} int offsets[4] = int[](-2, -1, 1, 2);
const float Sharpness = 20.0;
for (int i = 0; i < 4; i++) {
vec2 offsetH = vec2(float(offsets[i]), 0.0) * texelSize;
vec2 uvH = inTextCoord + offsetH;
float neighborAOH = texture(ssaoSampler, uvH).r;
float neighborDepthH = texture(viewPosSampler, uvH).z;
float weightH = weights[i] * max(0.0, 1.0 - Sharpness * abs(centerDepth - neighborDepthH));
totalAO += neighborAOH * weightH;
totalWeight += weightH;
vec2 offsetV = vec2(0.0, float(offsets[i])) * texelSize;
vec2 uvV = inTextCoord + offsetV;
float neighborAOV = texture(ssaoSampler, uvV).r;
float neighborDepthV = texture(viewPosSampler, uvV).z;
float weightV = weights[i] * max(0.0, 1.0 - Sharpness * abs(centerDepth - neighborDepthV));
totalAO += neighborAOV * weightV;
totalWeight += weightV;
} }
outAO = result / 25.0; outAO = totalAO / totalWeight;
} }

View file

@ -2,13 +2,14 @@
layout(location = 0) in vec2 inTextCoord; layout(location = 0) in vec2 inTextCoord;
layout(location = 0) out float outAO; layout(location = 0) out float outAO;
layout(location = 1) out vec4 viewPos;
layout(set = 0, binding = 0) uniform sampler2D posSampler; layout(set = 0, binding = 0) uniform sampler2D posSampler;
layout(set = 0, binding = 1) uniform sampler2D normalSampler; layout(set = 0, binding = 1) uniform sampler2D normalSampler;
layout(set = 0, binding = 2) uniform sampler2D noiseSampler; layout(set = 0, binding = 2) uniform sampler2D noiseSampler;
layout(set = 1, binding = 0) readonly buffer SSAOKernel { layout(set = 1, binding = 0) uniform SSAOKernel {
vec4 samples[]; vec4 samples[64];
} kernel; } kernel;
layout(set = 2, binding = 0) uniform SSAOInfo { layout(set = 2, binding = 0) uniform SSAOInfo {
@ -17,79 +18,75 @@ layout(set = 2, binding = 0) uniform SSAOInfo {
vec2 screenSize; // 136 vec2 screenSize; // 136
float radius; //140 float radius; //140
float bias; //144 float bias; //144
int kernelSize; //160 int kernelSize; //148
float ResolutionScale; //152;
vec2 Padding; //160;
} ssao; } ssao;
void main() { void main() {
vec2 uv = inTextCoord;
vec3 worldPos = texture(posSampler, uv).xyz; vec2 ScreenSize = ssao.screenSize * ssao.ResolutionScale;
vec3 worldNormal = normalize(texture(normalSampler, uv).xyz);
vec2 noiseScale = ssao.screenSize / 4.0; int KERNEL_SIZE = ssao.kernelSize;
vec3 fragPos = texture(posSampler, inTextCoord).xyz;
vec3 worldNorm = normalize(texture(normalSampler, inTextCoord).xyz);
if (length(worldNormal) < 0.001) { if (dot(worldNorm, worldNorm) < 0.001) {
outAO = 1.0; outAO = 1.0;
return; return;
} }
vec3 fragPos = vec3(ssao.view * vec4(worldPos, 1.0)); vec3 normal = normalize(mat3(ssao.view) * worldNorm);
vec3 normal = normalize(mat3(ssao.view) * worldNormal);
vec3 randomVec = normalize(texture(noiseSampler, inTextCoord * noiseScale).xyz); viewPos = vec4(fragPos, 1);
vec2 noiseScale = ScreenSize / 4.0;
vec3 randomVec = texture(noiseSampler, inTextCoord * noiseScale).xyz;
vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal)); vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal));
vec3 bitangent = cross(normal, tangent); vec3 bitangent = cross(normal, tangent);
mat3 TBN = mat3(tangent, bitangent, normal); mat3 TBN = mat3(tangent, bitangent, normal);
float fragDepth = -fragPos.z;
float minOptimalDistance = 15;
float maxKernelSize = float(ssao.kernelSize);
// Calculate a dynamic loop limit based on proximity
// If closer than 1.5 units, smoothly scale down the loop count
int dynamicKernelSize = int(KERNEL_SIZE);
if (fragDepth < minOptimalDistance) {
float proximityFactor = clamp(fragDepth / minOptimalDistance, 0.2, 1.0);
dynamicKernelSize = int(maxKernelSize * proximityFactor);
}
// Force a hard minimum baseline of samples so SSAO doesn't completely disappear
dynamicKernelSize = max(dynamicKernelSize, 16);
float occlusion = 0.0; float occlusion = 0.0;
float validSamples = 0.0;;
for (int i = 0; i < ssao.kernelSize; i++) { float Passes = 0.0f;
vec3 samplePos = TBN * kernel.samples[i].xyz;
samplePos = fragPos + samplePos * ssao.radius;
vec4 offset = vec4(samplePos, 1.0); for (int i = 0; i < dynamicKernelSize; i++) {
offset = ssao.projection * offset; vec3 samplePos = fragPos + (TBN * kernel.samples[i].xyz) * ssao.radius;
vec4 offset = ssao.projection * vec4(samplePos, 1.0);
offset.xyz /= offset.w; offset.xyz /= offset.w;
offset.xyz = offset.xyz * 0.5 + 0.5; offset.xyz = offset.xyz * 0.5 + 0.5;
vec2 sampleUV = clamp(vec2(offset.x, 1.0 - offset.y), 0.0, 1.0);
vec2 sampleUV = offset.xy; vec3 sampleViewPos = texture(posSampler, sampleUV).xyz;
sampleUV.y = 1 - sampleUV.y; float sampleDepth = -sampleViewPos.z;
float depthDelta = abs(fragDepth - sampleDepth);
if (sampleUV.x < 0.0 || sampleUV.x > 1.0 || if (depthDelta > ssao.radius * 2.0) {
sampleUV.y < 0.0 || sampleUV.y > 1.0) {
continue; continue;
} }
float rangeCheck = smoothstep(0.0, 1.0, ssao.radius / depthDelta);
vec3 sampleWorldPos = texture(posSampler, sampleUV).xyz; float isOccluded = step(samplePos.z + ssao.bias, sampleViewPos.z);
vec3 sampleWorldNormal = texture(normalSampler, sampleUV).xyz; occlusion += isOccluded * rangeCheck;
Passes += 1.0;
if (length(sampleWorldNormal) < 0.001) {
continue;
} }
vec3 sampleViewPos = vec3(ssao.view * vec4(sampleWorldPos, 1.0)); float Subtraction = 0.0;
if(Passes > 0){
float depthDelta = abs(fragPos.z - sampleViewPos.z); Subtraction = (occlusion / Passes);
if (depthDelta > ssao.radius) {
continue;
} }
occlusion = 1.0 - Subtraction;
float rangeCheck = 1.0 - depthDelta / ssao.radius; outAO = clamp(pow(occlusion, 3), 0.0, 1.0);
rangeCheck = rangeCheck * rangeCheck * (3.0 - 2.0 * rangeCheck);
if (sampleViewPos.z >= samplePos.z + ssao.bias) {
occlusion += rangeCheck;
}
validSamples += 1;
}
if (validSamples <= 0.0) {
outAO = 1.0;
return;
}
occlusion = 1.0 - occlusion / validSamples;
outAO = occlusion * pow(occlusion, 3.0);
} }

View file

@ -11,7 +11,26 @@
"W": 1.0 "W": 1.0
}, },
"Roughness": 0.0, "Roughness": 0.0,
"Metallic": 0.0 "Metallic": 1.0,
"EmissiveTexture": "",
"EmissiveColour": {
"X": 0.0,
"Y": 0.0,
"Z": 0.0,
"W": 1.0
},
"TranslucencyTexture": "",
"Translucency": 0.0,
"OpacityTexture": "",
"Opacity": 1.0,
"ColorTransparency": {
"X": 0.0,
"Y": 0.0,
"Z": 0.0,
"W": 1.0
},
"Refractiveness": 1.0,
"Reflectiveness": 1.0
}, },
{ {
"ID": "Cube-mat-1", "ID": "Cube-mat-1",
@ -25,7 +44,26 @@
"W": 1.0 "W": 1.0
}, },
"Roughness": 0.0, "Roughness": 0.0,
"Metallic": 0.0 "Metallic": 1.0,
"EmissiveTexture": "",
"EmissiveColour": {
"X": 0.0,
"Y": 0.0,
"Z": 0.0,
"W": 1.0
},
"TranslucencyTexture": "",
"Translucency": 0.0,
"OpacityTexture": "",
"Opacity": 1.0,
"ColorTransparency": {
"X": 0.0,
"Y": 0.0,
"Z": 0.0,
"W": 1.0
},
"Refractiveness": 1.0,
"Reflectiveness": 1.0
}, },
{ {
"ID": "Cube-mat-2", "ID": "Cube-mat-2",
@ -39,6 +77,25 @@
"W": 1.0 "W": 1.0
}, },
"Roughness": 0.0, "Roughness": 0.0,
"Metallic": 0.0 "Metallic": 1.0,
"EmissiveTexture": "",
"EmissiveColour": {
"X": 0.0,
"Y": 0.0,
"Z": 0.0,
"W": 1.0
},
"TranslucencyTexture": "",
"Translucency": 0.0,
"OpacityTexture": "",
"Opacity": 1.0,
"ColorTransparency": {
"X": 0.0,
"Y": 0.0,
"Z": 0.0,
"W": 1.0
},
"Refractiveness": 1.0,
"Reflectiveness": 1.0
} }
] ]

View file

@ -13,6 +13,7 @@ import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.I
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.TextureCache; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.TextureCache;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.PostProcessing.PostProcess; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.PostProcessing.PostProcess;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.ScreenSpace.AmbientOcclusionRenderer; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.ScreenSpace.AmbientOcclusionRenderer;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.ScreenSpace.ReflectionsRenderer;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shadows.ShadowRenderer; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shadows.ShadowRenderer;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.VkModel.*; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.VkModel.*;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.SpriteRendering.SpriteRenderer; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.SpriteRendering.SpriteRenderer;
@ -53,6 +54,7 @@ public class VulkanRenderer implements Renderer {
private final Semaphore[] RenderCompleteSemaphores; private final Semaphore[] RenderCompleteSemaphores;
private final SceneRenderer sceneRender; private final SceneRenderer sceneRender;
private final AmbientOcclusionRenderer ssaoRenderer; private final AmbientOcclusionRenderer ssaoRenderer;
private final ReflectionsRenderer ssrRender;
private final SpriteRenderer spriteRenderer; private final SpriteRenderer spriteRenderer;
private final LightRenderer lightRenderer; private final LightRenderer lightRenderer;
private final PostProcess PostProcessor; private final PostProcess PostProcessor;
@ -117,7 +119,8 @@ public class VulkanRenderer implements Renderer {
attachments.add(ssaoRenderer.getSSAOBlurAttachment()); attachments.add(ssaoRenderer.getSSAOBlurAttachment());
attachments.add(shadowRender.getShadowAttachment()); attachments.add(shadowRender.getShadowAttachment());
lightRenderer = new LightRenderer(RendererContext, attachments); lightRenderer = new LightRenderer(RendererContext, attachments);
PostProcessor = new PostProcess(RendererContext, lightRenderer.getAttachment()); ssrRender = new ReflectionsRenderer(RendererContext, sceneRender.GetMRTAttachments().GetColourAttachments(), lightRenderer.getAttachment());
PostProcessor = new PostProcess(RendererContext, ssrRender.GetSSRAttachment());
} else{ } else{
sceneRender = new ForwardSceneRender(RendererContext); sceneRender = new ForwardSceneRender(RendererContext);
@ -125,6 +128,7 @@ public class VulkanRenderer implements Renderer {
PostProcessor = new PostProcess(RendererContext, sceneRender.GetAttachmentColour()); PostProcessor = new PostProcess(RendererContext, sceneRender.GetAttachmentColour());
lightRenderer = null; lightRenderer = null;
shadowRender = null; shadowRender = null;
ssrRender = null;
} }
spriteRenderer= new SpriteRenderer(engineInstance, RendererContext, PostProcessor.GetAttachment()); spriteRenderer= new SpriteRenderer(engineInstance, RendererContext, PostProcessor.GetAttachment());
GuiRender = new GuiRenderer(engineInstance, RendererContext, GraphicsQueue, PostProcessor.GetAttachment()); GuiRender = new GuiRenderer(engineInstance, RendererContext, GraphicsQueue, PostProcessor.GetAttachment());
@ -195,6 +199,7 @@ public class VulkanRenderer implements Renderer {
Logger.debug("Waiting Vulkan Context"); Logger.debug("Waiting Vulkan Context");
sceneRender.cleanup(RendererContext); sceneRender.cleanup(RendererContext);
if(ssaoRenderer != null)ssaoRenderer.cleanup(RendererContext); if(ssaoRenderer != null)ssaoRenderer.cleanup(RendererContext);
if(ssrRender != null)ssrRender.cleanup(RendererContext);
if(shadowRender != null)shadowRender.cleanup(RendererContext); if(shadowRender != null)shadowRender.cleanup(RendererContext);
if(lightRenderer != null)lightRenderer.cleanup(RendererContext); if(lightRenderer != null)lightRenderer.cleanup(RendererContext);
PostProcessor.CleanUp(RendererContext); PostProcessor.CleanUp(RendererContext);
@ -219,6 +224,23 @@ public class VulkanRenderer implements Renderer {
VulkanUtils.CleanUpRemaining(RendererContext.GetDevice()); VulkanUtils.CleanUpRemaining(RendererContext.GetDevice());
RendererContext.cleanup(); RendererContext.cleanup();
} }
public enum DebugRenderMode{
Albedo,
Normals,
Pos,
SSAO,
Depth,
NoPosProcess,
Emissive,
Translucency,
Opacity,
PBR
}
public static volatile boolean Debug = false;
public static volatile DebugRenderMode debugMode = DebugRenderMode.Albedo;
public void DeferredRender(EngineInstance engineInstance){ public void DeferredRender(EngineInstance engineInstance){
SwapChain swapChain = RendererContext.GetSwapChain(); SwapChain swapChain = RendererContext.GetSwapChain();
WaitForFence(CurrentFrame); WaitForFence(CurrentFrame);
@ -227,12 +249,6 @@ public class VulkanRenderer implements Renderer {
var CommandPool = CommandPools[CurrentFrame]; var CommandPool = CommandPools[CurrentFrame];
var CommandBuffer = CommandBuffers[CurrentFrame]; var CommandBuffer = CommandBuffers[CurrentFrame];
int ImageIndex;
if (Resize || (ImageIndex = swapChain.FetchNextImage(RendererContext.GetDevice(), PresentCompleteSemaphores[imageAcquisitionIndex])) < 0){
resize(engineInstance);
return;
}
RecordingStart(CommandPool, CommandBuffer); RecordingStart(CommandPool, CommandBuffer);
sceneRender.Render(engineInstance,RendererContext,CommandBuffer, modelsCache,materialsCache,CurrentFrame); sceneRender.Render(engineInstance,RendererContext,CommandBuffer, modelsCache,materialsCache,CurrentFrame);
@ -243,9 +259,17 @@ public class VulkanRenderer implements Renderer {
lightRenderer.render(engineInstance, RendererContext, CommandBuffer, sceneRender.GetMRTAttachments(), lightRenderer.render(engineInstance, RendererContext, CommandBuffer, sceneRender.GetMRTAttachments(),
shadowRender.getShadowAttachment(), ssaoRenderer.getSSAOBlurAttachment(), CurrentFrame, shadowRender.getCascadeShadows(CurrentFrame)); shadowRender.getShadowAttachment(), ssaoRenderer.getSSAOBlurAttachment(), CurrentFrame, shadowRender.getCascadeShadows(CurrentFrame));
} else lightRenderer.render(engineInstance, RendererContext, CommandBuffer, sceneRender.GetMRTAttachments(),ssaoRenderer.getSSAOBlurAttachment(),CurrentFrame); } else lightRenderer.render(engineInstance, RendererContext, CommandBuffer, sceneRender.GetMRTAttachments(),ssaoRenderer.getSSAOBlurAttachment(),CurrentFrame);
PostProcessor.Render(RendererContext,CommandBuffer,lightRenderer.getAttachment()); ssrRender.Render( RendererContext, engineInstance, CommandBuffer, CurrentFrame);
PostProcessor.Render(RendererContext,CommandBuffer,ssrRender.GetSSRAttachment());
spriteRenderer.Render(engineInstance,RendererContext,CommandBuffer,PostProcessor.GetAttachment(),modelsCache,CurrentFrame); spriteRenderer.Render(engineInstance,RendererContext,CommandBuffer,PostProcessor.GetAttachment(),modelsCache,CurrentFrame);
GuiRender.Render(RendererContext,CommandBuffer,CurrentFrame,PostProcessor.GetAttachment()); GuiRender.Render(RendererContext,CommandBuffer,CurrentFrame,PostProcessor.GetAttachment());
int ImageIndex;
if (Resize || (ImageIndex = swapChain.FetchNextImage(RendererContext.GetDevice(), PresentCompleteSemaphores[imageAcquisitionIndex])) < 0){
resize(engineInstance);
return;
}
swapChainRender.Render(RendererContext,CommandBuffer,PostProcessor.GetAttachment(),ImageIndex); swapChainRender.Render(RendererContext,CommandBuffer,PostProcessor.GetAttachment(),ImageIndex);
RecordingStop(CommandBuffer); RecordingStop(CommandBuffer);
@ -290,8 +314,8 @@ public class VulkanRenderer implements Renderer {
RebuildShadowsRequested = false; RebuildShadowsRequested = false;
RebuildShadows(); RebuildShadows();
} }
if (Deferred) DeferredRender(engineInstance);
if(Deferred) DeferredRender(engineInstance); // else if(Deferred)DebugDeferredRender(engineInstance, debugMode);
else ForwardRender(engineInstance); else ForwardRender(engineInstance);
} }
@ -338,14 +362,21 @@ public class VulkanRenderer implements Renderer {
sceneRender.Resize(engineInstance,RendererContext); sceneRender.Resize(engineInstance,RendererContext);
if(Deferred) { if(Deferred) {
List<Attachment> attachments = new ArrayList<>(sceneRender.GetMRTAttachments().GetColourAttachments()); List<Attachment> attachments = new ArrayList<>(sceneRender.GetMRTAttachments().GetColourAttachments());
List<Attachment> ssaoAttachments = new ArrayList<>();
ssaoAttachments.add(attachments.get(0));
ssaoAttachments.add(attachments.get(2));
ssaoRenderer.resize(RendererContext, ssaoAttachments);
attachments.add(ssaoRenderer.getSSAOBlurAttachment()); attachments.add(ssaoRenderer.getSSAOBlurAttachment());
attachments.add(shadowRender.getShadowAttachment()); attachments.add(shadowRender.getShadowAttachment());
lightRenderer.resize(RendererContext, attachments); lightRenderer.resize(RendererContext, attachments);
PostProcessor.Resize(RendererContext, lightRenderer.getAttachment()); List<Attachment> ssaoAttachments = new ArrayList<>();
ssaoAttachments.add(attachments.get(7));
ssaoAttachments.add(attachments.get(2));
ssaoRenderer.resize(RendererContext, ssaoAttachments);
ssaoAttachments.clear();
ssaoAttachments.add(lightRenderer.getAttachment());
ssaoAttachments.add(attachments.get(0));
ssaoAttachments.add(attachments.get(2));
ssaoAttachments.add(attachments.get(3));
ssrRender.resize(RendererContext, ssaoAttachments);
PostProcessor.Resize(RendererContext, ssrRender.GetSSRAttachment());
} else{ } else{
PostProcessor.Resize(RendererContext, sceneRender.GetAttachmentColour()); PostProcessor.Resize(RendererContext, sceneRender.GetAttachmentColour());
} }

View file

@ -139,12 +139,20 @@ public class ModelCompiler {
SpecularArray = new float[]{0.0f}; SpecularArray = new float[]{0.0f};
} }
float[] GlossinessArray = new float[]{0.0f};
Result = aiGetMaterialFloatArray(aiMaterial,AI_MATKEY_GLOSSINESS_FACTOR,aiTextureType_NONE,0,GlossinessArray,MaxPointer);
if(Result != aiReturn_SUCCESS){
GlossinessArray = new float[]{0.0f};
}
if(SpecularArray[0] == 0.0f && GlossinessArray[0] != 0.0f)
SpecularArray[0] = GlossinessArray[0];
if(MetallicArray[0] == 0.0f && SpecularArray[0] != 0.0f) if(MetallicArray[0] == 0.0f && SpecularArray[0] != 0.0f)
MetallicArray[0] = SpecularArray[0]; MetallicArray[0] = SpecularArray[0];
if(MetallicRoughTexture.isEmpty()){ if(MetallicRoughTexture.isEmpty()){
MetallicRoughTexture = SpecularTexture; MetallicRoughTexture = SpecularTexture;
} }
float[] RoughnessArray = new float[]{0.0f}; float[] RoughnessArray = new float[]{0.0f};
Result = aiGetMaterialFloatArray(aiMaterial,AI_MATKEY_ROUGHNESS_FACTOR,aiTextureType_NONE,0,RoughnessArray,MaxPointer); Result = aiGetMaterialFloatArray(aiMaterial,AI_MATKEY_ROUGHNESS_FACTOR,aiTextureType_NONE,0,RoughnessArray,MaxPointer);
if(Result != aiReturn_SUCCESS){ if(Result != aiReturn_SUCCESS){
@ -169,6 +177,13 @@ public class ModelCompiler {
OpacityArray = new float[]{0.0f}; OpacityArray = new float[]{0.0f};
} }
AIColor4D colour_transparency = AIColor4D.create();
Vector4f ColorTransparency = new Vector4f();
Result = aiGetMaterialColor(aiMaterial,AI_MATKEY_COLOR_TRANSPARENT,aiTextureType_NONE,0,colour_transparency);
if(Result != aiReturn_SUCCESS){
ColorTransparency.set(colour_transparency.r(),colour_transparency.g(),colour_transparency.b(),colour_transparency.a());
}
float[] RefractionArray = new float[]{0.0f}; float[] RefractionArray = new float[]{0.0f};
Result = aiGetMaterialFloatArray(aiMaterial,AI_MATKEY_REFRACTI,aiTextureType_NONE,0,RefractionArray,MaxPointer); Result = aiGetMaterialFloatArray(aiMaterial,AI_MATKEY_REFRACTI,aiTextureType_NONE,0,RefractionArray,MaxPointer);
if(Result != aiReturn_SUCCESS){ if(Result != aiReturn_SUCCESS){
@ -181,14 +196,6 @@ public class ModelCompiler {
ReflectionArray = new float[]{0.0f}; ReflectionArray = new float[]{0.0f};
} }
AIColor4D colour_transparency = AIColor4D.create();
Vector4f ColorTransparency = new Vector4f();
Result = aiGetMaterialColor(aiMaterial,AI_MATKEY_COLOR_TRANSPARENT,aiTextureType_NONE,0,colour_transparency);
if(Result != aiReturn_SUCCESS){
ColorTransparency.set(colour_transparency.r(),colour_transparency.g(),colour_transparency.b(),colour_transparency.a());
}
return new MaterialData(ModelName + "-mat-" + Position,DiffuseTexture,NormalTexture, MetallicRoughTexture,diffuse,RoughnessArray[0],MetallicArray[0], EmissiveTexture,emissiveColour, TranslucencyTexture, TranslucencyArray[0], OpacityTexture, OpacityArray[0],ColorTransparency,RefractionArray[0], ReflectionArray[0]); return new MaterialData(ModelName + "-mat-" + Position,DiffuseTexture,NormalTexture, MetallicRoughTexture,diffuse,RoughnessArray[0],MetallicArray[0], EmissiveTexture,emissiveColour, TranslucencyTexture, TranslucencyArray[0], OpacityTexture, OpacityArray[0],ColorTransparency,RefractionArray[0], ReflectionArray[0]);
} }

View file

@ -52,7 +52,7 @@ import static org.lwjgl.glfw.GLFW.*;
public class GameCore implements GameLogic { public class GameCore implements GameLogic {
private static final float MOUSE_SENSITIVITY = 0.1f; private static final float MOUSE_SENSITIVITY = 0.1f;
private static final float MOVEMENT_SPEED = 0.1f; private static final float MOVEMENT_SPEED = 0.01f;
public static boolean LoadingLevel = false; public static boolean LoadingLevel = false;
private Vector2f LastMousePos = new Vector2f(0,0); private Vector2f LastMousePos = new Vector2f(0,0);
@ -100,11 +100,15 @@ public class GameCore implements GameLogic {
List<ModelData> models = new ArrayList<>(); List<ModelData> models = new ArrayList<>();
List<MaterialData> materials = new ArrayList<>(); List<MaterialData> materials = new ArrayList<>();
ModelData SponzaData = ModelLoader.LoadModel("resources/models/Cafe/exterior.json"); ModelData SponzaData = ModelLoader.LoadModel("resources/models/Cafe/exterior.json");
models.add(SponzaData);
List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Cafe/exterior_mat.json"); List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Cafe/exterior_mat.json");
materials.addAll(SponzaMaterial);
ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/Cafe/interior.json"); ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/Cafe/interior.json");
models.add(SponzaData1);
List<MaterialData> SponzaMaterial1= ModelLoader.LoadMaterials("resources/models/Cafe/interior_mat.json"); List<MaterialData> SponzaMaterial1= ModelLoader.LoadMaterials("resources/models/Cafe/interior_mat.json");
scene.AddActor(new Actor3D("Sponza1", SponzaData.ID(), new Vector3f(0,0f,-5f)).SetScale(0.1f)); materials.addAll(SponzaMaterial1);
scene.AddActor(new Actor3D("Sponza2", SponzaData1.ID(), new Vector3f(0,0f,-5f)).SetScale(0.1f)); scene.AddActor(new Actor3D("Sponza1", SponzaData.ID(), new Vector3f(0,0f,-5f)).SetScale(0.05f));
scene.AddActor(new Actor3D("Sponza2", SponzaData1.ID(), new Vector3f(0,0f,-5f)).SetScale(0.05f));
// ModelData treeModel = ModelLoader.LoadModel("resources/models/tree/tree.json"); // ModelData treeModel = ModelLoader.LoadModel("resources/models/tree/tree.json");
// models.add(treeModel); // models.add(treeModel);
// Actor3D treeEntity = new Actor3D("treeEntity", treeModel.ID(), new Vector3f(0.0f, 0.0f, 0.0f)); // Actor3D treeEntity = new Actor3D("treeEntity", treeModel.ID(), new Vector3f(0.0f, 0.0f, 0.0f));
@ -113,8 +117,8 @@ public class GameCore implements GameLogic {
// materials.addAll(ModelLoader.LoadMaterials("resources/models/tree/tree_mat.json")); // materials.addAll(ModelLoader.LoadMaterials("resources/models/tree/tree_mat.json"));
// ModelData treeModel = ModelLoader.LoadModel("resources/models/Forest/forest.json"); // ModelData treeModel = ModelLoader.LoadModel("resources/models/Forest/forest.json");
// models.add(treeModel); // models.add(treeModel);
// Actor3D treeEntity = new Actor3D("treeEntity", treeModel.ID(), new Vector3f(0.0f, -100.0f, 0.0f)); // Actor3D treeEntity = new Actor3D("treeEntity", treeModel.ID(), new Vector3f(0.0f, 00.0f, 0.0f));
// treeEntity.SetScale(10f); // treeEntity.SetScale(0.1f);
// scene.AddActor(treeEntity); // scene.AddActor(treeEntity);
// materials.addAll(ModelLoader.LoadMaterials("resources/models/Forest/forest_mat.json")); // materials.addAll(ModelLoader.LoadMaterials("resources/models/Forest/forest_mat.json"));
MelonaData = ModelLoader.LoadModel("resources/models/cube/Cube.json"); MelonaData = ModelLoader.LoadModel("resources/models/cube/Cube.json");
@ -158,10 +162,6 @@ public class GameCore implements GameLogic {
} }
boolean createOfflinePlayer = !PrimaryRuntime.IsServer && !ClientSideNetworkUtils.Connected; boolean createOfflinePlayer = !PrimaryRuntime.IsServer && !ClientSideNetworkUtils.Connected;
materials.addAll(SponzaMaterial);
materials.addAll(SponzaMaterial1);
models.add(SponzaData);
models.add(SponzaData1);
materials.addAll(MelonaMat); materials.addAll(MelonaMat);
materials.addAll(CollisionVisualisationMat); materials.addAll(CollisionVisualisationMat);
materials.addAll(MelonaMaterial); materials.addAll(MelonaMaterial);
@ -191,90 +191,105 @@ public class GameCore implements GameLogic {
} }
scene.GetLightingManager().GetAmbientLightColour().set(1.0f, 0.9f, 0.75f); scene.GetLightingManager().GetAmbientLightColour().set(1.0f, 0.9f, 0.75f);
scene.GetLightingManager().SetAmbientLightIntensity(0.15f); scene.GetLightingManager().SetAmbientLightIntensity(0.1f);
scene.GetLightingManager().GetAmbientLightColour().set(0.3f, 0.35f, 0.5f); // scene.GetLightingManager().GetAmbientLightColour().set(0.6f, 0.5f, 0.4f);
scene.GetLightingManager().SetAmbientLightIntensity(0.05f); // scene.GetLightingManager().SetAmbientLightIntensity(0.1f);
SkyLight = new Light(new Vector3f(1.5f, 1.20f, 1.0f),new Vector3f(0.0f, -1.0f, 0.3f), true, 4.00f);
SkyLight = new Light(new Vector3f(0.25f, 0.75f, 1.3f),new Vector3f(0.0f, -1.0f, 0.0f), true, 4.0f);
SkyLight.SetType(Light.LightType.Directional);
List<ILight> lights = new ArrayList<>(); List<ILight> lights = new ArrayList<>();
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-433, 445f, -424f).div(10.0f),false,3000.0f+ (float)(Math.random() * 100.0)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-210, 445f, 460f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-966, 445f, 204f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-176, 445f, 1000f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(777, 445f, 858).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(376, 445f, -2136).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,2.0f),new Vector3f(2163, 445f, 1880).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3334, 445f, 2405).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3509, 445f, 1825).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3877, 445f, 3378).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(4925, 445f, 3430).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-2083, 445f, -1826).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2076, 410, 1272).div(10.0f),false,100.0f)); SkyLight = new Light(new Vector3f(1.5f, 1.20f, 1.0f),new Vector3f(0.0f, -1.0f, 0.3f), true, 4.00f);
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2446, 465, 2303).div(10.0f),false,100.0f)); // SkyLight = new Light(new Vector3f(2.75f, 1.75f, 0.3f),new Vector3f(0.0f, -1.0f, 0.0f), true, 6.0f);
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-842, 410, -1141).div(10.0f),false,100.0f)); //SkyLight = new Light(new Vector3f(1.5f, 1.20f, 1.0f),new Vector3f(0.0f, -1.0f, 0.3f), true, 5.00f);
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-207, 410, -1830).div(10.0f),false,100.0f)); SkyLight.SetType(Light.LightType.Directional);
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(899, 460, -2015).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1775, 460, -3448).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1800, 460, -4154).div(10.0f),false,1000.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -387).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1198, 410, -964).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1778, 410, -1502).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2692, 333, -2109).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2849, 333, -1724).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2019, 410, -729).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -389).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1337, 410, 122).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(615.8f, 305.5f, -904.1f).div(10.0f),false,200.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(425.4f, 305.5f, -541.0f).div(10.0f),false,200.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(501.4f, 305.5f, -102.7f).div(10.0f),false,200.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(803.0f, 305.5f, 50.2f).div(10.0f),false,200.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(720.4f, 261.6f, -329.2f).div(10.0f),false,75.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(879.4f,261.6f,-246.3f).div(10.0f),false,75.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1037.7f,261.6f,-155.0f).div(10.0f),false,75.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(663.4f,261.6f,-468.9f).div(10.0f),false,75.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(772.3f,243.7f,-513.7f).div(10.0f),false,50.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(193.1f,260.7f,-859.3f).div(10.0f),false,50.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(51.0f,260.7f,-603.0f).div(10.0f),false,50.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(-95.0f,260.7f,-334.2f).div(10.0f),false,50.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(41.5f,260.7f,5.7f).div(10.0f),false,50.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(335.8f,260.7f,144.6f).div(10.0f),false,50.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(616.9f,260.7f,255.4f).div(10.0f),false,50.0f));
lights.add(new Light(new Vector3f(0.75f,2.0f,0.75f),new Vector3f(1086, 425, -3375).div(10.0f),false,500.0f));
// lights.add(new Light(new Vector3f(3.0f,2.25f,0.0f),new Vector3f(350.0f, 1500.0f, -420.0f),false,10000.0f));
// lights.add(new Light(new Vector3f(3.0f,2.25f,0.0f),new Vector3f(400.0f, 1550.0f, -350.0f),false,10000.0f));
lights.add(SkyLight); lights.add(SkyLight);
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-433, 445f, -424f).div(20.0f),false,3000.0f/10.0f+ (float)(Math.random() * 100.0/10.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-210, 445f, 460f).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-966, 445f, 204f).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-176, 445f, 1000f).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(777, 445f, 858).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(376, 445f, -2136).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,2.0f),new Vector3f(2163, 445f, 1880).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3334, 445f, 2405).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3509, 445f, 1825).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3877, 445f, 3378).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(4925, 445f, 3430).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-2083, 445f, -1826).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f)));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2076, 410, 1272).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2446, 465, 2303).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-842, 410, -1141).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-207, 410, -1830).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(899, 460, -2015).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1775, 460, -3448).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1800, 460, -4154).div(20.0f),false,1000.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -387).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1198, 410, -964).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1778, 410, -1502).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2692, 333, -2109).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2849, 333, -1724).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2019, 410, -729).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -389).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1337, 410, 122).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(615.8f, 305.5f, -904.1f).div(20.0f),false,200.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(425.4f, 305.5f, -541.0f).div(20.0f),false,200.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(501.4f, 305.5f, -102.7f).div(20.0f),false,200.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(803.0f, 305.5f, 50.2f).div(20.0f),false,200.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(720.4f, 261.6f, -329.2f).div(20.0f),false,75.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(879.4f,261.6f,-246.3f).div(20.0f),false,75.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1037.7f,261.6f,-155.0f).div(20.0f),false,75.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(663.4f,261.6f,-468.9f).div(20.0f),false,75.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(772.3f,243.7f,-513.7f).div(20.0f),false,50.0f/10.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(193.1f,260.7f,-859.3f).div(20.0f),false,50.0f/10.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(51.0f,260.7f,-603.0f).div(20.0f),false,50.0f/10.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(-95.0f,260.7f,-334.2f).div(20.0f),false,50.0f/10.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(41.5f,260.7f,5.7f).div(20.0f),false,50.0f/10.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(335.8f,260.7f,144.6f).div(20.0f),false,50.0f/10.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(616.9f,260.7f,255.4f).div(20.0f),false,50.0f/10.0f));
lights.add(new Light(new Vector3f(0.75f,2.0f,0.75f),new Vector3f(1086, 425, -3375).div(20.0f),false,500.0f));
lights.add(new Light(new Vector3f(3.0f,2.25f,0.0f),new Vector3f(350.0f, 1500.0f, -420.0f),false,10000.0f));
lights.add(new Light(new Vector3f(3.0f,2.25f,0.0f),new Vector3f(400.0f, 1550.0f, -350.0f),false,10000.0f));
ILight[] lightArr = new ILight[lights.size()]; ILight[] lightArr = new ILight[lights.size()];
lightArr = lights.toArray(lightArr); lightArr = lights.toArray(lightArr);
scene.GetLightingManager().AddLights(lightArr); scene.GetLightingManager().AddLights(lightArr);
Vector3f Position = new Vector3f(-40, 5, 10);
SpawnPosition.set(Position);
rotationMatrix.set(new Matrix4f().rotateX((float)Math.random()).rotateY((float)Math.random()).rotateZ((float)Math.random()));
SpawnDirection.set(new Vector3f((float)Math.random()));
rotationMatrix.positiveZ(SpawnDirection).negate().mul(5);
SpawnPosition.add(SpawnDirection);
var Cube = new Actor3D("MelonaSpawned" + scene.GetActors().size(), CubeModelID, new Vector3f(SpawnPosition));
Cube.SetScale(5f);
ConvexMesh mesh = ConvexMesh.Box(0.5f,0.5f,0.5f);
Cube.CreatePhysicsController(mesh ,0);
Cube.SetPositionOffset(new Vector3f(0,0,0));
Cube.SetServerSynced(false);
scene.AddActor(Cube);
InitiateAudio(engineInstance); InitiateAudio(engineInstance);
for(int i = 0; i < ActorEditorComponents.size(); i++){ // permutation.GeneratePermutationArray(5783904701859L);
ActorEditorComponents.get(i).UpdateAll();
}
//if(PrimaryRuntime.IsServer) {
permutation.GeneratePermutationArray(5783904701859L);
// for(int x = -1; x < 2; x++){ // for(int x = -1; x < 2; x++){
// for(int y = -1; y < 2; y++){ // for(int y = -1; y < 2; y++){
// GenerateChunk(new Vector3i(x, 0, y), 16); // GenerateChunk(new Vector3i(x, 0, y), 16);
//
// } // }
// } // }
// for(int i = 0; i < 20; i++){ // for(int i = 0; i < 20; i++){
// SpawnNewActor(engineInstance, new Vector3f(-5 + (float)Math.random() * 10,10 + (float)Math.random() * 10, -5 + (float)Math.random() * 10), new Vector3f(0, 0, 0), new Vector3f(1, 1, 1)); // SpawnNewActor(engineInstance, new Vector3f(-5 + (float)Math.random() * 10,10 + (float)Math.random() * 10, -5 + (float)Math.random() * 10), new Vector3f(0, 0, 0), new Vector3f(1, 1, 1));
// } // }
//}
Settings.textBuffer.set(ClientSideNetworkUtils.ServerIP); Settings.textBuffer.set(ClientSideNetworkUtils.ServerIP);
Settings.UsernameBuffer.set("Player"); Settings.UsernameBuffer.set("Player");
return new InitData(models,materials,guiTextures); return new InitData(models,materials,guiTextures);
@ -348,7 +363,7 @@ public class GameCore implements GameLogic {
RigidPhysicsController physicsController = (RigidPhysicsController) Melona.GetPhysicsController(); RigidPhysicsController physicsController = (RigidPhysicsController) Melona.GetPhysicsController();
//RigidBody.RigidBodyRegister.get(physicsController.RigidBodyID).LinearVelocity.set(0,0,-20f -(40f * (float)Math.random())); //RigidBody.RigidBodyRegister.get(physicsController.RigidBodyID).LinearVelocity.set(0,0,-20f -(40f * (float)Math.random()));
scene.AddActor(Melona); //scene.AddActor(Melona);
} }
public void SetPlayerActorID(String id) { public void SetPlayerActorID(String id) {
this.PlayerActorID = id; this.PlayerActorID = id;

View file

@ -4,20 +4,28 @@ import imgui.ImGui;
import imgui.flag.ImGuiCond; import imgui.flag.ImGuiCond;
import imgui.flag.ImGuiWindowFlags; import imgui.flag.ImGuiWindowFlags;
import imgui.type.ImFloat; import imgui.type.ImFloat;
import net.halbear.Terrain4J.EngineCore.Display.VulkanRenderer;
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig; import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance; import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
import net.halbear.Terrain4J.EngineCore.Main.AudioInstance; import net.halbear.Terrain4J.EngineCore.Main.AudioInstance;
import net.halbear.Terrain4J.EngineCore.Main.GameCore; import net.halbear.Terrain4J.EngineCore.Main.GameCore;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime; import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIOverlay; import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIOverlay;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.PostProcessing.PostProcess;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.ScreenSpace.AmbientOcclusionRenderer;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.DeferredSceneRender; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.DeferredSceneRender;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ForwardSceneRender; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ForwardSceneRender;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanBuffer;
import org.tinylog.Logger; import org.tinylog.Logger;
public class PerformanceOverlay implements GUIOverlay { public class PerformanceOverlay implements GUIOverlay {
private final ImFloat GammaValue = new ImFloat(0.8545f); private final ImFloat GammaValue = new ImFloat(0.8545f);
public int[] ShadowSize = new int[]{4096}; public int[] ShadowSize = new int[]{4096};
public int[] ShadowDistance = new int[]{1000}; public int[] ShadowDistance = new int[]{1000};
public float[] Gamma = new float[]{1.75f};
public float[] Exposure = new float[]{2.5f};
public float[] BlurRadius = new float[]{2.5f};
public float[] SSAOscale = new float[]{1.0f};
public PerformanceOverlay(){ public PerformanceOverlay(){
ShadowSize[0] = EngineConfig.getInstance().GetShadowMapSize(); ShadowSize[0] = EngineConfig.getInstance().GetShadowMapSize();
@ -46,6 +54,64 @@ public class PerformanceOverlay implements GUIOverlay {
ImGui.separator(); ImGui.separator();
ImGui.text("GRAPHICS SETTINGS:"); ImGui.text("GRAPHICS SETTINGS:");
ImGui.text(" "); ImGui.text(" ");
// ImGui.text("Debug Options");
// ImGui.text(" ");
// if(ImGui.button("Debug On")){
// Logger.debug("Debug On");
// VulkanRenderer.Debug = true;
// }
// ImGui.sameLine();
// if(ImGui.button("Debug Off")){
// Logger.debug("Debug Off");
// VulkanRenderer.Debug = false;
// }
// if(ImGui.button("Albedo")){
// Logger.debug("Albedo");
// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.Albedo;
// }
// ImGui.sameLine();
// if(ImGui.button("Normals")){
// Logger.debug("Normals");
// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.Normals;
// }
// ImGui.sameLine();
// if(ImGui.button("PBR")){
// Logger.debug("PBR");
// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.PBR;
// }
// ImGui.sameLine();
// if(ImGui.button("SSAO")){
// Logger.debug("SSAO");
// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.SSAO;
// }
// if(ImGui.button("Position")){
// Logger.debug("Position");
// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.Pos;
// }
// ImGui.sameLine();
// if(ImGui.button("Emissive")){
// Logger.debug("Emissive");
// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.Emissive;
// }
// ImGui.sameLine();
// if(ImGui.button("Opacity")){
// Logger.debug("Opacity");
// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.Opacity;
// }
// ImGui.sameLine();
// if(ImGui.button("Translucency")){
// Logger.debug("Translucency");
// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.Translucency;
// }
// if(ImGui.button("No PostFX")){
// Logger.debug("No PostFX");
// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.NoPosProcess;
// }
// ImGui.sameLine();
// if(ImGui.button("Depth")){
// Logger.debug("Depth");
// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.Depth;
// }
ImGui.text("Rendering API:"); ImGui.text("Rendering API:");
if(ImGui.button("Vulkan")){ if(ImGui.button("Vulkan")){
Logger.debug("Switch to Vulkan"); Logger.debug("Switch to Vulkan");
@ -162,6 +228,18 @@ public class PerformanceOverlay implements GUIOverlay {
parent.CoolDown = 2000; parent.CoolDown = 2000;
EngineConfig.getInstance().MaxShadowDistance(ShadowDistance[0]); EngineConfig.getInstance().MaxShadowDistance(ShadowDistance[0]);
} }
if (ImGui.sliderFloat("Gamma", Gamma, 0,10f)) {
PostProcess.GAMMA = Gamma[0];
}
if (ImGui.sliderFloat("Exposure", Exposure, 0,10f)) {
PostProcess.EXPOSURE = Exposure[0];
}
if (ImGui.sliderFloat("Bloom Radius", BlurRadius, 0,10f)) {
PostProcess.BLOOM_RADIUS = BlurRadius[0];
}
if (ImGui.sliderFloat("SSAO Resolution", SSAOscale, 0,2f)) {
AmbientOcclusionRenderer.SSAO_RESOLUTION_SCALE = SSAOscale[0];
}
ImGui.text(" "); ImGui.text(" ");
ImGui.text("anti aliasing:"); ImGui.text("anti aliasing:");
if(ImGui.button("No AA")){ if(ImGui.button("No AA")){
@ -234,10 +312,6 @@ public class PerformanceOverlay implements GUIOverlay {
EngineConfig.getInstance().SetAlphaToCoverage(true); EngineConfig.getInstance().SetAlphaToCoverage(true);
if(engineInstance.window().GetLinkedApi() == EngineConfig.RenderAPI.Vulkan) PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext()); if(engineInstance.window().GetLinkedApi() == EngineConfig.RenderAPI.Vulkan) PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
} }
ImGui.inputFloat("Gamma", GammaValue, 0.0025f, 0.22725f, "%.4f");
if (ImGui.isItemDeactivatedAfterEdit()) {
// EngineConfig.getInstance().Gamma = GammaValue.get();
}
ImGui.separator(); ImGui.separator();
ImGui.text("Level Tools:"); ImGui.text("Level Tools:");
if(ImGui.button("Spawn Melona")){ if(ImGui.button("Spawn Melona")){

View file

@ -32,9 +32,9 @@ public class SSAO_Utils {
} }
public static ByteBuffer GenerateNoiseTexture() { public static ByteBuffer GenerateNoiseTexture() {
ByteBuffer buffer = BufferUtils.createByteBuffer(16 * 4 * Float.BYTES); ByteBuffer buffer = BufferUtils.createByteBuffer(4 * 4 * 4 * Float.BYTES);
Random rnd = new Random(); Random rnd = new Random();
for (int i = 0; i < 16; i++) { for (int i = 0; i < 4 * 4; i++) {
float x = rnd.nextFloat() * 2.0f - 1.0f; float x = rnd.nextFloat() * 2.0f - 1.0f;
float y = rnd.nextFloat() * 2.0f - 1.0f; float y = rnd.nextFloat() * 2.0f - 1.0f;
buffer.putFloat(x); buffer.putFloat(x);

View file

@ -82,7 +82,7 @@ public class LightRenderer {
lightSpecConsts = new LightSpecConsts(); lightSpecConsts = new LightSpecConsts();
ShaderModule[] shaderModules = CreateShaderModules(VkCtx, lightSpecConsts,true); ShaderModule[] shaderModules = CreateShaderModules(VkCtx, lightSpecConsts,true);
var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_REPEAT, var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true); VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true);
textureSampler = new TextureSampler(VkCtx, textureSamplerInfo); textureSampler = new TextureSampler(VkCtx, textureSamplerInfo);
int numAttachments = attachments.size(); int numAttachments = attachments.size();
@ -155,7 +155,7 @@ public class LightRenderer {
SwapChain swapChain = VkCtx.GetSwapChain(); SwapChain swapChain = VkCtx.GetSwapChain();
VkExtent2D swapChainExtent = swapChain.GetSwapChainExtent(); VkExtent2D swapChainExtent = swapChain.GetSwapChainExtent();
return new Attachment(VkCtx, swapChainExtent.width(), swapChainExtent.height(), return new Attachment(VkCtx, swapChainExtent.width(), swapChainExtent.height(),
COLOUR_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,1); COLOUR_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,1);
} }
private static VkRenderingAttachmentInfo.Buffer CreateColourAttachmentInfo(Attachment attachment, VkClearValue clearValue) { private static VkRenderingAttachmentInfo.Buffer CreateColourAttachmentInfo(Attachment attachment, VkClearValue clearValue) {

View file

@ -12,13 +12,16 @@ import static org.lwjgl.vulkan.VK10.VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
public class MultiRenderTargetAttachments { public class MultiRenderTargetAttachments {
public static final int ALBEDO_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; public static final int ALBEDO_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
public static final int SSR_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
public static final int DEPTH_FORMAT = VK_FORMAT_D32_SFLOAT; public static final int DEPTH_FORMAT = VK_FORMAT_D32_SFLOAT;
public static final int REFLECT_REFRACT = VK_FORMAT_R16G16_SFLOAT;
public static final int NORMAL_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; public static final int NORMAL_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
public static final int PBR_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; public static final int PBR_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
public static final int EMISSIVE_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; public static final int EMISSIVE_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
public static final int TRANSLUCECNY_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; public static final int TRANSLUCECNY_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
public static final int OPACITY_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; public static final int OPACITY_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
public static final int POSITION_FORMAT = VK_FORMAT_R32G32B32A32_SFLOAT; public static final int POSITION_FORMAT = VK_FORMAT_R32G32B32A32_SFLOAT;
public static final int VIEW_POS_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
public static final int SSAO_RAW_ATTACHMENT = VK_FORMAT_R8_UNORM; public static final int SSAO_RAW_ATTACHMENT = VK_FORMAT_R8_UNORM;
public static final int SSAO_BLUR_ATTACHMENT = VK_FORMAT_R8_UNORM; public static final int SSAO_BLUR_ATTACHMENT = VK_FORMAT_R8_UNORM;
private final List<Attachment> ColourAttachments; private final List<Attachment> ColourAttachments;
@ -53,6 +56,10 @@ public class MultiRenderTargetAttachments {
//Opacity //Opacity
Attachment = new Attachment(VkCtx, Width, Height, OPACITY_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 1); Attachment = new Attachment(VkCtx, Width, Height, OPACITY_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 1);
ColourAttachments.add(Attachment); ColourAttachments.add(Attachment);
//ViewPos
Attachment = new Attachment(VkCtx, Width, Height, VIEW_POS_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 1);
ColourAttachments.add(Attachment);
DepthAttachment = new Attachment(VkCtx, Width, Height, DEPTH_FORMAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 1); DepthAttachment = new Attachment(VkCtx, Width, Height, DEPTH_FORMAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 1);
} }

View file

@ -11,6 +11,7 @@ import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.P
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shader.*; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shader.*;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.CommandBuffer; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.CommandBuffer;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.Device; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.Device;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ImageView;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.SwapChain.SwapChain; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.SwapChain.SwapChain;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanBuffer; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanBuffer;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils;
@ -20,9 +21,12 @@ import org.lwjgl.util.shaderc.Shaderc;
import org.lwjgl.vulkan.*; import org.lwjgl.vulkan.*;
import org.tinylog.Logger; import org.tinylog.Logger;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer; import java.nio.FloatBuffer;
import java.nio.LongBuffer; import java.nio.LongBuffer;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
import static org.lwjgl.vulkan.VK10.*; import static org.lwjgl.vulkan.VK10.*;
import static org.lwjgl.vulkan.VK13.*; import static org.lwjgl.vulkan.VK13.*;
@ -30,56 +34,124 @@ import static org.lwjgl.vulkan.VK13.*;
public class PostProcess { public class PostProcess {
public static final int COLOUR_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; public static final int COLOUR_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
private static final String DESCRIPTOR_ID_ATTACHMENT = "POST_DESC_ID_ATT"; private static final String DESCRIPTOR_ID_ATTACHMENT = "POST_DESC_ID_ATT";
private static final String DESCRIPTOR_ID_BLOOM_PROPERTIES_HORIZONTAL = "POST_DESC_ID_BLOOM_PROPERTIES_HORIZONTAL";
private static final String DESCRIPTOR_ID_BLOOM_PROPERTIES_VERTICAL = "POST_DESC_ID_BLOOM_PROPERTIES_VERTICAL";
private static final String DESCRIPTOR_ID_BLOOM_PROPERTIES_FINAL = "POST_DESC_ID_BLOOM_PROPERTIES_FINAL";
private static final String DESCRIPTOR_ID_BLOOM_ATTACHMENT = "POST_DESC_ID_BLOOM_ATT";
private static final String DESCRIPTOR_ID_BLOOM_PONG_ATTACHMENT = "POST_DESC_ID_BLOOM_PONG_ATT";
private static final String DESCRIPTOR_ID_BLOOM_IMAGE_ATTACHMENT = "POST_DESC_ID_BLOOM_IMAGE_ATT";
private static final String DESCRIPTOR_ID_SCREEN_SIZE = "POST_DESC_ID_SCREEN_SIZE"; private static final String DESCRIPTOR_ID_SCREEN_SIZE = "POST_DESC_ID_SCREEN_SIZE";
private static final String MULTI_PASS_FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/multi-sampled_post_process_frag.glsl"; private static final String MULTI_PASS_FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/multi-sampled_post_process_frag.glsl";
private static final String MULTI_PASS_FRAGMENT_SHADER_FILE_SPV = MULTI_PASS_FRAGMENT_SHADER_FILE_GLSL + ".spv"; private static final String MULTI_PASS_FRAGMENT_SHADER_FILE_SPV = MULTI_PASS_FRAGMENT_SHADER_FILE_GLSL + ".spv";
private static final String BLOOM_FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/bloom_pass_frag.glsl";
private static final String BLOOM_FRAGMENT_SHADER_FILE_SPV = BLOOM_FRAGMENT_SHADER_FILE_GLSL + ".spv";
private static final String SINGLE_PASS_FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/post_process_frag.glsl"; private static final String SINGLE_PASS_FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/post_process_frag.glsl";
private static final String SINGLE_PASS_FRAGMENT_SHADER_FILE_SPV = SINGLE_PASS_FRAGMENT_SHADER_FILE_GLSL + ".spv"; private static final String SINGLE_PASS_FRAGMENT_SHADER_FILE_SPV = SINGLE_PASS_FRAGMENT_SHADER_FILE_GLSL + ".spv";
private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/basic_screen_vertex.glsl"; private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/basic_screen_vertex.glsl";
private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv"; private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv";
private final DescriptorSetLayout AttachmentDescriptorSetLayout; private final DescriptorSetLayout AttachmentDescriptorSetLayout;
private final DescriptorSetLayout[] MultiAttachmentDescriptorSetLayout = new DescriptorSetLayout[2];
private final VkClearValue ClearValueColour; private final VkClearValue ClearValueColour;
private final DescriptorSetLayout FragmentUniformDescriptorSetLayout; private final DescriptorSetLayout FragmentUniformDescriptorSetLayout;
private final Pipeline pipeline; private final Pipeline pipeline;
private final Pipeline bloomPipeline;
private final VulkanBuffer ScreenSizeBuffer; private final VulkanBuffer ScreenSizeBuffer;
private final VulkanBuffer BloomPropertiesHorizontalBuffer;
private final VulkanBuffer BloomPropertiesVerticalBuffer;
private final VulkanBuffer BloomPropertiesFinalBuffer;
private final SpecializationConstants specConstants; private final SpecializationConstants specConstants;
private final TextureSampler textureSampler; private final TextureSampler textureSampler;
private Attachment ColourAttachment; private Attachment ColourAttachment;
private VkRenderingAttachmentInfo.Buffer ColourAttachmentInfo; private VkRenderingAttachmentInfo.Buffer ColourAttachmentInfo;
private VkRenderingAttachmentInfo.Buffer FinalOutputInfo;
private Attachment BloomPingAttachment;
private Attachment BloomPongAttachment;
private Attachment FinalAttachment;
private VkRenderingAttachmentInfo.Buffer BloomPingAttachmentInfo;
private VkRenderingAttachmentInfo.Buffer BloomPongAttachmentInfo;
private VkRenderingInfo RenderingInfo; private VkRenderingInfo RenderingInfo;
private VkRenderingInfo SingleRenderingInfo;
private VkRenderingInfo BloomPingRenderingInfo;
private VkRenderingInfo BloomPongRenderingInfo;
public PostProcess(VulkanContext VkCtx, Attachment SrcAttachment){ public PostProcess(VulkanContext VkCtx, Attachment SrcAttachment){
ClearValueColour = VkClearValue.calloc(); ClearValueColour = VkClearValue.calloc();
ClearValueColour.color(c->c.float32(0,0.0f).float32(1,0.0f).float32(2,0.0f).float32(3,0.0f)); ClearValueColour.color(c->c.float32(0,0.0f).float32(1,0.0f).float32(2,0.0f).float32(3,0.0f));
ColourAttachment = CreateColourAttachment(VkCtx); ColourAttachment = CreateColourAttachment(VkCtx);
ColourAttachmentInfo = CreateColourAttachmentInfo(ColourAttachment,ClearValueColour); BloomPingAttachment = CreateColourAttachment(VkCtx);
RenderingInfo = CreateRenderInfo(ColourAttachment,ColourAttachmentInfo); BloomPongAttachment = CreateColourAttachment(VkCtx);
FinalAttachment = CreateColourAttachment(VkCtx);
var TextureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_REPEAT,VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK,1,true); List<Attachment> attachments = new ArrayList<>();
textureSampler = new TextureSampler(VkCtx, TextureSamplerInfo); attachments.add(ColourAttachment);
attachments.add(BloomPingAttachment);
ColourAttachmentInfo = CreateColourAttachmentInfos(attachments,ClearValueColour);
BloomPingAttachmentInfo = CreateColourAttachmentInfo(BloomPingAttachment,ClearValueColour);
BloomPongAttachmentInfo = CreateColourAttachmentInfo(BloomPongAttachment,ClearValueColour);
FinalOutputInfo = CreateColourAttachmentInfo(FinalAttachment,ClearValueColour);
RenderingInfo = CreateRenderInfo(ColourAttachment,ColourAttachmentInfo);
BloomPingRenderingInfo = CreateRenderInfo(BloomPingAttachment, BloomPingAttachmentInfo);
BloomPongRenderingInfo = CreateRenderInfo(BloomPongAttachment, BloomPongAttachmentInfo);
SingleRenderingInfo = CreateRenderInfo(FinalAttachment,FinalOutputInfo);
var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true);
textureSampler = new TextureSampler(VkCtx, textureSamplerInfo);
DescriptorSetLayout.LayoutInformation[] descSetLayouts = new DescriptorSetLayout.LayoutInformation[2];
for (int i = 0; i < 2; i++) {
descSetLayouts[i] = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, i, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
}
var LayoutInfo = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,0,1,VK_SHADER_STAGE_FRAGMENT_BIT); var LayoutInfo = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,0,1,VK_SHADER_STAGE_FRAGMENT_BIT);
AttachmentDescriptorSetLayout = new DescriptorSetLayout(VkCtx, LayoutInfo); AttachmentDescriptorSetLayout = new DescriptorSetLayout(VkCtx, LayoutInfo);
CreateAttachmentDescriptorSet(VkCtx, AttachmentDescriptorSetLayout, SrcAttachment,textureSampler); MultiAttachmentDescriptorSetLayout[0] = new DescriptorSetLayout(VkCtx, descSetLayouts);
CreateAttachmentDescriptorSet(VkCtx, AttachmentDescriptorSetLayout, SrcAttachment,textureSampler, DESCRIPTOR_ID_ATTACHMENT);
CreateAttachmentDescriptorSets(VkCtx, MultiAttachmentDescriptorSetLayout[0], new Attachment[]{BloomPingAttachment, BloomPingAttachment},textureSampler, DESCRIPTOR_ID_BLOOM_ATTACHMENT);
CreateAttachmentDescriptorSets(VkCtx, MultiAttachmentDescriptorSetLayout[0], new Attachment[]{BloomPongAttachment, BloomPongAttachment},textureSampler, DESCRIPTOR_ID_BLOOM_PONG_ATTACHMENT);
CreateAttachmentDescriptorSets(VkCtx, MultiAttachmentDescriptorSetLayout[0], new Attachment[]{ColourAttachment, BloomPingAttachment},textureSampler, DESCRIPTOR_ID_BLOOM_IMAGE_ATTACHMENT);
LayoutInfo = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0,1,VK_SHADER_STAGE_FRAGMENT_BIT); LayoutInfo = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0,1,VK_SHADER_STAGE_FRAGMENT_BIT);
FragmentUniformDescriptorSetLayout = new DescriptorSetLayout(VkCtx, LayoutInfo); FragmentUniformDescriptorSetLayout = new DescriptorSetLayout(VkCtx, LayoutInfo);
ScreenSizeBuffer = VulkanUtils.CreateHostVisibleBuffer(VkCtx, VulkanUtils.VEC2_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,DESCRIPTOR_ID_SCREEN_SIZE,FragmentUniformDescriptorSetLayout); ScreenSizeBuffer = VulkanUtils.CreateHostVisibleBuffer(VkCtx, VulkanUtils.VEC2_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,DESCRIPTOR_ID_SCREEN_SIZE,FragmentUniformDescriptorSetLayout);
BloomPropertiesHorizontalBuffer = VulkanUtils.CreateHostVisibleBuffer(VkCtx, VulkanUtils.BOOLEAN_SIZE * 2 + VulkanUtils.FLOAT_SIZE * 2+ VulkanUtils.VEC4_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,DESCRIPTOR_ID_BLOOM_PROPERTIES_HORIZONTAL,FragmentUniformDescriptorSetLayout);
BloomPropertiesVerticalBuffer = VulkanUtils.CreateHostVisibleBuffer(VkCtx, VulkanUtils.BOOLEAN_SIZE * 2 + VulkanUtils.FLOAT_SIZE * 2 + VulkanUtils.VEC4_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,DESCRIPTOR_ID_BLOOM_PROPERTIES_VERTICAL,FragmentUniformDescriptorSetLayout);
BloomPropertiesFinalBuffer = VulkanUtils.CreateHostVisibleBuffer(VkCtx, VulkanUtils.BOOLEAN_SIZE * 2 + VulkanUtils.FLOAT_SIZE * 2+ VulkanUtils.VEC4_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,DESCRIPTOR_ID_BLOOM_PROPERTIES_FINAL,FragmentUniformDescriptorSetLayout);
SetScreenSizeBuffer(VkCtx); SetScreenSizeBuffer(VkCtx);
SetBloomPropertiesBuffer(VkCtx, BloomPropertiesHorizontalBuffer, true, false);
SetBloomPropertiesBuffer(VkCtx, BloomPropertiesVerticalBuffer, false, false);
SetBloomPropertiesBuffer(VkCtx, BloomPropertiesFinalBuffer, false, true);
specConstants = new SpecializationConstants(); specConstants = new SpecializationConstants();
ShaderModule[] shaderModules = CreateShaderModules(VkCtx, specConstants); ShaderModule[] shaderModules = CreateShaderModules(VkCtx, specConstants);
pipeline = CreatePipeline(VkCtx, shaderModules, new DescriptorSetLayout[]{AttachmentDescriptorSetLayout, FragmentUniformDescriptorSetLayout}); pipeline = CreatePipeline(VkCtx, shaderModules, new DescriptorSetLayout[]{AttachmentDescriptorSetLayout, FragmentUniformDescriptorSetLayout});
Arrays.asList(shaderModules).forEach(shader->shader.CleanUp(VkCtx)); Arrays.asList(shaderModules).forEach(shader->shader.CleanUp(VkCtx));
shaderModules = CreateBloomShaderModules(VkCtx, specConstants);
bloomPipeline = CreateSingleOutputPipeline(VkCtx, shaderModules, new DescriptorSetLayout[]{MultiAttachmentDescriptorSetLayout[0], FragmentUniformDescriptorSetLayout});
Logger.debug("Post Process Renderer Pipeline -> [{}]",pipeline.GetVulkanPipeline()); Logger.debug("Post Process Renderer Pipeline -> [{}]",pipeline.GetVulkanPipeline());
} }
private static VkRenderingAttachmentInfo.Buffer CreateColourAttachmentInfos(List<Attachment> attachments, VkClearValue ClearValue){
int numAttachments = attachments.size();
VkRenderingAttachmentInfo.Buffer result = VkRenderingAttachmentInfo.calloc(numAttachments);
for (int i = 0; i < numAttachments; ++i) {
result.get(i)
.sType$Default()
.imageView(attachments.get(i).GetVkImageView().GetVulkanImageView())
.imageLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
.loadOp(VK_ATTACHMENT_LOAD_OP_CLEAR)
.storeOp(VK_ATTACHMENT_STORE_OP_STORE)
.clearValue(ClearValue);
}
return result;
}
private static Attachment CreateColourAttachment(VulkanContext VkCtx){ private static Attachment CreateColourAttachment(VulkanContext VkCtx){
SwapChain swapChain = VkCtx.GetSwapChain(); SwapChain swapChain = VkCtx.GetSwapChain();
VkExtent2D SwapChainExtent = swapChain.GetSwapChainExtent(); VkExtent2D SwapChainExtent = swapChain.GetSwapChainExtent();
return new Attachment(VkCtx,SwapChainExtent.width(),SwapChainExtent.height(),COLOUR_FORMAT,VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); return new Attachment(VkCtx,SwapChainExtent.width(),SwapChainExtent.height(),COLOUR_FORMAT,VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
} }
private static VkRenderingAttachmentInfo.Buffer CreateColourAttachmentInfo(Attachment SrcAttachment, VkClearValue ClearValue){ private static VkRenderingAttachmentInfo.Buffer CreateColourAttachmentInfo(Attachment SrcAttachment, VkClearValue ClearValue){
@ -94,8 +166,20 @@ public class PostProcess {
private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] shaderModules, DescriptorSetLayout[] descriptorSetLayouts){ private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] shaderModules, DescriptorSetLayout[] descriptorSetLayouts){
var VertexBufferStruct = new EmptyVertexBufferStruct(); var VertexBufferStruct = new EmptyVertexBufferStruct();
var BuildInfo = new PipelineBuildInfo(shaderModules,VertexBufferStruct.GetVertexInput(),new int[]{COLOUR_FORMAT}).SetDescriptorSetLayouts(descriptorSetLayouts).BlendingIsUsed(true); var BuildInfo = new PipelineBuildInfo(shaderModules, VertexBufferStruct.GetVertexInput(), new int[]{COLOUR_FORMAT, COLOUR_FORMAT})
var PipeLine = new DefaultPipeline(VkCtx,BuildInfo); .SetDescriptorSetLayouts(descriptorSetLayouts)
.BlendingIsUsed(true);
var PipeLine = new DefaultPipeline(VkCtx, BuildInfo);
VertexBufferStruct.CleanUp();
return PipeLine;
}
private static Pipeline CreateSingleOutputPipeline(VulkanContext VkCtx, ShaderModule[] shaderModules, DescriptorSetLayout[] descriptorSetLayouts){
var VertexBufferStruct = new EmptyVertexBufferStruct();
var BuildInfo = new PipelineBuildInfo(shaderModules, VertexBufferStruct.GetVertexInput(), new int[]{COLOUR_FORMAT})
.SetDescriptorSetLayouts(descriptorSetLayouts)
.BlendingIsUsed(true);
var PipeLine = new DefaultPipeline(VkCtx, BuildInfo);
VertexBufferStruct.CleanUp(); VertexBufferStruct.CleanUp();
return PipeLine; return PipeLine;
} }
@ -116,13 +200,37 @@ public class PostProcess {
return renderingInfo; return renderingInfo;
} }
private static void CreateAttachmentDescriptorSet(VulkanContext VkCtx, DescriptorSetLayout descriptorSetLayout, Attachment attachment, TextureSampler textureSampler){ private static void CreateAttachmentDescriptorSets(VulkanContext VkCtx, DescriptorSetLayout descriptorSetLayout, Attachment[] attachment, TextureSampler textureSampler, String descriptorID){
DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator(); DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator();
Device device = VkCtx.GetDevice(); Device device = VkCtx.GetDevice();
DescriptorSet descriptorSet = descriptorAllocator.AddDescriptorSets(device,DESCRIPTOR_ID_ATTACHMENT,1 , descriptorSetLayout)[0]; DescriptorSet descriptorSet = descriptorAllocator.AddDescriptorSets(device,descriptorID,1 , descriptorSetLayout)[0];
List<ImageView> images = new ArrayList<>();
for(int i = 0; i < attachment.length; i++) {
images.add(attachment[i].GetVkImageView());
}
descriptorSet.SetImages(device,images,textureSampler,0);
}
private static void CreateAttachmentDescriptorSet(VulkanContext VkCtx, DescriptorSetLayout descriptorSetLayout, Attachment attachment, TextureSampler textureSampler, String descriptorID){
DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator();
Device device = VkCtx.GetDevice();
DescriptorSet descriptorSet = descriptorAllocator.AddDescriptorSets(device,descriptorID,1 , descriptorSetLayout)[0];
descriptorSet.SetImage(device,attachment.GetVkImageView(),textureSampler,0); descriptorSet.SetImage(device,attachment.GetVkImageView(),textureSampler,0);
} }
private static ShaderModule[] CreateBloomShaderModules(VulkanContext VkCtx, SpecializationConstants specConstants){
if(EngineConfig.getInstance().RecompileShaders()){
ShaderCompiler.CompileGLSLShaderOnChange(VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader);
ShaderCompiler.CompileGLSLShaderOnChange(BLOOM_FRAGMENT_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_fragment_shader);
}
return new ShaderModule[]{
new ShaderModule(VkCtx,VK_SHADER_STAGE_VERTEX_BIT,VERTEX_SHADER_FILE_SPV,null),
new ShaderModule(VkCtx,VK_SHADER_STAGE_FRAGMENT_BIT,BLOOM_FRAGMENT_SHADER_FILE_SPV,null)
};
}
private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, SpecializationConstants specConstants){ private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, SpecializationConstants specConstants){
String ShaderPath = SINGLE_PASS_FRAGMENT_SHADER_FILE_GLSL; String ShaderPath = SINGLE_PASS_FRAGMENT_SHADER_FILE_GLSL;
if(EngineConfig.getInstance().RecompileShaders()){ if(EngineConfig.getInstance().RecompileShaders()){
@ -140,6 +248,9 @@ public class PostProcess {
} }
public void Render(VulkanContext VkCtx, CommandBuffer commandBuffer, Attachment SrcAttachment){ public void Render(VulkanContext VkCtx, CommandBuffer commandBuffer, Attachment SrcAttachment){
SetBloomPropertiesBuffer(VkCtx, BloomPropertiesHorizontalBuffer, true, false);
SetBloomPropertiesBuffer(VkCtx, BloomPropertiesVerticalBuffer, false, false);
SetBloomPropertiesBuffer(VkCtx, BloomPropertiesFinalBuffer, false, true);
try(var MemStack = MemoryStack.stackPush()){ try(var MemStack = MemoryStack.stackPush()){
SwapChain swapChain = VkCtx.GetSwapChain(); SwapChain swapChain = VkCtx.GetSwapChain();
VkCommandBuffer CommandHandle = commandBuffer.GetVulkanCommandBuffer(); VkCommandBuffer CommandHandle = commandBuffer.GetVulkanCommandBuffer();
@ -150,6 +261,12 @@ public class PostProcess {
VulkanUtils.ImageBarrier(MemStack,CommandHandle,ColourAttachment.GetVkImage().getVulkanImage(), VulkanUtils.ImageBarrier(MemStack,CommandHandle,ColourAttachment.GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_UNDEFINED,VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT,VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_IMAGE_LAYOUT_UNDEFINED,VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT,VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_2_NONE,VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,VK_IMAGE_ASPECT_COLOR_BIT); VK_ACCESS_2_NONE,VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,VK_IMAGE_ASPECT_COLOR_BIT);
VulkanUtils.ImageBarrier(MemStack,CommandHandle,BloomPingAttachment.GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_UNDEFINED,VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT,VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_2_NONE,VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,VK_IMAGE_ASPECT_COLOR_BIT);
VulkanUtils.ImageBarrier(MemStack,CommandHandle,BloomPongAttachment.GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_UNDEFINED,VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT,VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_2_NONE,VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,VK_IMAGE_ASPECT_COLOR_BIT);
vkCmdBeginRendering(CommandHandle,RenderingInfo); vkCmdBeginRendering(CommandHandle,RenderingInfo);
vkCmdBindPipeline(CommandHandle,VK_PIPELINE_BIND_POINT_GRAPHICS,pipeline.GetVulkanPipeline()); vkCmdBindPipeline(CommandHandle,VK_PIPELINE_BIND_POINT_GRAPHICS,pipeline.GetVulkanPipeline());
@ -177,9 +294,82 @@ public class PostProcess {
vkCmdBindDescriptorSets(CommandHandle,VK_PIPELINE_BIND_POINT_GRAPHICS,pipeline.GetVulkanPipelineLayout(),0,DescriptorSets,null); vkCmdBindDescriptorSets(CommandHandle,VK_PIPELINE_BIND_POINT_GRAPHICS,pipeline.GetVulkanPipelineLayout(),0,DescriptorSets,null);
vkCmdDraw(CommandHandle,3,1,0,0); vkCmdDraw(CommandHandle,3,1,0,0);
vkCmdEndRendering(CommandHandle); vkCmdEndRendering(CommandHandle);
VulkanUtils.ImageBarrier(MemStack,CommandHandle,ColourAttachment.GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,VK_ACCESS_2_SHADER_READ_BIT,VK_IMAGE_ASPECT_COLOR_BIT);
VulkanUtils.ImageBarrier(MemStack,CommandHandle,BloomPingAttachment.GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,VK_ACCESS_2_SHADER_READ_BIT,VK_IMAGE_ASPECT_COLOR_BIT);
int Passes = 10;
boolean bloomPongHasBeenWritten = false;
for(int i = 0; i < Passes; i++){
boolean writePong = i % 2 == 0;
Attachment srcBloomAttachment = writePong ? BloomPingAttachment : BloomPongAttachment;
Attachment dstBloomAttachment = writePong ? BloomPongAttachment : BloomPingAttachment;
VkRenderingInfo dstRenderingInfo = writePong ? BloomPongRenderingInfo : BloomPingRenderingInfo;
String srcDescriptorId = writePong ? DESCRIPTOR_ID_BLOOM_ATTACHMENT : DESCRIPTOR_ID_BLOOM_PONG_ATTACHMENT;
String bloomPropertiesDescriptorId = writePong ? DESCRIPTOR_ID_BLOOM_PROPERTIES_HORIZONTAL : DESCRIPTOR_ID_BLOOM_PROPERTIES_VERTICAL;
int dstOldLayout = writePong && !bloomPongHasBeenWritten
? VK_IMAGE_LAYOUT_UNDEFINED
: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
VulkanUtils.ImageBarrier(MemStack,CommandHandle,dstBloomAttachment.GetVkImage().getVulkanImage(),
dstOldLayout,VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_2_SHADER_READ_BIT,VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
VK_IMAGE_ASPECT_COLOR_BIT);
vkCmdBeginRendering(CommandHandle,dstRenderingInfo);
vkCmdBindPipeline(CommandHandle,VK_PIPELINE_BIND_POINT_GRAPHICS,bloomPipeline.GetVulkanPipeline());
vkCmdSetViewport(CommandHandle,0,Viewport);
vkCmdSetScissor(CommandHandle,0,Scissor);
LongBuffer BloomDescriptorSets = MemStack.mallocLong(2)
.put(0,descriptorAllocator.GetDescriptorSet(srcDescriptorId).GetVkDescriptorSet())
.put(1,descriptorAllocator.GetDescriptorSet(bloomPropertiesDescriptorId).GetVkDescriptorSet());
vkCmdBindDescriptorSets(CommandHandle,VK_PIPELINE_BIND_POINT_GRAPHICS,bloomPipeline.GetVulkanPipelineLayout(),0,BloomDescriptorSets,null);
vkCmdDraw(CommandHandle,3,1,0,0);
vkCmdEndRendering(CommandHandle);
VulkanUtils.ImageBarrier(MemStack,CommandHandle,dstBloomAttachment.GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,VK_ACCESS_2_SHADER_READ_BIT,
VK_IMAGE_ASPECT_COLOR_BIT);
if(writePong){
bloomPongHasBeenWritten = true;
} }
} }
VulkanUtils.ImageBarrier(MemStack,CommandHandle,FinalAttachment.GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_UNDEFINED,VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT,VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_2_NONE,VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
VK_IMAGE_ASPECT_COLOR_BIT);
vkCmdBeginRendering(CommandHandle,SingleRenderingInfo);
vkCmdBindPipeline(CommandHandle,VK_PIPELINE_BIND_POINT_GRAPHICS,bloomPipeline.GetVulkanPipeline());
vkCmdSetViewport(CommandHandle,0,Viewport);
vkCmdSetScissor(CommandHandle,0,Scissor);
LongBuffer BloomDescriptorSets = MemStack.mallocLong(2)
.put(0,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_BLOOM_IMAGE_ATTACHMENT).GetVkDescriptorSet())
.put(1,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_BLOOM_PROPERTIES_FINAL).GetVkDescriptorSet());
vkCmdBindDescriptorSets(CommandHandle,VK_PIPELINE_BIND_POINT_GRAPHICS,bloomPipeline.GetVulkanPipelineLayout(),0,BloomDescriptorSets,null);
vkCmdDraw(CommandHandle,3,1,0,0);
vkCmdEndRendering(CommandHandle);
}
}
public void Resize(VulkanContext VkCtx, Attachment SrcAttachment){ public void Resize(VulkanContext VkCtx, Attachment SrcAttachment){
RenderingInfo.free();; RenderingInfo.free();;
ColourAttachment.CleanUp(VkCtx); ColourAttachment.CleanUp(VkCtx);
@ -188,11 +378,14 @@ public class PostProcess {
ColourAttachmentInfo = CreateColourAttachmentInfo(ColourAttachment,ClearValueColour); ColourAttachmentInfo = CreateColourAttachmentInfo(ColourAttachment,ClearValueColour);
RenderingInfo = CreateRenderInfo(ColourAttachment,ColourAttachmentInfo); RenderingInfo = CreateRenderInfo(ColourAttachment,ColourAttachmentInfo);
DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator(); CreateAttachmentDescriptorSet(VkCtx, AttachmentDescriptorSetLayout, SrcAttachment,textureSampler, DESCRIPTOR_ID_ATTACHMENT);
DescriptorSet descriptorSet = descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_ATTACHMENT); CreateAttachmentDescriptorSets(VkCtx, MultiAttachmentDescriptorSetLayout[0], new Attachment[]{BloomPingAttachment, BloomPingAttachment},textureSampler, DESCRIPTOR_ID_BLOOM_ATTACHMENT);
descriptorSet.SetImage(VkCtx.GetDevice(),SrcAttachment.GetVkImageView(),textureSampler,0); CreateAttachmentDescriptorSets(VkCtx, MultiAttachmentDescriptorSetLayout[0], new Attachment[]{BloomPongAttachment, BloomPongAttachment},textureSampler, DESCRIPTOR_ID_BLOOM_PONG_ATTACHMENT);
CreateAttachmentDescriptorSets(VkCtx, MultiAttachmentDescriptorSetLayout[0], new Attachment[]{ColourAttachment, BloomPingAttachment},textureSampler, DESCRIPTOR_ID_BLOOM_IMAGE_ATTACHMENT);
SetScreenSizeBuffer(VkCtx); SetScreenSizeBuffer(VkCtx);
SetBloomPropertiesBuffer(VkCtx, BloomPropertiesHorizontalBuffer, true, false);
SetBloomPropertiesBuffer(VkCtx, BloomPropertiesVerticalBuffer, false, false);
SetBloomPropertiesBuffer(VkCtx, BloomPropertiesFinalBuffer, false, true);
} }
private void SetScreenSizeBuffer(VulkanContext VkCtx){ private void SetScreenSizeBuffer(VulkanContext VkCtx){
@ -204,11 +397,35 @@ public class PostProcess {
ScreenSizeBuffer.UnMapMemory(VkCtx); ScreenSizeBuffer.UnMapMemory(VkCtx);
} }
public Attachment GetAttachment(){return ColourAttachment;} public static float GAMMA = 1.75f;
public static float EXPOSURE = 2.5f;
public static float BLOOM_RADIUS = 2.5f;
private void SetBloomPropertiesBuffer(VulkanContext VkCtx, VulkanBuffer buffer, boolean horizontal, boolean Complete){
long MappedMemory = buffer.MapMemory(VkCtx);
ByteBuffer dataBuffer = MemoryUtil.memByteBuffer(MappedMemory,(int)buffer.GetRequestedSize());
int Offset = 0;
dataBuffer.putInt(Offset,Complete ? 1 : 0);
Offset += VulkanUtils.BOOLEAN_SIZE;
dataBuffer.putInt(Offset,horizontal ? 1 : 0);
Offset += VulkanUtils.BOOLEAN_SIZE;
dataBuffer.putFloat(Offset,GAMMA);
Offset += VulkanUtils.FLOAT_SIZE;
dataBuffer.putFloat(Offset,EXPOSURE);
Offset += VulkanUtils.FLOAT_SIZE;
dataBuffer.putFloat(Offset,BLOOM_RADIUS);
Offset += VulkanUtils.FLOAT_SIZE;
buffer.UnMapMemory(VkCtx);
}
public Attachment GetAttachment(){return FinalAttachment;}
public void CleanUp(VulkanContext VkCtx){ public void CleanUp(VulkanContext VkCtx){
ClearValueColour.free(); ClearValueColour.free();
ColourAttachment.CleanUp(VkCtx); ColourAttachment.CleanUp(VkCtx);
BloomPingAttachment.CleanUp(VkCtx);
BloomPongAttachment.CleanUp(VkCtx);
FinalAttachment.CleanUp(VkCtx);
textureSampler.CleanUp(VkCtx); textureSampler.CleanUp(VkCtx);
AttachmentDescriptorSetLayout.CleanUp(VkCtx); AttachmentDescriptorSetLayout.CleanUp(VkCtx);
FragmentUniformDescriptorSetLayout.CleanUp(VkCtx); FragmentUniformDescriptorSetLayout.CleanUp(VkCtx);
@ -216,6 +433,9 @@ public class PostProcess {
RenderingInfo.free(); RenderingInfo.free();
ColourAttachmentInfo.free(); ColourAttachmentInfo.free();
ScreenSizeBuffer.cleanup(VkCtx); ScreenSizeBuffer.cleanup(VkCtx);
BloomPropertiesHorizontalBuffer.cleanup(VkCtx);
BloomPropertiesVerticalBuffer.cleanup(VkCtx);
BloomPropertiesFinalBuffer.cleanup(VkCtx);
specConstants.CleanUp(); specConstants.CleanUp();
} }
} }

View file

@ -34,8 +34,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import static net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments.SSAO_BLUR_ATTACHMENT; import static net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments.*;
import static net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments.SSAO_RAW_ATTACHMENT;
import static org.lwjgl.vulkan.VK10.*; import static org.lwjgl.vulkan.VK10.*;
import static org.lwjgl.vulkan.VK10.VK_SHADER_STAGE_FRAGMENT_BIT; import static org.lwjgl.vulkan.VK10.VK_SHADER_STAGE_FRAGMENT_BIT;
import static org.lwjgl.vulkan.VK13.*; import static org.lwjgl.vulkan.VK13.*;
@ -47,9 +46,9 @@ public class AmbientOcclusionRenderer {
VulkanUtils.MATRIX4X4_SIZE + // view VulkanUtils.MATRIX4X4_SIZE + // view
VulkanUtils.VEC4_SIZE + // screenSize.xy, radius, bias VulkanUtils.VEC4_SIZE + // screenSize.xy, radius, bias
VulkanUtils.VEC4_SIZE; // kernelSize + padding VulkanUtils.VEC4_SIZE; // kernelSize + padding
private static final int SSAO_KERNEL_SIZE = 32; private static final int SSAO_KERNEL_SIZE = 64;
private static final float SSAO_RADIUS = 5.0f; private static final float SSAO_RADIUS = 2.75f;
private static final float SSAO_BIAS = 0.15f; private static final float SSAO_BIAS = 0.25f;
private static final long SSAO_KERNEL_BUFFER_SIZE = SSAO_KERNEL_SIZE * 4L * VulkanUtils.FLOAT_SIZE; private static final long SSAO_KERNEL_BUFFER_SIZE = SSAO_KERNEL_SIZE * 4L * VulkanUtils.FLOAT_SIZE;
private static final String DESC_ID_SSAO_ATTACHMENTS = "SSAO_DESC_ID_ATTACHMENTS"; private static final String DESC_ID_SSAO_ATTACHMENTS = "SSAO_DESC_ID_ATTACHMENTS";
@ -67,7 +66,9 @@ public class AmbientOcclusionRenderer {
private VkRenderingAttachmentInfo.Buffer ssaoAttachmentInfo; private VkRenderingAttachmentInfo.Buffer ssaoAttachmentInfo;
private Attachment ssaoBlurAttachment; private Attachment ssaoBlurAttachment;
private VkRenderingAttachmentInfo.Buffer ssaoBlurAttachmentInfo; private VkRenderingAttachmentInfo.Buffer ssaoBlurAttachmentInfo;
private final Attachment[] SSAO_ATTACHMENTS = new Attachment[2]; private Attachment ssaoViewPosAttachment;
private VkRenderingAttachmentInfo.Buffer ssaoViewPosAttachmentInfo;
private final Attachment[] SSAO_ATTACHMENTS = new Attachment[3];
private final Pipeline ssaoPipeline; private final Pipeline ssaoPipeline;
private final Pipeline blurPipeline; private final Pipeline blurPipeline;
@ -90,14 +91,15 @@ public class AmbientOcclusionRenderer {
public AmbientOcclusionRenderer(VulkanContext VkCtx, List<Attachment> MRTAttachments, Queue queue) { public AmbientOcclusionRenderer(VulkanContext VkCtx, List<Attachment> MRTAttachments, Queue queue) {
List<Attachment> attachments = new ArrayList<>(); List<Attachment> attachments = new ArrayList<>();
attachments.add(MRTAttachments.get(0)); // position attachments.add(MRTAttachments.get(7)); // position
attachments.add(MRTAttachments.get(2)); // normal attachments.add(MRTAttachments.get(2)); // normal
CreateAttachments(VkCtx); CreateAttachments(VkCtx);
clearColour = VkClearValue.calloc().color( clearColour = VkClearValue.calloc().color(
c -> c.float32(0, 0.0f).float32(1, 0.0f).float32(2, 0.0f).float32(3, 0.0f)); c -> c.float32(0, 0.0f).float32(1, 0.0f).float32(2, 0.0f).float32(3, 0.0f));
ssaoAttachmentInfo = CreateColourAttachmentInfo(ssaoAttachment, clearColour); ssaoAttachmentInfo = CreateColourAttachmentInfo(ssaoAttachment, clearColour);
ssaoBlurAttachmentInfo = CreateColourAttachmentInfo(ssaoBlurAttachment, clearColour); ssaoBlurAttachmentInfo = CreateColourAttachmentInfo(ssaoBlurAttachment, clearColour);
var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_REPEAT, ssaoViewPosAttachmentInfo = CreateColourAttachmentInfo(ssaoViewPosAttachment, clearColour);
var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true); VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true);
textureSampler = new TextureSampler(VkCtx, textureSamplerInfo); textureSampler = new TextureSampler(VkCtx, textureSamplerInfo);
@ -118,9 +120,9 @@ public class AmbientOcclusionRenderer {
attachments.add(NoiseImageAttachment); attachments.add(NoiseImageAttachment);
ssaoKernelDescriptorLayout = new DescriptorSetLayout(VkCtx, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, ssaoKernelDescriptorLayout = new DescriptorSetLayout(VkCtx, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
0, 1, VK_SHADER_STAGE_FRAGMENT_BIT)); 0, 1, VK_SHADER_STAGE_FRAGMENT_BIT));
sampleKernelBuffer = VulkanUtils.CreateHostVisibleBuffer(VkCtx, SSAO_KERNEL_BUFFER_SIZE, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, sampleKernelBuffer = VulkanUtils.CreateHostVisibleBuffer(VkCtx, SSAO_KERNEL_BUFFER_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
DESC_ID_SSAO_KERNEL, ssaoKernelDescriptorLayout); DESC_ID_SSAO_KERNEL, ssaoKernelDescriptorLayout);
long MappedMemory = sampleKernelBuffer.MapMemory(VkCtx); long MappedMemory = sampleKernelBuffer.MapMemory(VkCtx);
FloatBuffer KernelBuffer = SSAO_Utils.GenerateSampleKernel(SSAO_KERNEL_SIZE, MappedMemory); FloatBuffer KernelBuffer = SSAO_Utils.GenerateSampleKernel(SSAO_KERNEL_SIZE, MappedMemory);
@ -137,16 +139,20 @@ public class AmbientOcclusionRenderer {
ssaoInfoDescriptorLayout = new DescriptorSetLayout(VkCtx,new DescriptorSetLayout.LayoutInformation( VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, ssaoInfoDescriptorLayout = new DescriptorSetLayout(VkCtx,new DescriptorSetLayout.LayoutInformation( VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
0,1,VK_SHADER_STAGE_FRAGMENT_BIT )); 0,1,VK_SHADER_STAGE_FRAGMENT_BIT ));
blurDescriptorLayout = new DescriptorSetLayout(VkCtx,new DescriptorSetLayout.LayoutInformation( VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, DescriptorSetLayout.LayoutInformation[] descriptorSetLayouts = new DescriptorSetLayout.LayoutInformation[]{
0,1,VK_SHADER_STAGE_FRAGMENT_BIT )); new DescriptorSetLayout.LayoutInformation( VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
0,1,VK_SHADER_STAGE_FRAGMENT_BIT ),
new DescriptorSetLayout.LayoutInformation( VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
1,1,VK_SHADER_STAGE_FRAGMENT_BIT )};
blurDescriptorLayout = new DescriptorSetLayout(VkCtx,descriptorSetLayouts);
CreateBlurDescriptorSet(VkCtx); CreateBlurDescriptorSet(VkCtx);
ssaoInfoBuffers = VulkanUtils.CreateHostVisibleBuffers(VkCtx,SSAO_INFO_BUFFER_SIZE, VulkanUtils.MAX_IN_FLIGHT, ssaoInfoBuffers = VulkanUtils.CreateHostVisibleBuffers(VkCtx,SSAO_INFO_BUFFER_SIZE, VulkanUtils.MAX_IN_FLIGHT,
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, DESC_ID_SSAO_INFO,ssaoInfoDescriptorLayout); VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, DESC_ID_SSAO_INFO,ssaoInfoDescriptorLayout);
ssaoRenderInfo = CreateRenderInfo(ssaoAttachment, ssaoAttachmentInfo); ssaoRenderInfo = CreateRenderInfo(ssaoAttachment, ssaoAttachmentInfo,true);
ssaoBlurRenderInfo = CreateRenderInfo(ssaoBlurAttachment, ssaoBlurAttachmentInfo); ssaoBlurRenderInfo = CreateRenderInfo(ssaoBlurAttachment, ssaoBlurAttachmentInfo,false);
ShaderModule[] shaderModules = CreateRawShaderModules(VkCtx); ShaderModule[] shaderModules = CreateRawShaderModules(VkCtx);
ssaoPipeline = CreatePipeline(VkCtx, shaderModules, ssaoPipeline = CreatePipeline(VkCtx, shaderModules,
@ -159,15 +165,20 @@ public class AmbientOcclusionRenderer {
shaderModules = CreateBlurShaderModules(VkCtx); shaderModules = CreateBlurShaderModules(VkCtx);
blurPipeline = CreatePipeline( VkCtx, shaderModules, blurPipeline = CreatePipeline( VkCtx, shaderModules,
new DescriptorSetLayout[]{ blurDescriptorLayout }, new DescriptorSetLayout[]{ blurDescriptorLayout },true );
true );
Arrays.stream(shaderModules).toList().forEach(shaderModule -> shaderModule.CleanUp(VkCtx)); Arrays.stream(shaderModules).toList().forEach(shaderModule -> shaderModule.CleanUp(VkCtx));
} }
private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] shaderModules, DescriptorSetLayout[] descSetLayouts, boolean blur) { private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] shaderModules, DescriptorSetLayout[] descSetLayouts, boolean blur) {
var vtxBuffStruct = new EmptyVertexBufferStruct(); var vtxBuffStruct = new EmptyVertexBufferStruct();
var buildInfo = new PipelineBuildInfo(shaderModules, vtxBuffStruct.GetVertexInput(),new int[]{blur ? SSAO_BLUR_ATTACHMENT : SSAO_RAW_ATTACHMENT}) int[] formats;
if(blur){
formats = new int[]{SSAO_BLUR_ATTACHMENT, VIEW_POS_FORMAT};
} else {
formats = new int[]{SSAO_RAW_ATTACHMENT, VIEW_POS_FORMAT};
}
var buildInfo = new PipelineBuildInfo(shaderModules, vtxBuffStruct.GetVertexInput(),formats)
.SetDescriptorSetLayouts(descSetLayouts) .SetDescriptorSetLayouts(descSetLayouts)
.BlendingIsUsed(false) .BlendingIsUsed(false)
.SetDepthWrite(false) .SetDepthWrite(false)
@ -209,14 +220,17 @@ public class AmbientOcclusionRenderer {
.clearValue(clearValue); .clearValue(clearValue);
} }
private static VkRenderingInfo CreateRenderInfo(Attachment attachment, VkRenderingAttachmentInfo.Buffer attachmentInfo) { private static VkRenderingInfo CreateRenderInfo(Attachment attachment, VkRenderingAttachmentInfo.Buffer attachmentInfo, boolean Raw) {
int Width = attachment.GetVkImage().GetWidth();
int Height = attachment.GetVkImage().GetHeight();
return VkRenderingInfo.calloc() return VkRenderingInfo.calloc()
.sType$Default() .sType$Default()
.renderArea(area -> area .renderArea(area -> area
.offset(offset -> offset.x(0).y(0)) .offset(offset -> offset.x(0).y(0))
.extent(extent -> extent .extent(extent -> extent
.width(attachment.GetVkImage().GetWidth()) .width(Width)
.height(attachment.GetVkImage().GetHeight()))) .height(Height)))
.layerCount(1) .layerCount(1)
.pColorAttachments(attachmentInfo); .pColorAttachments(attachmentInfo);
} }
@ -236,19 +250,31 @@ public class AmbientOcclusionRenderer {
DescriptorSet descSet = vkCtx.GetDescriptorAllocator().AddDescriptorSet( DescriptorSet descSet = vkCtx.GetDescriptorAllocator().AddDescriptorSet(
vkCtx.GetDevice(),DESC_ID_SSAO_BLUR_INPUT, blurDescriptorLayout); vkCtx.GetDevice(),DESC_ID_SSAO_BLUR_INPUT, blurDescriptorLayout);
descSet.SetImage(vkCtx.GetDevice(), ssaoAttachment.GetVkImageView(), List<ImageView> imageViews = new ArrayList<>();
textureSampler,0); imageViews.add(ssaoAttachment.GetVkImageView());
imageViews.add(ssaoViewPosAttachment.GetVkImageView());
descSet.SetImages(vkCtx.GetDevice(), imageViews,textureSampler,0);
} }
private void CreateAttachments(VulkanContext VkCtx){ private void CreateAttachments(VulkanContext VkCtx){
SwapChain swapChain = VkCtx.GetSwapChain(); SwapChain swapChain = VkCtx.GetSwapChain();
VkExtent2D swapChainExtent = swapChain.GetSwapChainExtent(); VkExtent2D swapChainExtent = swapChain.GetSwapChainExtent();
float AspectRatio = (float)swapChainExtent.width()/(float)swapChainExtent.height();
int Width = swapChainExtent.width();
int Height = swapChainExtent.height();
int RawWidth = (int)(Math.round(Math.min(swapChainExtent.width()/2.0f, 1920 * AspectRatio)));
int RawHeight = (int)(Math.round(Math.min(swapChainExtent.height()/2.0f, 1080)));
//SSAO Raw //SSAO Raw
ssaoAttachment = new Attachment(VkCtx, swapChainExtent.width(), swapChainExtent.height(), SSAO_RAW_ATTACHMENT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 1); ssaoAttachment = new Attachment(VkCtx, Width, Height, SSAO_RAW_ATTACHMENT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 1);
SSAO_ATTACHMENTS[0] = ssaoAttachment; SSAO_ATTACHMENTS[0] = ssaoAttachment;
//SSAO Blur //SSAO Blur
ssaoBlurAttachment = new Attachment(VkCtx, swapChainExtent.width(), swapChainExtent.height(), SSAO_BLUR_ATTACHMENT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 1); ssaoBlurAttachment = new Attachment(VkCtx, Width, Height, SSAO_BLUR_ATTACHMENT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 1);
SSAO_ATTACHMENTS[1] = ssaoBlurAttachment; SSAO_ATTACHMENTS[1] = ssaoBlurAttachment;
ssaoViewPosAttachment = new Attachment(VkCtx, Width, Height, VIEW_POS_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 1);
SSAO_ATTACHMENTS[1] = ssaoViewPosAttachment;
} }
public void Render(VulkanContext VkCtx,EngineInstance engineInstance, CommandBuffer cmdBuffer, MultiRenderTargetAttachments MRT,int CurrentFrame) { public void Render(VulkanContext VkCtx,EngineInstance engineInstance, CommandBuffer cmdBuffer, MultiRenderTargetAttachments MRT,int CurrentFrame) {
@ -268,6 +294,15 @@ public class AmbientOcclusionRenderer {
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
VK_IMAGE_ASPECT_COLOR_BIT); VK_IMAGE_ASPECT_COLOR_BIT);
VulkanUtils.ImageBarrier(stack, cmdHandle, ssaoViewPosAttachment.GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_2_SHADER_READ_BIT,
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
VK_IMAGE_ASPECT_COLOR_BIT);
TransitionMRTtoReadOnly(stack, cmdHandle, MRT); TransitionMRTtoReadOnly(stack, cmdHandle, MRT);
@ -371,6 +406,8 @@ public class AmbientOcclusionRenderer {
vkCmdSetScissor(cmdHandle, 0, scissor); vkCmdSetScissor(cmdHandle, 0, scissor);
} }
public static float SSAO_RESOLUTION_SCALE = 0.5f;
private void UpdateSSAOInfo(VulkanContext vkCtx, EngineInstance engineInstance, int currentFrame) { private void UpdateSSAOInfo(VulkanContext vkCtx, EngineInstance engineInstance, int currentFrame) {
VulkanBuffer buffer = ssaoInfoBuffers[currentFrame]; VulkanBuffer buffer = ssaoInfoBuffers[currentFrame];
long mappedMemory = buffer.MapMemory(vkCtx); long mappedMemory = buffer.MapMemory(vkCtx);
@ -383,15 +420,16 @@ public class AmbientOcclusionRenderer {
engineInstance.scene().GetCamera().GetViewMatrix().get(offset, data); engineInstance.scene().GetCamera().GetViewMatrix().get(offset, data);
offset += VulkanUtils.MATRIX4X4_SIZE; offset += VulkanUtils.MATRIX4X4_SIZE;
//SSAO Raw
data.putFloat(offset, ssaoAttachment.GetVkImage().GetWidth()); data.putFloat(offset, ssaoAttachment.GetVkImage().GetWidth());
data.putFloat(offset + VulkanUtils.FLOAT_SIZE, ssaoAttachment.GetVkImage().GetHeight()); data.putFloat(offset + VulkanUtils.FLOAT_SIZE, ssaoAttachment.GetVkImage().GetHeight());
data.putFloat(offset + VulkanUtils.FLOAT_SIZE * 2, SSAO_RADIUS); data.putFloat(offset + VulkanUtils.FLOAT_SIZE * 2, SSAO_RADIUS);
data.putFloat(offset + VulkanUtils.FLOAT_SIZE * 3, SSAO_BIAS); data.putFloat(offset + VulkanUtils.FLOAT_SIZE * 3, SSAO_BIAS);
offset += VulkanUtils.VEC4_SIZE; offset += VulkanUtils.VEC4_SIZE;
data.putInt(offset, SSAO_KERNEL_SIZE); data.putInt(offset, SSAO_KERNEL_SIZE);
offset +=VulkanUtils.INT_SIZE;
data.putFloat(offset, SSAO_RESOLUTION_SCALE);
offset += VulkanUtils.FLOAT_SIZE;
buffer.UnMapMemory(vkCtx); buffer.UnMapMemory(vkCtx);
} }
@ -411,8 +449,8 @@ public class AmbientOcclusionRenderer {
ssaoAttachmentInfo = CreateColourAttachmentInfo(ssaoAttachment, clearColour); ssaoAttachmentInfo = CreateColourAttachmentInfo(ssaoAttachment, clearColour);
ssaoBlurAttachmentInfo = CreateColourAttachmentInfo(ssaoBlurAttachment, clearColour); ssaoBlurAttachmentInfo = CreateColourAttachmentInfo(ssaoBlurAttachment, clearColour);
ssaoRenderInfo = CreateRenderInfo(ssaoAttachment, ssaoAttachmentInfo); ssaoRenderInfo = CreateRenderInfo(ssaoAttachment, ssaoAttachmentInfo,true);
ssaoBlurRenderInfo = CreateRenderInfo(ssaoBlurAttachment, ssaoBlurAttachmentInfo); ssaoBlurRenderInfo = CreateRenderInfo(ssaoBlurAttachment, ssaoBlurAttachmentInfo,false);
attachments.add(NoiseImageAttachment); attachments.add(NoiseImageAttachment);

View file

@ -0,0 +1,310 @@
package net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.ScreenSpace;
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.EmptyVertexBufferStruct;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.DefaultPipeline;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.Attachment;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.Image;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.Texture;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Pipeline;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.PipelineBuildInfo;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shader.*;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.CommandBuffer;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.Queues.Queue;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ImageView;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.SwapChain.SwapChain;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanBuffer;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils;
import org.joml.Matrix4f;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.system.MemoryUtil;
import org.lwjgl.util.shaderc.Shaderc;
import org.lwjgl.vulkan.*;
import java.nio.ByteBuffer;
import java.nio.LongBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments.*;
import static org.lwjgl.vulkan.VK10.*;
import static org.lwjgl.vulkan.VK13.*;
public class ReflectionsRenderer {
private static final long SSR_INFO_BUFFER_SIZE =
VulkanUtils.MATRIX4X4_SIZE + // projection
VulkanUtils.MATRIX4X4_SIZE + // projection inv
VulkanUtils.MATRIX4X4_SIZE + // view
VulkanUtils.MATRIX4X4_SIZE + // view inv
VulkanUtils.VEC4_SIZE + // steps, distance, max steps
VulkanUtils.VEC4_SIZE; //Camera
public static float STEP_SIZE = 0.25f;
public static float MAX_DIST = 200.0f;
public static int MAX_STEPS = 64;
private static final String DESC_ID_SSR_ATTACHMENTS = "SSR_DESC_ID_ATTACHMENTS";
private static final String DESC_ID_SSR_INFO = "SSR_DESC_ID_INFO";
private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/screen_space_reflection_frag.glsl";
private static final String FRAGMENT_SHADER_FILE_SPV = FRAGMENT_SHADER_FILE_GLSL + ".spv";
private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/basic_screen_vertex.glsl";
private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv";
private Attachment ssrAttachment;
private Attachment renderedSceneAttachment;
private VkRenderingAttachmentInfo.Buffer ssrAttachmentInfo;
private final Pipeline ssrPipeline;
private final TextureSampler textureSampler;
private DescriptorSetLayout ssrAttachmentDescriptorLayout;
private DescriptorSetLayout ssrInfoDescriptorLayout;
private final VkClearValue clearColour;
private VkRenderingInfo ssrRenderInfo;
private VulkanBuffer[] ssrInfoBuffers;
public ReflectionsRenderer(VulkanContext VkCtx, List<Attachment> MRTAttachments, Attachment Rendered) {
this.renderedSceneAttachment = Rendered;
List<Attachment> attachments = new ArrayList<>();
attachments.add(Rendered);
attachments.add(MRTAttachments.get(0)); // position
attachments.add(MRTAttachments.get(2)); // normal
attachments.add(MRTAttachments.get(3)); // pbr
CreateAttachments(VkCtx);
clearColour = VkClearValue.calloc().color(
c -> c.float32(0, 0.0f).float32(1, 0.0f).float32(2, 0.0f).float32(3, 0.0f));
ssrAttachmentInfo = CreateColourAttachmentInfo(ssrAttachment, clearColour);
var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true);
textureSampler = new TextureSampler(VkCtx, textureSamplerInfo);
int numAttachments = attachments.size();
DescriptorSetLayout.LayoutInformation[] descSetLayouts = new DescriptorSetLayout.LayoutInformation[numAttachments];
for (int i = 0; i < numAttachments; i++) {
descSetLayouts[i] = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, i, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
}
ssrAttachmentDescriptorLayout = new DescriptorSetLayout(VkCtx, descSetLayouts);
CreateSSRAttachmentDescriptorSet(VkCtx, attachments);
ssrInfoDescriptorLayout = new DescriptorSetLayout(VkCtx,new DescriptorSetLayout.LayoutInformation( VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
0,1,VK_SHADER_STAGE_FRAGMENT_BIT ));
ssrInfoBuffers = VulkanUtils.CreateHostVisibleBuffers(VkCtx,SSR_INFO_BUFFER_SIZE, VulkanUtils.MAX_IN_FLIGHT,
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, DESC_ID_SSR_INFO,ssrInfoDescriptorLayout);
ssrRenderInfo = CreateRenderInfo(ssrAttachment, ssrAttachmentInfo,true);
ShaderModule[] shaderModules = CreateRawShaderModules(VkCtx);
ssrPipeline = CreatePipeline(VkCtx, shaderModules,
new DescriptorSetLayout[]{
ssrAttachmentDescriptorLayout,
ssrInfoDescriptorLayout
});
Arrays.stream(shaderModules).toList().forEach(shaderModule -> shaderModule.CleanUp(VkCtx));
}
private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] shaderModules, DescriptorSetLayout[] descSetLayouts ) {
var vtxBuffStruct = new EmptyVertexBufferStruct();
int[] formats = new int[]{SSR_FORMAT};
var buildInfo = new PipelineBuildInfo(shaderModules, vtxBuffStruct.GetVertexInput(), formats)
.SetDescriptorSetLayouts(descSetLayouts)
.BlendingIsUsed(false)
.SetDepthWrite(false)
.SetDepthTest(false);
var pipeline = new DefaultPipeline(VkCtx, buildInfo);
vtxBuffStruct.CleanUp();
return pipeline;
}
private static ShaderModule[] CreateRawShaderModules(VulkanContext VkCtx) {
if (EngineConfig.getInstance().RecompileShaders()) {
ShaderCompiler.CompileGLSLShaderOnChange(VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader);
ShaderCompiler.CompileGLSLShaderOnChange( FRAGMENT_SHADER_FILE_GLSL , Shaderc.shaderc_glsl_fragment_shader);
}
return new ShaderModule[]{
new ShaderModule(VkCtx, VK_SHADER_STAGE_VERTEX_BIT, VERTEX_SHADER_FILE_SPV, null),
new ShaderModule(VkCtx, VK_SHADER_STAGE_FRAGMENT_BIT, FRAGMENT_SHADER_FILE_SPV, null),
};
}
private static VkRenderingAttachmentInfo.Buffer CreateColourAttachmentInfo(Attachment attachment, VkClearValue clearValue) {
return VkRenderingAttachmentInfo.calloc(1)
.sType$Default()
.imageView(attachment.GetVkImageView().GetVulkanImageView())
.imageLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
.loadOp(VK_ATTACHMENT_LOAD_OP_CLEAR)
.storeOp(VK_ATTACHMENT_STORE_OP_STORE)
.clearValue(clearValue);
}
private static VkRenderingInfo CreateRenderInfo(Attachment attachment, VkRenderingAttachmentInfo.Buffer attachmentInfo, boolean Raw) {
int Width = attachment.GetVkImage().GetWidth();
int Height = attachment.GetVkImage().GetHeight();
return VkRenderingInfo.calloc()
.sType$Default()
.renderArea(area -> area
.offset(offset -> offset.x(0).y(0))
.extent(extent -> extent
.width(Width)
.height(Height)))
.layerCount(1)
.pColorAttachments(attachmentInfo);
}
private void CreateSSRAttachmentDescriptorSet(VulkanContext vkCtx, List<Attachment> Attachments ) {
DescriptorSet descSet = vkCtx.GetDescriptorAllocator().AddDescriptorSet(
vkCtx.GetDevice(), DESC_ID_SSR_ATTACHMENTS, ssrAttachmentDescriptorLayout);
List<ImageView> imageViews = new ArrayList<>();
Attachments.forEach(a -> imageViews.add(a.GetVkImageView()));
descSet.SetImages(vkCtx.GetDevice(), imageViews, textureSampler, 0);
}
private void CreateAttachments(VulkanContext VkCtx){
SwapChain swapChain = VkCtx.GetSwapChain();
VkExtent2D swapChainExtent = swapChain.GetSwapChainExtent();
float AspectRatio = (float)swapChainExtent.width()/(float)swapChainExtent.height();
int Width = swapChainExtent.width();
int Height = swapChainExtent.height();
int RawWidth = (int)(Math.round(Math.min(swapChainExtent.width()/2.0f, 1920 * AspectRatio)));
int RawHeight = (int)(Math.round(Math.min(swapChainExtent.height()/2.0f, 1080)));
//SSR Raw
ssrAttachment = new Attachment(VkCtx, Width, Height, SSR_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 1);
}
public void Render(VulkanContext VkCtx,EngineInstance engineInstance, CommandBuffer cmdBuffer, int CurrentFrame) {
try (var stack = MemoryStack.stackPush()) {
VkCommandBuffer cmdHandle = cmdBuffer.GetVulkanCommandBuffer();
UpdateSSRInfo(VkCtx, engineInstance, CurrentFrame);
VulkanUtils.ImageBarrier(stack, cmdHandle, renderedSceneAttachment.GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_SHADER_READ_BIT,
VK_IMAGE_ASPECT_COLOR_BIT);
VulkanUtils.ImageBarrier(stack, cmdHandle, ssrAttachment.GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_2_NONE, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
VK_IMAGE_ASPECT_COLOR_BIT);
vkCmdBeginRendering(cmdHandle, ssrRenderInfo);
vkCmdBindPipeline(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, ssrPipeline.GetVulkanPipeline());
SetViewportAndScissor(stack, cmdHandle, ssrAttachment);
DescriptorAllocator descAllocator = VkCtx.GetDescriptorAllocator();
LongBuffer descriptorSets = stack.mallocLong(2)
.put(0, descAllocator.GetDescriptorSet(DESC_ID_SSR_ATTACHMENTS).GetVkDescriptorSet())
.put(1, descAllocator.GetDescriptorSet(DESC_ID_SSR_INFO, CurrentFrame).GetVkDescriptorSet());
vkCmdBindDescriptorSets(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS,
ssrPipeline.GetVulkanPipelineLayout(), 0, descriptorSets, null);
vkCmdDraw(cmdHandle, 3, 1, 0, 0);
vkCmdEndRendering(cmdHandle);
}
}
private void SetViewportAndScissor(MemoryStack stack, VkCommandBuffer cmdHandle, Attachment attachment){
Image ColourImage = attachment.GetVkImage();
int width = ColourImage.GetWidth();
int height = ColourImage.GetHeight();
var viewport = VkViewport.calloc(1, stack)
.x(0)
.y(height)
.height(-height)
.width(width)
.minDepth(0.0f)
.maxDepth(1.0f);
vkCmdSetViewport(cmdHandle, 0, viewport);
var scissor = VkRect2D.calloc(1, stack)
.extent(it -> it.width(width).height(height))
.offset(it -> it.x(0).y(0));
vkCmdSetScissor(cmdHandle, 0, scissor);
}
public Attachment GetSSRAttachment() {
return ssrAttachment;
}
private void UpdateSSRInfo(VulkanContext vkCtx, EngineInstance engineInstance, int currentFrame) {
VulkanBuffer buffer = ssrInfoBuffers[currentFrame];
long mappedMemory = buffer.MapMemory(vkCtx);
ByteBuffer data = MemoryUtil.memByteBuffer(mappedMemory, (int) buffer.GetRequestedSize());
int offset = 0;
engineInstance.scene().GetProjection().GetProjectionMatrix().get(offset, data);
offset += VulkanUtils.MATRIX4X4_SIZE;
engineInstance.scene().GetProjection().GetProjectionMatrix().invert(new Matrix4f()).get(offset, data);
offset += VulkanUtils.MATRIX4X4_SIZE;
engineInstance.scene().GetCamera().GetViewMatrix().get(offset, data);
offset += VulkanUtils.MATRIX4X4_SIZE;
engineInstance.scene().GetCamera().GetViewMatrix().invert(new Matrix4f()).get(offset, data);
offset += VulkanUtils.MATRIX4X4_SIZE;
data.putFloat(offset, STEP_SIZE);
data.putFloat(offset + VulkanUtils.FLOAT_SIZE, MAX_DIST);
data.putInt(offset + VulkanUtils.FLOAT_SIZE * 2, MAX_STEPS);
data.putInt(offset + VulkanUtils.FLOAT_SIZE * 3, 0);
offset += VulkanUtils.VEC4_SIZE;
engineInstance.scene().GetCamera().GetPosition().get(offset, data);
data.putFloat(offset + VulkanUtils.VEC3_SIZE, 1.0f);
offset += VulkanUtils.VEC4_SIZE;
buffer.UnMapMemory(vkCtx);
}
public void resize(VulkanContext VkCtx, List<Attachment> attachments) {
ssrRenderInfo.free();
ssrAttachmentInfo.free();
ssrAttachment.CleanUp(VkCtx);
renderedSceneAttachment = attachments.get(0);
CreateAttachments(VkCtx);
ssrAttachmentInfo = CreateColourAttachmentInfo(ssrAttachment, clearColour);
ssrRenderInfo = CreateRenderInfo(ssrAttachment, ssrAttachmentInfo,true);
CreateSSRAttachmentDescriptorSet(VkCtx, attachments);
}
public void cleanup(VulkanContext VkCtx) {
ssrRenderInfo.free();
ssrAttachmentInfo.free();
ssrAttachment.CleanUp(VkCtx);
ssrPipeline.CleanUp(VkCtx);
clearColour.free();
Arrays.stream(ssrInfoBuffers).toList().forEach(b -> b.cleanup(VkCtx));
ssrAttachmentDescriptorLayout.CleanUp(VkCtx);
ssrInfoDescriptorLayout.CleanUp(VkCtx);
textureSampler.CleanUp(VkCtx);
}
}

View file

@ -22,7 +22,7 @@ import static org.lwjgl.util.vma.Vma.VMA_MEMORY_USAGE_AUTO;
import static org.lwjgl.vulkan.VK10.*; import static org.lwjgl.vulkan.VK10.*;
public class MaterialsCache { public class MaterialsCache {
private static final int MATERIAL_RAW_SIZE = VulkanUtils.VEC4_SIZE * 4 + (VulkanUtils.INT_SIZE * 2 + VulkanUtils.FLOAT_SIZE) * 2 + (VulkanUtils.INT_SIZE * 2); private static final int MATERIAL_RAW_SIZE = VulkanUtils.VEC4_SIZE * 4 + (VulkanUtils.INT_SIZE * 2 + VulkanUtils.FLOAT_SIZE) * 2 + (VulkanUtils.INT_SIZE * 4) + VulkanUtils.FLOAT_SIZE * 2;
private static final int MATERIAL_SIZE = 16 * (int)(Math.ceil(MATERIAL_RAW_SIZE/16.0)); private static final int MATERIAL_SIZE = 16 * (int)(Math.ceil(MATERIAL_RAW_SIZE/16.0));
private final IndexedLinkedHashMap<String, VulkanMaterial> MaterialsMap; private final IndexedLinkedHashMap<String, VulkanMaterial> MaterialsMap;
private VulkanBuffer MaterialsBuffer; private VulkanBuffer MaterialsBuffer;
@ -151,6 +151,12 @@ public class MaterialsCache {
data.putFloat(Offset, Material.Opacity()); data.putFloat(Offset, Material.Opacity());
Offset += VulkanUtils.FLOAT_SIZE; Offset += VulkanUtils.FLOAT_SIZE;
data.putFloat(Offset, Material.Reflectiveness());
Offset += VulkanUtils.FLOAT_SIZE;
data.putFloat(Offset, Material.Refractiveness());
Offset += VulkanUtils.FLOAT_SIZE;
Offset = materialBaseOffset + MATERIAL_SIZE; Offset = materialBaseOffset + MATERIAL_SIZE;
} }
// data.position(0); // data.position(0);

View file

@ -244,7 +244,8 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
MultiRenderTargetAttachments.PBR_FORMAT, MultiRenderTargetAttachments.PBR_FORMAT,
MultiRenderTargetAttachments.EMISSIVE_FORMAT, MultiRenderTargetAttachments.EMISSIVE_FORMAT,
MultiRenderTargetAttachments.TRANSLUCECNY_FORMAT, MultiRenderTargetAttachments.TRANSLUCECNY_FORMAT,
MultiRenderTargetAttachments.OPACITY_FORMAT MultiRenderTargetAttachments.OPACITY_FORMAT,
MultiRenderTargetAttachments.VIEW_POS_FORMAT
}; };
try (MemoryStack MemStack = MemoryStack.stackPush()) { try (MemoryStack MemStack = MemoryStack.stackPush()) {
@ -285,7 +286,7 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
MultiRenderTargetAttachments.POSITION_FORMAT, MultiRenderTargetAttachments.ALBEDO_FORMAT, MultiRenderTargetAttachments.POSITION_FORMAT, MultiRenderTargetAttachments.ALBEDO_FORMAT,
MultiRenderTargetAttachments.NORMAL_FORMAT, MultiRenderTargetAttachments.PBR_FORMAT, MultiRenderTargetAttachments.NORMAL_FORMAT, MultiRenderTargetAttachments.PBR_FORMAT,
MultiRenderTargetAttachments.EMISSIVE_FORMAT, MultiRenderTargetAttachments.TRANSLUCECNY_FORMAT, MultiRenderTargetAttachments.EMISSIVE_FORMAT, MultiRenderTargetAttachments.TRANSLUCECNY_FORMAT,
MultiRenderTargetAttachments.OPACITY_FORMAT}) MultiRenderTargetAttachments.OPACITY_FORMAT, MultiRenderTargetAttachments.VIEW_POS_FORMAT})
.SetDepthFormat(MultiRenderTargetAttachments.DEPTH_FORMAT) .SetDepthFormat(MultiRenderTargetAttachments.DEPTH_FORMAT)
.SetDepthWrite(DepthWrite) .SetDepthWrite(DepthWrite)
.SetPushConstantRanges( .SetPushConstantRanges(

View file

@ -38,6 +38,7 @@ public class VulkanUtils {
public static final int VEC4_SIZE = 4 * FLOAT_SIZE; public static final int VEC4_SIZE = 4 * FLOAT_SIZE;
public static final int VEC2_SIZE = 2 * FLOAT_SIZE; public static final int VEC2_SIZE = 2 * FLOAT_SIZE;
public static final int SHORT_LENGTH = 2; public static final int SHORT_LENGTH = 2;
public static final int BOOLEAN_SIZE = 4;
private static final List<DeferredResource> DeletionQueue = new ArrayList<>(); private static final List<DeferredResource> DeletionQueue = new ArrayList<>();