Skip to content

Commit 1fdbcfc

Browse files
authored
Merge branch 'AcademySoftwareFoundation:main' into test-improved-runtest_py
2 parents 5d5806b + 532053e commit 1fdbcfc

File tree

27 files changed

+387
-177
lines changed

27 files changed

+387
-177
lines changed

.github/workflows/ci.yml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,18 @@ jobs:
267267
simd: avx2,f16c
268268
batched: b8_AVX2
269269
# setenvs: export CONAN_PACKAGES="ptex/2.4.2@aswf/vfx2024"
270+
- desc: VP2025 gcc11/C++17 llvm18 py3.11 oiio-3.0 avx2
271+
nametag: linux-vfx2025
272+
runner: ubuntu-latest
273+
container: aswftesting/ci-osl:2025-clang18
274+
cxx_std: 17
275+
python_ver: "3.11"
276+
# pybind11_ver: v2.11.1
277+
simd: avx2,f16c
278+
batched: b8_AVX2
279+
setenvs: export CTEST_EXCLUSIONS="broken|python-oslquery"
280+
# ^^ exclude python-oslquery test until the ASWF container properly
281+
# includes OIIO's python bindings, then we can remove that.
270282

271283
# Address and leak sanitizers
272284
- desc: sanitizers
@@ -667,5 +679,4 @@ jobs:
667679
skip_tests: ${{ (github.repository_owner == 'AcademySoftwareFoundation' && '0') || '1' }}
668680
setenvs: export OSL_CMAKE_FLAGS="-DOSL_USE_OPTIX=1"
669681
OPTIX_VERSION=8.0.0
670-
OPENIMAGEIO_CMAKE_FLAGS=-DBUILD_FMT_VERSION=9.1.0
671682
CTEST_EXCLUSIONS="broken|render-microfacet|example-cuda|python-oslquery"

INSTALL.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ NEW or CHANGED minimum dependencies since the last major release are **bold**.
4949
$OpenImageIO_ROOT/lib to be in your LD_LIBRARY_PATH (or
5050
DYLD_LIBRARY_PATH on OS X).
5151

52-
* [LLVM](http://www.llvm.org) 11, 12, 13, 14, 15, 16, 17, 18, or 19, including
53-
clang libraries. **LLVM 20 is not yet supported.**
52+
* [LLVM](http://www.llvm.org) 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, including
53+
clang libraries.
5454

5555
* (optional) For GPU rendering on NVIDIA GPUs:
5656
* [OptiX](https://developer.nvidia.com/rtx/ray-tracing/optix) 7.0 or higher.

src/cmake/externalpackages.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ checked_find_package (pugixml REQUIRED
5858
# LLVM library setup
5959
checked_find_package (LLVM REQUIRED
6060
VERSION_MIN 11.0
61-
VERSION_MAX 19.9
61+
VERSION_MAX 20.9
6262
PRINT LLVM_SYSTEM_LIBRARIES CLANG_LIBRARIES
6363
LLVM_SHARED_MODE)
6464
# ensure include directory is added (in case of non-standard locations

src/include/OSL/platform.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include <cstring>
2222
#include <memory>
23+
#include <cstdint>
2324

2425
#include <OSL/oslversion.h>
2526

src/libbsdl/include/BSDL/MTX/bsdf_conductor_decl.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// SPDX-License-Identifier: BSD-3-Clause
33
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
44

5-
65
#pragma once
76

87
#include <BSDL/bsdf_decl.h>

src/libbsdl/include/BSDL/MTX/bsdf_conductor_impl.h

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// SPDX-License-Identifier: BSD-3-Clause
33
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
44

5-
65
#pragma once
76

87
#include <BSDL/MTX/bsdf_conductor_decl.h>
@@ -122,15 +121,9 @@ BSDL_INLINE_METHOD Sample
122121
ConductorLobe<BSDF_ROOT>::sample_impl(const Imath::V3f& wo,
123122
const Imath::V3f& rnd) const
124123
{
125-
const float cosNO = wo.z;
126-
if (cosNO <= 0)
127-
return {};
128-
129-
// sample microfacet (half vector)
130-
// generate outgoing direction
131-
Imath::V3f wi = reflect(wo, dist.sample(wo, rnd.x, rnd.y));
132-
// evaluate brdf on outgoing direction
133-
return eval_impl(wo, wi);
124+
Sample s = sample_turquin_microms_reflection(dist, fresnel, E_ms, wo, rnd);
125+
s.roughness = Base::roughness();
126+
return s;
134127
}
135128

136129
} // namespace mtx

src/libbsdl/include/BSDL/microfacet_tools_decl.h

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// SPDX-License-Identifier: BSD-3-Clause
33
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
44

5-
65
#pragma once
76

87
#include <BSDL/config.h>
@@ -33,6 +32,12 @@ struct GGXDist {
3332
BSDL_INLINE_METHOD Imath::V3f sample(const Imath::V3f& wo, float randu,
3433
float randv) const;
3534

35+
// Reflection specific improved sample/pdf functions
36+
BSDL_INLINE_METHOD Imath::V3f
37+
sample_reflection(const Imath::V3f& wo, float randu, float randv) const;
38+
BSDL_INLINE_METHOD float pdf_reflection(const Imath::V3f& wo,
39+
const Imath::V3f& wi) const;
40+
3641
BSDL_INLINE_METHOD float roughness() const { return std::max(ax, ay); }
3742

3843
private:
@@ -131,10 +136,29 @@ template<typename Fresnel> struct MicrofacetMS {
131136
};
132137

133138
// Turquin style microfacet with multiple scattering
134-
template<typename Dist, typename Fresnel>
139+
template<typename Fresnel>
135140
BSDL_INLINE Sample
136-
eval_turquin_microms_reflection(const Dist& dist, const Fresnel& fresnel,
141+
eval_turquin_microms_reflection(const GGXDist& dist, const Fresnel& fresnel,
137142
float E_ms, const Imath::V3f& wo,
138143
const Imath::V3f& wi);
139144

145+
template<typename Fresnel>
146+
BSDL_INLINE Sample
147+
sample_turquin_microms_reflection(const GGXDist& dist, const Fresnel& fresnel,
148+
float E_ms, const Imath::V3f& wo,
149+
const Imath::V3f& rnd);
150+
151+
// SPI style microfacet with multiple scattering
152+
template<typename Dist, typename Fresnel>
153+
BSDL_INLINE Sample
154+
eval_spi_microms_reflection(const Dist& dist, const Fresnel& fresnel,
155+
float E_ms, float E_ms_avg, const Imath::V3f& wo,
156+
const Imath::V3f& wi);
157+
158+
template<typename Dist, typename Fresnel>
159+
BSDL_INLINE Sample
160+
sample_spi_microms_reflection(const Dist& dist, const Fresnel& fresnel,
161+
float E_ms, float E_ms_avg, const Imath::V3f& wo,
162+
const Imath::V3f& rnd);
163+
140164
BSDL_LEAVE_NAMESPACE

src/libbsdl/include/BSDL/microfacet_tools_impl.h

Lines changed: 129 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// SPDX-License-Identifier: BSD-3-Clause
33
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
44

5-
65
#pragma once
76

87
#include <BSDL/config.h>
@@ -70,6 +69,50 @@ GGXDist::sample(const Imath::V3f& wo, float randu, float randv) const
7069
return Imath::V3f(ax * N.x, ay * N.y, std::max(N.z, 0.0f)).normalized();
7170
}
7271

72+
BSDL_INLINE_METHOD Imath::V3f
73+
GGXDist::sample_reflection(const Imath::V3f& wo, float randu, float randv) const
74+
{
75+
// From "Bounded VNDF Sampling for Smith–GGX Reflections" Eto - Tokuyoshi.
76+
// This code is taken from listing 1 almost verbatim.
77+
Imath::V3f i_std = Imath::V3f(wo.x * ax, wo.y * ay, wo.z).normalized();
78+
// Sample a spherical cap
79+
const float phi = 2.0f * PI * randu;
80+
const float a = CLAMP(std::min(ax, ay), 0.0f, 1.0f); // Eq. 6
81+
const float s = 1 + sqrtf(SQR(wo.x) + SQR(wo.y)); // Omit sgn for a <=1
82+
const float a2 = SQR(a);
83+
const float s2 = SQR(s);
84+
const float k = (1 - a2) * s2 / (s2 + a2 * SQR(wo.z)); // Eq. 5
85+
const float b = k * i_std.z;
86+
const float z = (1 - randv) * (1 + b) - b;
87+
const float sinTheta = sqrtf(CLAMP(1 - SQR(z), 0.0f, 1.0f));
88+
constexpr auto cos = BSDLConfig::Fast::cosf;
89+
constexpr auto sin = BSDLConfig::Fast::sinf;
90+
Imath::V3f o_std = { sinTheta * cos(phi), sinTheta * sin(phi), z };
91+
// Compute the microfacet normal m
92+
Imath::V3f m_std = i_std + o_std;
93+
Imath::V3f m = Imath::V3f(m_std.x * ax, m_std.y * ay, m_std.z).normalized();
94+
// Return the reflection vector o
95+
return 2 * wo.dot(m) * m - wo;
96+
}
97+
98+
BSDL_INLINE_METHOD float
99+
GGXDist::pdf_reflection(const Imath::V3f& wo, const Imath::V3f& wi) const
100+
{
101+
// From "Bounded VNDF Sampling for Smith–GGX Reflections" Eto - Tokuyoshi.
102+
// This code is taken from listing 2 almost verbatim.
103+
const Imath::V3f m = (wo + wi).normalized();
104+
const float ndf = D(m);
105+
const Imath::V2f ai = { wo.x * ax, wo.y * ay };
106+
const float len2 = ai.dot(ai);
107+
const float t = sqrtf(len2 + SQR(wo.z));
108+
const float a = CLAMP(std::min(ax, ay), 0.0f, 1.0f); // Eq. 6
109+
const float s = 1 + sqrtf(SQR(wo.x) + SQR(wo.y)); // Omit sgn for a <=1
110+
const float a2 = SQR(a);
111+
const float s2 = SQR(s);
112+
const float k = (1 - a2) * s2 / (s2 + a2 * SQR(wo.z)); // Eq. 5
113+
return ndf / (2 * (k * wo.z + t)); // Eq. 8 * || dm/do ||
114+
}
115+
73116
template<typename BSDF>
74117
BSDL_INLINE_METHOD float
75118
TabulatedEnergyCurve<BSDF>::interpolate_emiss(int i) const
@@ -299,9 +342,9 @@ MicrofacetMS<Fresnel>::computeFmiss() const
299342
}
300343

301344
// Turquin style microfacet with multiple scattering
302-
template<typename Dist, typename Fresnel>
345+
template<typename Fresnel>
303346
BSDL_INLINE Sample
304-
eval_turquin_microms_reflection(const Dist& dist, const Fresnel& fresnel,
347+
eval_turquin_microms_reflection(const GGXDist& dist, const Fresnel& fresnel,
305348
float E_ms, const Imath::V3f& wo,
306349
const Imath::V3f& wi)
307350
{
@@ -315,8 +358,8 @@ eval_turquin_microms_reflection(const Dist& dist, const Fresnel& fresnel,
315358
float cosMO = m.dot(wo);
316359
const float D = dist.D(m);
317360
const float G1 = dist.G1(wo);
318-
const float out = dist.G2_G1(wi, wo);
319-
float s_pdf = (G1 * D) / (4.0f * cosNO);
361+
float s_pdf = dist.pdf_reflection(wo, wi);
362+
const float out = dist.G2_G1(wi, wo) * (G1 * D) / (4.0f * cosNO * s_pdf);
320363
// fresnel term between outgoing direction and microfacet
321364
const Power F = fresnel.eval(cosMO);
322365
// From "Practical multiple scattering compensation for microfacet models" - Emmanuel Turquin
@@ -329,4 +372,85 @@ eval_turquin_microms_reflection(const Dist& dist, const Fresnel& fresnel,
329372
return { wi, O, s_pdf, -1 /* roughness set by caller */ };
330373
}
331374

375+
template<typename Fresnel>
376+
BSDL_INLINE Sample
377+
sample_turquin_microms_reflection(const GGXDist& dist, const Fresnel& fresnel,
378+
float E_ms, const Imath::V3f& wo,
379+
const Imath::V3f& rnd)
380+
{
381+
const float cosNO = wo.z;
382+
if (cosNO <= 0)
383+
return {};
384+
385+
Imath::V3f wi = dist.sample_reflection(wo, rnd.x, rnd.y);
386+
if (wi.z <= 0)
387+
return {};
388+
389+
// evaluate brdf on outgoing direction
390+
return eval_turquin_microms_reflection(dist, fresnel, E_ms, wo, wi);
391+
}
392+
393+
// SPI style microfacet with multiple scattering, with a diffuse lobe
394+
template<typename Dist, typename Fresnel>
395+
BSDL_INLINE Sample
396+
eval_spi_microms_reflection(const Dist& dist, const Fresnel& fresnel,
397+
float E_ms, float E_ms_avg, const Imath::V3f& wo,
398+
const Imath::V3f& wi)
399+
{
400+
const float cosNO = wo.z;
401+
const float cosNI = wi.z;
402+
if (cosNI <= 0 || cosNO <= 0)
403+
return {};
404+
405+
// get half vector
406+
Imath::V3f m = (wo + wi).normalized();
407+
float cosMO = m.dot(wo);
408+
const float D = dist.D(m);
409+
const float G1 = dist.G1(wo);
410+
const float out = dist.G2_G1(wi, wo);
411+
float s_pdf = (G1 * D) / (4.0f * cosNO);
412+
// fresnel term between outgoing direction and microfacet
413+
const Power F = fresnel.eval(cosMO);
414+
const Power O = out * F;
415+
416+
const Power one = Power(1, 1);
417+
// Like Turquin we are using F_avg = F instead of an average fresnel, the
418+
// render integrator has an average effect for high roughness.
419+
//const Power F0 = fresnel.F0();
420+
const Power F_avg = F;
421+
// Evaluate multiple scattering lobe, roughness set by caller. The
422+
// 1 / (1 - F_avg * E_ms_avg) term comes from the series summation.
423+
const Power O_ms = SQR(F_avg) * (1 - E_ms_avg) / (one - F_avg * E_ms_avg);
424+
425+
Sample ec = { wi, O_ms, E_ms * cosNI * ONEOVERPI, -1 };
426+
ec.update(O, s_pdf, 1 - E_ms);
427+
428+
return ec;
429+
}
430+
431+
template<typename Dist, typename Fresnel>
432+
BSDL_INLINE Sample
433+
sample_spi_microms_reflection(const Dist& dist, const Fresnel& fresnel,
434+
float E_ms, float E_ms_avg, const Imath::V3f& wo,
435+
const Imath::V3f& rnd)
436+
{
437+
const float cosNO = wo.z;
438+
if (cosNO <= 0)
439+
return {};
440+
441+
Imath::V3f wi;
442+
if (rnd.z < E_ms) {
443+
// sample diffuse energy compensation lobe
444+
wi = sample_cos_hemisphere(rnd.x, rnd.y);
445+
} else {
446+
// sample microfacet (half vector)
447+
// generate outgoing direction
448+
wi = reflect(wo, dist.sample(wo, rnd.x, rnd.y));
449+
if (wi.z <= 0)
450+
return {};
451+
}
452+
// evaluate brdf on outgoing direction
453+
return eval_spi_microms_reflection(dist, fresnel, E_ms, E_ms_avg, wo, wi);
454+
}
455+
332456
BSDL_LEAVE_NAMESPACE

src/liboslcomp/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ target_link_libraries (${local_lib}
3030
${CMAKE_DL_LIBS}
3131
${CLANG_LIBRARIES} ${LLVM_LIBRARIES} ${LLVM_LDFLAGS}
3232
${LLVM_SYSTEM_LIBRARIES})
33+
target_include_directories (${local_lib} BEFORE PRIVATE ${OpenImageIO_INCLUDES})
3334

3435
# link with (system) library to prevent missing symbols inside clangDriver.lib
3536
if (MSVC)

src/liboslexec/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,9 @@ target_include_directories (${local_lib}
539539
"${CMAKE_SOURCE_DIR}/src/liboslcomp"
540540
${ROBINMAP_INCLUDES}
541541
)
542+
543+
target_include_directories (${local_lib} BEFORE PRIVATE ${OpenImageIO_INCLUDES})
544+
542545
target_compile_definitions (${local_lib}
543546
PRIVATE
544547
OSL_EXPORTS
@@ -607,16 +610,19 @@ install_targets (${local_lib})
607610
if (OSL_BUILD_TESTS AND BUILD_TESTING)
608611
add_executable (accum_test accum_test.cpp)
609612
target_link_libraries (accum_test PRIVATE oslexec ${CMAKE_DL_LIBS})
613+
target_include_directories (accum_test BEFORE PRIVATE ${OpenImageIO_INCLUDES})
610614
set_target_properties (accum_test PROPERTIES FOLDER "Unit Tests")
611615
add_test (unit_accum ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/accum_test)
612616

613617
add_executable (dual_test dual_test.cpp)
614618
target_link_libraries (dual_test PRIVATE OpenImageIO::OpenImageIO Imath::Imath ${CMAKE_DL_LIBS})
619+
target_include_directories (dual_test BEFORE PRIVATE ${OpenImageIO_INCLUDES})
615620
set_target_properties (dual_test PROPERTIES FOLDER "Unit Tests")
616621
add_test (unit_dual ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/dual_test)
617622

618623
add_executable (llvmutil_test llvmutil_test.cpp)
619624
target_link_libraries (llvmutil_test PRIVATE oslexec ${CMAKE_DL_LIBS})
625+
target_include_directories (llvmutil_test BEFORE PRIVATE ${OpenImageIO_INCLUDES})
620626
set_target_properties (llvmutil_test PROPERTIES FOLDER "Unit Tests")
621627
add_test (unit_llvmutil ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/llvmutil_test)
622628
endif ()

0 commit comments

Comments
 (0)