Skip to content

Commit

Permalink
More improvements (#52)
Browse files Browse the repository at this point in the history
* Should fix scene unloading

* Some smaller changes

* More improvements

* Many fixes + prefab file serialization

* Prefabs should be working now

* Some HDR changes

* Fixed profiler performance

* Fix long range shadow issue

* Try fix pipeline issues

* Geometry brush is working now

* Improve history clipping

* Code style fixes
  • Loading branch information
tippesi committed Mar 24, 2024
1 parent 1d5f9eb commit 42615d6
Show file tree
Hide file tree
Showing 116 changed files with 1,230 additions and 462 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,5 @@ data/subway
data/material demo
data/emissivesphere.gltf
data/.cache
data/.config
data/.config
6 changes: 4 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,10 @@ endif()

# Options and compiler settings ###################################################################
option(ATLAS_BUILD_SHARED "Force build as shared library" OFF)
option(ATLAS_OPENGL_ES "Use OpenGL ES instead of OpenGL" OFF)
option(ATLAS_EXPORT_MAIN "Add main file in root of directory tree. Add ${ATLAS_ENGINE_MAIN_FILE} to your executable" OFF)
option(ATLAS_NO_APP "Disables the engines main function" OFF)
option(ATLAS_DEMO "Build demo executable" OFF)
option(ATLAS_DEMO "Build editor executable" ON)
option(ATLAS_EDITOR "Build editor executable" ON)
option(ATLAS_IMGUI "Activate ImGui integration" OFF)
option(ATLAS_ASSIMP "Activate Assimp integration" ON)
option(ATLAS_HEADLESS "Activate support for running the engine in headless mode" OFF)
Expand All @@ -45,6 +44,9 @@ endif()
if (ATLAS_TESTS)
set (ATLAS_IMGUI ON)
endif()
if (ATLAS_EDITOR)
set (ATLAS_IMGUI ON)
endif()

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_BINARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/bin/${CMAKE_BUILD_TYPE})
Expand Down
Binary file added data/editor/icons/prefab.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions data/editor/icons/prefab.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added data/editor/icons/prefab_light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion data/scenes/sponza.aescene

Large diffs are not rendered by default.

41 changes: 35 additions & 6 deletions data/shader/clouds/integrate.hsh
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,26 @@ void CalculateTexCoords(vec3 pos, out vec3 shapeTexCoords, out vec3 detailTexCoo

void CalculateRayLength(vec3 rayOrigin, vec3 rayDirection, out float minDist, out float maxDist) {

/*
// This is an option for the future to make the clouds wrap down at the distance limit into the horizon
float radiusDiff = cloudUniforms.outerRadius - cloudUniforms.innerRadius;

float outerRadius = cloudUniforms.distanceLimit;
float innerRadius = cloudUniforms.distanceLimit - radiusDiff;

float innerHeight = cloudUniforms.innerRadius - cloudUniforms.planetRadius;

vec3 planetCenterDir = normalize(rayOrigin - cloudPlanetCenter);
vec3 surfacePos = cloudPlanetCenter + planetCenterDir * cloudUniforms.planetRadius;

vec3 spherePos = surfacePos - (innerRadius - innerHeight) * planetCenterDir;
vec2 planetDist = IntersectSphere(rayOrigin, rayDirection, globalData.planetCenter.xyz, cloudUniforms.planetRadius);
vec2 inDist = IntersectSphere(rayOrigin, rayDirection, spherePos, innerRadius);
vec2 outDist = IntersectSphere(rayOrigin, rayDirection, spherePos, outerRadius);
*/

vec3 spherePos = cloudPlanetCenter;
vec2 planetDist = IntersectSphere(rayOrigin, rayDirection, spherePos, cloudUniforms.planetRadius);
vec2 planetDist = IntersectSphere(rayOrigin, rayDirection, globalData.planetCenter.xyz, cloudUniforms.planetRadius);
vec2 inDist = IntersectSphere(rayOrigin, rayDirection, spherePos, cloudUniforms.innerRadius);
vec2 outDist = IntersectSphere(rayOrigin, rayDirection, spherePos, cloudUniforms.outerRadius);

Expand All @@ -43,7 +61,7 @@ void CalculateRayLength(vec3 rayOrigin, vec3 rayDirection, out float minDist, ou
}
// We can see the inner layer and are in between layers
if (inDist.x > 0.0 && inDist.y > 0.0 &&
outDist.x < 0.0 && outDist.y >= 0.0) {
outDist.x < 0.0 && outDist.y >= 0.0) {
minDist = 0.0;
maxDist = planetDist.x >= 0.0 ? inDist.x : outDist.y;
}
Expand Down Expand Up @@ -74,11 +92,14 @@ vec4 GetExtinctionToLight(vec3 pos, int ditherIdx, vec4 noiseVector) {

#ifdef STOCHASTIC_OCCLUSION_SAMPLING
// Dither secondary rays
float noiseOffset = noiseVector[ditherIdx % 4];
float noiseOffset = noiseVector[1];
#else
float noiseOffset = 0.5;
#endif

// Start with certain base lod to sampe one lod lower earlier
float lod = 0.5;

vec4 extinctionAccumulation = vec4(0.0);
for (int i = 0; i < lightSampleCount; i++) {
if (extinctionAccumulation.a < logEpsilon) {
Expand All @@ -98,11 +119,13 @@ vec4 GetExtinctionToLight(vec3 pos, int ditherIdx, vec4 noiseVector) {
CalculateTexCoords(samplePoint, shapeTexCoords, detailTexCoords, coverageTexCoords);

float density = saturate(SampleDensity(samplePoint, shapeTexCoords, detailTexCoords,
coverageTexCoords, vec3(1.0), floor(0.0), true));
coverageTexCoords, vec3(1.0), floor(lod), true));
vec4 extinctionCoefficient = cloudUniforms.extinctionFactor *
cloudUniforms.extinctionCoefficients * density;

extinctionAccumulation += extinctionCoefficient * delta * rayLength;

lod += 0.5;
}
}

Expand Down Expand Up @@ -146,6 +169,9 @@ vec4 IntegrateVolumetricClouds(vec3 rayOrigin, vec3 rayDirection, float rayStart
vec4 extinction = vec4(1.0);
vec3 scattering = vec3(0.0);

float lod = 0.0;
float lodOffset = 4.0 / float(raySampleCount);

int noiseIdx = 0;
for (int i = 0; i < raySampleCount; i++) {

Expand All @@ -169,7 +195,7 @@ vec4 IntegrateVolumetricClouds(vec3 rayOrigin, vec3 rayDirection, float rayStart
}

float density = saturate(SampleDensity(rayPos, shapeTexCoords, detailTexCoords,
coverageTexCoords, vec3(1.0), 0.0, true));
coverageTexCoords, vec3(1.0), floor(lod), true));

if (density > 0.0) {
vec3 scatteringCoefficient = cloudUniforms.scatteringFactor *
Expand All @@ -187,7 +213,7 @@ vec4 IntegrateVolumetricClouds(vec3 rayOrigin, vec3 rayDirection, float rayStart

float lightDotView = dot(normalize(cloudUniforms.light.direction.xyz), normalize(rayDirection));
vec3 lightColor = cloudUniforms.light.color.rgb * cloudUniforms.light.intensity;
vec4 lightExtinction = GetExtinctionToLight(rayPos, 1, noiseVector);
vec4 lightExtinction = GetExtinctionToLight(rayPos, i % 4, noiseVector);

float phaseFunction = DualPhaseFunction(cloudUniforms.eccentricityFirstPhase,
cloudUniforms.eccentricitySecondPhase, cloudUniforms.phaseAlpha, lightDotView);
Expand All @@ -198,6 +224,9 @@ vec4 IntegrateVolumetricClouds(vec3 rayOrigin, vec3 rayDirection, float rayStart
scattering += luminanceIntegral * extinction.rgb;
extinction *= stepExtinction;
}

lod += lodOffset;
lod = min(lod, 0.0);
}

rayPos += stepVector;
Expand Down
3 changes: 2 additions & 1 deletion data/shader/clouds/shadow.csh
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,9 @@ vec2 ComputeVolumetricClouds(vec3 minDepthPos, vec3 maxDepthPos) {
vec3 shapeTexCoords, detailTexCoords;
CalculateTexCoords(rayPos, shapeTexCoords, detailTexCoords, coverageTexCoords);

// Use lower lod (2.0) for shadows
float density = saturate(SampleDensity(rayPos, shapeTexCoords, detailTexCoords,
coverageTexCoords, vec3(1.0), 0.0, false));
coverageTexCoords, vec3(1.0), 2.0, false));

float extinctionCoefficient = cloudUniforms.extinctionFactor *
cloudUniforms.extinctionCoefficients.a * density;
Expand Down
16 changes: 11 additions & 5 deletions data/shader/clouds/temporal.csh
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,8 @@ void main() {
vec4 historyValue = history;
vec4 currentValue = texelFetch(currentTexture, pixel, 0);

float currentDepth = texelFetch(depthTexture, pixel, 0).r;

historyValue = clamp(historyValue, localNeighbourhoodMin, localNeighbourhoodMax);

// We don't want to do anything fancy here, just a bit of constant accumulation
Expand All @@ -223,23 +225,27 @@ void main() {
|| uv.y > 1.0) ? 0.0 : factor;
ivec2 historyPixel = ivec2(vec2(pixel) + velocity * resolution);
float minConfidence = 1.0;
float minWeight = 1.0;
// Calculate confidence over 2x2 bilinear neighborhood
// Note that 3x3 neighborhoud could help on edges
for (int i = 0; i < 9; i++) {
ivec2 offsetPixel = historyPixel + offsets[i];
float confidence = 1.0;
float sampleLinearDepth = ConvertDepthToViewSpaceDepth(currentDepth);
if (offsetPixel.x < imageSize(resolveImage).x && offsetPixel.y < imageSize(resolveImage).y &&
offsetPixel.x >= 0 && offsetPixel.y >= 0) {
float historyDepth = texelFetch(historyDepthTexture, offsetPixel, 0).r;
confidence *= historyDepth < 1.0 ? 0.0 : 1.0;
float historyDepth = texelFetch(historyDepthTexture, offsetPixel, 0).r;
float historyLinearDepth = ConvertDepthToViewSpaceDepth(historyDepth);
float weight = min(1.0 , exp(-abs(historyLinearDepth - sampleLinearDepth)));
minConfidence = min(minConfidence, confidence);
minWeight = min(minWeight, weight);
}
}
factor *= minConfidence;
factor *= minWeight;
vec4 resolve = mix(currentValue, historyValue, factor);
Expand Down
8 changes: 1 addition & 7 deletions data/shader/common/eotf.hsh
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,14 @@ vec3 InverseHybridLogGammeEotf(vec3 color) {

vec3 InversePerceptualQuantizerEotf(vec3 color) {

// Multiply by whitepoint of 100 (color needs to be in luminance/m^2)
// Tradtionally SDR RGB displays have a whitepoint of rgb = vec3(1.0) -> 100 nits
// Allowed are colors up to 10000 nits, so 100 times the whitepoint
color *= 100.0;

// ST2084 Perceptual Quantizer (PQ) EOTF
float m1 = 2610.0 / 4096.0 * (1.0 / 4.0);
float m2 = 2523.0 / 4096.0 * 128.0;
float c1 = 3424.0 / 4096.0;
float c2 = 2413.0 / 4096.0 * 32.0;
float c3 = 2392.0 / 4096.0 * 32.0;

vec3 Y = color / 10000.0;
vec3 Ym1 = pow(Y, vec3(m1));
vec3 Ym1 = pow(color, vec3(m1));

color = pow((c1 + c2 * Ym1) / (1 + c3 * Ym1), vec3(m2));

Expand Down
14 changes: 14 additions & 0 deletions data/shader/common/ycocg.hsh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const mat3 RGBToYCoCgMatrix = mat3(0.25, 0.5, -0.25, 0.5, 0.0, 0.5, 0.25, -0.5, -0.25);
const mat3 YCoCgToRGBMatrix = mat3(1.0, 1.0, 1.0, 1.0, 0.0, -1.0, -1.0, 1.0, -1.0);

vec3 RGBToYCoCg(vec3 RGB) {

return RGBToYCoCgMatrix * RGB;

}

vec3 YCoCgToRGB(vec3 YCoCg) {

return YCoCgToRGBMatrix * YCoCg;

}
3 changes: 3 additions & 0 deletions data/shader/impostor/impostor.fsh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <../common/normalencode.hsh>

layout (location = 0) out vec4 baseColorFS;
layout (location = 1) out vec2 normalFS;
layout (location = 2) out vec2 geometryNormalFS;
layout (location = 3) out vec3 roughnessMetalnessAoFS;
layout (location = 4) out uint materialIdxFS;
Expand Down Expand Up @@ -91,6 +92,8 @@ void main() {
geometryNormal = normalize(geometryNormal);
geometryNormalFS = EncodeNormal(geometryNormal);

normalFS = geometryNormalFS;

#ifdef INTERPOLATION
vec3 matInfo0 = texture(roughnessMetalnessAoMap, vec3(texCoordVS, float(index0VS)), uniforms.mipBias).rgb;
vec3 matInfo1 = texture(roughnessMetalnessAoMap, vec3(texCoordVS, float(index1VS)), uniforms.mipBias).rgb;
Expand Down
9 changes: 8 additions & 1 deletion data/shader/pathtracer/temporal.csh
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <../common/utility.hsh>
#include <../common/convert.hsh>
#include <../common/ycocg.hsh>
#include <../common/PI.hsh>
#include <../common/stencil.hsh>
#include <../common/flatten.hsh>
Expand Down Expand Up @@ -334,7 +335,7 @@ void ComputeVarianceMinMax(out vec3 mean, out vec3 std) {
for (int j = -radius; j <= radius; j++) {
int sharedMemoryIdx = GetSharedMemoryIndex(ivec2(i, j));
vec3 sampleRadiance = FetchCurrentRadiance(sharedMemoryIdx);
vec3 sampleRadiance = RGBToYCoCg(FetchCurrentRadiance(sharedMemoryIdx));
float sampleLinearDepth = FetchDepth(sharedMemoryIdx);
float depthPhi = max(1.0, abs(0.025 * linearDepth));
Expand Down Expand Up @@ -384,6 +385,9 @@ void main() {
bool success = SampleCatmullRom(pixel, historyUV, history);
historyRadiance = success && valid ? history.rgb : historyRadiance;
historyRadiance = RGBToYCoCg(historyRadiance);
currentRadiance = RGBToYCoCg(currentRadiance);
vec3 historyNeighbourhoodMin = mean - std;
vec3 historyNeighbourhoodMax = mean + std;
Expand All @@ -397,6 +401,9 @@ void main() {
currentRadiance = clamp(currentRadiance, currentNeighbourhoodMin, currentNeighbourhoodMax);
//historyRadiance = mix(historyRadiance, currentRadiance, adjClipBlend);
historyRadiance = YCoCgToRGB(historyRadiance);
currentRadiance = YCoCgToRGB(currentRadiance);
float temporalWeight = (pushConstants.maxHistoryLength - 1.0) / pushConstants.maxHistoryLength;
float factor = mix(0.0, temporalWeight, 1.0 - adjClipBlend);
factor = (historyUV.x < 0.0 || historyUV.y < 0.0 || historyUV.x > 1.0
Expand Down
24 changes: 22 additions & 2 deletions data/shader/postprocessing.fsh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ layout(set = 3, binding = 3) uniform sampler2D bloomThirdTexture;

layout(set = 3, binding = 4) uniform UniformBuffer {
float exposure;
float whitePoint;
float paperWhiteLuminance;
float maxScreenLuminance;
float saturation;
float contrast;
float filmGrainStrength;
Expand All @@ -28,6 +29,8 @@ layout(set = 3, binding = 4) uniform UniformBuffer {
} Uniforms;

const float gamma = 1.0 / 2.2;
float screenMaxNits = Uniforms.maxScreenLuminance;
float paperWhiteNits = Uniforms.paperWhiteLuminance;

vec3 ACESToneMap(vec3 hdrColor) {
float a = 2.51;
Expand All @@ -39,6 +42,15 @@ vec3 ACESToneMap(vec3 hdrColor) {
(hdrColor*(c*hdrColor+d)+e), 0.0, 1.0);
}

vec3 ACESFilmRec2020(vec3 hdrColor) {
float a = 15.8;
float b = 2.12;
float c = 1.2;
float d = 5.92;
float e = 1.9;
return (hdrColor * (a * hdrColor + b)) / (hdrColor * (c * hdrColor + d) + e);
}

vec3 ToneMap(vec3 hdrColor) {

return vec3(1.0) - exp(-hdrColor);
Expand Down Expand Up @@ -133,17 +145,26 @@ void main() {
// Apply the tone mapping because we want the colors to be back in
// normal range
#ifdef HDR
// Interesting approach to make bright parts look more white using luma: https://github.com/libretro/RetroArch/blob/14ce660a38f99d448b32ed752ddaf1f250dcf669/gfx/drivers/d3d_shaders/hdr_sm5.hlsl.h

// Note: Tuned these two eotfs to be perceptually the same. Not sure how it turns out.
// Haven't tested with Dolby Vision
#ifdef HYBRID_LOG_GAMMA_EOTF
// Dark regions are getting crushed too much, correct for that
color = pow(color, vec3(0.9));
color = Rec709ToRec2020(color);
// Made for 1000nits max brightness, so scale by this factor
color = ACESFilmRec2020(color) * screenMaxNits / 1000.0;

color.rgb = InverseHybridLogGammeEotf(color);
#endif

#ifdef PERCEPTUAL_QUANTIZER_EOTF
color = Rec709ToRec2020(color);
// Made for 1000nits max brightness, so scale by this factor
color = ACESFilmRec2020(color) * screenMaxNits / 1000.0;

color *= paperWhiteNits / 10000.0;
color = InversePerceptualQuantizerEotf(color);
#endif

Expand All @@ -169,7 +190,6 @@ void main() {

color = mix(Uniforms.vignetteColor.rgb, color, Uniforms.vignetteFactor);
#endif

outColor = vec4(color, 1.0);

}
12 changes: 8 additions & 4 deletions data/shader/reflection/temporal.csh
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//#define BICUBIC_FILTER

#include <../common/utility.hsh>
#include <../common/ycocg.hsh>
#include <../common/convert.hsh>
#include <../common/PI.hsh>
#include <../common/stencil.hsh>
Expand Down Expand Up @@ -324,7 +325,7 @@ void ComputeVarianceMinMax(out vec3 mean, out vec3 std) {
for (int j = -radius; j <= radius; j++) {
int sharedMemoryIdx = GetSharedMemoryIndex(ivec2(i, j));
vec3 sampleRadiance = FetchCurrentRadiance(sharedMemoryIdx);
vec3 sampleRadiance = RGBToYCoCg(FetchCurrentRadiance(sharedMemoryIdx));
float sampleLinearDepth = FetchDepth(sharedMemoryIdx);
float depthPhi = max(1.0, abs(0.025 * linearDepth));
Expand Down Expand Up @@ -371,11 +372,11 @@ void main() {
history = success && valid ? catmullRomHistory : history;
#endif
vec3 historyColor = history.rgb;
vec3 currentColor = texelFetch(currentTexture, pixel, 0).rgb;
vec3 historyColor = RGBToYCoCg(history.rgb);
vec3 currentColor = RGBToYCoCg(texelFetch(currentTexture, pixel, 0).rgb);
vec2 currentMoments;
currentMoments.r = Luma(currentColor);
currentMoments.r = currentColor.r;
currentMoments.g = currentMoments.r * currentMoments.r;
vec3 historyNeighbourhoodMin = mean - std;
Expand All @@ -391,6 +392,9 @@ void main() {
currentColor = clamp(currentColor, currentNeighbourhoodMin, currentNeighbourhoodMax);
//historyColor = mix(historyColor, currentColor, adjClipBlend);
historyColor = YCoCgToRGB(historyColor);
currentColor = YCoCgToRGB(currentColor);
uint materialIdx = texelFetch(materialIdxTexture, pixel, 0).r;
Material material = UnpackMaterial(materialIdx);
Expand Down
Loading

0 comments on commit 42615d6

Please sign in to comment.