Giter Site home page Giter Site logo

project-10 / openrt Goto Github PK

View Code? Open in Web Editor NEW
111.0 3.0 21.0 132.79 MB

Open Source Ray Tracing Library

Home Page: http://www.openrt.org

License: Other

CMake 5.01% C++ 94.76% Batchfile 0.23%
openrt c-plus-plus computer-graphics raytracing-render global-illumination ray-tracer

openrt's Introduction

Open Source Ray Tracing Library

License CodeFactor Build status

OpenRT is a C++ ray-tracing library, which allows for synthesis of photo-realistic images. First of all, the library is developed for academic purposes: as an accompaniment to the computer graphics course and as a teaching aid for university students. Specifically, it includes the following features:

  • Distribution Ray Tracing
  • Global Illumination

OpenRT aims for a realistic simulation of light transport, as compared to other rendering libraries, such as based on rasterisation, which focuses more on the realistic simulation of geometry. Effects such as reflections and shadows, which are difficult to simulate using other algorithms, are a natural result of the ray tracing algorithm. The computational independence of each ray makes our ray-tracing library amenable to a basic level of parallelisation. OpenRT is released under a BSD license and hence it is free for both academic and commercial use. The code is written entirely in C++ with using the OpenCV library.

Check out the project site for all the details like

  • Online documentation
  • Installation guide
  • Tutorials

Please join the OpenRT-user Q&A forum to ask questions and talk about methods and models. Framework development discussions and thorough bug reports are collected on Issues.

Installation

OpenRT is a cross-platform C++ library. The description here was tested on Windows 10 / Visual Studio 2019, macOS Catalina 10.15.6 / Xcode 11.4 and Ubuntu 18.04 / gcc 7.3.0. If you encounter errors after following the steps described below, feel free to contact us via our User Q&A forum or Issues. We'll do our best to help you out. OpenRT has only one dependency: it is based on OpenCV library. In order to use the OpenRT library, the OpenCV library should be also installed.

Installing OpenCV

Installing OpenRT

  • Download either the latest stable OpenRT version from Project X Research or fork the latest snapshot from our GitHub repository
  • Unpack it to your local folder (for example to disk C:\ for Windows or to /Users/username/ for MacOS, so the library path will be C:\OpenRT\ or /Users/username/OpenRT/)

Installation in Windows and macOS

Building OpenRT from Source Using CMake GUI

In case you want to build the library (recommended), follow these instructions, otherwise - skip this step and proceed to Using the Pre-built Libraries. This step also assumes that you have downloaded the sources of the OpenRT library.

  • Download and install CMake for your operating system
  • Run cmake-gui.exe in Windows or CMake.app in MacOS
  • In the "Where is the source code" field choose the OpenRT source directory: OpenRT. In the "Where to build the binaries" field choose directory where Visual Studio or Xcode project files will be generated: e.g. OpenRT/build
  • Press Configure button and choose Visual Studio for using 32-bit compiler, Visual Studio Win64 for using 64-bit compiler or Xcode as building environment
  • Be sure that the OpenCV_DIR is pointing to the OpenCV installation directory (e.g. OpenCV/build/install or /usr/local/share/OpenCV), where OpenCVConfig.cmake file is located
  • (Optionally) you can change CMAKE_INSTALL_PREFIX to the directory where the OpenRT binaries will be installed (e.g. to OpenRT/build/install)
  • Press one more time Configure and then Generate, so the IDE project files will be generated in the OpenRT/build
  • Open the generated project by pressing the Open Project button or directly by opening file OpenRT/build/OpenRT.sln or OpenRT/build/OpenRT.xcodeproj
  • Build ALL_BUILD and INSTALL projects first for Debug and then for Release configuration. That will copy OpenRT headers, binaries and demonstration applications to the install folder OpenRT/build/install
  • Windows users may copy the OpenCV binaries into the install folder by executing script /OpenRT/build/install/bin/copyOpenCVDLL.bat
  • (Optionally) you can copy the install folder with the ready-to-use OpenRT library (e.g. OpenRT/build/install) to any other folder
Using the Pre-built Libraries

This step assumes that you have downloaded OpenRT-package with the pre-build binaries. In such case the type and version of the downloaded binaries should correspond to your C++ compiler. If it is not, please return to the Building OpenRT from Source Using CMake GUI section and generate the binaries with your compiler. The content of the install folder (e.g. OpenRT/build/install) will correspond to the downloaded pre-build OpenRT package.

Installation in Linux

Building OpenRT from Source Using Terminal

For installing the OpenRT library for Ubuntu we assume that the OpenCV library was already installed (Installing OpenCV), thus GCC, CMake and Git are also installed. In order to download and install the latest version from master input the following commands in terminal:

cd ~/<my_working_directory>
git clone https://github.com/Project-10/OpenRT.git
cd OpenRT
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=RELEASE -DCMAKE_INSTALL_PREFIX=/usr/local
make
make install
make clean


openrt's People

Contributors

ereator avatar ezanageressu avatar fjolladedaj avatar mahmoudeb avatar otmanesabir avatar takundei avatar vaage avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

openrt's Issues

[FEATURE REQUEST] Shadow shader

Is your feature request related to a problem? Please describe.
To fit a three-dimensional object into a photo, we also need to render the shadow from that object. To do this, we need a transparent object, such as a plane on which only the shadow is visible. We need a special shader for this plane.

Describe the solution you'd like
Develop a new shader, e.g. CShaderShadow which would be 100% transparent, except the shadows. A special parameter to tune the shadow's intensity may be passed via constructor.

CSG Nested Difference Operation Bug

There’s currently an issue with the logic in the composite geometry (master). I suspect this is because of the logic we currently have in the CCompositeGeometry. To understand it we can try breaking it down:

When you create a composite geometry, use it to subtract from some other composite, then add it to the scene; the scene actually only contains one IPrim. The intersect function defined in the interface is then called inside of the scene and since in that case, it’s the composite then we call for the intersect function inside CCompositeGeometry. This function has 2 parts: 1) getting the closest and furthest intersection of the left and right geometry; 2) performing some arithmetic logic on the pair of [in, out] rays. The first part is where the bug occurs.

We try to find the intersection for all the IPrim’s in the left and right geometries; however, since these are also composites then it’s actually only one primitive in each. Therefore, the loop that we have that currently retrieves the in and out actually only runs once. Meaning that the [in, out] results are always the same since all the rest of the computations are done a level deeper in the nest and will ALWAYS return the same result for the same ray. Since we only need the [out] ray in the difference function, then this explains why this logic doesn’t cause any issues in any other operations except for the difference.

Steps to reproduce:

  • Replace the current main function contents in DemoCSG.cpp with the code below.
void differenceBug() {
    const Vec3f bgColor = RGB(1, 1, 1);
    const Size resolution = Size(1920, 1200);
    const float intensity = 5e4;

    // Scene
    CScene scene(bgColor);
    auto pShaderRed = std::make_shared<CShaderEyelight>(RGB(214.0/ 255.0, 40.0/255.0, 40/255.0));

    auto solidCylinder = CSolidCylinder(pShaderRed, Vec3f(1, 0, -13), 0.5, 4, 1, 24, true);
    auto solidCylinder2 = CSolidCylinder(pShaderRed, Vec3f(1, 0, -13), 0.5, 4, 1, 24, true);

    // Getting the bounding box and setting the correct pivot point
    auto bBox = CBoundingBox();
    for (const auto& prim : solidCylinder2.getPrims()) {
        bBox.extend(prim->getBoundingBox());
    }
    solidCylinder2.setPivot(bBox.getCenter());
    solidCylinder2.transform(CTransform().rotate(Vec3f(0, 0, 1), 90).get());
    ptr_prim_t pCylinderComposite = std::make_shared<CCompositeGeometry>(solidCylinder, solidCylinder2, BoolOp::Union);

    auto solidSphere1 = CSolidSphere(pShaderRed, Vec3f(1, 2, -13), 1.3f, 30, true);
    ptr_prim_t pDifferenceRoot = std::make_shared<CCompositeGeometry>(solidSphere1,  pCylinderComposite, BoolOp::Difference);
    scene.add(pDifferenceRoot);

    // cameras
    auto targetCamera = std::make_shared<CCameraPerspectiveTarget>(resolution, Vec3f(-4, 5, -3), pDifferenceRoot->getBoundingBox().getCenter(), Vec3f(0, 1, 0), 45.0f);
    scene.add(targetCamera);

    // Light
    auto pLight = std::make_shared<CLightOmni>(intensity * RGB(1.0f, 0.839f, 0.494f), Vec3f(100, 150.0f, 100), false);
    scene.add(pLight);

    scene.buildAccelStructure(20, 2);

    Timer::start("Rendering... ");
    Mat img = scene.render(std::make_shared<CSamplerStratified>(2, true, true));
    Timer::stop();

    imshow("image", img);
    waitKey();
}
  • Run DemoCSG.

Expected result:
The two cylinders to be subtracted from the sphere. Similar to the image below (was able to recreate the image through a workaround). The first image is to show the cylinders used for the difference operation.
image
image

Actual result:
An image of the actual result is attached (the artifacts indicate the area where the in is actually indeed needed for the computation; therefore, further strengthening the hypothesis):
image

lack of build guide

hi, could you please update build guide in README.md, I use cmake. & make, it seems doesn't work, thanks very much

Create a simpler constructor for CSolidQuad

Given that we typically use the CSolidQuad to generate floor or similar items, I think it would be much friendlier to introduce a constructor that can generate a CSolidQuad from an origin point and length/width parameters. We can also introduce angles for inclination but I also believe that can be achieved with transformation.

@ereator if you think this minor modification can be helpful then I would be happy to quickly work on this :)

[FEATURE REQUEST] Background image of a scene

Is your feature request related to a problem? Please describe.
In many cases it makes sense to have a background image in a rendered scene. Currently it is possible to set only the background color.

Describe the solution you'd like
Add one more constructor to the CScene class, which will take a texture CTexture as an argument. If a ray goes to infinity, return a texel from that texture according to the rendered pixel coordinates.

[FEATURE REQUEST] Procedural textures

Is your feature request related to a problem? Please describe.
Unlike a bitmapped texture, in which the texture is represented as a bitmap, a procedural texture describes the texture mathematically. Although not widely used, this method is resolution independent and can create more precise textures, especially if there is great and varying depth to the objects being textured. Procedural textures may be 2D or 3D.

Describe the solution you'd like
Many procedural textures for such materials as marble, stone and wood are generated based on the Perlin noise.

Additional context
Lecture slides
Wikipedia
Victor’s blog
YouTube

Wrong normal orientation in resulting geometry composites

Hi @otmanesabir
In class CCompositeGeometry in the method CCompositeGeometry::computeDifference :

if (stateA == IntersectionState::Exit && stateB == IntersectionState::Enter) {
if (minA.t < minB.t) {
auto t = computeTrueDistance(ray, minA);
res = minA;
res.t = t;
auto currentNormal = res.hit->getNormal(res);
auto dummyPrim = std::make_shared<CPrimDummy>(res.hit->getShader(), -currentNormal,
res.hit->getTextureCoords(res));
res.hit = dummyPrim;
} else {
auto t = computeTrueDistance(ray, minB);
res = minB;
res.t = t;
}
break;
}

for the cases when the camera is inside the composite (i.e. when intersection with prim B is closer than intersection with prim A), the normals for the difference area are directed towards the camera. But as the camera is inside, all the normals should be directed outwards the camera. To check the bug, one may render the scene:

std::shared_ptr<CScene> buildSceneTest(const Vec3f& bgColor, const Size resolution)
{
	auto pScene = std::make_shared<CScene>(bgColor);
	
	// shaders
	auto pShader = std::make_shared<CShaderFlat>(Vec3f(1, 1, 1));
	
	// geometry
	ptr_prim_t largeSphere = std::make_shared<CPrimSphere>(pShader, Vec3f(0, 0, 0), 5.0f);
	ptr_prim_t smallSphere = std::make_shared<CPrimSphere>(pShader, Vec3f(0, 0, -5), 1.0f);
	ptr_prim_t composite 	 = std::make_shared<CCompositeGeometry>(largeSphere, smallSphere, BoolOp::Difference);
	
	//pScene->add(largeSphere);
	//pScene->add(smallSphere);
	pScene->add(composite);
	
	// Light
	pScene->add(std::make_shared<CLightOmni>(Vec3f::all(1e3), Vec3f(0, 0, 0), true));
	
	// camera
	pScene->add(std::make_shared<CCameraPerspective>(resolution, Vec3f(0, 0, 0), Vec3f(0, 0, -1), Vec3f(0, 1, 0), 45.0f));
	
	return pScene;
} 

flipNormal()

By default when creating a geometric object, its normals point outward of the object. For some cases it is useful to force the normals to point inside the object. Thus there is a need for a void flipNormals(void) method.

Add reading/saving shaders from/to .mtl files

Is your feature request related to a problem? Please describe.
When loading geometry from an .obj files containing multiple objects (e.g. as groups [g]) it is often the case that these objects have links to theirs materials, saved in accompanying .mtl files. Thus, it is very important to add reading / saving shaders into / from .mtl files. The description of the Wavefront material template library file format may be found at Wikipedia.

Describe the solution you'd like
Add methods load() and save() to CShader class.

[FEATURE REQUEST] Direct light

Is your feature request related to a problem? Please describe.
A new direct light source CLightDirect class should accompany existing spot light source CLightSpot class.

Describe the solution you'd like
Implement the CLightDirect class with the following parameters:

  • Vec3f intensity
  • Vec3f org
  • Vec3f dir
  • float hotspotRadius - radius of an inner cylinder with constant surface illumination
  • float falloffRadius - radius of an outer cylinder with attenuated illumination (attenuation function might be taken from the CLightSpot class)
  • bool castShadow

demos link error

CMakeFiles/Demo_AreaLight.dir/Demo_AreaLight.cpp.o: In function main': Demo AreaLight.cpp:(.text+0x833): undefined reference to rt::CSolid::CSolid(std::shared_ptrrt::IShader, std::_cxx11::basic_string<char, std::char_traits, std::allocator > const&)'
Demo AreaLight.cpp:(.text+0xe20): undefined reference to rt::CSolid::transform(cv::Mat const&)' Demo AreaLight.cpp:(.text+0x129c): undefined reference to rt::CScene::render(std::shared_ptrrt::CSampler) const'
Demo AreaLight.cpp:(.text+0x12c4): undefined reference to rt::CScene::renderDepth() const' CMakeFiles/Demo_AreaLight.dir/Demo_AreaLight.cpp.o: In function rt::CCameraPerspective::CCameraPerspective(cv::Size
, cv::Vec<float, 3> const&, cv::Vec<float, 3> const&, cv::Vec<float, 3> const&, float)':
Demo AreaLight.cpp:(.text._ZN2rt18CCameraPerspectiveC2EN2cv5Size_IiEERKNS1_3VecIfLi3EEES7_S7_f[_ZN2rt18CCameraPerspectiveC5EN2cv5Size_IiEERKNS1_3VecIfLi3EEES7_S7_f]+0x5a): undefined reference to vtable for rt::CCameraPerspective' CMakeFiles/Demo_AreaLight.dir/Demo_AreaLight.cpp.o: In function rt::CLightOmni::CLightOmni(cv::Vec<float, 3> const&, cv::Vec<float, 3> const&, bool)':
Demo AreaLight.cpp:(.text._ZN2rt10CLightOmniC2ERKN2cv3VecIfLi3EEES5_b[_ZN2rt10CLightOmniC5ERKN2cv3VecIfLi3EEES5_b]+0x2f): undefined reference to vtable for rt::CLightOmni' CMakeFiles/Demo_AreaLight.dir/Demo_AreaLight.cpp.o: In function rt::CPrimSphere::CPrimSphere(std::shared_ptrrt::IShader, cv::Vec<float, 3>, float)':
Demo AreaLight.cpp:(.text._ZN2rt11CPrimSphereC2ESt10shared_ptrINS_7IShaderEEN2cv3VecIfLi3EEEf[_ZN2rt11CPrimSphereC5ESt10shared_ptrINS_7IShaderEEN2cv3VecIfLi3EEEf]+0x5e): undefined reference to vtable for rt::CPrimSphere' CMakeFiles/Demo_AreaLight.dir/Demo_AreaLight.cpp.o: In function rt::CPrimPlane::CPrimPlane(std::shared_ptrrt::IShader, cv::Vec<float, 3>, cv::Vec<float, 3>)':
Demo AreaLight.cpp:(.text.ZN2rt10CPrimPlaneC2ESt10shared_ptrINS_7IShaderEEN2cv3VecIfLi3EEES6[ZN2rt10CPrimPlaneC5ESt10shared_ptrINS_7IShaderEEN2cv3VecIfLi3EEES6]+0x5d): undefined reference to vtable for rt::CPrimPlane' CMakeFiles/Demo_AreaLight.dir/Demo_AreaLight.cpp.o: In function rt::CPrimTriangle::CPrimTriangle(std::shared_ptrrt::IShader, cv::Vec<float, 3> const&, cv::Vec<float, 3> const&, cv::Vec<float, 3> const&, cv::Vec<float, 2> const&, cv::Vec<float, 2> const&, cv::Vec<float, 2> const&)':
Demo AreaLight.cpp:(.text.ZN2rt13CPrimTriangleC2ESt10shared_ptrINS_7IShaderEERKN2cv3VecIfLi3EEES8_S8_RKNS5_IfLi2EEESB_SB[ZN2rt13CPrimTriangleC5ESt10shared_ptrINS_7IShaderEERKN2cv3VecIfLi3EEES8_S8_RKNS5_IfLi2EEESB_SB]+0x75): undefined reference to vtable for rt::CPrimTriangle' CMakeFiles/Demo_AreaLight.dir/Demo_AreaLight.cpp.o: In function rt::CPrimTriangle::if_intersect(rt::Ray const&) const':
Demo AreaLight.cpp:(.text._ZNK2rt13CPrimTriangle12if_intersectERKNS_3RayE[_ZNK2rt13CPrimTriangle12if_intersectERKNS_3RayE]+0x32): undefined reference to rt::CPrimTriangle::MoellerTrumbore(rt::Ray const&) const' CMakeFiles/Demo_AreaLight.dir/Demo_AreaLight.cpp.o: In function rt::CTransform::scale(float) const':
Demo AreaLight.cpp:(.text._ZNK2rt10CTransform5scaleEf[_ZNK2rt10CTransform5scaleEf]+0x4e): undefined reference to rt::CTransform::scale(cv::Vec<float, 3> const&) const' CMakeFiles/Demo_AreaLight.dir/Demo_AreaLight.cpp.o: In function rt::CPrimTriangle::~CPrimTriangle()':
Demo AreaLight.cpp:(.text._ZN2rt13CPrimTriangleD2Ev[_ZN2rt13CPrimTriangleD5Ev]+0xf): undefined reference to vtable for rt::CPrimTriangle' CMakeFiles/Demo_AreaLight.dir/Demo_AreaLight.cpp.o: In function rt::CPrimTriangleSmooth::transform(cv::Mat const&)':

Get rid of CPrimDummy class

Hi @otmanesabir,
I thought about how to get rid of that class without making the intersect methods to be non-constant. The idea to try is to invert normals in constructor of the composite primitive for the object B, if the boolean operation is substraction B from A.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.