Improved performance in shaders and transformations.

This commit is contained in:
Jonathas Costa
2018-03-01 16:24:20 -05:00
parent cf8371f304
commit 1b9622c7dd
5 changed files with 119 additions and 77 deletions

View File

@@ -58,6 +58,8 @@ public:
virtual std::string deferredcastFSPath() const = 0;
virtual void initializeCachedVariables(ghoul::opengl::ProgramObject&) = 0;
/**
* Return a path to a glsl file with helper functions required for the
* transformation and raycast steps.

View File

@@ -247,6 +247,7 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData& renderData,
program.setUniform("dInverseModelTransformMatrix", inverseModelMatrix);
program.setUniform("dModelTransformMatrix", _modelTransform);
/*
// The following scale comes from PSC transformations.
float fScaleFactor = renderData.camera.scaling().x *
pow(10.f, renderData.camera.scaling().y);
@@ -255,30 +256,25 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData& renderData,
"dInverseScaleTransformMatrix",
glm::inverse(dfScaleCamTransf)
);
// World to Eye Space in OS
program.setUniform(
"dInverseCamRotTransform",
glm::mat4_cast(
static_cast<glm::dquat>(renderData.camera.rotationQuaternion())
)
);
program.setUniform(
"dInverseSgctEyeToWorldTranform",
glm::inverse(renderData.camera.combinedViewMatrix())
);
*/
// Eye Space in OS to Eye Space in SGCT
glm::dmat4 dOsEye2SGCTEye = glm::dmat4(renderData.camera.viewMatrix());
glm::dmat4 dSgctEye2OSEye = glm::inverse(dOsEye2SGCTEye);
program.setUniform("dSgctEyeToOSEyeTranform", dSgctEye2OSEye);
glm::dmat4 dSgctEye2OSEye = glm::inverse(
glm::dmat4(renderData.camera.viewMatrix()));
// Eye Space in SGCT to Projection (Clip) Space in SGCT
glm::dmat4 dSgctEye2Clip = glm::dmat4(renderData.camera.projectionMatrix());
glm::dmat4 dInverseProjection = glm::inverse(dSgctEye2Clip);
glm::dmat4 dInverseProjection = glm::inverse(
glm::dmat4(renderData.camera.projectionMatrix()));
program.setUniform("dInverseSgctProjectionMatrix", dInverseProjection);
glm::dmat4 dInverseCameraRotationToSgctEyeTransform = glm::mat4_cast(
static_cast<glm::dquat>(renderData.camera.rotationQuaternion())
) * dSgctEye2OSEye;
program.setUniform("dInverseSgctProjectionToTmpRotTransformMatrix",
dInverseCameraRotationToSgctEyeTransform * dInverseProjection);
program.setUniform("dInverseSGCTEyeToTmpRotTransformMatrix",
dInverseCameraRotationToSgctEyeTransform);
program.setUniform("dObjpos", glm::dvec4(renderData.position.dvec3(), 1.0));
program.setUniform("dCampos", renderData.camera.positionVec3());
@@ -446,6 +442,47 @@ std::string AtmosphereDeferredcaster::helperPath() const {
return ""; // no helper file
}
void AtmosphereDeferredcaster::initializeCachedVariables(ghoul::opengl::ProgramObject& program) {
_uniformCache.cullAtmosphere = program.uniformLocation("cullAtmosphere");
_uniformCache.Rg = program.uniformLocation("Rg");
_uniformCache.Rt = program.uniformLocation("Rt");
_uniformCache.AverageGroundReflectance = program.uniformLocation("AverageGroundReflectance");
_uniformCache.groundRadianceEmittion = program.uniformLocation("groundRadianceEmittion");
_uniformCache.HR = program.uniformLocation("HR");
_uniformCache.betaRayleigh = program.uniformLocation("betaRayleigh");
_uniformCache.HM = program.uniformLocation("HM");
_uniformCache.betaMieScattering = program.uniformLocation("betaMieScattering");
_uniformCache.betaMieExtinction = program.uniformLocation("betaMieExtinction");
_uniformCache.mieG = program.uniformLocation("mieG");
_uniformCache.sunRadiance = program.uniformLocation("sunRadiance");
_uniformCache.ozoneLayerEnabled = program.uniformLocation("ozoneLayerEnabled");
_uniformCache.HO = program.uniformLocation("HO");
_uniformCache.betaOzoneExtinction = program.uniformLocation("betaOzoneExtinction");
_uniformCache.TRANSMITTANCE_W = program.uniformLocation("TRANSMITTANCE_W");
_uniformCache.TRANSMITTANCE_H = program.uniformLocation("TRANSMITTANCE_H");
_uniformCache.SKY_W = program.uniformLocation("SKY_W");
_uniformCache.SKY_H = program.uniformLocation("SKY_H");
_uniformCache.OTHER_TEXTURES_W = program.uniformLocation("OTHER_TEXTURES_W");
_uniformCache.OTHER_TEXTURES_H = program.uniformLocation("OTHER_TEXTURES_H");
_uniformCache.SAMPLES_R = program.uniformLocation("SAMPLES_R");
_uniformCache.SAMPLES_MU = program.uniformLocation("SAMPLES_MU");
_uniformCache.SAMPLES_MU_S = program.uniformLocation("SAMPLES_MU_S");
_uniformCache.SAMPLES_NU = program.uniformLocation("SAMPLES_NU");
_uniformCache2.ModelTransformMatrix = program.uniformLocation("ModelTransformMatrix");
_uniformCache2.dInverseModelTransformMatrix = program.uniformLocation("dInverseModelTransformMatrix");
_uniformCache2.dModelTransformMatrix = program.uniformLocation("dModelTransformMatrix");
_uniformCache2.dInverseSgctProjectionToTmpRotTransformMatrix = program.uniformLocation("dInverseSgctProjectionToTmpRotTransformMatrix");
_uniformCache2.dInverseSGCTEyeToTmpRotTransformMatrix = program.uniformLocation("dInverseSGCTEyeToTmpRotTransformMatrix");
_uniformCache2.dObjpos = program.uniformLocation("dObjpos");
_uniformCache2.dCampos = program.uniformLocation("dCampos");
_uniformCache2.sunDirectionObj = program.uniformLocation("sunDirectionObj");
_uniformCache2.ellipsoidRadii = program.uniformLocation("ellipsoidRadii");
_uniformCache2.hardShadows = program.uniformLocation("hardShadows");
_uniformCache2.transmittanceTexture = program.uniformLocation("transmittanceTexture");
_uniformCache2.irradianceTexture = program.uniformLocation("irradianceTexture");
_uniformCache2.inscatterTexture = program.uniformLocation("inscatterTexture");
}
void AtmosphereDeferredcaster::setModelTransform(const glm::dmat4& transform) {
_modelTransform = transform;
}

View File

@@ -29,6 +29,7 @@
#include <ghoul/glm.h>
#include <ghoul/opengl/textureunit.h>
#include <ghoul/opengl/uniformcache.h>
#include <string>
#include <vector>
@@ -61,6 +62,8 @@ public:
std::string deferredcastFSPath() const override;
std::string helperPath() const override;
void initializeCachedVariables(ghoul::opengl::ProgramObject&) override;
void preCalculateAtmosphereParam();
void setModelTransform(const glm::dmat4 &transform);
@@ -124,6 +127,19 @@ private:
std::unique_ptr<ghoul::opengl::ProgramObject> _atmosphereProgramObject;
std::unique_ptr<ghoul::opengl::ProgramObject> _deferredAtmosphereProgramObject;
UniformCache(cullAtmosphere, Rg, Rt, AverageGroundReflectance,
groundRadianceEmittion, HR, betaRayleigh, HM, betaMieScattering,
betaMieExtinction, mieG, sunRadiance, ozoneLayerEnabled,
HO, betaOzoneExtinction, TRANSMITTANCE_W, TRANSMITTANCE_H,
SKY_W, SKY_H, OTHER_TEXTURES_W, OTHER_TEXTURES_H, SAMPLES_R,
SAMPLES_MU, SAMPLES_MU_S, SAMPLES_NU) _uniformCache;
UniformCache(ModelTransformMatrix, dInverseModelTransformMatrix, dModelTransformMatrix,
dInverseSgctProjectionToTmpRotTransformMatrix,
dInverseSGCTEyeToTmpRotTransformMatrix,
dObjpos, dCampos, sunDirectionObj, ellipsoidRadii,
hardShadows, transmittanceTexture, irradianceTexture,
inscatterTexture) _uniformCache2;
GLuint _transmittanceTableTexture;
GLuint _irradianceTableTexture;
GLuint _inScatteringTableTexture;

View File

@@ -92,6 +92,9 @@ uniform dmat4 dInverseCamRotTransform;
uniform dmat4 dInverseModelTransformMatrix;
uniform dmat4 dModelTransformMatrix;
//uniform dmat4 dSGCTEyeToOSWorldTransformMatrix;
uniform dmat4 dInverseSgctProjectionToOSEyeTransformMatrix;
uniform dmat4 dInverseSgctProjectionToTmpRotTransformMatrix;
uniform dmat4 dInverseSGCTEyeToTmpRotTransformMatrix;
uniform dvec4 dObjpos;
uniform dvec3 dCampos;
@@ -258,16 +261,10 @@ void dCalculateRayRenderableGlobe(in int mssaSample, out dRay ray,
msaaSamplePatter[mssaSample+1]);
dvec4 clipCoords = dvec4(interpolatedNDCPos.xy + samplePos, interpolatedNDCPos.z, 1.0) / gl_FragCoord.w;
// Clip to SGCT Eye
dvec4 sgctEyeCoords = dInverseSgctProjectionMatrix * clipCoords;
sgctEyeCoords.w = 1.0;
// SGCT Eye to OS Eye
dvec4 tOSEyeCoordsInv = dSgctEyeToOSEyeTranform * sgctEyeCoords;
// OS Eye to World coords
dvec4 tmpRInv = dInverseCamRotTransform * tOSEyeCoordsInv;
dvec4 worldCoords = dvec4(dvec3(tmpRInv) + dCampos, 1.0);
// Clip to OS Cam Rig Rotation
dvec4 tmpRInv = dInverseSgctProjectionToTmpRotTransformMatrix * clipCoords;
dvec4 worldCoords = dvec4(tmpRInv.xyz + dCampos, 1.0);
// World to Object
dvec4 objectCoords = dInverseModelTransformMatrix * worldCoords;
@@ -546,25 +543,28 @@ vec3 sunColor(const vec3 x, const float t, const vec3 v, const vec3 s, const flo
return transmittance * sunFinalColor;
}
void main() {
void main() {
ivec2 fragCoords = ivec2(gl_FragCoord);
if (cullAtmosphere == 0) {
vec4 atmosphereFinalColor = vec4(0.0f);
int nSamples = 1;
// First we determine if the pixel is complex (different fragments on it)
bool complex = false;
vec4 oldColor, currentColor;
//vec4 colorArray[16];
//int colorIndexArray[16];
oldColor = texelFetch(mainColorTexture, ivec2(gl_FragCoord), 0);
oldColor = texelFetch(mainColorTexture, fragCoords, 0);
//colorArray[0] = oldColor;
//colorIndexArray[0] = 0;
for (int i = 1; i < nAaSamples; i++) {
//vec4 normal = texelFetch(mainNormalTexture, ivec2(gl_FragCoord), i);
vec4 currentColor = texelFetch(mainColorTexture, ivec2(gl_FragCoord), i);
//vec4 normal = texelFetch(mainNormalTexture, fragCoords, i);
vec4 currentColor = texelFetch(mainColorTexture, fragCoords, i);
//colorArray[i] = currentColor;
if (currentColor != oldColor) {
complex = true;
//nSamples = nAaSamples;
nSamples = nAaSamples > 1 ? nAaSamples / 2 : nAaSamples;
break;
// for (int c = 0; c < nAaSamples; c++) {
// if (currentColor == colorArray[c]) {
@@ -583,18 +583,10 @@ void main() {
// }
oldColor = currentColor;
}
int nSamples = 1;
if (complex) {
//nSamples = nAaSamples;
nSamples = nAaSamples > 1 ? nAaSamples/2 : nAaSamples;
}
for (int i = 0; i < nSamples; i++) {
vec4 normal = texelFetch(mainNormalTexture, ivec2(gl_FragCoord), i);
vec4 color = texelFetch(mainColorTexture, ivec2(gl_FragCoord), i);
// Data in the mainPositionTexture are written in view space (view plus camera rig)
vec4 position = texelFetch(mainPositionTexture, ivec2(gl_FragCoord), i);
// Color from G-Buffer
vec4 color = texelFetch(mainColorTexture, fragCoords, i);
// Ray in object space
dRay ray;
@@ -612,9 +604,9 @@ void main() {
bool intersectATM = false;
// Instead of ray-ellipsoid intersection lets transform the ray to a sphere:
dRay transfRay;
transfRay.origin = ray.origin;
transfRay.direction = ray.direction;
//dRay transfRay;
//transfRay.origin = ray.origin;
//transfRay.direction = ray.direction;
// transfRay.origin.z *= 1000.0/ellipsoidRadii.x;
// transfRay.direction.z *= 1000.0/ellipsoidRadii.x;
@@ -624,9 +616,9 @@ void main() {
// transfRay.direction.y *= 1000.0/ellipsoidRadii.z;
// transfRay.direction.xyz = normalize(transfRay.direction.xyz);
intersectATM = dAtmosphereIntersection(planetPositionObjectCoords.xyz, transfRay,
Rt - ATM_EPSILON/100.0, insideATM, offset, maxLength );
intersectATM = dAtmosphereIntersection(planetPositionObjectCoords.xyz, ray,
Rt - (ATM_EPSILON * 0.001), insideATM, offset, maxLength );
if ( intersectATM ) {
// Now we check is if the atmosphere is occluded, i.e., if the distance to the pixel
// in the depth buffer is less than the distance to the atmosphere then the atmosphere
@@ -634,8 +626,13 @@ void main() {
// Fragments positions into G-Buffer are written in OS Eye Space (Camera Rig Coords)
// when using their positions later, one must convert them to the planet's coords
// Get data from G-Buffer
vec4 normal = texelFetch(mainNormalTexture, fragCoords, i);
// Data in the mainPositionTexture are written in view space (view plus camera rig)
vec4 position = texelFetch(mainPositionTexture, fragCoords, i);
// OS Eye to World coords
dvec4 tmpRInvPos = dInverseCamRotTransform * dSgctEyeToOSEyeTranform * position;
dvec4 tmpRInvPos = dInverseSGCTEyeToTmpRotTransformMatrix * position;
dvec4 fragWorldCoords = dvec4(dvec3(tmpRInvPos) + dCampos, 1.0);
// World to Object (Normal and Position in meters)
@@ -652,19 +649,19 @@ void main() {
float dC = float(length(cameraPositionInObject.xyz));
float x1 = 1e8;
if (dC > x1) {
pixelDepth += 1000.0;
pixelDepth += 1000.0;
float alpha = 1000.0;
float beta = 1000000.0;
float x2 = 1e9;
float diffGreek = beta - alpha;
float diffDist = x2 - x1;
float varA = diffGreek/diffDist;
float varB = (alpha - varA * x1);
pixelDepth += double(varA * dC + varB);
float varA = diffGreek/diffDist;
float varB = (alpha - varA * x1);
pixelDepth += double(varA * dC + varB);
}
// All calculations are done in Km:
pixelDepth *= 0.001;
pixelDepth *= 0.001;
fragObjectCoords.xyz *= 0.001;
if (position.xyz != vec3(0.0) && (pixelDepth < offset)) {
@@ -679,9 +676,9 @@ void main() {
// If the observer is already inside the atm, offset = 0.0
// and no changes at all.
vec3 x = vec3(ray.origin.xyz + t*ray.direction.xyz);
float r = 0.0;//length(x);
float r = 0.0f;//length(x);
vec3 v = vec3(ray.direction.xyz);
float mu = 0.0;//dot(x, v) / r;
float mu = 0.0f;//dot(x, v) / r;
vec3 s = vec3(sunDirectionObj);
float tF = float(maxLength - t);
@@ -690,7 +687,7 @@ void main() {
// next comparison with the planet's ground make sense:
pixelDepth -= offset;
dvec4 onATMPos = dModelTransformMatrix * dvec4(x*1000.0, 1.0);
dvec4 onATMPos = dModelTransformMatrix * dvec4(x * 1000.0, 1.0);
vec4 eclipseShadowATM = calcShadow(shadowDataArray, onATMPos.xyz, false);
vec4 eclipseShadowPlanet = calcShadow(shadowDataArray, fragWorldCoords.xyz, true);
@@ -718,7 +715,7 @@ void main() {
else { // no intersection
//discard;
atmosphereFinalColor += vec4(HDR(color.xyz * backgroundConstant, atmExposure), color.a);
}
}
}
renderTarget = atmosphereFinalColor / float(nSamples);
@@ -727,7 +724,7 @@ void main() {
if (firstPaint) {
vec4 bColor = vec4(0.0f);
for (int f = 0; f < nAaSamples; f++) {
bColor += texelFetch(mainColorTexture, ivec2(gl_FragCoord), f);
bColor += texelFetch(mainColorTexture, fragCoords, f);
}
bColor /= float(nAaSamples);
renderTarget = vec4(HDR(bColor.xyz * backgroundConstant, atmExposure), bColor.a);

View File

@@ -539,6 +539,7 @@ void FramebufferRenderer::updateDeferredcastData() {
absPath(vsPath),
absPath(deferredShaderPath),
deferredDict);
using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError;
_deferredcastPrograms[caster]->setIgnoreSubroutineUniformLocationError(
IgnoreError::Yes
@@ -546,6 +547,8 @@ void FramebufferRenderer::updateDeferredcastData() {
_deferredcastPrograms[caster]->setIgnoreUniformLocationError(
IgnoreError::Yes
);
caster->initializeCachedVariables(*_deferredcastPrograms[caster]);
}
catch (ghoul::RuntimeError& e) {
LERRORC(e.component, e.message);
@@ -1203,20 +1206,7 @@ void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasure
}
}
if (!tasks.deferredcasterTasks.empty()) {
// JCC: Temporarily disabled. Need to test it on mac and linux before final
// merging.
/*glBindFramebuffer(GL_READ_FRAMEBUFFER, _deferredFramebuffer);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, defaultFbo);
GLenum dBuffer[] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, dBuffer);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBlitFramebuffer(0, 0, GLsizei(_resolution.x), GLsizei(_resolution.y),
0, 0, GLsizei(_resolution.x), GLsizei(_resolution.y),
GL_COLOR_BUFFER_BIT, GL_NEAREST);
*/
//glBindFramebuffer(GL_FRAMEBUFFER, defaultFbo);
} else {
if (tasks.deferredcasterTasks.empty()) {
glBindFramebuffer(GL_FRAMEBUFFER, defaultFbo);
_resolveProgram->activate();