Loading...
Searching...
No Matches
renderer.h
1//
2// Copyright 2018 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7#ifndef PXR_IMAGING_PLUGIN_HD_EMBREE_RENDERER_H
8#define PXR_IMAGING_PLUGIN_HD_EMBREE_RENDERER_H
9
10#include "pxr/pxr.h"
11
12#include "pxr/imaging/plugin/hdEmbree/context.h"
13#include "pxr/imaging/plugin/hdEmbree/light.h"
14
15#include "pxr/imaging/hd/aov.h"
16#include "pxr/imaging/hd/renderThread.h"
17
19#include "pxr/base/gf/rect2i.h"
20
21#include <embree4/rtcore.h>
22#include <embree4/rtcore_device.h>
23#include <embree4/rtcore_ray.h>
24
25#include <random>
26#include <atomic>
27#include <map>
28#include <mutex>
29
30PXR_NAMESPACE_OPEN_SCOPE
31
32enum HdEmbree_RayMask: uint32_t {
33 None = 0,
34
35 Camera = 1 << 0,
36 Shadow = 1 << 1,
37
38 All = UINT_MAX,
39};
40
53{
54public:
55 using WriteMutex = std::mutex;
56 using ScopedLock = std::scoped_lock<WriteMutex>;
57
60
63
66 void SetScene(RTCScene scene);
67
70 void SetDataWindow(const GfRect2i &dataWindow);
71
75 void SetCamera(const GfMatrix4d& viewMatrix, const GfMatrix4d& projMatrix);
76
79 void SetAovBindings(HdRenderPassAovBindingVector const &aovBindings);
80
82 void AddLight(SdfPath const& lightPath, HdEmbree_Light* light);
83
85 void RemoveLight(SdfPath const& lightPath, HdEmbree_Light* light);
86
89 HdRenderPassAovBindingVector const& GetAovBindings() const {
90 return _aovBindings;
91 }
92
96 void SetSamplesToConvergence(int samplesToConvergence);
97
101 void SetAmbientOcclusionSamples(int ambientOcclusionSamples);
102
107 void SetDomeLightCameraVisibility(bool domeLightCameraVisibility);
108
112 void SetEnableSceneColors(bool enableSceneColors);
113
118 void SetRandomNumberSeed(int randomNumberSeed);
119
122 void SetEnableLighting(bool enableLighting);
123
129 void Render(HdRenderThread *renderThread);
130
132 void Clear();
133
136
139
140private:
141 // Perform validation and setup immediately before starting a render
142 void _PreRenderSetup();
143
144 // Validate the internal consistency of aov bindings provided to
145 // SetAovBindings. If the aov bindings are invalid, this will issue
146 // appropriate warnings. If the function returns false, Render() will fail
147 // early.
148 //
149 // This function thunks itself using _aovBindingsNeedValidation and
150 // _aovBindingsValid.
151 // \return True if the aov bindings are valid for rendering.
152 bool _ValidateAovBindings();
153
154 // Return the clear color to use for the given VtValue.
155 static GfVec4f _GetClearColor(VtValue const& clearValue);
156
157 // Render square tiles of pixels. This function is one unit of threadpool
158 // work. For each tile, iterate over pixels in the tile, generating camera
159 // rays, and following them/calculating color with _TraceRay. This function
160 // renders all tiles between tileStart and tileEnd.
161 void _RenderTiles(HdRenderThread *renderThread, int sampleNum,
162 size_t tileStart, size_t tileEnd);
163
164 // Cast a ray into the scene and if it hits an object, write to the bound
165 // aov buffers.
166 void _TraceRay(unsigned int x, unsigned int y,
167 GfVec3f const& origin, GfVec3f const& dir,
168 std::default_random_engine &random);
169
170 // Compute the color at the given ray hit.
171 GfVec4f _ComputeColor(RTCRayHit const& rayHit,
172 std::default_random_engine &random,
173 GfVec4f const& clearColor);
174 // Compute the depth at the given ray hit.
175 bool _ComputeDepth(RTCRayHit const& rayHit, float *depth, bool clip);
176 // Compute the given ID at the given ray hit.
177 bool _ComputeId(RTCRayHit const& rayHit, TfToken const& idType, int32_t *id);
178 // Compute the normal at the given ray hit.
179 bool _ComputeNormal(RTCRayHit const& rayHit, GfVec3f *normal, bool eye);
180 // Compute a primvar at the given ray hit.
181 bool _ComputePrimvar(RTCRayHit const& rayHit, TfToken const& primvar,
182 GfVec3f *value);
183
184 // Compute the ambient occlusion term at a given point by firing rays
185 // from "position" in the hemisphere centered on "normal"; the occlusion
186 // factor is the fraction of those rays that are visible.
187 //
188 // Modulating surface color by occlusionFactor is similar to taking
189 // the light contribution of an infinitely far, pure white dome light.
190 float _ComputeAmbientOcclusion(GfVec3f const& position,
191 GfVec3f const& normal,
192 std::default_random_engine &random);
193
196 GfVec3f _ComputeLighting(
197 GfVec3f const& position,
198 GfVec3f const& normal,
199 std::default_random_engine &random,
200 HdEmbreePrototypeContext const* prototypeContext) const;
201
202 // Return the visibility from `position` along `direction`
203 float _Visibility(GfVec3f const& position,
204 GfVec3f const& direction,
205 float offset = 1.0e-3f) const;
206
207 // Should the ray continue based on the possibly intersected prim's visibility settings?
208 bool _RayShouldContinue(RTCRayHit const& rayHit) const;
209
210 // The bound aovs for this renderer.
211 HdRenderPassAovBindingVector _aovBindings;
212 // Parsed AOV name tokens.
213 HdParsedAovTokenVector _aovNames;
214
215 // Do the aov bindings need to be re-validated?
216 bool _aovBindingsNeedValidation;
217 // Are the aov bindings valid?
218 bool _aovBindingsValid;
219
220 // Data window - as in CameraUtilFraming.
221 GfRect2i _dataWindow;
222
223 // The width of the render buffers.
224 unsigned int _width;
225 // The height of the render buffers.
226 unsigned int _height;
227
228 // View matrix: world space to camera space.
229 GfMatrix4d _viewMatrix;
230 // Projection matrix: camera space to NDC space.
231 GfMatrix4d _projMatrix;
232 // The inverse view matrix: camera space to world space.
233 GfMatrix4d _inverseViewMatrix;
234 // The inverse projection matrix: NDC space to camera space.
235 GfMatrix4d _inverseProjMatrix;
236
237 // Our handle to the embree scene.
238 RTCScene _scene;
239
240 // How many samples should we render to convergence?
241 int _samplesToConvergence;
242 // How many samples should we use for ambient occlusion?
243 int _ambientOcclusionSamples;
244 // Should we enable scene colors?
245 bool _enableSceneColors;
246 // Should we sample dome lights on ray miss?
247 bool _domeLightCameraVisibility;
248 // If other than -1, use this to seed the random number generator with.
249 int _randomNumberSeed;
250 // Should we enable direct lighting from the scene?
251 bool _enableLighting;
252
253 // How many samples have been completed.
254 std::atomic<int> _completedSamples;
255
256 // Lights
257 mutable WriteMutex _lightsWriteMutex; // protects the 2 below
258 std::map<SdfPath, HdEmbree_Light*> _lightMap;
259 std::vector<HdEmbree_Light*> _domes;
260};
261
262PXR_NAMESPACE_CLOSE_SCOPE
263
264#endif // PXR_IMAGING_PLUGIN_HD_EMBREE_RENDERER_H
Stores a 4x4 matrix of double elements.
Definition: matrix4d.h:71
A 2D rectangle with integer coordinates.
Definition: rect2i.h:43
Basic type for a vector of 3 float components.
Definition: vec3f.h:46
Basic type for a vector of 4 float components.
Definition: vec4f.h:46
HdEmbreeRenderer implements a renderer on top of Embree's raycasting abilities.
Definition: renderer.h:53
void SetSamplesToConvergence(int samplesToConvergence)
Set how many samples to render before considering an image converged.
void SetRandomNumberSeed(int randomNumberSeed)
Sets a number to seed the random number generator with.
void RemoveLight(SdfPath const &lightPath, HdEmbree_Light *light)
Remove a light.
void SetAmbientOcclusionSamples(int ambientOcclusionSamples)
Set how many samples to use for ambient occlusion.
void SetEnableSceneColors(bool enableSceneColors)
Sets whether to use scene colors while rendering.
void Render(HdRenderThread *renderThread)
Rendering entrypoint: add one sample per pixel to the whole sample buffer, and then loop until the im...
void SetEnableLighting(bool enableLighting)
Sets whether to enable direct lighting (disables ambient occlusion).
void AddLight(SdfPath const &lightPath, HdEmbree_Light *light)
Add a light.
HdEmbreeRenderer()
Renderer constructor.
~HdEmbreeRenderer()
Renderer destructor.
void MarkAovBuffersUnconverged()
Mark the aov buffers as unconverged.
void SetAovBindings(HdRenderPassAovBindingVector const &aovBindings)
Set the aov bindings to use for rendering.
void SetDomeLightCameraVisibility(bool domeLightCameraVisibility)
Sets whether dome light direct camera visibility should be enabled.
int GetCompletedSamples() const
Get the number of samples completed so far.
void SetScene(RTCScene scene)
Set the embree scene that this renderer should raycast into.
void SetCamera(const GfMatrix4d &viewMatrix, const GfMatrix4d &projMatrix)
Set the camera to use for rendering.
void Clear()
Clear the bound aov buffers (typically before rendering).
void SetDataWindow(const GfRect2i &dataWindow)
Set the data window to fill (same meaning as in CameraUtilFraming with coordinate system also being y...
HdRenderPassAovBindingVector const & GetAovBindings() const
Get the aov bindings being used for rendering.
Definition: renderer.h:89
HdRenderThread is a utility that specific render delegates can choose to use depending on their needs...
Definition: renderThread.h:129
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:280
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:71
Provides a container which may hold any type, and provides introspection and iteration over array typ...
Definition: value.h:90
A small bit of state attached to each bit of prototype geometry in embree, for the benefit of HdEmbre...
Definition: context.h:29