Skip to content

Commit

Permalink
Add dedicated renderers for deep sky objects
Browse files Browse the repository at this point in the history
  • Loading branch information
375gnu committed May 15, 2023
1 parent 4616f5f commit b7ae735
Show file tree
Hide file tree
Showing 26 changed files with 2,071 additions and 1,511 deletions.
2 changes: 2 additions & 0 deletions src/celengine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ set(CELENGINE_SOURCES
frametree.h
galaxy.cpp
galaxy.h
galaxyform.cpp
galaxyform.h
geometry.h
glmarker.cpp
globular.cpp
Expand Down
6 changes: 0 additions & 6 deletions src/celengine/deepskyobj.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,6 @@ class DeepSkyObject
double& distanceToPicker,
double& cosAngleToBoundCenter) const = 0;
virtual bool load(const AssociativeArray*, const fs::path& resPath);
virtual void render(const Eigen::Vector3f& offset,
const Eigen::Quaternionf& viewerOrientation,
float brightness,
float pixelSize,
const Matrices& m,
Renderer*) = 0;

virtual uint64_t getRenderMask() const { return 0; }
virtual unsigned int getLabelMask() const { return 0; }
Expand Down
143 changes: 85 additions & 58 deletions src/celengine/dsorenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,67 @@

#include <celengine/dsodb.h>
#include <celengine/deepskyobj.h>
#include <celmath/geomutil.h>
#include <celmath/vecgl.h>
#include "glsupport.h"
#include <celrender/galaxyrenderer.h>
#include <celrender/globularrenderer.h>
#include <celrender/nebularenderer.h>
#include <celrender/openclusterrenderer.h>
#include "render.h"

#include "dsorenderer.h"

using namespace Eigen;
using namespace celestia;
using namespace celmath;

namespace
{
// The parameter 'enhance' adjusts the DSO brightness as viewed from "inside"
// (e.g. MilkyWay as seen from Earth). It provides an enhanced apparent core
// (e.g. MilkyWay as seen from Earth). It provides an enhanced apparent core
// brightness appMag ~ absMag - enhance. 'enhance' thus serves to uniformly
// enhance the too low sprite luminosity at close distance.
constexpr const double enhance = 4.0;
constexpr const double pc10 = 32.6167; // 10 parsecs
static const float CubeCornerToCenterDistance = sqrt(3.0f);
constexpr double enhance = 4.0;
constexpr double pc10 = 32.6167; // 10 parsecs
constexpr float CubeCornerToCenterDistance = 1.7320508075688772f;

enum class DeepSkyObjectType
{
Galaxy,
Globular,
Nebula,
OpenCluster
};

DeepSkyObjectType
GetDSOType(const DeepSkyObject* dso)
{
if (!strcmp(dso->getObjTypeName(), "galaxy"))
return DeepSkyObjectType::Galaxy;

if (!strcmp(dso->getObjTypeName(), "globular"))
return DeepSkyObjectType::Globular;

if (!strcmp(dso->getObjTypeName(), "nebula"))
return DeepSkyObjectType::Nebula;

if (!strcmp(dso->getObjTypeName(), "opencluster"))
return DeepSkyObjectType::OpenCluster;
}

This comment has been minimized.

Copy link
@munix9

munix9 May 16, 2023

Contributor

build error on openSUSE Tumbleweed with gcc 13

[   92s] /home/abuild/rpmbuild/BUILD/celestia-1.7.0~git20230515+2f8f3b0/src/celengine/dsorenderer.cpp: In function '{anonymous}::DeepSkyObjectType {anonymous}::GetDSOType(const DeepSkyObject*)':
[   92s] /home/abuild/rpmbuild/BUILD/celestia-1.7.0~git20230515+2f8f3b0/src/celengine/dsorenderer.cpp:53:1: error: control reaches end of non-void function [-Werror=return-type]
[   92s]    53 | }
[   92s]       | ^
[   92s] cc1plus: some warnings being treated as errors

https://build.opensuse.org/package/live_build_log/home:munix9:unstable/celestia/openSUSE_Tumbleweed/x86_64

This comment has been minimized.

Copy link
@375gnu

375gnu May 16, 2023

Author Collaborator

Thanks for reporting. Fixed in #1707


float
brightness(float avgAbsMag, float absMag, float appMag, float brightnessCorr, float faintestMag)
{
// Input: display looks satisfactory for 0.2 < brightness < O(1.0)
// Ansatz: brightness = a - b * appMag(distanceToDSO), emulating eye sensitivity...
// determine a,b such that
// a - b * absMag = absMag / avgAbsMag ~ 1; a - b * faintestMag = 0.2.
// The 2nd eq. guarantees that the faintest galaxies are still visible.

float r = absMag / avgAbsMag;
float b = r - (r - 0.2f) * (absMag - appMag) / (absMag - faintestMag);

// obviously, brightness(appMag = absMag) = r and
// brightness(appMag = faintestMag) = 0.2, as desired.

return std::max(0.0f, b * brightnessCorr);
}

} // anonymous namespace

DSORenderer::DSORenderer() :
ObjectRenderer<DeepSkyObject*, double>(DSO_OCTREE_ROOT_SIZE)
Expand All @@ -41,15 +84,15 @@ void DSORenderer::process(DeepSkyObject* const &dso,
if (distanceToDSO > distanceLimit || !dso->isVisible())
return;

Vector3f relPos = (dso->getPosition() - obsPos).cast<float>();
Vector3f center = orientationMatrixT * relPos;
Eigen::Vector3f relPos = (dso->getPosition() - obsPos).cast<float>();
Eigen::Vector3f center = orientationMatrixT * relPos;

// Test the object's bounding sphere against the view frustum. If we
// avoid this stage, overcrowded octree cells may hit performance badly:
// each object (even if it's not visible) would be sent to the OpenGL
// pipeline.
double dsoRadius = dso->getBoundingSphereRadius();
if (frustum.testSphere(center, (float) dsoRadius) == Frustum::Outside)
if (frustum.testSphere(center, (float) dsoRadius) == celmath::Frustum::Outside)
return;

float appMag;
Expand All @@ -62,59 +105,45 @@ void DSORenderer::process(DeepSkyObject* const &dso,
{
dsosProcessed++;

// Input: display looks satisfactory for 0.2 < brightness < O(1.0)
// Ansatz: brightness = a - b * appMag(distanceToDSO), emulating eye sensitivity...
// determine a,b such that
// a - b * absMag = absMag / avgAbsMag ~ 1; a - b * faintestMag = 0.2.
// The 2nd eq. guarantees that the faintest galaxies are still visible.

if (!strcmp(dso->getObjTypeName(), "globular"))
avgAbsMag = -6.86f; // average over 150 globulars in globulars.dsc.
else if (!strcmp(dso->getObjTypeName(), "galaxy"))
avgAbsMag = -19.04f; // average over 10937 galaxies in galaxies.dsc.

float r = absMag / avgAbsMag;
float brightness = r - (r - 0.2f) * (absMag - appMag) / (absMag - faintestMag);

// obviously, brightness(appMag = absMag) = r and
// brightness(appMag = faintestMag) = 0.2, as desired.

brightness *= 2.3f * (faintestMag - 4.75f) / renderer->getFaintestAM45deg();

if (brightness < 0)
brightness = 0;

Matrix4f mv = celmath::translate(renderer->getModelViewMatrix(), relPos);
Matrix4f pr;

float nearZ = 0.0f, farZ = 0.0f;
if (dsoRadius < 1000.0)
{
// Small objects may be prone to clipping; give them special
// handling. We don't want to always set the projection
// matrix, since that could be expensive with large galaxy
// catalogs.
auto nearZ = (float)(distanceToDSO / 2);
auto farZ = (float)(distanceToDSO + dsoRadius * 2 * CubeCornerToCenterDistance);
if (nearZ < dsoRadius * 0.001)
nearZ = static_cast<float>(distanceToDSO / 2.0);
farZ = static_cast<float>(distanceToDSO + dsoRadius * 2.0 * CubeCornerToCenterDistance);
auto minZ = static_cast<float>(dsoRadius * 0.001);
if (nearZ < minZ)
{
nearZ = (float)(dsoRadius * 0.001);
nearZ = minZ;
farZ = nearZ * 10000.0f;
}

float t = renderer->getAspectRatio();
if (renderer->getProjectionMode() == Renderer::ProjectionMode::FisheyeMode)
pr = Ortho(-t, t, -1.0f, 1.0f, nearZ, farZ);
else
pr = Perspective(fov, t, nearZ, farZ);
}
else

float b = 2.3f * (faintestMag - 4.75f) / renderer->getFaintestAM45deg(); // brightnesCorr
switch (GetDSOType(dso))
{
pr = renderer->getProjectionMatrix();
case DeepSkyObjectType::Galaxy:
// -19.04f == average over 10937 galaxies in galaxies.dsc.
b = brightness(-19.04f, absMag, appMag, b, faintestMag);
galaxyRenderer->add(reinterpret_cast<Galaxy*>(dso), relPos, b, nearZ, farZ);
break;
case DeepSkyObjectType::Globular:
// -6.86f == average over 150 globulars in globulars.dsc.
b = brightness(-6.86f, absMag, appMag, b, faintestMag);
globularRenderer->add(reinterpret_cast<Globular*>(dso), relPos, b, nearZ, farZ);
break;
case DeepSkyObjectType::Nebula:
b = brightness(avgAbsMag, absMag, appMag, b, faintestMag);
nebulaRenderer->add(reinterpret_cast<Nebula*>(dso), relPos, b, nearZ, farZ);
break;
case DeepSkyObjectType::OpenCluster:
b = brightness(avgAbsMag, absMag, appMag, b, faintestMag);
openClusterRenderer->add(reinterpret_cast<OpenCluster*>(dso), relPos, b, nearZ, farZ);
break;
}

dso->render(relPos, observer->getOrientationf(), brightness,
pixelSize, { &pr, &mv }, renderer);

} // renderFlags check

// Only render those labels that are in front of the camera:
Expand Down Expand Up @@ -169,9 +198,7 @@ void DSORenderer::process(DeepSkyObject* const &dso,
if (appMagEff < labelThresholdMag)
{
// introduce distance dependent label transparency.
float distr = step * (labelThresholdMag - appMagEff) / labelThresholdMag;
if (distr > 1.0f)
distr = 1.0f;
float distr = std::min(1.0f, step * (labelThresholdMag - appMagEff) / labelThresholdMag);
labelColor.alpha(distr * labelColor.alpha());

renderer->addBackgroundAnnotation(rep,
Expand Down
12 changes: 9 additions & 3 deletions src/celengine/dsorenderer.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// dsorenderer.h
//
// Copyright (C) 2001-2020, the Celestia Development Team
// Copyright (C) 2001-present, the Celestia Development Team
// Original version by Chris Laurel <[email protected]>
//
// This program is free software; you can redistribute it and/or
Expand All @@ -12,23 +12,29 @@

#include <Eigen/Core>
#include <celmath/frustum.h>
#include <celrender/rendererfwd.h>
#include "objectrenderer.h"

class DeepSkyObject;

class DSORenderer : public ObjectRenderer<DeepSkyObject*, double>
{
public:
public:
DSORenderer();

void process(DeepSkyObject* const &, double, float);

public:
Eigen::Vector3d obsPos;
Eigen::Matrix3f orientationMatrixT;
celmath::Frustum frustum { 45.0_deg, 1.0f, 1.0f };
DSODatabase* dsoDB { nullptr };

float avgAbsMag { 0.0f };
uint32_t dsosProcessed { 0 };

celestia::render::GalaxyRenderer *galaxyRenderer{ nullptr };
celestia::render::GlobularRenderer *globularRenderer{ nullptr };
celestia::render::NebulaRenderer *nebulaRenderer{ nullptr };
celestia::render::OpenClusterRenderer *openClusterRenderer{ nullptr };

};
Loading

0 comments on commit b7ae735

Please sign in to comment.