QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
qgsambientocclusionrenderentity.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsambientocclusionrenderentity.cpp
3 --------------------------------------
4 Date : June 2022
5 Copyright : (C) 2022 by Belgacem Nedjima
6 Email : belgacem dot nedjima at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17
18#include <random>
19
20#include <Qt3DRender/QParameter>
21
22QgsAmbientOcclusionRenderEntity::QgsAmbientOcclusionRenderEntity( Qt3DRender::QTexture2D *depthTexture, Qt3DRender::QCamera *camera, QNode *parent )
23 : QgsRenderPassQuad( parent )
24{
25 mDepthTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "depthTexture" ), depthTexture );
26 mMaterial->addParameter( mDepthTextureParameter );
27
28 mFarPlaneParameter = new Qt3DRender::QParameter( QStringLiteral( "farPlane" ), camera->farPlane() );
29 mMaterial->addParameter( mFarPlaneParameter );
30 connect( camera, &Qt3DRender::QCamera::farPlaneChanged, mFarPlaneParameter, [&]( float farPlane )
31 {
32 mFarPlaneParameter->setValue( farPlane );
33 } );
34 mNearPlaneParameter = new Qt3DRender::QParameter( QStringLiteral( "nearPlane" ), camera->nearPlane() );
35 mMaterial->addParameter( mNearPlaneParameter );
36 connect( camera, &Qt3DRender::QCamera::nearPlaneChanged, mNearPlaneParameter, [&]( float nearPlane )
37 {
38 mNearPlaneParameter->setValue( nearPlane );
39 } );
40 mProjMatrixParameter = new Qt3DRender::QParameter( QStringLiteral( "origProjMatrix" ), camera->projectionMatrix() );
41 mMaterial->addParameter( mProjMatrixParameter );
42 connect( camera, &Qt3DRender::QCamera::projectionMatrixChanged, mProjMatrixParameter, [&]( const QMatrix4x4 & projectionMatrix )
43 {
44 mProjMatrixParameter->setValue( projectionMatrix );
45 } );
46 mAspectRatioParameter = new Qt3DRender::QParameter( QStringLiteral( "uAspectRatio" ), camera->aspectRatio() );
47 mMaterial->addParameter( mAspectRatioParameter );
48 connect( camera, &Qt3DRender::QCamera::aspectRatioChanged, mAspectRatioParameter, [&]( float ratio )
49 {
50 mAspectRatioParameter->setValue( ratio );
51 } );
52 mTanHalfFovParameter = new Qt3DRender::QParameter( QStringLiteral( "uTanHalfFov" ), tan( camera->fieldOfView() / 2 * M_PI / 180 ) );
53 mMaterial->addParameter( mTanHalfFovParameter );
54 connect( camera, &Qt3DRender::QCamera::fieldOfViewChanged, mTanHalfFovParameter, [&]( float fov )
55 {
56 mTanHalfFovParameter->setValue( tan( fov / 2 * M_PI / 180 ) );
57 } );
58
59 QVariantList ssaoKernelValues;
60
61 std::uniform_real_distribution<float> randomFloats( 0.0, 1.0 ); // random floats between [0.0, 1.0]
62 std::default_random_engine generator;
63 unsigned int kernelSize = 64;
64 for ( unsigned int i = 0; i < kernelSize; ++i )
65 {
66 QVector3D sample(
67 randomFloats( generator ) * 2.0 - 1.0,
68 randomFloats( generator ) * 2.0 - 1.0,
69 randomFloats( generator ) * 2.0 - 1.0
70 );
71 sample.normalize();
72 float scale = i / kernelSize;
73 scale = 0.1 + 0.9 * scale * scale;
74 sample *= scale;
75 ssaoKernelValues.push_back( sample );
76 }
77
78 // 4x4 array of random rotation vectors
79 QVariantList ssaoNoise;
80 for ( unsigned int i = 0; i < 16; ++i )
81 {
82 QVector3D sample(
83 randomFloats( generator ),
84 randomFloats( generator ),
85 0.0
86 );
87 ssaoNoise.push_back( sample );
88 }
89 mAmbientOcclusionKernelParameter = new Qt3DRender::QParameter( QStringLiteral( "ssaoKernel[0]" ), ssaoKernelValues );
90 mMaterial->addParameter( mAmbientOcclusionKernelParameter );
91
92 Qt3DRender::QParameter *noiseParameter = new Qt3DRender::QParameter( QStringLiteral( "ssaoNoise[0]" ), ssaoNoise );
93 mMaterial->addParameter( noiseParameter );
94
95 mIntensityParameter = new Qt3DRender::QParameter( QStringLiteral( "intensity" ), 0.5f );
96 mMaterial->addParameter( mIntensityParameter );
97
98 mRadiusParameter = new Qt3DRender::QParameter( QStringLiteral( "radius" ), 25.0f );
99 mMaterial->addParameter( mRadiusParameter );
100
101 mThresholdParameter = new Qt3DRender::QParameter( QStringLiteral( "threshold" ), 0.5f );
102 mMaterial->addParameter( mThresholdParameter );
103
104 const QString vertexShaderPath = QStringLiteral( "qrc:/shaders/ssao_factor_render.vert" );
105 const QString fragmentShaderPath = QStringLiteral( "qrc:/shaders/ssao_factor_render.frag" );
106
107 mShader->setVertexShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( vertexShaderPath ) ) );
108 mShader->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( fragmentShaderPath ) ) );
109}
110
112{
113 mIntensityParameter->setValue( intensity );
114}
115
117{
118 mRadiusParameter->setValue( radius );
119}
120
122{
123 mThresholdParameter->setValue( threshold );
124}
void setThreshold(float threshold)
Sets the amount of occlusion when the effects starts to kick in.
QgsAmbientOcclusionRenderEntity(Qt3DRender::QTexture2D *depthTexture, Qt3DRender::QCamera *camera, QNode *parent=nullptr)
Constructor.
void setRadius(float radius)
Sets the radius for the ambient occlusion effect.
void setIntensity(float intensity)
Sets the intensity for the ambient occlusion effect.
Qt3DRender::QShaderProgram * mShader
Qt3DRender::QMaterial * mMaterial