Fermat
direct_lighting_rl.h
1 /*
2  * Fermat
3  *
4  * Copyright (c) 2017-2019, NVIDIA CORPORATION. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the NVIDIA CORPORATION nor the
14  * names of its contributors may be used to endorse or promote products
15  * derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #pragma once
30 
31 #include <lights.h>
32 #include <clustered_rl.h>
33 #include <vtl_mesh_view.h>
34 #include <spatial_hash.h>
35 
38 
41 
46 {
48 
49  static const uint32 INVALID_SLOT = 0xFFFFFFFF;
50  static const uint32 INVALID_SAMPLE = 0xFFFFFFFF;
51 
54  FERMAT_HOST_DEVICE
56 
59  FERMAT_HOST_DEVICE
61  RLMap _rl,
62  VTLMeshView _vtls) :
63  vtl_rl(_rl), vtls(_vtls) {}
64 
67  FERMAT_DEVICE
69  const RenderingContextView& renderer,
70  const EyeVertex& ev,
71  const uint32 pixel,
72  const uint32 bounce,
73  const bool is_secondary_diffuse,
74  const float cone_radius,
75  const cugar::Bbox3f scene_bbox)
76  {
77  // compute a spatial hash
78  const float cone_scale = 32.0f;
79  const float filter_scale = is_secondary_diffuse ? 0.2f : 1.5f;
80 
81  const uint32 base_dim = (is_secondary_diffuse ? 0 : renderer.instance) * 6;
82  const uint32 random_set = cugar::hash(pixel + renderer.res_x * renderer.res_y * bounce);
83 
84  const float jitter[6] = {
85  cugar::randfloat( base_dim + 0, random_set ),
86  cugar::randfloat( base_dim + 1, random_set ),
87  cugar::randfloat( base_dim + 2, random_set ),
88  cugar::randfloat( base_dim + 3, random_set ),
89  cugar::randfloat( base_dim + 4, random_set ),
90  cugar::randfloat( base_dim + 5, random_set ),
91  };
92 
93  const float bbox_delta = cugar::max_comp( scene_bbox[1] - scene_bbox[0] );
94 
95  const uint64 shading_key = spatial_hash(
96  pixel,
97  ev.geom.position,
98  dot(ev.in, ev.geom.normal_s) > 0.0f ? ev.geom.normal_s : -ev.geom.normal_s,
99  ev.geom.tangent,
100  ev.geom.binormal,
101  scene_bbox,
102  jitter,
103  cugar::min( cone_radius * cone_scale, bbox_delta * 0.05f ),
104  //cone_radius * cone_scale,
105  filter_scale);
106 
107  return vtl_rl.find_slot(shading_key);
108  }
109 
112  FERMAT_DEVICE
113  uint32 sample(
114  const uint32 nee_slot,
115  const float z[3],
116  VertexGeometryId* light_vertex,
117  VertexGeometry* light_vertex_geom,
118  float* light_pdf,
119  Edf* light_edf)
120  {
121  // sample the light source surface
122  //
123  if (nee_slot != INVALID_SLOT)
124  {
125  uint32 vtl_cluster;
126 
127  // 1. use the clustered-RL to sample a VPL
128  float vtl_pdf;
129  uint32 vtl_idx = vtl_rl.sample( nee_slot, z[2], &vtl_pdf, &vtl_cluster );
130 
131  // 2. sample the selected VTL uniformly
132  vtls.sample( vtl_idx, cugar::Vector2f(z[0],z[1]), &light_vertex->prim_id, &light_vertex->uv, light_vertex_geom, light_pdf, light_edf );
133 
134  // 3. multiply by the RL-sampling pdf
135  *light_pdf *= vtl_pdf;
136 
137  return vtl_cluster;
138  }
139  else
140  {
141  const uint32 vtl_idx = cugar::quantize( z[2], vtls.vtl_count() );
142 
143  // sample the selected VTL uniformly
144  vtls.sample( vtl_idx, cugar::Vector2f(z[0],z[1]), &light_vertex->prim_id, &light_vertex->uv, light_vertex_geom, light_pdf, light_edf );
145 
146  return INVALID_SAMPLE;
147  }
148  }
149 
152  FERMAT_DEVICE
153  void map(
154  const uint32 prev_nee_slot,
155  const uint32 triId,
156  const cugar::Vector2f uv,
157  const VertexGeometry light_vertex_geom,
158  float* light_pdf,
159  Edf* light_edf)
160  {
161  const uint32 vtl_idx = vtls.map(triId, uv, light_vertex_geom, light_pdf, light_edf);
162  if (prev_nee_slot != uint32(-1) && vtl_idx != uint32(-1))
163  {
164  // multiply by the clustered-RL pdf
165  *light_pdf *= vtl_rl.pdf( prev_nee_slot, vtl_idx );
166  }
167  }
168 
171  FERMAT_DEVICE
172  void update(
173  const uint32 nee_slot,
174  const uint32 nee_cluster,
175  const cugar::Vector3f w,
176  const bool occluded)
177  {
178  // update the NEE RL pdfs
179  if (nee_cluster != INVALID_SAMPLE)
180  {
181  const float new_value = cugar::max_comp(w.xyz()) * (occluded == false ? 1.0f : 0.0f);
182 
183  vtl_rl.update(nee_slot, nee_cluster, new_value);
184  }
185  }
186 
187  RLMap vtl_rl;
188  VTLMeshView vtls;
189 };
190 
Definition: direct_lighting_rl.h:45
FERMAT_HOST_DEVICE uint32 map(const uint32_t prim_id, const cugar::Vector2f &uv, const VertexGeometry &geom, float *pdf, Edf *edf) const
Definition: vtl_mesh_view.h:87
FERMAT_DEVICE float pdf(const uint32 cell_slot, const uint32 index) const
Definition: clustered_rl_inline.h:159
CUGAR_HOST_DEVICE uint32 quantize(const float x, const uint32 n)
Definition: numbers.h:600
FERMAT_DEVICE uint32 find_slot(const uint64 key)
Definition: clustered_rl_inline.h:117
FERMAT_DEVICE void update(const uint32 nee_slot, const uint32 nee_cluster, const cugar::Vector3f w, const bool occluded)
Definition: direct_lighting_rl.h:172
Definition: vertex.h:105
Definition: vertex.h:92
FERMAT_FORCEINLINE FERMAT_HOST_DEVICE uint64 spatial_hash(const cugar::Vector3f P, const cugar::Vector3f N, const cugar::Bbox3f bbox, const float samples[6], const float cone_radius, const uint32 normal_bits=4)
Definition: spatial_hash.h:44
FERMAT_DEVICE uint32 sample(const uint32 cell_slot, const float z, float *pdf, uint32 *cluster_idx) const
Definition: clustered_rl_inline.h:127
FERMAT_DEVICE void map(const uint32 prev_nee_slot, const uint32 triId, const cugar::Vector2f uv, const VertexGeometry light_vertex_geom, float *light_pdf, Edf *light_edf)
Definition: direct_lighting_rl.h:153
FERMAT_HOST_DEVICE void sample(const uint32 vtl_idx, const cugar::Vector2f vtl_uv, uint32_t *prim_id, cugar::Vector2f *uv, VertexGeometry *geom, float *pdf, Edf *edf) const
Definition: vtl_mesh_view.h:54
Definition: clustered_rl.h:123
Definition: bpt_utils.h:583
FERMAT_HOST_DEVICE DirectLightingRL(RLMap _rl, VTLMeshView _vtls)
Definition: direct_lighting_rl.h:60
Definition: vtl_mesh_view.h:40
FERMAT_HOST_DEVICE DirectLightingRL()
Definition: direct_lighting_rl.h:55
FERMAT_DEVICE uint32 preprocess_vertex(const RenderingContextView &renderer, const EyeVertex &ev, const uint32 pixel, const uint32 bounce, const bool is_secondary_diffuse, const float cone_radius, const cugar::Bbox3f scene_bbox)
Definition: direct_lighting_rl.h:68
Definition: edf.h:49
FERMAT_DEVICE void update(const uint32 cell_slot, const uint32 cluster_idx, const float val, const float alpha=0.05f)
Definition: clustered_rl_inline.h:183
FERMAT_DEVICE uint32 sample(const uint32 nee_slot, const float z[3], VertexGeometryId *light_vertex, VertexGeometry *light_vertex_geom, float *light_pdf, Edf *light_edf)
Definition: direct_lighting_rl.h:113
Definition: renderer_view.h:80
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE uint32 hash(uint32 a)
Definition: numbers.h:649
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE float randfloat(unsigned i, unsigned p)
Definition: numbers.h:753