Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(optix): Support different camera programs #778

Merged
merged 2 commits into from
Jun 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions engines/optix/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ set(BRAYNSOPTIXENGINE_SOURCES
OptiXFrameBuffer.cpp
OptiXScene.cpp
OptiXCamera.cpp
OptiXPerspectiveCamera.cpp
OptiXRenderer.cpp
OptiXEngine.cpp
OptiXMaterial.cpp
Expand All @@ -61,6 +62,7 @@ set_source_files_properties(
OptiXFrameBuffer.cpp
OptiXScene.cpp
OptiXCamera.cpp
OptiXPerspectiveCamera.cpp
OptiXRenderer.cpp
OptiXEngine.cpp
OptiXMaterial.cpp
Expand All @@ -74,6 +76,8 @@ set(BRAYNSOPTIXENGINE_HEADERS
OptiXFrameBuffer.h
OptiXScene.h
OptiXCamera.h
OptiXCameraProgram.h
OptiXPerspectiveCamera.h
OptiXRenderer.h
OptiXEngine.h
)
Expand Down
63 changes: 8 additions & 55 deletions engines/optix/OptiXCamera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,52 +24,25 @@

namespace
{
const std::string CUDA_ATTR_CAMERA_BAD_COLOR = "bad_color";
const std::string CUDA_ATTR_CAMERA_OFFSET = "offset";
const std::string CUDA_ATTR_CAMERA_EYE = "eye";
const std::string CUDA_ATTR_CAMERA_U = "U";
const std::string CUDA_ATTR_CAMERA_V = "V";
const std::string CUDA_ATTR_CAMERA_W = "W";
const std::string CUDA_ATTR_CAMERA_APERTURE_RADIUS = "aperture_radius";
const std::string CUDA_ATTR_CAMERA_FOCAL_SCALE = "focal_scale";

const std::string CUDA_CLIP_PLANES = "clip_planes";
const std::string CUDA_NB_CLIP_PLANES = "nb_clip_planes";
} // namespace

namespace brayns
{
OptiXCamera::OptiXCamera()
{
_camera = OptiXContext::get().createCamera();
}

OptiXCamera::~OptiXCamera()
{
if (_camera)
_camera->destroy();
}

void OptiXCamera::commit()
{
auto context = OptiXContext::get().getOptixContext();

Vector3d u, v, w;
if (_currentCamera != getCurrentType())
{
_currentCamera = getCurrentType();
OptiXContext::get().setCamera(_currentCamera);
}

const Vector3d& pos = getPosition();
auto cameraProgram = OptiXContext::get().getCamera(_currentCamera);

_calculateCameraVariables(u, v, w);
auto context = OptiXContext::get().getOptixContext();

context[CUDA_ATTR_CAMERA_EYE]->setFloat(pos.x, pos.y, pos.z);
context[CUDA_ATTR_CAMERA_U]->setFloat(u.x, u.y, u.z);
context[CUDA_ATTR_CAMERA_V]->setFloat(v.x, v.y, v.z);
context[CUDA_ATTR_CAMERA_W]->setFloat(w.x, w.y, w.z);
context[CUDA_ATTR_CAMERA_APERTURE_RADIUS]->setFloat(
getPropertyOrValue<double>("apertureRadius", 0.0));
context[CUDA_ATTR_CAMERA_FOCAL_SCALE]->setFloat(
getPropertyOrValue<double>("focusDistance", 1.0));
context[CUDA_ATTR_CAMERA_BAD_COLOR]->setFloat(1.f, 0.f, 1.f);
context[CUDA_ATTR_CAMERA_OFFSET]->setFloat(0, 0);
cameraProgram->commit(*this, context);

if (_clipPlanesBuffer)
_clipPlanesBuffer->destroy();
Expand Down Expand Up @@ -103,24 +76,4 @@ void OptiXCamera::commit()
context[CUDA_NB_CLIP_PLANES]->setUint(numClipPlanes);
}

void OptiXCamera::_calculateCameraVariables(Vector3d& U, Vector3d& V,
Vector3d& W)
{
const auto& position = getPosition();
const auto& up = glm::rotate(getOrientation(), Vector3d(0, 1, 0));

float ulen, vlen, wlen;
W = getTarget() - position;

wlen = glm::length(W);
U = normalize(glm::cross(W, up));
V = normalize(glm::cross(U, W));

vlen = wlen *
tanf(0.5f * getPropertyOrValue<double>("fovy", 45.0) * M_PI / 180.f);
V *= vlen;
ulen = vlen * getPropertyOrValue<double>("aspect", 1.0);
U *= ulen;
}

} // namespace brayns
13 changes: 1 addition & 12 deletions engines/optix/OptiXCamera.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,26 +35,15 @@ namespace brayns
class OptiXCamera : public Camera
{
public:
OptiXCamera();
~OptiXCamera();

/**
Commits the changes held by the camera object so that
attributes become available to the OptiX rendering engine
*/
void commit() final;

/**
Gets the OptiX implementation of the camera object
@return OptiX implementation of the camera object
*/
optix::Program& impl() { return _camera; }
private:
void _calculateCameraVariables(Vector3d& U, Vector3d& V, Vector3d& W);

optix::Program _camera{nullptr};

optix::Buffer _clipPlanesBuffer{nullptr};
Planes _clipPlanes;
std::string _currentCamera;
};
} // namespace brayns
58 changes: 58 additions & 0 deletions engines/optix/OptiXCameraProgram.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/* Copyright (c) 2019, EPFL/Blue Brain Project
* All rights reserved. Do not distribute without permission.
*
* This file is part of Brayns <https://github.com/BlueBrain/Brayns>
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3.0 as published
* by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#pragma once

#include <memory>

#include <optixu/optixpp_namespace.h>

namespace brayns
{
class OptiXCamera;

/**
* @brief The OptiXCameraProgram class is an abstract class that provides the
* required programs for launching rays from a camera
*/
class OptiXCameraProgram
{
public:
virtual ~OptiXCameraProgram() = default;

::optix::Program getRayGenerationProgram() { return _rayGenerationProgram; }
::optix::Program getMissProgram() { return _missProgram; }
::optix::Program getExceptionProgram() { return _exceptionProgram; }
/**
* @brief commit Virtual method for commiting camera specific variables to
* the context
* @param camera The main brayns camera
* @param context The OptiX context
*/
virtual void commit(const OptiXCamera& camera,
::optix::Context context) = 0;

protected:
::optix::Program _rayGenerationProgram{nullptr};
::optix::Program _missProgram{nullptr};
::optix::Program _exceptionProgram{nullptr};
};

using OptiXCameraProgramPtr = std::shared_ptr<OptiXCameraProgram>;
}
55 changes: 23 additions & 32 deletions engines/optix/OptiXContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@
#include "OptiXContext.h"

#include <engines/optix/braynsOptixEngine_generated_Cones.cu.ptx.h>
#include <engines/optix/braynsOptixEngine_generated_Constantbg.cu.ptx.h>
#include <engines/optix/braynsOptixEngine_generated_Cylinders.cu.ptx.h>
#include <engines/optix/braynsOptixEngine_generated_PerspectiveCamera.cu.ptx.h>
#include <engines/optix/braynsOptixEngine_generated_Spheres.cu.ptx.h>
#include <engines/optix/braynsOptixEngine_generated_TriangleMesh.cu.ptx.h>

Expand All @@ -38,19 +36,12 @@ const std::string CUDA_CYLINDERS = braynsOptixEngine_generated_Cylinders_cu_ptx;
const std::string CUDA_CONES = braynsOptixEngine_generated_Cones_cu_ptx;
const std::string CUDA_TRIANGLES_MESH =
braynsOptixEngine_generated_TriangleMesh_cu_ptx;
const std::string CUDA_PERSPECTIVE_CAMERA =
braynsOptixEngine_generated_PerspectiveCamera_cu_ptx;
const std::string CUDA_MISS = braynsOptixEngine_generated_Constantbg_cu_ptx;

const std::string CUDA_FUNC_BOUNDS = "bounds";
const std::string CUDA_FUNC_INTERSECTION = "intersect";
const std::string CUDA_FUNC_ROBUST_INTERSECTION = "robust_intersect";
const std::string CUDA_FUNC_EXCEPTION = "exception";

const std::string CUDA_FUNC_PERSPECTIVE_CAMERA = "perspectiveCamera";
const std::string CUDA_FUNC_CAMERA_EXCEPTION = "exception";
const std::string CUDA_FUNC_CAMERA_ENVMAP_MISS = "envmap_miss";

template <typename T>
T white();

Expand Down Expand Up @@ -157,12 +148,12 @@ ::optix::Material OptiXContext::createMaterial()
}

void OptiXContext::addRenderer(const std::string& name,
const OptixShaderProgram& program)
OptiXShaderProgramPtr program)
{
_rendererProgram[name] = program;
}

const OptixShaderProgram& OptiXContext::getRenderer(const std::string& name)
OptiXShaderProgramPtr OptiXContext::getRenderer(const std::string& name)
{
auto it = _rendererProgram.find(name);
if (it == _rendererProgram.end())
Expand All @@ -171,28 +162,28 @@ const OptixShaderProgram& OptiXContext::getRenderer(const std::string& name)
return it->second;
}

::optix::Program OptiXContext::createCamera()
void OptiXContext::addCamera(const std::string& name,
OptiXCameraProgramPtr program)
{
_cameraProgram[name] = program;
}

OptiXCameraProgramPtr OptiXContext::getCamera(const std::string& name)
{
auto it = _cameraProgram.find(name);
if (it == _cameraProgram.end())
throw std::runtime_error("Camera program not found for camera '" +
name + "'");
return it->second;
}

void OptiXContext::setCamera(const std::string& name)
{
::optix::Program camera;
// Ray generation program
camera =
_optixContext->createProgramFromPTXString(CUDA_PERSPECTIVE_CAMERA,
CUDA_FUNC_PERSPECTIVE_CAMERA);
_optixContext->setRayGenerationProgram(0, camera);

// Miss programs
::optix::Program missProgram =
_optixContext->createProgramFromPTXString(CUDA_MISS,
CUDA_FUNC_CAMERA_ENVMAP_MISS);
_optixContext->setMissProgram(0, missProgram);

// Exception program
_optixContext->setExceptionProgram(
0,
_optixContext->createProgramFromPTXString(CUDA_PERSPECTIVE_CAMERA,
CUDA_FUNC_CAMERA_EXCEPTION));
BRAYNS_DEBUG << "Camera created" << std::endl;
return camera;
auto camera = getCamera(name);
_optixContext->setRayGenerationProgram(0,
camera->getRayGenerationProgram());
_optixContext->setMissProgram(0, camera->getMissProgram());
_optixContext->setExceptionProgram(0, camera->getExceptionProgram());
}

::optix::TextureSampler OptiXContext::createTextureSampler(Texture2DPtr texture)
Expand Down
16 changes: 11 additions & 5 deletions engines/optix/OptiXContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

#include <optixu/optixpp_namespace.h>

#include "OptiXCameraProgram.h"

#include <memory>
#include <mutex>
#include <unordered_map>
Expand All @@ -45,6 +47,8 @@ struct OptixShaderProgram
::optix::Program closest_hit_textured{nullptr};
};

using OptiXShaderProgramPtr = std::shared_ptr<OptixShaderProgram>;

class OptiXContext
{
public:
Expand All @@ -53,7 +57,9 @@ class OptiXContext

::optix::Context getOptixContext() { return _optixContext; }
// Camera
::optix::Program createCamera();
void addCamera(const std::string& name, OptiXCameraProgramPtr program);
OptiXCameraProgramPtr getCamera(const std::string& name);
void setCamera(const std::string& name);

// Geometry
::optix::Geometry createGeometry(const OptixGeometryType type);
Expand All @@ -65,9 +71,8 @@ class OptiXContext
::optix::TextureSampler createTextureSampler(Texture2DPtr texture);

// Others
void addRenderer(const std::string& name,
const OptixShaderProgram& program);
const OptixShaderProgram& getRenderer(const std::string& name);
void addRenderer(const std::string& name, OptiXShaderProgramPtr program);
OptiXShaderProgramPtr getRenderer(const std::string& name);

std::unique_lock<std::mutex> getScopeLock()
{
Expand All @@ -84,7 +89,8 @@ class OptiXContext

::optix::Context _optixContext{nullptr};

std::map<std::string, OptixShaderProgram> _rendererProgram;
std::map<std::string, OptiXShaderProgramPtr> _rendererProgram;
std::map<std::string, OptiXCameraProgramPtr> _cameraProgram;

std::map<OptixGeometryType, ::optix::Program> _bounds;
std::map<OptixGeometryType, ::optix::Program> _intersects;
Expand Down
Loading