Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
HDR skyboxes implementation
  • Loading branch information
NEDJIMAbelgacem committed Aug 1, 2020
1 parent 45bc2d7 commit db75d88
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 2 deletions.
3 changes: 2 additions & 1 deletion src/3d/qgs3dmapscene.cpp
Expand Up @@ -205,7 +205,8 @@ Qgs3DMapScene::Qgs3DMapScene( const Qgs3DMapSettings &map, QgsAbstract3DEngine *
// if ( map.hasSkyboxEnabled() )
// {
// mSkybox = new QgsSkyboxEntity("file:///home/nedjima/dev/cpp/qt3d/examples/qt3d/exampleresources/assets/cubemaps/default/default_specular", ".dds", this);
mSkybox = new QgsSkyboxEntity( "file:///home/nedjima/dev/cpp/Standard-Cube-Map2/cube_map", ".png", this );
// mSkybox = new QgsSkyboxEntity( "file:///home/nedjima/dev/cpp/Standard-Cube-Map2/cube_map", ".png", this );
mSkybox = new QgsSkyboxEntity( "file:///home/nedjima/dev/cpp/abandoned_tank_farm_04_1k.hdr", this );
// mSkybox->setEnabled(false);

// docs say frustum culling must be disabled for skybox.
Expand Down
77 changes: 76 additions & 1 deletion src/3d/qgsskyboxentity.cpp
Expand Up @@ -36,6 +36,8 @@ QgsSkyboxEntity::QgsSkyboxEntity( const QString &baseName, const QString &extens
, mTextureParameter( new Qt3DRender::QParameter( this ) )
, mExtension( extension )
, mBaseName( baseName )
, mHDRTexturePath( QString() )
, mIsUsingHDR( false )
{
mGl3Shader->setVertexShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral( "qrc:/shaders/skybox.vert" ) ) ) );
mGl3Shader->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral( "qrc:/shaders/skybox.frag" ) ) ) );
Expand Down Expand Up @@ -90,11 +92,84 @@ QgsSkyboxEntity::QgsSkyboxEntity( const QString &baseName, const QString &extens
reloadTexture();
}

QgsSkyboxEntity::QgsSkyboxEntity( const QString &hdrTexturePath, Qt3DCore::QNode *parent )
: Qt3DCore::QEntity( parent )
, mEffect( new Qt3DRender::QEffect( this ) )
, mMaterial( new Qt3DRender::QMaterial( this ) )
, mGl3Shader( new Qt3DRender::QShaderProgram( this ) )
, mGl3Technique( new Qt3DRender::QTechnique( this ) )
, mFilterKey( new Qt3DRender::QFilterKey( this ) )
, mGl3RenderPass( new Qt3DRender::QRenderPass( this ) )
, mMesh( new Qt3DExtras::QCuboidMesh( this ) )
, mGammaStrengthParameter( new Qt3DRender::QParameter( QStringLiteral( "gammaStrength" ), 0.0f ) )
, mTextureParameter( new Qt3DRender::QParameter( this ) )
, mHDRTexturePath( hdrTexturePath )
, mIsUsingHDR( true )
{
mGl3Shader->setVertexShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral( "qrc:/shaders/hdr_skybox.vert" ) ) ) );
mGl3Shader->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral( "qrc:/shaders/hdr_skybox.frag" ) ) ) );

mGl3Technique->graphicsApiFilter()->setApi( Qt3DRender::QGraphicsApiFilter::OpenGL );
mGl3Technique->graphicsApiFilter()->setMajorVersion( 3 );
mGl3Technique->graphicsApiFilter()->setMinorVersion( 3 );
mGl3Technique->graphicsApiFilter()->setProfile( Qt3DRender::QGraphicsApiFilter::CoreProfile );

mFilterKey->setParent( mEffect );
mFilterKey->setName( QStringLiteral( "renderingStyle" ) );
mFilterKey->setValue( QStringLiteral( "forward" ) );

mGl3Technique->addFilterKey( mFilterKey );

mGl3RenderPass->setShaderProgram( mGl3Shader );

Qt3DRender::QCullFace *cullFront = new Qt3DRender::QCullFace();
cullFront->setMode( Qt3DRender::QCullFace::Front );
Qt3DRender::QDepthTest *depthTest = new Qt3DRender::QDepthTest();
depthTest->setDepthFunction( Qt3DRender::QDepthTest::LessOrEqual );
Qt3DRender::QSeamlessCubemap *seamlessCubemap = new Qt3DRender::QSeamlessCubemap();

mGl3RenderPass->addRenderState( cullFront );
mGl3RenderPass->addRenderState( depthTest );
mGl3RenderPass->addRenderState( seamlessCubemap );

mGl3Technique->addRenderPass( mGl3RenderPass );

mEffect->addTechnique( mGl3Technique );

mMaterial->setEffect( mEffect );
mMaterial->addParameter( mGammaStrengthParameter );
mMaterial->addParameter( mTextureParameter );

// mMesh->setXExtent( 2.0f );
// mMesh->setYExtent( 2.0f );
// mMesh->setZExtent( 2.0f );
mMesh->setXYMeshResolution( QSize( 2, 2 ) );
mMesh->setXZMeshResolution( QSize( 2, 2 ) );
mMesh->setYZMeshResolution( QSize( 2, 2 ) );

// TODO: change the kybox position according to
Qt3DCore::QTransform *transform = new Qt3DCore::QTransform( this );
transform->setTranslation( QVector3D( 0.0f, 0.0f, 0.0f ) );
transform->setScale( 1000.0f );
addComponent( transform );

addComponent( mMesh );
addComponent( mMaterial );

reloadTexture();
}

void QgsSkyboxEntity::reloadTexture()
{
if ( mSkyboxTextureLoader != nullptr )
delete mSkyboxTextureLoader;
if ( mExtension == QStringLiteral( ".dds" ) )
if ( mIsUsingHDR )
{
mSkyboxTextureLoader = new QgsHDRSkyboxTextureLoader( mHDRTexturePath, this );
mTextureParameter->setName( QStringLiteral( "skyboxTexture" ) );
mTextureParameter->setValue( mSkyboxTextureLoader->getTextureParameter() );
}
else if ( mExtension == QStringLiteral( ".dds" ) )
{
mSkyboxTextureLoader = new QgsDDSSkyboxLoader( mBaseName, mExtension, this );
mTextureParameter->setName( QStringLiteral( "skyboxTexture" ) );
Expand Down
19 changes: 19 additions & 0 deletions src/3d/qgsskyboxentity.h
Expand Up @@ -93,11 +93,28 @@ class QgsSkyboxTextureColloectionLoader : public QgsSkyboxTexturesLoader
Qt3DRender::QTextureImage *mNegZImage = nullptr;
};

class QgsHDRSkyboxTextureLoader : public QgsSkyboxTexturesLoader
{
public:
QgsHDRSkyboxTextureLoader( const QString &textureFilePath, Qt3DCore::QNode *parent = nullptr )
: QgsSkyboxTexturesLoader( parent )
{
mLoadedTexture = new Qt3DRender::QTextureLoader( this );
mLoadedTexture->setGenerateMipMaps( false );
mLoadedTexture->setSource( QUrl( textureFilePath ) );
}

QVariant getTextureParameter() override { return QVariant::fromValue( mLoadedTexture ); }
private:
Qt3DRender::QTextureLoader *mLoadedTexture;
};

class QgsSkyboxEntity : public Qt3DCore::QEntity
{
Q_OBJECT
public:
QgsSkyboxEntity( const QString &baseName, const QString &extension, Qt3DCore::QNode *parent = nullptr );
QgsSkyboxEntity( const QString &hdrTexturePath, Qt3DCore::QNode *parent = nullptr );

QString baseName() const { return mBaseName; };
QString extension() const { return mExtension; };
Expand Down Expand Up @@ -128,6 +145,8 @@ class QgsSkyboxEntity : public Qt3DCore::QEntity
Qt3DRender::QParameter *mTextureParameter;
QString mExtension;
QString mBaseName;
QString mHDRTexturePath;
bool mIsUsingHDR;
QVector3D mPosition;
};

Expand Down
2 changes: 2 additions & 0 deletions src/3d/shaders.qrc
Expand Up @@ -14,5 +14,7 @@
<file>shaders/mesh/mesh.frag</file>
<file>shaders/skybox.frag</file>
<file>shaders/skybox.vert</file>
<file>shaders/hdr_skybox.frag</file>
<file>shaders/hdr_skybox.vert</file>
</qresource>
</RCC>
34 changes: 34 additions & 0 deletions src/3d/shaders/hdr_skybox.frag
@@ -0,0 +1,34 @@
#version 330

in vec3 texCoord0;
out vec4 fragColor;
uniform sampler2D skyboxTexture;

// Gamma correction
uniform float gamma = 2.2;

uniform float gammaStrength;

vec3 gammaCorrect(const in vec3 color)
{
return pow(color, vec3(1.0 / gamma));
}

const vec2 invAtan = vec2(0.1591f, 0.3183f);
vec2 SampleSphericalMap(vec3 v)
{
vec2 uv = vec2(atan(v.z, v.x), asin(v.y));
uv *= invAtan;
uv += 0.5;
return uv;
}

void main()
{
vec2 texCoords = SampleSphericalMap( normalize( texCoord0 ) );
vec4 baseColor = texture(skyboxTexture, texCoords);
vec4 gammaColor = vec4(gammaCorrect(baseColor.rgb), 1.0);
// This is an odd way to enable or not gamma correction,
// but this is a way to avoid branching until we can generate shaders
fragColor = mix(baseColor, gammaColor, gammaStrength);
}
16 changes: 16 additions & 0 deletions src/3d/shaders/hdr_skybox.vert
@@ -0,0 +1,16 @@
#version 330

in vec3 vertexPosition;
out vec3 texCoord0;

uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;

void main()
{
texCoord0 = vertexPosition.xyz;
// Converting the viewMatrix to a mat3, then back to a mat4
// removes the translation component from it
gl_Position = vec4(projectionMatrix * mat4(mat3(viewMatrix)) * modelMatrix * vec4(vertexPosition, 1.0)).xyww;
}

0 comments on commit db75d88

Please sign in to comment.