mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-04 00:06:46 -05:00
[3d] Ambient Occlusion (reworked) (#49702)
* Initial implementation * - Add disabling of blur pass - Change default parameter for shading factor - fix some tests * - Implement bilateral filtering - Optimize textures - Fix layout test * rename SSAO to ambient occlusion fix ssao settings widget margin * Remove unused variable * fix naming and add tooltips * - Refactor quad entities - Address Stefanos's suggestions * Rework SSAO implementation Previously we based the code on CloudCompare's implementation, however that did not work too well for us for a couple of reasons: - the code does not deal well with perspective projection, causing incorrect shading (CC uses orthographic projection) - there was no range check, so we would be getting false ambient occlusion on larger depth discontinuities (silhouttes) - banding artifacts as the sampling kernel was not getting rotated - parameters (shading radius, distance attenuation) that are difficult to understand The new implementation is based on John Chapman's tutorial and LearnOpenGL page (derived from the original tutorial): https://john-chapman-graphics.blogspot.com/2013/01/ssao-tutorial.html https://learnopengl.com/Advanced-Lighting/SSAO The general approach of the SSAO is the following: - for each pixel, we pick a couple of random points nearby (64 samples currently) and check with the depth buffer whether they are visible from the camera or not. The nearby points that are occluded contribute to darkening of the pixel, this is saved to a texture - in the next rendering pass, we blur the texture using 4x4 box. This is because in the first step we use 4x4 random noise pattern and it leaves a noticeable noise pattern on the screen. This pass gets rid of that noise - in the post-processing step, the blurred texture is blended with the rendered scene There are few differences to J.C.'s tutorial and LearnOpenGL page: - the approches above use normal maps (a texture with a normal vector for each pixel), but we don't because we also want to support point clouds that do not have normals (at least not by default) - we use full sphere for sampling instead of hemisphere (which is possible when you have normals), so maybe we are getting a bit lower quality / performance - LearnOpenGL also uses a texture with positions of all pixels - we only use depth map to get the original positions (like JC's original code does) * Clean up ssao parameters and GUI, add intensity parameter * Add missing Q_OBJECT macro * Add more missing Q_OBJECT macros * Add occlusion threshold parameter to control the darkening With the default threshold of 50%, pixels only start to get darker when more than half of the neighborhood samples are occluded. That means flat surfaces should not get any darker. (What we had previously is an equivalent of having threshold set at 0%) The downside is that with increased threshold, more subtle occlusions get lost. * Review from Stefanos * More review and better defaults * Clear button fix Co-authored-by: NEDJIMAbelgacem <gb_nedjima@esi.dz>
This commit is contained in:
parent
cc933eefbc
commit
91100f816b
@ -542,6 +542,8 @@ Default value is 96
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool isSkyboxEnabled() const;
|
||||
%Docstring
|
||||
Returns whether the skybox is enabled.
|
||||
@ -874,6 +876,14 @@ Emitted when shadow rendering settings are changed
|
||||
.. versionadded:: 3.16
|
||||
%End
|
||||
|
||||
|
||||
void ambientOcclusionSettingsChanged();
|
||||
%Docstring
|
||||
Emitted when ambient occlusion rendering settings are changed
|
||||
|
||||
.. versionadded:: 3.28
|
||||
%End
|
||||
|
||||
void fpsCounterEnabledChanged( bool fpsCounterEnabled );
|
||||
%Docstring
|
||||
Emitted when the FPS counter is enabled or disabled
|
||||
|
||||
@ -34,10 +34,14 @@ set(QGIS_3D_SRCS
|
||||
qgsskyboxsettings.cpp
|
||||
qgsshadowrenderingframegraph.cpp
|
||||
qgspostprocessingentity.cpp
|
||||
qgsrenderpassquad.cpp
|
||||
qgsambientocclusionrenderentity.cpp
|
||||
qgsambientocclusionblurentity.cpp
|
||||
qgspreviewquad.cpp
|
||||
qgsshadowsettings.cpp
|
||||
qgscolorramptexture.cpp
|
||||
qgsrubberband3d.cpp
|
||||
qgsambientocclusionsettings.cpp
|
||||
|
||||
qgspointcloudlayer3drenderer.cpp
|
||||
qgspointcloudlayerchunkloader_p.cpp
|
||||
@ -130,6 +134,10 @@ set(QGIS_3D_HDRS
|
||||
qgspreviewquad.h
|
||||
qgsshadowsettings.h
|
||||
qgspointcloudlayer3drenderer.h
|
||||
qgsrenderpassquad.h
|
||||
qgsambientocclusionrenderentity.h
|
||||
qgsambientocclusionblurentity.h
|
||||
qgsambientocclusionsettings.h
|
||||
|
||||
lights/qgsdirectionallightsettings.h
|
||||
lights/qgslightsource.h
|
||||
|
||||
@ -138,6 +138,7 @@ Qgs3DMapScene::Qgs3DMapScene( Qgs3DMapSettings &map, QgsAbstract3DEngine *engine
|
||||
connect( &map, &Qgs3DMapSettings::renderersChanged, this, &Qgs3DMapScene::onRenderersChanged );
|
||||
connect( &map, &Qgs3DMapSettings::skyboxSettingsChanged, this, &Qgs3DMapScene::onSkyboxSettingsChanged );
|
||||
connect( &map, &Qgs3DMapSettings::shadowSettingsChanged, this, &Qgs3DMapScene::onShadowSettingsChanged );
|
||||
connect( &map, &Qgs3DMapSettings::ambientOcclusionSettingsChanged, this, &Qgs3DMapScene::onAmbientOcclusionSettingsChanged );
|
||||
connect( &map, &Qgs3DMapSettings::eyeDomeLightingEnabledChanged, this, &Qgs3DMapScene::onEyeDomeShadingSettingsChanged );
|
||||
connect( &map, &Qgs3DMapSettings::eyeDomeLightingStrengthChanged, this, &Qgs3DMapScene::onEyeDomeShadingSettingsChanged );
|
||||
connect( &map, &Qgs3DMapSettings::eyeDomeLightingDistanceChanged, this, &Qgs3DMapScene::onEyeDomeShadingSettingsChanged );
|
||||
@ -237,6 +238,8 @@ Qgs3DMapScene::Qgs3DMapScene( Qgs3DMapSettings &map, QgsAbstract3DEngine *engine
|
||||
// force initial update of debugging setting of preview quads
|
||||
onDebugShadowMapSettingsChanged();
|
||||
onDebugDepthMapSettingsChanged();
|
||||
// force initial update of ambient occlusion settings
|
||||
onAmbientOcclusionSettingsChanged();
|
||||
|
||||
mCameraController->setCameraNavigationMode( mMap.cameraNavigationMode() );
|
||||
onCameraMovementSpeedChanged();
|
||||
@ -1102,6 +1105,16 @@ void Qgs3DMapScene::onShadowSettingsChanged()
|
||||
shadowRenderingFrameGraph->setShadowRenderingEnabled( false );
|
||||
}
|
||||
|
||||
void Qgs3DMapScene::onAmbientOcclusionSettingsChanged()
|
||||
{
|
||||
QgsShadowRenderingFrameGraph *shadowRenderingFrameGraph = mEngine->frameGraph();
|
||||
QgsAmbientOcclusionSettings ambientOcclusionSettings = mMap.ambientOcclusionSettings();
|
||||
shadowRenderingFrameGraph->setAmbientOcclusionEnabled( ambientOcclusionSettings.isEnabled() );
|
||||
shadowRenderingFrameGraph->setAmbientOcclusionRadius( ambientOcclusionSettings.radius() );
|
||||
shadowRenderingFrameGraph->setAmbientOcclusionIntensity( ambientOcclusionSettings.intensity() );
|
||||
shadowRenderingFrameGraph->setAmbientOcclusionThreshold( ambientOcclusionSettings.threshold() );
|
||||
}
|
||||
|
||||
void Qgs3DMapScene::onDebugShadowMapSettingsChanged()
|
||||
{
|
||||
QgsShadowRenderingFrameGraph *shadowRenderingFrameGraph = mEngine->frameGraph();
|
||||
|
||||
@ -201,6 +201,7 @@ class _3D_EXPORT Qgs3DMapScene : public Qt3DCore::QEntity
|
||||
void onRenderersChanged();
|
||||
void onSkyboxSettingsChanged();
|
||||
void onShadowSettingsChanged();
|
||||
void onAmbientOcclusionSettingsChanged();
|
||||
void onEyeDomeShadingSettingsChanged();
|
||||
void onDebugShadowMapSettingsChanged();
|
||||
void onDebugDepthMapSettingsChanged();
|
||||
|
||||
@ -78,6 +78,7 @@ Qgs3DMapSettings::Qgs3DMapSettings( const Qgs3DMapSettings &other )
|
||||
, mIsSkyboxEnabled( other.mIsSkyboxEnabled )
|
||||
, mSkyboxSettings( other.mSkyboxSettings )
|
||||
, mShadowSettings( other.mShadowSettings )
|
||||
, mAmbientOcclusionSettings( other.mAmbientOcclusionSettings )
|
||||
, mEyeDomeLightingEnabled( other.mEyeDomeLightingEnabled )
|
||||
, mEyeDomeLightingStrength( other.mEyeDomeLightingStrength )
|
||||
, mEyeDomeLightingDistance( other.mEyeDomeLightingDistance )
|
||||
@ -290,6 +291,9 @@ void Qgs3DMapSettings::readXml( const QDomElement &elem, const QgsReadWriteConte
|
||||
QDomElement elemShadows = elem.firstChildElement( QStringLiteral( "shadow-rendering" ) );
|
||||
mShadowSettings.readXml( elemShadows, context );
|
||||
|
||||
QDomElement elemAmbientOcclusion = elem.firstChildElement( QStringLiteral( "screen-space-ambient-occlusion" ) );
|
||||
mAmbientOcclusionSettings.readXml( elemAmbientOcclusion, context );
|
||||
|
||||
QDomElement elemEyeDomeLighting = elem.firstChildElement( QStringLiteral( "eye-dome-lighting" ) );
|
||||
mEyeDomeLightingEnabled = elemEyeDomeLighting.attribute( "enabled", QStringLiteral( "0" ) ).toInt();
|
||||
mEyeDomeLightingStrength = elemEyeDomeLighting.attribute( "eye-dome-lighting-strength", QStringLiteral( "1000.0" ) ).toDouble();
|
||||
@ -419,6 +423,10 @@ QDomElement Qgs3DMapSettings::writeXml( QDomDocument &doc, const QgsReadWriteCon
|
||||
mShadowSettings.writeXml( elemShadows, context );
|
||||
elem.appendChild( elemShadows );
|
||||
|
||||
QDomElement elemAmbientOcclusion = doc.createElement( QStringLiteral( "screen-space-ambient-occlusion" ) );
|
||||
mAmbientOcclusionSettings.writeXml( elemAmbientOcclusion, context );
|
||||
elem.appendChild( elemAmbientOcclusion );
|
||||
|
||||
QDomElement elemDebug = doc.createElement( QStringLiteral( "debug" ) );
|
||||
elemDebug.setAttribute( QStringLiteral( "bounding-boxes" ), mShowTerrainBoundingBoxes ? 1 : 0 );
|
||||
elemDebug.setAttribute( QStringLiteral( "terrain-tile-info" ), mShowTerrainTileInfo ? 1 : 0 );
|
||||
@ -861,6 +869,12 @@ void Qgs3DMapSettings::setShadowSettings( const QgsShadowSettings &shadowSetting
|
||||
emit shadowSettingsChanged();
|
||||
}
|
||||
|
||||
void Qgs3DMapSettings::setAmbientOcclusionSettings( const QgsAmbientOcclusionSettings &ambientOcclusionSettings )
|
||||
{
|
||||
mAmbientOcclusionSettings = ambientOcclusionSettings;
|
||||
emit ambientOcclusionSettingsChanged();
|
||||
}
|
||||
|
||||
void Qgs3DMapSettings::setDebugShadowMapSettings( bool enabled, Qt::Corner corner, double size )
|
||||
{
|
||||
mDebugShadowMapEnabled = enabled;
|
||||
@ -959,6 +973,7 @@ void Qgs3DMapSettings::connectChangedSignalsToSettingsChanged()
|
||||
connect( this, &Qgs3DMapSettings::shadowSettingsChanged, this, &Qgs3DMapSettings::settingsChanged );
|
||||
connect( this, &Qgs3DMapSettings::fpsCounterEnabledChanged, this, &Qgs3DMapSettings::settingsChanged );
|
||||
connect( this, &Qgs3DMapSettings::axisSettingsChanged, this, &Qgs3DMapSettings::settingsChanged );
|
||||
connect( this, &Qgs3DMapSettings::ambientOcclusionSettingsChanged, this, &Qgs3DMapSettings::settingsChanged );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
#include "qgsshadowsettings.h"
|
||||
#include "qgscameracontroller.h"
|
||||
#include "qgstemporalrangeobject.h"
|
||||
#include "qgsambientocclusionsettings.h"
|
||||
|
||||
class QgsMapLayer;
|
||||
class QgsRasterLayer;
|
||||
@ -530,6 +531,12 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject, public QgsTemporalRangeObjec
|
||||
*/
|
||||
QgsShadowSettings shadowSettings() const SIP_SKIP { return mShadowSettings; }
|
||||
|
||||
/**
|
||||
* Returns the current configuration of screen space ambient occlusion
|
||||
* \since QGIS 3.28
|
||||
*/
|
||||
QgsAmbientOcclusionSettings ambientOcclusionSettings() const SIP_SKIP { return mAmbientOcclusionSettings; }
|
||||
|
||||
/**
|
||||
* Sets the current configuration of the skybox
|
||||
* \since QGIS 3.16
|
||||
@ -542,6 +549,12 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject, public QgsTemporalRangeObjec
|
||||
*/
|
||||
void setShadowSettings( const QgsShadowSettings &shadowSettings ) SIP_SKIP;
|
||||
|
||||
/**
|
||||
* Sets the current configuration of screen space ambient occlusion
|
||||
* \since QGIS 3.28
|
||||
*/
|
||||
void setAmbientOcclusionSettings( const QgsAmbientOcclusionSettings &ambientOcclusionSettings ) SIP_SKIP;
|
||||
|
||||
/**
|
||||
* Returns whether the skybox is enabled.
|
||||
* \see setIsSkyboxEnabled()
|
||||
@ -824,6 +837,13 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject, public QgsTemporalRangeObjec
|
||||
*/
|
||||
void shadowSettingsChanged();
|
||||
|
||||
|
||||
/**
|
||||
* Emitted when ambient occlusion rendering settings are changed
|
||||
* \since QGIS 3.28
|
||||
*/
|
||||
void ambientOcclusionSettingsChanged();
|
||||
|
||||
/**
|
||||
* Emitted when the FPS counter is enabled or disabled
|
||||
* \since QGIS 3.18
|
||||
@ -896,6 +916,7 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject, public QgsTemporalRangeObjec
|
||||
bool mIsSkyboxEnabled = false; //!< Whether the skybox is enabled
|
||||
QgsSkyboxSettings mSkyboxSettings; //!< Skybox related configuration
|
||||
QgsShadowSettings mShadowSettings; //!< Shadow rendering related settings
|
||||
QgsAmbientOcclusionSettings mAmbientOcclusionSettings; //!< Screen Space Ambient Occlusion related settings
|
||||
|
||||
bool mEyeDomeLightingEnabled = false;
|
||||
double mEyeDomeLightingStrength = 1000.0;
|
||||
|
||||
32
src/3d/qgsambientocclusionblurentity.cpp
Normal file
32
src/3d/qgsambientocclusionblurentity.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
/***************************************************************************
|
||||
qgsambientocclusionblurentity.cpp
|
||||
--------------------------------------
|
||||
Date : June 2022
|
||||
Copyright : (C) 2022 by Belgacem Nedjima
|
||||
Email : belgacem dot nedjima at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsambientocclusionblurentity.h"
|
||||
|
||||
#include <Qt3DRender/QParameter>
|
||||
|
||||
QgsAmbientOcclusionBlurEntity::QgsAmbientOcclusionBlurEntity( Qt3DRender::QTexture2D *texture, QNode *parent )
|
||||
: QgsRenderPassQuad( parent )
|
||||
{
|
||||
mAmbientOcclusionFactorTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "texture" ), texture );
|
||||
mMaterial->addParameter( mAmbientOcclusionFactorTextureParameter );
|
||||
|
||||
const QString vertexShaderPath = QStringLiteral( "qrc:/shaders/ssao_factor_blur.vert" );
|
||||
const QString fragmentShaderPath = QStringLiteral( "qrc:/shaders/ssao_factor_blur.frag" );
|
||||
|
||||
mShader->setVertexShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( vertexShaderPath ) ) );
|
||||
mShader->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( fragmentShaderPath ) ) );
|
||||
}
|
||||
|
||||
41
src/3d/qgsambientocclusionblurentity.h
Normal file
41
src/3d/qgsambientocclusionblurentity.h
Normal file
@ -0,0 +1,41 @@
|
||||
/***************************************************************************
|
||||
qgsambientocclusionblurentity.h
|
||||
--------------------------------------
|
||||
Date : June 2022
|
||||
Copyright : (C) 2022 by Belgacem Nedjima
|
||||
Email : belgacem dot nedjima at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSAMBIENTOCCLUSIONBLURENTITY_H
|
||||
#define QGSAMBIENTOCCLUSIONBLURENTITY_H
|
||||
|
||||
#include "qgsrenderpassquad.h"
|
||||
|
||||
#define SIP_NO_FILE
|
||||
|
||||
/**
|
||||
* \ingroup 3d
|
||||
* \brief An entity that is responsible for blurring the ambient occlusion factor texture.
|
||||
*
|
||||
* \note Not available in Python bindings
|
||||
*
|
||||
* \since QGIS 3.28
|
||||
*/
|
||||
class QgsAmbientOcclusionBlurEntity : public QgsRenderPassQuad
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
//! Constructor
|
||||
QgsAmbientOcclusionBlurEntity( Qt3DRender::QTexture2D *texture, QNode *parent = nullptr );
|
||||
private:
|
||||
Qt3DRender::QParameter *mAmbientOcclusionFactorTextureParameter = nullptr;
|
||||
};
|
||||
|
||||
#endif // QGSAMBIENTOCCLUSIONBLURENTITY_H
|
||||
124
src/3d/qgsambientocclusionrenderentity.cpp
Normal file
124
src/3d/qgsambientocclusionrenderentity.cpp
Normal file
@ -0,0 +1,124 @@
|
||||
/***************************************************************************
|
||||
qgsambientocclusionrenderentity.cpp
|
||||
--------------------------------------
|
||||
Date : June 2022
|
||||
Copyright : (C) 2022 by Belgacem Nedjima
|
||||
Email : belgacem dot nedjima at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsambientocclusionrenderentity.h"
|
||||
|
||||
#include <random>
|
||||
|
||||
#include <Qt3DRender/QParameter>
|
||||
|
||||
QgsAmbientOcclusionRenderEntity::QgsAmbientOcclusionRenderEntity( Qt3DRender::QTexture2D *depthTexture, Qt3DRender::QCamera *camera, QNode *parent )
|
||||
: QgsRenderPassQuad( parent )
|
||||
{
|
||||
mDepthTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "depthTexture" ), depthTexture );
|
||||
mMaterial->addParameter( mDepthTextureParameter );
|
||||
|
||||
mFarPlaneParameter = new Qt3DRender::QParameter( QStringLiteral( "farPlane" ), camera->farPlane() );
|
||||
mMaterial->addParameter( mFarPlaneParameter );
|
||||
connect( camera, &Qt3DRender::QCamera::farPlaneChanged, mFarPlaneParameter, [&]( float farPlane )
|
||||
{
|
||||
mFarPlaneParameter->setValue( farPlane );
|
||||
} );
|
||||
mNearPlaneParameter = new Qt3DRender::QParameter( QStringLiteral( "nearPlane" ), camera->nearPlane() );
|
||||
mMaterial->addParameter( mNearPlaneParameter );
|
||||
connect( camera, &Qt3DRender::QCamera::nearPlaneChanged, mNearPlaneParameter, [&]( float nearPlane )
|
||||
{
|
||||
mNearPlaneParameter->setValue( nearPlane );
|
||||
} );
|
||||
mProjMatrixParameter = new Qt3DRender::QParameter( QStringLiteral( "origProjMatrix" ), camera->projectionMatrix() );
|
||||
mMaterial->addParameter( mProjMatrixParameter );
|
||||
connect( camera, &Qt3DRender::QCamera::projectionMatrixChanged, mProjMatrixParameter, [&]( const QMatrix4x4 & projectionMatrix )
|
||||
{
|
||||
mProjMatrixParameter->setValue( projectionMatrix );
|
||||
} );
|
||||
mAspectRatioParameter = new Qt3DRender::QParameter( QStringLiteral( "uAspectRatio" ), camera->aspectRatio() );
|
||||
mMaterial->addParameter( mAspectRatioParameter );
|
||||
connect( camera, &Qt3DRender::QCamera::aspectRatioChanged, mAspectRatioParameter, [&]( float ratio )
|
||||
{
|
||||
mAspectRatioParameter->setValue( ratio );
|
||||
} );
|
||||
mTanHalfFovParameter = new Qt3DRender::QParameter( QStringLiteral( "uTanHalfFov" ), tan( camera->fieldOfView() / 2 * M_PI / 180 ) );
|
||||
mMaterial->addParameter( mTanHalfFovParameter );
|
||||
connect( camera, &Qt3DRender::QCamera::fieldOfViewChanged, mTanHalfFovParameter, [&]( float fov )
|
||||
{
|
||||
mTanHalfFovParameter->setValue( tan( fov / 2 * M_PI / 180 ) );
|
||||
} );
|
||||
|
||||
QVariantList ssaoKernelValues;
|
||||
|
||||
std::uniform_real_distribution<float> randomFloats( 0.0, 1.0 ); // random floats between [0.0, 1.0]
|
||||
std::default_random_engine generator;
|
||||
unsigned int kernelSize = 64;
|
||||
for ( unsigned int i = 0; i < kernelSize; ++i )
|
||||
{
|
||||
QVector3D sample(
|
||||
randomFloats( generator ) * 2.0 - 1.0,
|
||||
randomFloats( generator ) * 2.0 - 1.0,
|
||||
randomFloats( generator ) * 2.0 - 1.0
|
||||
);
|
||||
sample.normalize();
|
||||
float scale = i / kernelSize;
|
||||
scale = 0.1 + 0.9 * scale * scale;
|
||||
sample *= scale;
|
||||
ssaoKernelValues.push_back( sample );
|
||||
}
|
||||
|
||||
// 4x4 array of random rotation vectors
|
||||
QVariantList ssaoNoise;
|
||||
for ( unsigned int i = 0; i < 16; ++i )
|
||||
{
|
||||
QVector3D sample(
|
||||
randomFloats( generator ),
|
||||
randomFloats( generator ),
|
||||
0.0
|
||||
);
|
||||
ssaoNoise.push_back( sample );
|
||||
}
|
||||
mAmbientOcclusionKernelParameter = new Qt3DRender::QParameter( QStringLiteral( "ssaoKernel[0]" ), ssaoKernelValues );
|
||||
mMaterial->addParameter( mAmbientOcclusionKernelParameter );
|
||||
|
||||
Qt3DRender::QParameter *noiseParameter = new Qt3DRender::QParameter( QStringLiteral( "ssaoNoise[0]" ), ssaoNoise );
|
||||
mMaterial->addParameter( noiseParameter );
|
||||
|
||||
mIntensityParameter = new Qt3DRender::QParameter( QStringLiteral( "intensity" ), 0.5f );
|
||||
mMaterial->addParameter( mIntensityParameter );
|
||||
|
||||
mRadiusParameter = new Qt3DRender::QParameter( QStringLiteral( "radius" ), 25.0f );
|
||||
mMaterial->addParameter( mRadiusParameter );
|
||||
|
||||
mThresholdParameter = new Qt3DRender::QParameter( QStringLiteral( "threshold" ), 0.5f );
|
||||
mMaterial->addParameter( mThresholdParameter );
|
||||
|
||||
const QString vertexShaderPath = QStringLiteral( "qrc:/shaders/ssao_factor_render.vert" );
|
||||
const QString fragmentShaderPath = QStringLiteral( "qrc:/shaders/ssao_factor_render.frag" );
|
||||
|
||||
mShader->setVertexShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( vertexShaderPath ) ) );
|
||||
mShader->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( fragmentShaderPath ) ) );
|
||||
}
|
||||
|
||||
void QgsAmbientOcclusionRenderEntity::setIntensity( float intensity )
|
||||
{
|
||||
mIntensityParameter->setValue( intensity );
|
||||
}
|
||||
|
||||
void QgsAmbientOcclusionRenderEntity::setRadius( float radius )
|
||||
{
|
||||
mRadiusParameter->setValue( radius );
|
||||
}
|
||||
|
||||
void QgsAmbientOcclusionRenderEntity::setThreshold( float threshold )
|
||||
{
|
||||
mThresholdParameter->setValue( threshold );
|
||||
}
|
||||
65
src/3d/qgsambientocclusionrenderentity.h
Normal file
65
src/3d/qgsambientocclusionrenderentity.h
Normal file
@ -0,0 +1,65 @@
|
||||
/***************************************************************************
|
||||
qgsambientocclusionrenderentity.h
|
||||
--------------------------------------
|
||||
Date : June 2022
|
||||
Copyright : (C) 2022 by Belgacem Nedjima
|
||||
Email : belgacem dot nedjima at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSAMBIENTOCCLUSIONRENDERENTITY_H
|
||||
#define QGSAMBIENTOCCLUSIONRENDERENTITY_H
|
||||
|
||||
#include "qgsrenderpassquad.h"
|
||||
|
||||
#define SIP_NO_FILE
|
||||
|
||||
/**
|
||||
* \ingroup 3d
|
||||
* \brief An entity that is responsible for producing an ambient occlusion factor map.
|
||||
*
|
||||
* \note Not available in Python bindings
|
||||
*
|
||||
* \since QGIS 3.28
|
||||
*/
|
||||
class QgsAmbientOcclusionRenderEntity : public QgsRenderPassQuad
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
//! Constructor
|
||||
QgsAmbientOcclusionRenderEntity( Qt3DRender::QTexture2D *depthTexture, Qt3DRender::QCamera *camera, QNode *parent = nullptr );
|
||||
|
||||
//! Sets the intensity for the ambient occlusion effect
|
||||
void setIntensity( float intensity );
|
||||
|
||||
//! Sets the radius for the ambient occlusion effect
|
||||
void setRadius( float radius );
|
||||
|
||||
//! Sets the amount of occlusion when the effects starts to kick in
|
||||
void setThreshold( float threshold );
|
||||
|
||||
private:
|
||||
|
||||
Qt3DRender::QParameter *mDepthTextureParameter = nullptr;
|
||||
Qt3DRender::QParameter *mAmbientOcclusionKernelParameter = nullptr;
|
||||
|
||||
// user configurable
|
||||
Qt3DRender::QParameter *mIntensityParameter = nullptr;
|
||||
Qt3DRender::QParameter *mRadiusParameter = nullptr;
|
||||
Qt3DRender::QParameter *mThresholdParameter = nullptr;
|
||||
|
||||
// derived from camera parameters
|
||||
Qt3DRender::QParameter *mFarPlaneParameter = nullptr;
|
||||
Qt3DRender::QParameter *mNearPlaneParameter = nullptr;
|
||||
Qt3DRender::QParameter *mProjMatrixParameter = nullptr;
|
||||
Qt3DRender::QParameter *mAspectRatioParameter = nullptr;
|
||||
Qt3DRender::QParameter *mTanHalfFovParameter = nullptr;
|
||||
};
|
||||
|
||||
#endif // QGSAMBIENTOCCLUSIONRENDERENTITY_H
|
||||
59
src/3d/qgsambientocclusionsettings.cpp
Normal file
59
src/3d/qgsambientocclusionsettings.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
/***************************************************************************
|
||||
qgsambientocclusionsettings.cpp
|
||||
--------------------------------------
|
||||
Date : June 2022
|
||||
Copyright : (C) 2022 by Belgacem Nedjima
|
||||
Email : belgacem dot nedjima at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsambientocclusionsettings.h"
|
||||
|
||||
#include <QDomDocument>
|
||||
|
||||
#include "qgsreadwritecontext.h"
|
||||
|
||||
|
||||
QgsAmbientOcclusionSettings::QgsAmbientOcclusionSettings( const QgsAmbientOcclusionSettings &other )
|
||||
: mEnabled( other.mEnabled )
|
||||
, mIntensity( other.mIntensity )
|
||||
, mRadius( other.mRadius )
|
||||
, mThreshold( other.mThreshold )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QgsAmbientOcclusionSettings &QgsAmbientOcclusionSettings::operator=( QgsAmbientOcclusionSettings const &rhs )
|
||||
{
|
||||
mEnabled = rhs.mEnabled;
|
||||
mIntensity = rhs.mIntensity;
|
||||
mRadius = rhs.mRadius;
|
||||
mThreshold = rhs.mThreshold;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void QgsAmbientOcclusionSettings::readXml( const QDomElement &element, const QgsReadWriteContext &context )
|
||||
{
|
||||
mEnabled = element.attribute( QStringLiteral( "enabled" ), QStringLiteral( "0" ) ).toInt();
|
||||
mIntensity = element.attribute( QStringLiteral( "intensity" ), QStringLiteral( "0.5" ) ).toFloat();
|
||||
mRadius = element.attribute( QStringLiteral( "radius" ), QStringLiteral( "25" ) ).toFloat();
|
||||
mThreshold = element.attribute( QStringLiteral( "threshold" ), QStringLiteral( "0.5" ) ).toFloat();
|
||||
|
||||
Q_UNUSED( context );
|
||||
}
|
||||
|
||||
void QgsAmbientOcclusionSettings::writeXml( QDomElement &element, const QgsReadWriteContext &context ) const
|
||||
{
|
||||
element.setAttribute( QStringLiteral( "enabled" ), mEnabled );
|
||||
element.setAttribute( QStringLiteral( "intensity" ), mIntensity );
|
||||
element.setAttribute( QStringLiteral( "radius" ), mRadius );
|
||||
element.setAttribute( QStringLiteral( "threshold" ), mThreshold );
|
||||
|
||||
Q_UNUSED( context );
|
||||
}
|
||||
81
src/3d/qgsambientocclusionsettings.h
Normal file
81
src/3d/qgsambientocclusionsettings.h
Normal file
@ -0,0 +1,81 @@
|
||||
/***************************************************************************
|
||||
qgsambientocclusionsettings.h
|
||||
--------------------------------------
|
||||
Date : June 2022
|
||||
Copyright : (C) 2022 by Belgacem Nedjima
|
||||
Email : belgacem dot nedjima at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSAMBIENTOCCLUSIONSETTINGS_H
|
||||
#define QGSAMBIENTOCCLUSIONSETTINGS_H
|
||||
|
||||
#include <QString>
|
||||
#include <QMap>
|
||||
|
||||
#include "qgis_3d.h"
|
||||
|
||||
class QgsReadWriteContext;
|
||||
class QDomElement;
|
||||
|
||||
#define SIP_NO_FILE
|
||||
|
||||
/**
|
||||
* \brief class containing the configuration of ambient occlusion rendering
|
||||
* \ingroup 3d
|
||||
* \note Not available in Python bindings
|
||||
* \since QGIS 3.28
|
||||
*/
|
||||
class _3D_EXPORT QgsAmbientOcclusionSettings
|
||||
{
|
||||
public:
|
||||
//! Default constructor
|
||||
QgsAmbientOcclusionSettings() = default;
|
||||
//! Copy constructor
|
||||
QgsAmbientOcclusionSettings( const QgsAmbientOcclusionSettings &other );
|
||||
//! delete assignment operator
|
||||
QgsAmbientOcclusionSettings &operator=( QgsAmbientOcclusionSettings const &rhs );
|
||||
|
||||
//! Reads settings from a DOM \a element
|
||||
void readXml( const QDomElement &element, const QgsReadWriteContext &context );
|
||||
//! Writes settings to a DOM \a element
|
||||
void writeXml( QDomElement &element, const QgsReadWriteContext &context ) const;
|
||||
|
||||
//! Sets whether ambient occlusion effect is enabled
|
||||
void setEnabled( bool enabled ) { mEnabled = enabled; }
|
||||
|
||||
//! Returns whether ambient occlusion effect is enabled
|
||||
bool isEnabled() const { return mEnabled; }
|
||||
|
||||
//! Sets the shading factor of the ambient occlusion effect
|
||||
void setIntensity( float factor ) { mIntensity = factor; }
|
||||
|
||||
//! Returns the shading factor of the ambient occlusion effect
|
||||
float intensity() const { return mIntensity; }
|
||||
|
||||
//! Sets the radius parameter of the ambient occlusion effect
|
||||
void setRadius( float radius ) { mRadius = radius; }
|
||||
|
||||
//! Returns the radius parameter of the ambient occlusion effect
|
||||
float radius() const { return mRadius; }
|
||||
|
||||
//! Sets at what amount of occlusion the effect will kick in
|
||||
void setThreshold( float threshold ) { mThreshold = threshold; }
|
||||
|
||||
//! Returns at what amount of occlusion the effect will kick in
|
||||
float threshold() const { return mThreshold; }
|
||||
|
||||
private:
|
||||
bool mEnabled = false;
|
||||
float mIntensity = 0.5f;
|
||||
float mRadius = 25.0f;
|
||||
float mThreshold = 0.5f;
|
||||
};
|
||||
|
||||
#endif // QGSAMBIENTOCCLUSIONSETTINGS_H
|
||||
@ -43,41 +43,17 @@ typedef Qt3DCore::QGeometry Qt3DQGeometry;
|
||||
#include "qgsshadowrenderingframegraph.h"
|
||||
|
||||
QgsPostprocessingEntity::QgsPostprocessingEntity( QgsShadowRenderingFrameGraph *frameGraph, QNode *parent )
|
||||
: Qt3DCore::QEntity( parent )
|
||||
: QgsRenderPassQuad( parent )
|
||||
, mFrameGraph( frameGraph )
|
||||
{
|
||||
Qt3DQGeometry *geom = new Qt3DQGeometry( this );
|
||||
Qt3DQAttribute *positionAttribute = new Qt3DQAttribute( this );
|
||||
const QVector<float> vert = { -1.0f, -1.0f, 0.0f, /**/ 1.0f, -1.0f, 0.0f, /**/ -1.0f, 1.0f, 0.0f, /**/ -1.0f, 1.0f, 0.0f, /**/ 1.0f, -1.0f, 0.0f, /**/ 1.0f, 1.0f, 0.0f };
|
||||
|
||||
const QByteArray vertexArr( ( const char * ) vert.constData(), vert.size() * sizeof( float ) );
|
||||
Qt3DQBuffer *vertexBuffer = nullptr;
|
||||
vertexBuffer = new Qt3DQBuffer( this );
|
||||
vertexBuffer->setData( vertexArr );
|
||||
|
||||
positionAttribute->setName( Qt3DQAttribute::defaultPositionAttributeName() );
|
||||
positionAttribute->setVertexBaseType( Qt3DQAttribute::Float );
|
||||
positionAttribute->setVertexSize( 3 );
|
||||
positionAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
|
||||
positionAttribute->setBuffer( vertexBuffer );
|
||||
positionAttribute->setByteOffset( 0 );
|
||||
positionAttribute->setByteStride( 3 * sizeof( float ) );
|
||||
positionAttribute->setCount( 6 );
|
||||
|
||||
geom->addAttribute( positionAttribute );
|
||||
|
||||
Qt3DRender::QGeometryRenderer *renderer = new Qt3DRender::QGeometryRenderer( this );
|
||||
renderer->setPrimitiveType( Qt3DRender::QGeometryRenderer::PrimitiveType::Triangles );
|
||||
renderer->setGeometry( geom );
|
||||
|
||||
addComponent( renderer );
|
||||
|
||||
mMaterial = new Qt3DRender::QMaterial( this );
|
||||
mColorTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "colorTexture" ), frameGraph->forwardRenderColorTexture() );
|
||||
mDepthTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "depthTexture" ), frameGraph->forwardRenderDepthTexture() );
|
||||
mShadowMapParameter = new Qt3DRender::QParameter( QStringLiteral( "shadowTexture" ), frameGraph->shadowMapTexture() );
|
||||
mAmbientOcclusionTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "ssaoTexture" ), frameGraph->blurredAmbientOcclusionFactorMap() );
|
||||
mMaterial->addParameter( mColorTextureParameter );
|
||||
mMaterial->addParameter( mDepthTextureParameter );
|
||||
mMaterial->addParameter( mShadowMapParameter );
|
||||
mMaterial->addParameter( mAmbientOcclusionTextureParameter );
|
||||
|
||||
mMainCamera = frameGraph->mainCamera();
|
||||
mLightCamera = frameGraph->lightCamera();
|
||||
@ -143,39 +119,19 @@ QgsPostprocessingEntity::QgsPostprocessingEntity( QgsShadowRenderingFrameGraph *
|
||||
mMaterial->addParameter( mEyeDomeLightingStrengthParameter );
|
||||
mMaterial->addParameter( mEyeDomeLightingDistanceParameter );
|
||||
|
||||
mAmbientOcclusionEnabledParameter = new Qt3DRender::QParameter( QStringLiteral( "ssaoEnabled" ), QVariant::fromValue( 0 ) );
|
||||
mMaterial->addParameter( mAmbientOcclusionEnabledParameter );
|
||||
|
||||
mLightPosition = new Qt3DRender::QParameter( QStringLiteral( "lightPosition" ), QVariant::fromValue( QVector3D() ) );
|
||||
mLightDirection = new Qt3DRender::QParameter( QStringLiteral( "lightDirection" ), QVariant::fromValue( QVector3D() ) );
|
||||
mMaterial->addParameter( mLightPosition );
|
||||
mMaterial->addParameter( mLightDirection );
|
||||
|
||||
mEffect = new Qt3DRender::QEffect( this );
|
||||
Qt3DRender::QTechnique *technique = new Qt3DRender::QTechnique( this );
|
||||
Qt3DRender::QGraphicsApiFilter *graphicsApiFilter = technique->graphicsApiFilter();
|
||||
graphicsApiFilter->setApi( Qt3DRender::QGraphicsApiFilter::Api::OpenGL );
|
||||
graphicsApiFilter->setProfile( Qt3DRender::QGraphicsApiFilter::OpenGLProfile::CoreProfile );
|
||||
graphicsApiFilter->setMajorVersion( 1 );
|
||||
graphicsApiFilter->setMinorVersion( 5 );
|
||||
Qt3DRender::QRenderPass *renderPass = new Qt3DRender::QRenderPass( this );
|
||||
Qt3DRender::QShaderProgram *shader = new Qt3DRender::QShaderProgram( this );
|
||||
|
||||
const QString vertexShaderPath = QStringLiteral( "qrc:/shaders/postprocess.vert" );
|
||||
const QString fragmentShaderPath = QStringLiteral( "qrc:/shaders/postprocess.frag" );
|
||||
|
||||
shader->setVertexShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( vertexShaderPath ) ) );
|
||||
shader->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( fragmentShaderPath ) ) );
|
||||
renderPass->setShaderProgram( shader );
|
||||
|
||||
Qt3DRender::QDepthTest *depthTest = new Qt3DRender::QDepthTest( this );
|
||||
depthTest->setDepthFunction( Qt3DRender::QDepthTest::Always );
|
||||
|
||||
renderPass->addRenderState( depthTest );
|
||||
|
||||
technique->addRenderPass( renderPass );
|
||||
|
||||
mEffect->addTechnique( technique );
|
||||
mMaterial->setEffect( mEffect );
|
||||
|
||||
addComponent( mMaterial );
|
||||
mShader->setVertexShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( vertexShaderPath ) ) );
|
||||
mShader->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( fragmentShaderPath ) ) );
|
||||
}
|
||||
|
||||
void QgsPostprocessingEntity::setupShadowRenderingExtent( float minX, float maxX, float minZ, float maxZ )
|
||||
@ -216,3 +172,8 @@ void QgsPostprocessingEntity::setEyeDomeLightingDistance( int distance )
|
||||
{
|
||||
mEyeDomeLightingDistanceParameter->setValue( QVariant::fromValue( distance ) );
|
||||
}
|
||||
|
||||
void QgsPostprocessingEntity::setAmbientOcclusionEnabled( bool enabled )
|
||||
{
|
||||
mAmbientOcclusionEnabledParameter->setValue( enabled );
|
||||
}
|
||||
|
||||
@ -16,11 +16,7 @@
|
||||
#ifndef QGSPOSTPROCESSINGENTITY_H
|
||||
#define QGSPOSTPROCESSINGENTITY_H
|
||||
|
||||
#include <Qt3DCore/QEntity>
|
||||
#include <Qt3DRender/QTexture>
|
||||
#include <Qt3DRender/QMaterial>
|
||||
#include <Qt3DRender/QEffect>
|
||||
#include <Qt3DRender/QCamera>
|
||||
#include "qgsrenderpassquad.h"
|
||||
|
||||
class QgsShadowRenderingFrameGraph;
|
||||
|
||||
@ -30,13 +26,11 @@ class QgsShadowRenderingFrameGraph;
|
||||
* \ingroup 3d
|
||||
* \brief An entity that is responsible for applying post processing effect.
|
||||
*
|
||||
* Now it is used to make shadows.
|
||||
*
|
||||
* \note Not available in Python bindings
|
||||
*
|
||||
* \since QGIS 3.16
|
||||
*/
|
||||
class QgsPostprocessingEntity : public Qt3DCore::QEntity
|
||||
class QgsPostprocessingEntity : public QgsRenderPassQuad
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@ -57,13 +51,21 @@ class QgsPostprocessingEntity : public Qt3DCore::QEntity
|
||||
void setEyeDomeLightingStrength( double strength );
|
||||
//! Sets the eye dome lighting distance (contributes to the contrast of the image)
|
||||
void setEyeDomeLightingDistance( int distance );
|
||||
|
||||
/**
|
||||
* Sets whether screen space ambient occlusion is enabled
|
||||
* \since QGIS 3.28
|
||||
*/
|
||||
void setAmbientOcclusionEnabled( bool enabled );
|
||||
|
||||
private:
|
||||
Qt3DRender::QMaterial *mMaterial = nullptr;
|
||||
Qt3DRender::QEffect *mEffect = nullptr;
|
||||
QgsShadowRenderingFrameGraph *mFrameGraph = nullptr;
|
||||
Qt3DRender::QCamera *mMainCamera = nullptr;
|
||||
|
||||
Qt3DRender::QParameter *mColorTextureParameter = nullptr;
|
||||
Qt3DRender::QParameter *mDepthTextureParameter = nullptr;
|
||||
Qt3DRender::QParameter *mShadowMapParameter = nullptr;
|
||||
Qt3DRender::QCamera *mMainCamera = nullptr;
|
||||
Qt3DRender::QParameter *mAmbientOcclusionTextureParameter = nullptr;
|
||||
Qt3DRender::QParameter *mFarPlaneParameter = nullptr;
|
||||
Qt3DRender::QParameter *mNearPlaneParameter = nullptr;
|
||||
Qt3DRender::QParameter *mMainCameraInvViewMatrixParameter = nullptr;
|
||||
@ -86,6 +88,8 @@ class QgsPostprocessingEntity : public Qt3DCore::QEntity
|
||||
Qt3DRender::QParameter *mEyeDomeLightingEnabledParameter = nullptr;
|
||||
Qt3DRender::QParameter *mEyeDomeLightingStrengthParameter = nullptr;
|
||||
Qt3DRender::QParameter *mEyeDomeLightingDistanceParameter = nullptr;
|
||||
|
||||
Qt3DRender::QParameter *mAmbientOcclusionEnabledParameter = nullptr;
|
||||
};
|
||||
|
||||
#endif // QGSPOSTPROCESSINGENTITY_H
|
||||
|
||||
105
src/3d/qgsrenderpassquad.cpp
Normal file
105
src/3d/qgsrenderpassquad.cpp
Normal file
@ -0,0 +1,105 @@
|
||||
/***************************************************************************
|
||||
qgsrenderpassquad.cpp
|
||||
--------------------------------------
|
||||
Date : June 2022
|
||||
Copyright : (C) 2022 by Belgacem Nedjima
|
||||
Email : belgacem dot nedjima at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsrenderpassquad.h"
|
||||
|
||||
#include <random>
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
#include <Qt3DRender/QAttribute>
|
||||
#include <Qt3DRender/QBuffer>
|
||||
#include <Qt3DRender/QGeometry>
|
||||
|
||||
typedef Qt3DRender::QAttribute Qt3DQAttribute;
|
||||
typedef Qt3DRender::QBuffer Qt3DQBuffer;
|
||||
typedef Qt3DRender::QGeometry Qt3DQGeometry;
|
||||
#else
|
||||
#include <Qt3DCore/QAttribute>
|
||||
#include <Qt3DCore/QBuffer>
|
||||
#include <Qt3DCore/QGeometry>
|
||||
|
||||
typedef Qt3DCore::QAttribute Qt3DQAttribute;
|
||||
typedef Qt3DCore::QBuffer Qt3DQBuffer;
|
||||
typedef Qt3DCore::QGeometry Qt3DQGeometry;
|
||||
#endif
|
||||
|
||||
#include <Qt3DRender/QGeometryRenderer>
|
||||
#include <Qt3DRender/QTechnique>
|
||||
#include <Qt3DRender/QGraphicsApiFilter>
|
||||
#include <Qt3DRender/QDepthTest>
|
||||
#include <Qt3DRender/QEffect>
|
||||
#include <QUrl>
|
||||
#include <QVector3D>
|
||||
|
||||
QgsRenderPassQuad::QgsRenderPassQuad( QNode *parent )
|
||||
: Qt3DCore::QEntity( parent )
|
||||
{
|
||||
Qt3DQGeometry *geom = new Qt3DQGeometry( this );
|
||||
Qt3DQAttribute *positionAttribute = new Qt3DQAttribute( this );
|
||||
const QVector<float> vert = { -1.0f, -1.0f, 0.0f, /**/ 1.0f, -1.0f, 0.0f, /**/ -1.0f, 1.0f, 0.0f, /**/ -1.0f, 1.0f, 0.0f, /**/ 1.0f, -1.0f, 0.0f, /**/ 1.0f, 1.0f, 0.0f };
|
||||
|
||||
const QByteArray vertexArr( ( const char * ) vert.constData(), vert.size() * sizeof( float ) );
|
||||
Qt3DQBuffer *vertexBuffer = nullptr;
|
||||
vertexBuffer = new Qt3DQBuffer( this );
|
||||
vertexBuffer->setData( vertexArr );
|
||||
|
||||
positionAttribute->setName( Qt3DQAttribute::defaultPositionAttributeName() );
|
||||
positionAttribute->setVertexBaseType( Qt3DQAttribute::Float );
|
||||
positionAttribute->setVertexSize( 3 );
|
||||
positionAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
|
||||
positionAttribute->setBuffer( vertexBuffer );
|
||||
positionAttribute->setByteOffset( 0 );
|
||||
positionAttribute->setByteStride( 3 * sizeof( float ) );
|
||||
positionAttribute->setCount( 6 );
|
||||
|
||||
geom->addAttribute( positionAttribute );
|
||||
|
||||
Qt3DRender::QGeometryRenderer *renderer = new Qt3DRender::QGeometryRenderer( this );
|
||||
renderer->setPrimitiveType( Qt3DRender::QGeometryRenderer::PrimitiveType::Triangles );
|
||||
renderer->setGeometry( geom );
|
||||
|
||||
addComponent( renderer );
|
||||
|
||||
mMaterial = new Qt3DRender::QMaterial( this );
|
||||
|
||||
Qt3DRender::QEffect *effect = new Qt3DRender::QEffect( this );
|
||||
Qt3DRender::QTechnique *technique = new Qt3DRender::QTechnique( this );
|
||||
Qt3DRender::QGraphicsApiFilter *graphicsApiFilter = technique->graphicsApiFilter();
|
||||
graphicsApiFilter->setApi( Qt3DRender::QGraphicsApiFilter::Api::OpenGL );
|
||||
graphicsApiFilter->setProfile( Qt3DRender::QGraphicsApiFilter::OpenGLProfile::CoreProfile );
|
||||
graphicsApiFilter->setMajorVersion( 3 );
|
||||
graphicsApiFilter->setMinorVersion( 1 );
|
||||
Qt3DRender::QRenderPass *renderPass = new Qt3DRender::QRenderPass( this );
|
||||
mShader = new Qt3DRender::QShaderProgram( this );
|
||||
|
||||
renderPass->setShaderProgram( mShader );
|
||||
|
||||
Qt3DRender::QDepthTest *depthTest = new Qt3DRender::QDepthTest( this );
|
||||
depthTest->setDepthFunction( Qt3DRender::QDepthTest::Always );
|
||||
|
||||
renderPass->addRenderState( depthTest );
|
||||
|
||||
technique->addRenderPass( renderPass );
|
||||
|
||||
effect->addTechnique( technique );
|
||||
mMaterial->setEffect( effect );
|
||||
|
||||
addComponent( mMaterial );
|
||||
|
||||
mLayer = new Qt3DRender::QLayer( this );
|
||||
mLayer->setRecursive( true );
|
||||
addComponent( mLayer );
|
||||
}
|
||||
|
||||
53
src/3d/qgsrenderpassquad.h
Normal file
53
src/3d/qgsrenderpassquad.h
Normal file
@ -0,0 +1,53 @@
|
||||
/***************************************************************************
|
||||
qgsrenderpassquad.h
|
||||
--------------------------------------
|
||||
Date : June 2022
|
||||
Copyright : (C) 2022 by Belgacem Nedjima
|
||||
Email : belgacem dot nedjima at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSRENDERPASSQUAD_H
|
||||
#define QGSRENDERPASSQUAD_H
|
||||
|
||||
#include <Qt3DCore/QEntity>
|
||||
#include <Qt3DRender/QTexture>
|
||||
#include <Qt3DRender/QParameter>
|
||||
#include <Qt3DRender/QMaterial>
|
||||
#include <Qt3DRender/QEffect>
|
||||
#include <Qt3DRender/QCamera>
|
||||
#include <Qt3DRender/QShaderProgram>
|
||||
#include <Qt3DRender/QLayer>
|
||||
|
||||
#define SIP_NO_FILE
|
||||
|
||||
/**
|
||||
* \ingroup 3d
|
||||
* \brief An entity that is responsible for rendering a screen quad for a specific rendering pass.
|
||||
*
|
||||
* \note Not available in Python bindings
|
||||
*
|
||||
* \since QGIS 3.28
|
||||
*/
|
||||
class QgsRenderPassQuad : public Qt3DCore::QEntity
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
//! Constructor
|
||||
QgsRenderPassQuad( QNode *parent = nullptr );
|
||||
|
||||
//! Returns the layer object used to select this entity for rendering in a specific rendering pass
|
||||
Qt3DRender::QLayer *layer() { return mLayer; }
|
||||
protected:
|
||||
Qt3DRender::QMaterial *mMaterial = nullptr;
|
||||
Qt3DRender::QShaderProgram *mShader = nullptr;
|
||||
Qt3DRender::QLayer *mLayer = nullptr;
|
||||
};
|
||||
|
||||
#endif // QGSRENDERPASSQUAD_H
|
||||
@ -17,6 +17,9 @@
|
||||
#include "qgsdirectionallightsettings.h"
|
||||
#include "qgspostprocessingentity.h"
|
||||
#include "qgspreviewquad.h"
|
||||
#include "qgs3dutils.h"
|
||||
#include "qgsambientocclusionrenderentity.h"
|
||||
#include "qgsambientocclusionblurentity.h"
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
#include <Qt3DRender/QAttribute>
|
||||
@ -230,7 +233,6 @@ Qt3DRender::QFrameGraphNode *QgsShadowRenderingFrameGraph::constructPostprocessi
|
||||
mPostProcessingCameraSelector->setCamera( mLightCamera );
|
||||
|
||||
mPostprocessPassLayerFilter = new Qt3DRender::QLayerFilter( mPostProcessingCameraSelector );
|
||||
mPostprocessPassLayerFilter->addLayer( mPostprocessPassLayer );
|
||||
|
||||
mPostprocessClearBuffers = new Qt3DRender::QClearBuffers( mPostprocessPassLayerFilter );
|
||||
|
||||
@ -274,9 +276,106 @@ Qt3DRender::QFrameGraphNode *QgsShadowRenderingFrameGraph::constructPostprocessi
|
||||
|
||||
mRenderCapture = new Qt3DRender::QRenderCapture( mRenderCaptureTargetSelector );
|
||||
|
||||
mPostprocessingEntity = new QgsPostprocessingEntity( this, mRootEntity );
|
||||
mPostprocessPassLayerFilter->addLayer( mPostprocessingEntity->layer() );
|
||||
|
||||
return mPostProcessingCameraSelector;
|
||||
}
|
||||
|
||||
Qt3DRender::QFrameGraphNode *QgsShadowRenderingFrameGraph::constructAmbientOcclusionRenderPass()
|
||||
{
|
||||
mAmbientOcclusionRenderCameraSelector = new Qt3DRender::QCameraSelector;
|
||||
mAmbientOcclusionRenderCameraSelector->setCamera( mMainCamera );
|
||||
|
||||
mAmbientOcclusionRenderStateSet = new Qt3DRender::QRenderStateSet( mAmbientOcclusionRenderCameraSelector );
|
||||
|
||||
Qt3DRender::QDepthTest *depthRenderDepthTest = new Qt3DRender::QDepthTest;
|
||||
depthRenderDepthTest->setDepthFunction( Qt3DRender::QDepthTest::Always );;
|
||||
Qt3DRender::QCullFace *depthRenderCullFace = new Qt3DRender::QCullFace;
|
||||
depthRenderCullFace->setMode( Qt3DRender::QCullFace::NoCulling );
|
||||
|
||||
mAmbientOcclusionRenderStateSet->addRenderState( depthRenderDepthTest );
|
||||
mAmbientOcclusionRenderStateSet->addRenderState( depthRenderCullFace );
|
||||
|
||||
mAmbientOcclusionRenderLayerFilter = new Qt3DRender::QLayerFilter( mAmbientOcclusionRenderStateSet );
|
||||
|
||||
mAmbientOcclusionRenderCaptureTargetSelector = new Qt3DRender::QRenderTargetSelector( mAmbientOcclusionRenderLayerFilter );
|
||||
Qt3DRender::QRenderTarget *depthRenderTarget = new Qt3DRender::QRenderTarget( mAmbientOcclusionRenderCaptureTargetSelector );
|
||||
|
||||
// The lifetime of the objects created here is managed
|
||||
// automatically, as they become children of this object.
|
||||
|
||||
// Create a render target output for rendering color.
|
||||
Qt3DRender::QRenderTargetOutput *colorOutput = new Qt3DRender::QRenderTargetOutput( depthRenderTarget );
|
||||
colorOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 );
|
||||
|
||||
// Create a texture to render into.
|
||||
mAmbientOcclusionRenderTexture = new Qt3DRender::QTexture2D( colorOutput );
|
||||
mAmbientOcclusionRenderTexture->setSize( mSize.width(), mSize.height() );
|
||||
mAmbientOcclusionRenderTexture->setFormat( Qt3DRender::QAbstractTexture::R32F );
|
||||
mAmbientOcclusionRenderTexture->setMinificationFilter( Qt3DRender::QAbstractTexture::Linear );
|
||||
mAmbientOcclusionRenderTexture->setMagnificationFilter( Qt3DRender::QAbstractTexture::Linear );
|
||||
|
||||
// Hook the texture up to our output, and the output up to this object.
|
||||
colorOutput->setTexture( mAmbientOcclusionRenderTexture );
|
||||
depthRenderTarget->addOutput( colorOutput );
|
||||
|
||||
mAmbientOcclusionRenderCaptureTargetSelector->setTarget( depthRenderTarget );
|
||||
|
||||
mAmbientOcclusionRenderEntity = new QgsAmbientOcclusionRenderEntity( mForwardDepthTexture, mMainCamera, mRootEntity );
|
||||
mAmbientOcclusionRenderLayerFilter->addLayer( mAmbientOcclusionRenderEntity->layer() );
|
||||
|
||||
return mAmbientOcclusionRenderCameraSelector;
|
||||
}
|
||||
|
||||
Qt3DRender::QFrameGraphNode *QgsShadowRenderingFrameGraph::constructAmbientOcclusionBlurPass()
|
||||
{
|
||||
mAmbientOcclusionBlurCameraSelector = new Qt3DRender::QCameraSelector;
|
||||
mAmbientOcclusionBlurCameraSelector->setCamera( mMainCamera );
|
||||
|
||||
mAmbientOcclusionBlurStateSet = new Qt3DRender::QRenderStateSet( mAmbientOcclusionBlurCameraSelector );
|
||||
|
||||
Qt3DRender::QDepthTest *depthRenderDepthTest = new Qt3DRender::QDepthTest;
|
||||
depthRenderDepthTest->setDepthFunction( Qt3DRender::QDepthTest::Always );;
|
||||
Qt3DRender::QCullFace *depthRenderCullFace = new Qt3DRender::QCullFace;
|
||||
depthRenderCullFace->setMode( Qt3DRender::QCullFace::NoCulling );
|
||||
|
||||
mAmbientOcclusionBlurStateSet->addRenderState( depthRenderDepthTest );
|
||||
mAmbientOcclusionBlurStateSet->addRenderState( depthRenderCullFace );
|
||||
|
||||
mAmbientOcclusionBlurLayerFilter = new Qt3DRender::QLayerFilter( mAmbientOcclusionBlurStateSet );
|
||||
|
||||
mAmbientOcclusionBlurRenderCaptureTargetSelector = new Qt3DRender::QRenderTargetSelector( mAmbientOcclusionBlurLayerFilter );
|
||||
Qt3DRender::QRenderTarget *depthRenderTarget = new Qt3DRender::QRenderTarget( mAmbientOcclusionBlurRenderCaptureTargetSelector );
|
||||
|
||||
// The lifetime of the objects created here is managed
|
||||
// automatically, as they become children of this object.
|
||||
|
||||
// Create a render target output for rendering color.
|
||||
Qt3DRender::QRenderTargetOutput *colorOutput = new Qt3DRender::QRenderTargetOutput( depthRenderTarget );
|
||||
colorOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 );
|
||||
|
||||
// Create a texture to render into.
|
||||
mAmbientOcclusionBlurTexture = new Qt3DRender::QTexture2D( colorOutput );
|
||||
mAmbientOcclusionBlurTexture->setSize( mSize.width(), mSize.height() );
|
||||
mAmbientOcclusionBlurTexture->setFormat( Qt3DRender::QAbstractTexture::R32F );
|
||||
mAmbientOcclusionBlurTexture->setMinificationFilter( Qt3DRender::QAbstractTexture::Linear );
|
||||
mAmbientOcclusionBlurTexture->setMagnificationFilter( Qt3DRender::QAbstractTexture::Linear );
|
||||
|
||||
// Hook the texture up to our output, and the output up to this object.
|
||||
colorOutput->setTexture( mAmbientOcclusionBlurTexture );
|
||||
depthRenderTarget->addOutput( colorOutput );
|
||||
|
||||
mAmbientOcclusionBlurRenderCaptureTargetSelector->setTarget( depthRenderTarget );
|
||||
|
||||
mAmbientOcclusionBlurEntity = new QgsAmbientOcclusionBlurEntity( mAmbientOcclusionRenderTexture, mRootEntity );
|
||||
mAmbientOcclusionBlurLayerFilter->addLayer( mAmbientOcclusionBlurEntity->layer() );
|
||||
|
||||
return mAmbientOcclusionBlurCameraSelector;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Qt3DRender::QFrameGraphNode *QgsShadowRenderingFrameGraph::constructDepthRenderPass()
|
||||
{
|
||||
// depth buffer render to copy pass
|
||||
@ -417,14 +516,12 @@ QgsShadowRenderingFrameGraph::QgsShadowRenderingFrameGraph( QSurface *surface, Q
|
||||
mMainCamera = mainCamera;
|
||||
mLightCamera = new Qt3DRender::QCamera;
|
||||
|
||||
mPostprocessPassLayer = new Qt3DRender::QLayer;
|
||||
mPreviewLayer = new Qt3DRender::QLayer;
|
||||
mCastShadowsLayer = new Qt3DRender::QLayer;
|
||||
mForwardRenderLayer = new Qt3DRender::QLayer;
|
||||
mDepthRenderPassLayer = new Qt3DRender::QLayer;
|
||||
mTransparentObjectsPassLayer = new Qt3DRender::QLayer;
|
||||
|
||||
mPostprocessPassLayer->setRecursive( true );
|
||||
mPreviewLayer->setRecursive( true );
|
||||
mCastShadowsLayer->setRecursive( true );
|
||||
mForwardRenderLayer->setRecursive( true );
|
||||
@ -455,6 +552,13 @@ QgsShadowRenderingFrameGraph::QgsShadowRenderingFrameGraph( QSurface *surface, Q
|
||||
Qt3DRender::QFrameGraphNode *depthBufferProcessingPass = constructDepthRenderPass();
|
||||
depthBufferProcessingPass->setParent( mMainViewPort );
|
||||
|
||||
// Ambient occlusion factor render pass
|
||||
Qt3DRender::QFrameGraphNode *ambientOcclusionFactorRender = constructAmbientOcclusionRenderPass();
|
||||
ambientOcclusionFactorRender->setParent( mMainViewPort );
|
||||
|
||||
Qt3DRender::QFrameGraphNode *ambientOcclusionBlurPass = constructAmbientOcclusionBlurPass();
|
||||
ambientOcclusionBlurPass->setParent( mMainViewPort );
|
||||
|
||||
// post process
|
||||
Qt3DRender::QFrameGraphNode *postprocessingPass = constructPostprocessingPass();
|
||||
postprocessingPass->setParent( mMainViewPort );
|
||||
@ -463,9 +567,6 @@ QgsShadowRenderingFrameGraph::QgsShadowRenderingFrameGraph( QSurface *surface, Q
|
||||
Qt3DRender::QFrameGraphNode *previewPass = constructTexturesPreviewPass();
|
||||
previewPass->setParent( mMainViewPort );
|
||||
|
||||
mPostprocessingEntity = new QgsPostprocessingEntity( this, mRootEntity );
|
||||
mPostprocessingEntity->addComponent( mPostprocessPassLayer );
|
||||
|
||||
Qt3DRender::QParameter *depthMapIsDepthParam = new Qt3DRender::QParameter( "isDepth", true );
|
||||
Qt3DRender::QParameter *shadowMapIsDepthParam = new Qt3DRender::QParameter( "isDepth", true );
|
||||
|
||||
@ -603,6 +704,31 @@ void QgsShadowRenderingFrameGraph::setShadowMapResolution( int resolution )
|
||||
mShadowMapTexture->setHeight( mShadowMapResolution );
|
||||
}
|
||||
|
||||
void QgsShadowRenderingFrameGraph::setAmbientOcclusionEnabled( bool enabled )
|
||||
{
|
||||
mAmbientOcclusionEnabled = enabled;
|
||||
mAmbientOcclusionRenderEntity->setEnabled( enabled );
|
||||
mPostprocessingEntity->setAmbientOcclusionEnabled( enabled );
|
||||
}
|
||||
|
||||
void QgsShadowRenderingFrameGraph::setAmbientOcclusionIntensity( float intensity )
|
||||
{
|
||||
mAmbientOcclusionIntensity = intensity;
|
||||
mAmbientOcclusionRenderEntity->setIntensity( intensity );
|
||||
}
|
||||
|
||||
void QgsShadowRenderingFrameGraph::setAmbientOcclusionRadius( float radius )
|
||||
{
|
||||
mAmbientOcclusionRadius = radius;
|
||||
mAmbientOcclusionRenderEntity->setRadius( radius );
|
||||
}
|
||||
|
||||
void QgsShadowRenderingFrameGraph::setAmbientOcclusionThreshold( float threshold )
|
||||
{
|
||||
mAmbientOcclusionThreshold = threshold;
|
||||
mAmbientOcclusionRenderEntity->setThreshold( threshold );
|
||||
}
|
||||
|
||||
void QgsShadowRenderingFrameGraph::setFrustumCullingEnabled( bool enabled )
|
||||
{
|
||||
if ( enabled == mFrustumCullingEnabled )
|
||||
@ -681,6 +807,9 @@ void QgsShadowRenderingFrameGraph::setSize( QSize s )
|
||||
mDepthRenderCaptureDepthTexture->setSize( mSize.width(), mSize.height() );
|
||||
mDepthRenderCaptureColorTexture->setSize( mSize.width(), mSize.height() );
|
||||
mRenderSurfaceSelector->setExternalRenderTargetSize( mSize );
|
||||
|
||||
mAmbientOcclusionRenderTexture->setSize( mSize.width(), mSize.height() );
|
||||
mAmbientOcclusionBlurTexture->setSize( mSize.width(), mSize.height() );
|
||||
}
|
||||
|
||||
void QgsShadowRenderingFrameGraph::setRenderCaptureEnabled( bool enabled )
|
||||
|
||||
@ -44,7 +44,9 @@ class QgsDirectionalLightSettings;
|
||||
class QgsCameraController;
|
||||
class QgsRectangle;
|
||||
class QgsPostprocessingEntity;
|
||||
class QgsAmbientOcclusionRenderEntity;
|
||||
class QgsPreviewQuad;
|
||||
class QgsAmbientOcclusionBlurEntity;
|
||||
|
||||
#define SIP_NO_FILE
|
||||
|
||||
@ -74,8 +76,18 @@ class QgsShadowRenderingFrameGraph : public Qt3DCore::QEntity
|
||||
//! Returns the shadow map (a depth texture for the shadow rendering pass)
|
||||
Qt3DRender::QTexture2D *shadowMapTexture() { return mShadowMapTexture; }
|
||||
|
||||
//! Returns a layer object used to indicate that an entity is to be rendered during the post processing rendering pass
|
||||
Qt3DRender::QLayer *postprocessingPassLayer() { return mPostprocessPassLayer; }
|
||||
/**
|
||||
* Returns ambient occlusion factor values texture
|
||||
* \since QGIS 3.28
|
||||
*/
|
||||
Qt3DRender::QTexture2D *ambientOcclusionFactorMap() { return mAmbientOcclusionRenderTexture; }
|
||||
|
||||
/**
|
||||
* Returns blurred ambient occlusion factor values texture
|
||||
* \since QGIS 3.28
|
||||
*/
|
||||
Qt3DRender::QTexture2D *blurredAmbientOcclusionFactorMap() { return mAmbientOcclusionBlurTexture; }
|
||||
|
||||
//! Returns a layer object used to indicate that an entity is to be rendered during the preview textures rendering pass
|
||||
Qt3DRender::QLayer *previewLayer() { return mPreviewLayer; }
|
||||
//! Returns a layer object used to indicate that an entity will cast shadows
|
||||
@ -125,6 +137,55 @@ class QgsShadowRenderingFrameGraph : public Qt3DCore::QEntity
|
||||
//! Sets the resolution of the shadow map
|
||||
void setShadowMapResolution( int resolution );
|
||||
|
||||
|
||||
/**
|
||||
* Sets whether Screen Space Ambient Occlusion will be enabled
|
||||
* \since QGIS 3.28
|
||||
*/
|
||||
void setAmbientOcclusionEnabled( bool enabled );
|
||||
|
||||
/**
|
||||
* Returns whether Screen Space Ambient Occlusion is enabled
|
||||
* \since QGIS 3.28
|
||||
*/
|
||||
bool ambientOcclusionEnabled() const { return mAmbientOcclusionEnabled; }
|
||||
|
||||
/**
|
||||
* Sets the ambient occlusion intensity
|
||||
* \since QGIS 3.28
|
||||
*/
|
||||
void setAmbientOcclusionIntensity( float intensity );
|
||||
|
||||
/**
|
||||
* Returns the ambient occlusion intensity
|
||||
* \since QGIS 3.28
|
||||
*/
|
||||
float ambientOcclusionIntensity() const { return mAmbientOcclusionIntensity; }
|
||||
|
||||
/**
|
||||
* Sets the ambient occlusion radius
|
||||
* \since QGIS 3.28
|
||||
*/
|
||||
void setAmbientOcclusionRadius( float radius );
|
||||
|
||||
/**
|
||||
* Returns the ambient occlusion radius
|
||||
* \since QGIS 3.28
|
||||
*/
|
||||
float ambientOcclusionRadius() const { return mAmbientOcclusionRadius; }
|
||||
|
||||
/**
|
||||
* Sets the ambient occlusion threshold
|
||||
* \since QGIS 3.28
|
||||
*/
|
||||
void setAmbientOcclusionThreshold( float threshold );
|
||||
|
||||
/**
|
||||
* Returns the ambient occlusion threshold
|
||||
* \since QGIS 3.28
|
||||
*/
|
||||
float ambientOcclusionThreshold() const { return mAmbientOcclusionThreshold; }
|
||||
|
||||
//! Sets the clear color of the scene (background color)
|
||||
void setClearColor( const QColor &clearColor );
|
||||
//! Adds an preview entity that shows a texture in real time for debugging purposes
|
||||
@ -212,6 +273,22 @@ class QgsShadowRenderingFrameGraph : public Qt3DCore::QEntity
|
||||
Qt3DRender::QTexture2D *mRenderCaptureColorTexture = nullptr;
|
||||
Qt3DRender::QTexture2D *mRenderCaptureDepthTexture = nullptr;
|
||||
|
||||
// Ambient occlusion factor generation pass
|
||||
Qt3DRender::QCameraSelector *mAmbientOcclusionRenderCameraSelector = nullptr;
|
||||
Qt3DRender::QRenderStateSet *mAmbientOcclusionRenderStateSet = nullptr;;
|
||||
Qt3DRender::QLayerFilter *mAmbientOcclusionRenderLayerFilter = nullptr;
|
||||
Qt3DRender::QRenderTargetSelector *mAmbientOcclusionRenderCaptureTargetSelector = nullptr;
|
||||
// Ambient occlusion factor generation pass texture related objects:
|
||||
Qt3DRender::QTexture2D *mAmbientOcclusionRenderTexture = nullptr;
|
||||
|
||||
// Ambient occlusion factor blur pass
|
||||
Qt3DRender::QCameraSelector *mAmbientOcclusionBlurCameraSelector = nullptr;
|
||||
Qt3DRender::QRenderStateSet *mAmbientOcclusionBlurStateSet = nullptr;;
|
||||
Qt3DRender::QLayerFilter *mAmbientOcclusionBlurLayerFilter = nullptr;
|
||||
Qt3DRender::QRenderTargetSelector *mAmbientOcclusionBlurRenderCaptureTargetSelector = nullptr;
|
||||
// Ambient occlusion factor blur pass texture related objects:
|
||||
Qt3DRender::QTexture2D *mAmbientOcclusionBlurTexture = nullptr;
|
||||
|
||||
// Texture preview:
|
||||
Qt3DRender::QLayerFilter *mPreviewLayerFilter = nullptr;
|
||||
Qt3DRender::QRenderStateSet *mPreviewRenderStateSet = nullptr;
|
||||
@ -222,6 +299,12 @@ class QgsShadowRenderingFrameGraph : public Qt3DCore::QEntity
|
||||
float mShadowBias = 0.00001f;
|
||||
int mShadowMapResolution = 2048;
|
||||
|
||||
// Ambient occlusion related settings
|
||||
bool mAmbientOcclusionEnabled = false;
|
||||
float mAmbientOcclusionIntensity = 0.5f;
|
||||
float mAmbientOcclusionRadius = 25.f;
|
||||
float mAmbientOcclusionThreshold = 0.5f;
|
||||
|
||||
QSize mSize = QSize( 1024, 768 );
|
||||
|
||||
bool mEyeDomeLightingEnabled = false;
|
||||
@ -237,7 +320,6 @@ class QgsShadowRenderingFrameGraph : public Qt3DCore::QEntity
|
||||
|
||||
Qt3DCore::QEntity *mRootEntity = nullptr;
|
||||
|
||||
Qt3DRender::QLayer *mPostprocessPassLayer = nullptr;
|
||||
Qt3DRender::QLayer *mPreviewLayer = nullptr;
|
||||
Qt3DRender::QLayer *mForwardRenderLayer = nullptr;
|
||||
Qt3DRender::QLayer *mCastShadowsLayer = nullptr;
|
||||
@ -245,6 +327,8 @@ class QgsShadowRenderingFrameGraph : public Qt3DCore::QEntity
|
||||
Qt3DRender::QLayer *mTransparentObjectsPassLayer = nullptr;
|
||||
|
||||
QgsPostprocessingEntity *mPostprocessingEntity = nullptr;
|
||||
QgsAmbientOcclusionRenderEntity *mAmbientOcclusionRenderEntity = nullptr;
|
||||
QgsAmbientOcclusionBlurEntity *mAmbientOcclusionBlurEntity = nullptr;
|
||||
|
||||
QVector<QgsPreviewQuad *> mPreviewQuads;
|
||||
|
||||
@ -253,6 +337,8 @@ class QgsShadowRenderingFrameGraph : public Qt3DCore::QEntity
|
||||
Qt3DRender::QFrameGraphNode *constructTexturesPreviewPass();
|
||||
Qt3DRender::QFrameGraphNode *constructPostprocessingPass();
|
||||
Qt3DRender::QFrameGraphNode *constructDepthRenderPass();
|
||||
Qt3DRender::QFrameGraphNode *constructAmbientOcclusionRenderPass();
|
||||
Qt3DRender::QFrameGraphNode *constructAmbientOcclusionBlurPass();
|
||||
|
||||
Qt3DCore::QEntity *constructDepthRenderQuad();
|
||||
|
||||
|
||||
@ -30,5 +30,9 @@
|
||||
<file>shaders/goochDataDefined.vert</file>
|
||||
<file>shaders/depth_render.frag</file>
|
||||
<file>shaders/depth_render.vert</file>
|
||||
<file>shaders/ssao_factor_render.frag</file>
|
||||
<file>shaders/ssao_factor_render.vert</file>
|
||||
<file>shaders/ssao_factor_blur.frag</file>
|
||||
<file>shaders/ssao_factor_blur.vert</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@ -4,6 +4,7 @@ uniform sampler2D colorTexture;
|
||||
uniform sampler2D depthTexture;
|
||||
//uniform sampler2DShadow shadowTexture;
|
||||
uniform sampler2D shadowTexture;
|
||||
uniform sampler2D ssaoTexture;
|
||||
|
||||
// light camera uniforms
|
||||
uniform mat4 viewMatrix;
|
||||
@ -32,6 +33,8 @@ uniform int edlEnabled;
|
||||
uniform float edlStrength;
|
||||
uniform int edlDistance;
|
||||
|
||||
uniform int ssaoEnabled;
|
||||
|
||||
in vec2 texCoord;
|
||||
|
||||
out vec4 fragColor;
|
||||
@ -131,4 +134,8 @@ void main()
|
||||
float shade = exp(-edlFactor(texCoord) * edlStrength);
|
||||
fragColor = vec4(fragColor.rgb * shade, fragColor.a);
|
||||
}
|
||||
if ( ssaoEnabled != 0 )
|
||||
{
|
||||
fragColor = vec4( fragColor.rgb * texture( ssaoTexture, texCoord ).r, fragColor.a );
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
|
||||
in vec3 vertexPosition;
|
||||
|
||||
out vec3 worldPosition;
|
||||
out vec2 texCoord;
|
||||
|
||||
void main()
|
||||
|
||||
21
src/3d/shaders/ssao_factor_blur.frag
Normal file
21
src/3d/shaders/ssao_factor_blur.frag
Normal file
@ -0,0 +1,21 @@
|
||||
#version 330
|
||||
|
||||
uniform sampler2D texture;
|
||||
|
||||
in vec2 texCoord;
|
||||
|
||||
out float fragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
// simple 4x4 box blur which smoothes the 4x4 noise pattern
|
||||
float result = 0.0;
|
||||
for (int x = -2; x < 2; ++x)
|
||||
{
|
||||
for (int y = -2; y < 2; ++y)
|
||||
{
|
||||
result += texelFetch(texture, ivec2(gl_FragCoord) + ivec2(x,y), 0).r;
|
||||
}
|
||||
}
|
||||
fragColor = result / (4.0 * 4.0);
|
||||
}
|
||||
11
src/3d/shaders/ssao_factor_blur.vert
Normal file
11
src/3d/shaders/ssao_factor_blur.vert
Normal file
@ -0,0 +1,11 @@
|
||||
#version 150 core
|
||||
|
||||
in vec3 vertexPosition;
|
||||
|
||||
out vec2 texCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(vertexPosition, 1.0f);
|
||||
texCoord = (vertexPosition.xy + vec2(1.0f)) / 2.0f;
|
||||
}
|
||||
77
src/3d/shaders/ssao_factor_render.frag
Normal file
77
src/3d/shaders/ssao_factor_render.frag
Normal file
@ -0,0 +1,77 @@
|
||||
#version 330
|
||||
|
||||
uniform sampler2D depthTexture;
|
||||
|
||||
uniform float farPlane;
|
||||
uniform float nearPlane;
|
||||
uniform mat4 origProjMatrix; // Perspective projection matrix used for forward rendering
|
||||
|
||||
uniform vec3 ssaoKernel[64]; // Random sample vectors in a unit sphere
|
||||
const int kernelSize = 64;
|
||||
uniform vec3 ssaoNoise[16]; // 4x4 random noise pattern
|
||||
|
||||
uniform float intensity; // Amplification of shading
|
||||
uniform float radius; // Radius of neighborhood sphere (in world units)
|
||||
uniform float threshold; // At what amount of occlusion to start darkening
|
||||
|
||||
noperspective in vec3 vViewRay; // Ray to far plane
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
|
||||
float linearizeDepth(float depth)
|
||||
{
|
||||
float ndc = depth * 2.0 - 1.0;
|
||||
return (2.0 * nearPlane * farPlane) / (farPlane + nearPlane - ndc * (farPlane - nearPlane));
|
||||
}
|
||||
|
||||
vec3 rotate_x(vec3 vct, float angle)
|
||||
{
|
||||
return vec3(vct.x*cos(angle)-vct.y*sin(angle), vct.x*sin(angle)+vct.y*cos(angle), vct.z);
|
||||
}
|
||||
vec3 rotate_y(vec3 vct, float angle)
|
||||
{
|
||||
return vec3(vct.x*cos(angle)+vct.z*sin(angle), vct.y, -vct.x*sin(angle)+vct.z*cos(angle));
|
||||
}
|
||||
|
||||
float ssao(vec3 originPos, vec3 noise)
|
||||
{
|
||||
float occlusion = 0.0;
|
||||
for (int i = 0; i < kernelSize; ++i)
|
||||
{
|
||||
// get sample position:
|
||||
vec3 samplePos = rotate_y(rotate_x(ssaoKernel[i], noise.x), noise.y);
|
||||
samplePos = samplePos * radius + originPos;
|
||||
|
||||
// project sample position:
|
||||
vec4 offset = origProjMatrix * vec4(samplePos, 1.0);
|
||||
offset.xy /= offset.w; // only need xy (range [-1,1])
|
||||
offset.xy = offset.xy * 0.5 + 0.5; // scale/bias to texcoords (range [0,1])
|
||||
|
||||
// get sample depth:
|
||||
float sampleDepth = texture(depthTexture, offset.xy).r;
|
||||
sampleDepth = linearizeDepth(sampleDepth);
|
||||
|
||||
float rangeCheck = smoothstep(0.0, 1.0, radius / abs(originPos.z - sampleDepth));
|
||||
occlusion += rangeCheck * step(sampleDepth, samplePos.z);
|
||||
}
|
||||
|
||||
return min(1.0, (1.0 - (occlusion / float(kernelSize))) / (1.0 - threshold));
|
||||
}
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
// calculate view-space 3D coordinates of this pixel
|
||||
vec2 texelSize = 1.0 / vec2(textureSize(depthTexture, 0));
|
||||
vec2 screenTexCoords = gl_FragCoord.xy * texelSize;
|
||||
float originDepth = linearizeDepth(texture(depthTexture, screenTexCoords).r);
|
||||
vec3 originPos = vViewRay * originDepth;
|
||||
|
||||
int a_idx = int(gl_FragCoord.x) % 4 + 4 * (int(gl_FragCoord.y) % 4);
|
||||
vec3 noise = ssaoNoise[a_idx] * 2*3.14;
|
||||
|
||||
float ssao_res = ssao(originPos, noise);
|
||||
|
||||
fragColor = vec4(pow(ssao_res,intensity));
|
||||
}
|
||||
23
src/3d/shaders/ssao_factor_render.vert
Normal file
23
src/3d/shaders/ssao_factor_render.vert
Normal file
@ -0,0 +1,23 @@
|
||||
#version 150 core
|
||||
|
||||
in vec3 vertexPosition;
|
||||
|
||||
out vec2 texCoord;
|
||||
|
||||
noperspective out vec3 vViewRay; // ray to far plane
|
||||
|
||||
// view frustum parameters:
|
||||
uniform float uTanHalfFov;
|
||||
uniform float uAspectRatio;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(vertexPosition, 1.0f);
|
||||
texCoord = (vertexPosition.xy + vec2(1.0f)) / 2.0f;
|
||||
|
||||
vViewRay = vec3(
|
||||
-vertexPosition.x * uTanHalfFov * uAspectRatio,
|
||||
-vertexPosition.y * uTanHalfFov,
|
||||
1.0 // since we'll be multiplying by linear depth, leave z as 1
|
||||
);
|
||||
}
|
||||
@ -154,6 +154,17 @@ Qgs3DMapCanvasWidget::Qgs3DMapCanvasWidget( const QString &name, bool isDocked )
|
||||
mCanvas->map()->setEyeDomeLightingEnabled( enabled );
|
||||
} );
|
||||
mOptionsMenu->addAction( mActionEnableEyeDome );
|
||||
|
||||
mActionEnableAmbientOcclusion = new QAction( tr( "Show Ambient Occlusion" ), this );
|
||||
mActionEnableAmbientOcclusion->setCheckable( true );
|
||||
connect( mActionEnableAmbientOcclusion, &QAction::triggered, this, [ = ]( bool enabled )
|
||||
{
|
||||
QgsAmbientOcclusionSettings ambientOcclusionSettings = mCanvas->map()->ambientOcclusionSettings();
|
||||
ambientOcclusionSettings.setEnabled( enabled );
|
||||
mCanvas->map()->setAmbientOcclusionSettings( ambientOcclusionSettings );
|
||||
} );
|
||||
mOptionsMenu->addAction( mActionEnableAmbientOcclusion );
|
||||
|
||||
mOptionsMenu->addSeparator();
|
||||
|
||||
mActionSync2DNavTo3D = new QAction( tr( "2D Map View Follows 3D Camera" ), this );
|
||||
@ -344,6 +355,7 @@ void Qgs3DMapCanvasWidget::setMapSettings( Qgs3DMapSettings *map )
|
||||
{
|
||||
whileBlocking( mActionEnableShadows )->setChecked( map->shadowSettings().renderShadows() );
|
||||
whileBlocking( mActionEnableEyeDome )->setChecked( map->eyeDomeLightingEnabled() );
|
||||
whileBlocking( mActionEnableAmbientOcclusion )->setChecked( map->ambientOcclusionSettings().isEnabled() );
|
||||
whileBlocking( mActionSync2DNavTo3D )->setChecked( map->viewSyncMode().testFlag( Qgis::ViewSyncModeFlag::Sync2DTo3D ) );
|
||||
whileBlocking( mActionSync3DNavTo2D )->setChecked( map->viewSyncMode().testFlag( Qgis::ViewSyncModeFlag::Sync3DTo2D ) );
|
||||
whileBlocking( mShowFrustumPolyogon )->setChecked( map->viewFrustumVisualizationEnabled() );
|
||||
@ -452,6 +464,7 @@ void Qgs3DMapCanvasWidget::configure()
|
||||
|
||||
whileBlocking( mActionEnableShadows )->setChecked( map->shadowSettings().renderShadows() );
|
||||
whileBlocking( mActionEnableEyeDome )->setChecked( map->eyeDomeLightingEnabled() );
|
||||
whileBlocking( mActionEnableAmbientOcclusion )->setChecked( map->ambientOcclusionSettings().isEnabled() );
|
||||
whileBlocking( mActionSync2DNavTo3D )->setChecked( map->viewSyncMode().testFlag( Qgis::ViewSyncModeFlag::Sync2DTo3D ) );
|
||||
whileBlocking( mActionSync3DNavTo2D )->setChecked( map->viewSyncMode().testFlag( Qgis::ViewSyncModeFlag::Sync3DTo2D ) );
|
||||
whileBlocking( mShowFrustumPolyogon )->setChecked( map->viewFrustumVisualizationEnabled() );
|
||||
|
||||
@ -108,6 +108,7 @@ class APP_EXPORT Qgs3DMapCanvasWidget : public QWidget
|
||||
QToolButton *mBtnMapThemes = nullptr;
|
||||
QAction *mActionEnableShadows = nullptr;
|
||||
QAction *mActionEnableEyeDome = nullptr;
|
||||
QAction *mActionEnableAmbientOcclusion = nullptr;
|
||||
QAction *mActionSync2DNavTo3D = nullptr;
|
||||
QAction *mActionSync3DNavTo2D = nullptr;
|
||||
QAction *mShowFrustumPolyogon = nullptr;
|
||||
|
||||
@ -33,6 +33,7 @@
|
||||
#include "qgssettings.h"
|
||||
#include "qgsskyboxrenderingsettingswidget.h"
|
||||
#include "qgsshadowrenderingsettingswidget.h"
|
||||
#include "qgsambientocclusionsettingswidget.h"
|
||||
#include "qgs3dmapcanvas.h"
|
||||
#include "qgs3dmapscene.h"
|
||||
#include "qgs3daxis.h"
|
||||
@ -245,6 +246,9 @@ Qgs3DMapConfigWidget::Qgs3DMapConfigWidget( Qgs3DMapSettings *map, QgsMapCanvas
|
||||
mDebugDepthMapGroupBox->setChecked( map->debugDepthMapEnabled() );
|
||||
mDebugDepthMapCornerComboBox->setCurrentIndex( static_cast<int>( map->debugDepthMapCorner() ) );
|
||||
mDebugDepthMapSizeSpinBox->setValue( map->debugDepthMapSize() );
|
||||
|
||||
// Ambient occlusion
|
||||
mAmbientOcclusionSettingsWidget->setAmbientOcclusionSettings( map->ambientOcclusionSettings() );
|
||||
}
|
||||
|
||||
Qgs3DMapConfigWidget::~Qgs3DMapConfigWidget()
|
||||
@ -392,6 +396,8 @@ void Qgs3DMapConfigWidget::apply()
|
||||
mMap->setEyeDomeLightingStrength( edlStrengthSpinBox->value() );
|
||||
mMap->setEyeDomeLightingDistance( edlDistanceSpinBox->value() );
|
||||
|
||||
mMap->setAmbientOcclusionSettings( mAmbientOcclusionSettingsWidget->toAmbientOcclusionSettings() );
|
||||
|
||||
Qgis::ViewSyncModeFlags viewSyncMode;
|
||||
viewSyncMode.setFlag( Qgis::ViewSyncModeFlag::Sync2DTo3D, mSync2DTo3DCheckbox->isChecked() );
|
||||
viewSyncMode.setFlag( Qgis::ViewSyncModeFlag::Sync3DTo2D, mSync3DTo2DCheckbox->isChecked() );
|
||||
|
||||
48
src/app/3d/qgsambientocclusionsettingswidget.cpp
Normal file
48
src/app/3d/qgsambientocclusionsettingswidget.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
/***************************************************************************
|
||||
qgsambientocclusionsettingswidget.cpp
|
||||
--------------------------------------
|
||||
Date : June 2022
|
||||
Copyright : (C) 2022 by Belgacem Nedjima
|
||||
Email : belgacem dot nedjima at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsambientocclusionsettingswidget.h"
|
||||
|
||||
QgsAmbientOcclusionSettingsWidget::QgsAmbientOcclusionSettingsWidget( QWidget *parent )
|
||||
: QWidget( parent )
|
||||
{
|
||||
setupUi( this );
|
||||
|
||||
mIntensitySpinBox->setToolTip( tr( "The strength of the shading applied, bigger values means more pronounced and darker colors." ) );
|
||||
mRadiusSpinBox->setToolTip( tr( "The radius of the neighborhood: bigger values mean objects further away will add to the occlusion." ) );
|
||||
mThresholdSpinBox->setToolTip( tr( "Only apply occlusion effect when at least the specified amount of neighboring points is occluded." ) );
|
||||
|
||||
mIntensitySpinBox->setClearValue( 0.5 );
|
||||
mRadiusSpinBox->setClearValue( 25. );
|
||||
mThresholdSpinBox->setClearValue( 50 );
|
||||
}
|
||||
|
||||
void QgsAmbientOcclusionSettingsWidget::setAmbientOcclusionSettings( const QgsAmbientOcclusionSettings &settings )
|
||||
{
|
||||
mAmbientOcclusionGroupBox->setChecked( settings.isEnabled() );
|
||||
mIntensitySpinBox->setValue( settings.intensity() );
|
||||
mRadiusSpinBox->setValue( settings.radius() );
|
||||
mThresholdSpinBox->setValue( settings.threshold() * 100 );
|
||||
}
|
||||
|
||||
QgsAmbientOcclusionSettings QgsAmbientOcclusionSettingsWidget::toAmbientOcclusionSettings()
|
||||
{
|
||||
QgsAmbientOcclusionSettings settings;
|
||||
settings.setEnabled( mAmbientOcclusionGroupBox->isChecked() );
|
||||
settings.setIntensity( mIntensitySpinBox->value() );
|
||||
settings.setRadius( mRadiusSpinBox->value() );
|
||||
settings.setThreshold( mThresholdSpinBox->value() / 100. );
|
||||
return settings;
|
||||
}
|
||||
35
src/app/3d/qgsambientocclusionsettingswidget.h
Normal file
35
src/app/3d/qgsambientocclusionsettingswidget.h
Normal file
@ -0,0 +1,35 @@
|
||||
/***************************************************************************
|
||||
qgsambientocclusionsettingswidget.h
|
||||
--------------------------------------
|
||||
Date : Juin 2022
|
||||
Copyright : (C) 2022 by Belgacem Nedjima
|
||||
Email : belgacem dot nedjima at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#ifndef QGSAMBIENTOCCLUSIONSETTINGSWIDGET_H
|
||||
#define QGSAMBIENTOCCLUSIONSETTINGSWIDGET_H
|
||||
|
||||
#include "ui_ambientocclusionsettingswidget.h"
|
||||
|
||||
#include "qgsambientocclusionsettings.h"
|
||||
|
||||
class QgsAmbientOcclusionSettingsWidget : public QWidget, private Ui::QgsAmbientOcclusionSettingsWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QgsAmbientOcclusionSettingsWidget( QWidget *parent = nullptr );
|
||||
|
||||
//! Sets the ambient occlusion settings in the current widget UI
|
||||
void setAmbientOcclusionSettings( const QgsAmbientOcclusionSettings &settings );
|
||||
//! Returns the ambient occlusion settings from the widget UI
|
||||
QgsAmbientOcclusionSettings toAmbientOcclusionSettings();
|
||||
};
|
||||
|
||||
#endif // QGSAMBIENTOCCLUSIONSETTINGSWIDGET_H
|
||||
@ -358,6 +358,7 @@ if (WITH_3D)
|
||||
layout/qgslayout3dmapwidget.cpp
|
||||
3d/qgsskyboxrenderingsettingswidget.cpp
|
||||
3d/qgsshadowrenderingsettingswidget.cpp
|
||||
3d/qgsambientocclusionsettingswidget.cpp
|
||||
3d/qgspointcloud3dsymbolwidget.cpp
|
||||
3d/qgspointcloudlayer3drendererwidget.cpp
|
||||
3d/qgs3dmapcanvaswidget.cpp
|
||||
|
||||
140
src/ui/3d/ambientocclusionsettingswidget.ui
Normal file
140
src/ui/3d/ambientocclusionsettingswidget.ui
Normal file
@ -0,0 +1,140 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>QgsAmbientOcclusionSettingsWidget</class>
|
||||
<widget class="QWidget" name="QgsAmbientOcclusionSettingsWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>185</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="mAmbientOcclusionGroupBox">
|
||||
<property name="title">
|
||||
<string>Ambient Occlusion</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Radius</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Intensity</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QgsDoubleSpinBox" name="mRadiusSpinBox">
|
||||
<property name="suffix">
|
||||
<string> map units</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1000.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>25.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QgsDoubleSpinBox" name="mIntensitySpinBox">
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>3.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.500000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Occlusion Threshold</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QgsSpinBox" name="mThresholdSpinBox">
|
||||
<property name="suffix">
|
||||
<string>%</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>95</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>50</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QgsDoubleSpinBox</class>
|
||||
<extends>QDoubleSpinBox</extends>
|
||||
<header>qgsdoublespinbox.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QgsSpinBox</class>
|
||||
<extends>QSpinBox</extends>
|
||||
<header>qgsspinbox.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>mAmbientOcclusionGroupBox</tabstop>
|
||||
<tabstop>mRadiusSpinBox</tabstop>
|
||||
<tabstop>mIntensitySpinBox</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@ -179,7 +179,7 @@
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="m3DOptionsStackedWidget">
|
||||
<property name="currentIndex">
|
||||
<number>3</number>
|
||||
<number>4</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="mPageTerrain">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_61">
|
||||
@ -206,7 +206,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>280</width>
|
||||
<height>301</height>
|
||||
<height>283</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayoutTerrain">
|
||||
@ -417,7 +417,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>77</width>
|
||||
<height>47</height>
|
||||
<height>43</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayoutLight">
|
||||
@ -500,8 +500,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>151</width>
|
||||
<height>47</height>
|
||||
<width>149</width>
|
||||
<height>43</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayoutShadow">
|
||||
@ -590,8 +590,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>816</width>
|
||||
<height>649</height>
|
||||
<width>335</width>
|
||||
<height>488</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayoutCameraSkybox">
|
||||
@ -802,8 +802,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>802</width>
|
||||
<height>732</height>
|
||||
<width>803</width>
|
||||
<height>706</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayoutAdvanced">
|
||||
@ -825,65 +825,7 @@
|
||||
<string>Advanced Settings</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_11">
|
||||
<item row="2" column="0">
|
||||
<widget class="QGroupBox" name="mDebugShadowMapGroupBox">
|
||||
<property name="title">
|
||||
<string>Debug Shadow Map</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_10">
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="mDebugShadowMapCornerComboBox"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Corner</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Size</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QgsDoubleSpinBox" name="mDebugShadowMapSizeSpinBox">
|
||||
<property name="maximum">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<spacer name="verticalSpacerAdvanced">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QGroupBox" name="mDebugDepthMapGroupBox">
|
||||
<property name="title">
|
||||
<string>Debug Depth Map</string>
|
||||
@ -1027,12 +969,12 @@
|
||||
</item>
|
||||
<item row="12" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="mDebugOverlayCheckBox">
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show debug overlay</string>
|
||||
</property>
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
@ -1065,6 +1007,51 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QGroupBox" name="mDebugShadowMapGroupBox">
|
||||
<property name="title">
|
||||
<string>Debug Shadow Map</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_10">
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="mDebugShadowMapCornerComboBox"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Corner</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Size</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QgsDoubleSpinBox" name="mDebugShadowMapSizeSpinBox">
|
||||
<property name="maximum">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QGroupBox" name="edlGroupBox">
|
||||
<property name="title">
|
||||
@ -1117,6 +1104,22 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<spacer name="verticalSpacerAdvanced">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QgsAmbientOcclusionSettingsWidget" name="mAmbientOcclusionSettingsWidget" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@ -1174,6 +1177,12 @@
|
||||
<header>qgslightswidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QgsAmbientOcclusionSettingsWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>qgsambientocclusionsettingswidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>m3DOptionsListWidget</tabstop>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user