Fermat
vertex.h
1 /*
2  * Fermat
3  *
4  * Copyright (c) 2016-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 // ------------------------------------------------------------------------- //
32 //
33 // Declaration of classes used to store intersections.
34 //
35 // ------------------------------------------------------------------------- //
36 
37 #include <types.h>
38 #include <cugar/linalg/vector.h>
39 #include <cugar/bsdf/differential_geometry.h>
41 #include <cuda_fp16.h>
42 
45 
57 
64 #if defined(OPTIX_COMPILATION)
65 // NOTE:
66 // with OptiX, we need to avoid inheritance here, as otherwise the compiler sees
67 // this struct as having dynamic constructors... (even if, in theory, it should be a POD)
68 //
69 struct VertexGeometry
70 {
71  cugar::Vector3f normal_s; // shading normal
72  cugar::Vector3f normal_g; // geometric normal
73  cugar::Vector3f tangent; // local tangent
74  cugar::Vector3f binormal; // local binormal
75 
76  cugar::Vector3f position;
77  float padding;
78  cugar::Vector4f texture_coords;
79  cugar::Vector2f lightmap_coords;
80 
81  FERMAT_HOST_DEVICE operator cugar::DifferentialGeometry() const
82  {
84  r.normal_s = normal_s;
85  r.normal_g = normal_g;
86  r.tangent = tangent;
87  r.binormal = binormal;
88  return r;
89  }
90 };
91 #else
93 {
94  cugar::Vector3f position;
95  float padding;
96  cugar::Vector4f texture_coords;
97  cugar::Vector2f lightmap_coords;
98 };
99 #endif
100 
106 {
107  cugar::Vector2f uv;
108  uint32 prim_id;
109 
110  FERMAT_HOST_DEVICE
111  VertexGeometryId() {}
112 
113  FERMAT_HOST_DEVICE
114  VertexGeometryId(const uint32 _prim_id, const float _u, const float _v) : prim_id(_prim_id), uv(_u, _v) {}
115 
116  FERMAT_HOST_DEVICE
117  VertexGeometryId(const uint32 _prim_id, const cugar::Vector2f _uv) : prim_id(_prim_id), uv(_uv) {}
118 };
119 
122 FERMAT_HOST_DEVICE FERMAT_FORCEINLINE
123 uint32 pack_direction(const cugar::Vector3f& dir)
124 {
126 
127  return cugar::quantize(sdir.x, 0xFFFFu) + (cugar::quantize(sdir.y, 0xFFFFu) << 16);
128 }
129 
132 FERMAT_HOST_DEVICE FERMAT_FORCEINLINE
133 cugar::Vector3f unpack_direction(const uint32 packed_dir)
134 {
135  const cugar::Vector2f sdir(
136  float((packed_dir >> 0) & 0xFFFFu) / float(0xFFFFu),
137  float((packed_dir >> 16) & 0xFFFFu) / float(0xFFFFu));
138 
139  return cugar::uniform_square_to_sphere( sdir );
140 }
141 
142 #if defined(__CUDACC__)
143 
146 FERMAT_DEVICE FERMAT_FORCEINLINE
147 uint32 pack_hemispherical_direction(const cugar::Vector3f& dir)
148 {
149  // Spheremap Transform
150  cugar::Vector2f enc = cugar::normalize(dir.xy()) * sqrtf(-dir.z*0.5f + 0.5f);
151  //enc = enc*0.5f + cugar::Vector2f(0.5f); // compress from [-1:1] to [0:1]
152  half2 h = __floats2half2_rn(enc.x, enc.y);
153  return cugar::binary_cast<uint32>(h);
154 }
157 FERMAT_DEVICE FERMAT_FORCEINLINE
158 cugar::Vector3f unpack_hemispherical_direction(const uint32 packed_dir)
159 {
160  // Inverse Spheremap Transform
161  float2 u = __half22float2( cugar::binary_cast<half2>(packed_dir) );
162 
163  //u.x = 2 * u.x - 1; // decompress from [0:1] to [-1:1]
164  //u.y = 2 * u.y - 1;
165 
166  const float l = 1 - u.x*u.x - u.y*u.y;
167  const float m = 2 * sqrtf(l);
168 
169  return cugar::Vector3f(u.x * m, u.y * m, l * 2 - 1);
170 }
171 
172 #endif
173 
CUGAR_HOST_DEVICE uint32 quantize(const float x, const uint32 n)
Definition: numbers.h:600
Definition: vertex.h:105
Defines various spherical mappings.
Definition: vertex.h:92
CUGAR_HOST CUGAR_DEVICE Vector2f uniform_sphere_to_square(const Vector3f &vec)
Definition: mappings_inline.h:174
Definition: differential_geometry.h:59
FERMAT_HOST_DEVICE FERMAT_FORCEINLINE uint32 pack_direction(const cugar::Vector3f &dir)
Definition: vertex.h:123
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE Out binary_cast(const In in)
Definition: types.h:288
CUGAR_HOST CUGAR_DEVICE Vector3f uniform_square_to_sphere(const Vector2f &uv)
Definition: mappings_inline.h:162
FERMAT_HOST_DEVICE FERMAT_FORCEINLINE cugar::Vector3f unpack_direction(const uint32 packed_dir)
Definition: vertex.h:133