Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/scene/shader.cpp
| Show All 26 Lines | |||||
| #ifdef WITH_OCIO | #ifdef WITH_OCIO | ||||
| # include <OpenColorIO/OpenColorIO.h> | # include <OpenColorIO/OpenColorIO.h> | ||||
| namespace OCIO = OCIO_NAMESPACE; | namespace OCIO = OCIO_NAMESPACE; | ||||
| #endif | #endif | ||||
| CCL_NAMESPACE_BEGIN | CCL_NAMESPACE_BEGIN | ||||
| thread_mutex ShaderManager::lookup_table_mutex; | thread_mutex ShaderManager::lookup_table_mutex; | ||||
| vector<float> ShaderManager::beckmann_table; | |||||
| bool ShaderManager::beckmann_table_ready = false; | |||||
| /* Beckmann sampling precomputed table, see bsdf_microfacet.h */ | |||||
| /* 2D slope distribution (alpha = 1.0) */ | |||||
| static float beckmann_table_P22(const float slope_x, const float slope_y) | |||||
| { | |||||
| return expf(-(slope_x * slope_x + slope_y * slope_y)); | |||||
| } | |||||
| /* maximal slope amplitude (range that contains 99.99% of the distribution) */ | |||||
| static float beckmann_table_slope_max() | |||||
| { | |||||
| return 6.0; | |||||
| } | |||||
| /* MSVC 2015 needs this ugly hack to prevent a codegen bug on x86 | |||||
| * see T50176 for details | |||||
| */ | |||||
| #if defined(_MSC_VER) && (_MSC_VER == 1900) | |||||
| # define MSVC_VOLATILE volatile | |||||
| #else | |||||
| # define MSVC_VOLATILE | |||||
| #endif | |||||
| /* Paper used: Importance Sampling Microfacet-Based BSDFs with the | |||||
| * Distribution of Visible Normals. Supplemental Material 2/2. | |||||
| * | |||||
| * http://hal.inria.fr/docs/01/00/66/20/ANNEX/supplemental2.pdf | |||||
| */ | |||||
| static void beckmann_table_rows(float *table, int row_from, int row_to) | |||||
| { | |||||
| /* allocate temporary data */ | |||||
| const int DATA_TMP_SIZE = 512; | |||||
| vector<double> slope_x(DATA_TMP_SIZE); | |||||
| vector<double> CDF_P22_omega_i(DATA_TMP_SIZE); | |||||
| /* loop over incident directions */ | |||||
| for (int index_theta = row_from; index_theta < row_to; index_theta++) { | |||||
| /* incident vector */ | |||||
| const float cos_theta = index_theta / (BECKMANN_TABLE_SIZE - 1.0f); | |||||
| const float sin_theta = safe_sqrtf(1.0f - cos_theta * cos_theta); | |||||
| /* for a given incident vector | |||||
| * integrate P22_{omega_i}(x_slope, 1, 1), Eq. (10) */ | |||||
| slope_x[0] = (double)-beckmann_table_slope_max(); | |||||
| CDF_P22_omega_i[0] = 0; | |||||
| for (MSVC_VOLATILE int index_slope_x = 1; index_slope_x < DATA_TMP_SIZE; ++index_slope_x) { | |||||
| /* slope_x */ | |||||
| slope_x[index_slope_x] = (double)(-beckmann_table_slope_max() + | |||||
| 2.0f * beckmann_table_slope_max() * index_slope_x / | |||||
| (DATA_TMP_SIZE - 1.0f)); | |||||
| /* dot product with incident vector */ | |||||
| float dot_product = fmaxf(0.0f, -(float)slope_x[index_slope_x] * sin_theta + cos_theta); | |||||
| /* marginalize P22_{omega_i}(x_slope, 1, 1), Eq. (10) */ | |||||
| float P22_omega_i = 0.0f; | |||||
| for (int j = 0; j < 100; ++j) { | |||||
| float slope_y = -beckmann_table_slope_max() + | |||||
| 2.0f * beckmann_table_slope_max() * j * (1.0f / 99.0f); | |||||
| P22_omega_i += dot_product * beckmann_table_P22((float)slope_x[index_slope_x], slope_y); | |||||
| } | |||||
| /* CDF of P22_{omega_i}(x_slope, 1, 1), Eq. (10) */ | |||||
| CDF_P22_omega_i[index_slope_x] = CDF_P22_omega_i[index_slope_x - 1] + (double)P22_omega_i; | |||||
| } | |||||
| /* renormalize CDF_P22_omega_i */ | |||||
| for (int index_slope_x = 1; index_slope_x < DATA_TMP_SIZE; ++index_slope_x) | |||||
| CDF_P22_omega_i[index_slope_x] /= CDF_P22_omega_i[DATA_TMP_SIZE - 1]; | |||||
| /* loop over random number U1 */ | |||||
| int index_slope_x = 0; | |||||
| for (int index_U = 0; index_U < BECKMANN_TABLE_SIZE; ++index_U) { | |||||
| const double U = 0.0000001 + 0.9999998 * index_U / (double)(BECKMANN_TABLE_SIZE - 1); | |||||
| /* inverse CDF_P22_omega_i, solve Eq.(11) */ | |||||
| while (CDF_P22_omega_i[index_slope_x] <= U) | |||||
| ++index_slope_x; | |||||
| const double interp = (CDF_P22_omega_i[index_slope_x] - U) / | |||||
| (CDF_P22_omega_i[index_slope_x] - CDF_P22_omega_i[index_slope_x - 1]); | |||||
| /* store value */ | |||||
| table[index_U + index_theta * BECKMANN_TABLE_SIZE] = | |||||
| (float)(interp * slope_x[index_slope_x - 1] + (1.0 - interp) * slope_x[index_slope_x]); | |||||
| } | |||||
| } | |||||
| } | |||||
| #undef MSVC_VOLATILE | |||||
| static void beckmann_table_build(vector<float> &table) | |||||
| { | |||||
| table.resize(BECKMANN_TABLE_SIZE * BECKMANN_TABLE_SIZE); | |||||
| /* multithreaded build */ | |||||
| TaskPool pool; | |||||
| for (int i = 0; i < BECKMANN_TABLE_SIZE; i += 8) | |||||
| pool.push(function_bind(&beckmann_table_rows, &table[0], i, i + 8)); | |||||
| pool.wait_work(); | |||||
| } | |||||
| /* Shader */ | /* Shader */ | ||||
| NODE_DEFINE(Shader) | NODE_DEFINE(Shader) | ||||
| { | { | ||||
| NodeType *type = NodeType::add("shader", create); | NodeType *type = NodeType::add("shader", create); | ||||
| static NodeEnum emission_sampling_method_enum; | static NodeEnum emission_sampling_method_enum; | ||||
| ▲ Show 20 Lines • Show All 335 Lines • ▼ Show 20 Lines | bool Shader::need_update_geometry() const | ||||
| return need_update_uvs || need_update_attribute || need_update_displacement; | return need_update_uvs || need_update_attribute || need_update_displacement; | ||||
| } | } | ||||
| /* Shader Manager */ | /* Shader Manager */ | ||||
| ShaderManager::ShaderManager() | ShaderManager::ShaderManager() | ||||
| { | { | ||||
| update_flags = UPDATE_ALL; | update_flags = UPDATE_ALL; | ||||
| beckmann_table_offset = TABLE_OFFSET_INVALID; | |||||
| init_xyz_transforms(); | init_xyz_transforms(); | ||||
| } | } | ||||
| ShaderManager::~ShaderManager() | ShaderManager::~ShaderManager() | ||||
| { | { | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 155 Lines • ▼ Show 20 Lines | foreach (Shader *shader, scene->shaders) { | ||||
| kshader->cryptomatte_id = util_hash_to_float(cryptomatte_id); | kshader->cryptomatte_id = util_hash_to_float(cryptomatte_id); | ||||
| kshader++; | kshader++; | ||||
| has_transparent_shadow |= (flag & SD_HAS_TRANSPARENT_SHADOW) != 0; | has_transparent_shadow |= (flag & SD_HAS_TRANSPARENT_SHADOW) != 0; | ||||
| } | } | ||||
| dscene->shaders.copy_to_device(); | dscene->shaders.copy_to_device(); | ||||
| /* lookup tables */ | |||||
| KernelTables *ktables = &dscene->data.tables; | |||||
| /* beckmann lookup table */ | |||||
| if (beckmann_table_offset == TABLE_OFFSET_INVALID) { | |||||
| if (!beckmann_table_ready) { | |||||
| thread_scoped_lock lock(lookup_table_mutex); | |||||
| if (!beckmann_table_ready) { | |||||
| beckmann_table_build(beckmann_table); | |||||
| beckmann_table_ready = true; | |||||
| } | |||||
| } | |||||
| beckmann_table_offset = scene->lookup_tables->add_table(dscene, beckmann_table); | |||||
| } | |||||
| ktables->beckmann_offset = (int)beckmann_table_offset; | |||||
| /* integrator */ | /* integrator */ | ||||
| KernelIntegrator *kintegrator = &dscene->data.integrator; | KernelIntegrator *kintegrator = &dscene->data.integrator; | ||||
| kintegrator->use_volumes = has_volumes; | kintegrator->use_volumes = has_volumes; | ||||
| /* TODO(sergey): De-duplicate with flags set in integrator.cpp. */ | /* TODO(sergey): De-duplicate with flags set in integrator.cpp. */ | ||||
| kintegrator->transparent_shadows = has_transparent_shadow; | kintegrator->transparent_shadows = has_transparent_shadow; | ||||
| /* film */ | /* film */ | ||||
| KernelFilm *kfilm = &dscene->data.film; | KernelFilm *kfilm = &dscene->data.film; | ||||
| /* color space, needs to be here because e.g. displacement shaders could depend on it */ | /* color space, needs to be here because e.g. displacement shaders could depend on it */ | ||||
| kfilm->xyz_to_r = float3_to_float4(xyz_to_r); | kfilm->xyz_to_r = float3_to_float4(xyz_to_r); | ||||
| kfilm->xyz_to_g = float3_to_float4(xyz_to_g); | kfilm->xyz_to_g = float3_to_float4(xyz_to_g); | ||||
| kfilm->xyz_to_b = float3_to_float4(xyz_to_b); | kfilm->xyz_to_b = float3_to_float4(xyz_to_b); | ||||
| kfilm->rgb_to_y = float3_to_float4(rgb_to_y); | kfilm->rgb_to_y = float3_to_float4(rgb_to_y); | ||||
| kfilm->rec709_to_r = float3_to_float4(rec709_to_r); | kfilm->rec709_to_r = float3_to_float4(rec709_to_r); | ||||
| kfilm->rec709_to_g = float3_to_float4(rec709_to_g); | kfilm->rec709_to_g = float3_to_float4(rec709_to_g); | ||||
| kfilm->rec709_to_b = float3_to_float4(rec709_to_b); | kfilm->rec709_to_b = float3_to_float4(rec709_to_b); | ||||
| kfilm->is_rec709 = is_rec709; | kfilm->is_rec709 = is_rec709; | ||||
| } | } | ||||
| void ShaderManager::device_free_common(Device *, DeviceScene *dscene, Scene *scene) | void ShaderManager::device_free_common(Device *, DeviceScene *dscene, Scene *scene) | ||||
| { | { | ||||
| scene->lookup_tables->remove_table(&beckmann_table_offset); | |||||
| dscene->shaders.free(); | dscene->shaders.free(); | ||||
| } | } | ||||
| void ShaderManager::add_default(Scene *scene) | void ShaderManager::add_default(Scene *scene) | ||||
| { | { | ||||
| /* default surface */ | /* default surface */ | ||||
| { | { | ||||
| ShaderGraph *graph = new ShaderGraph(); | ShaderGraph *graph = new ShaderGraph(); | ||||
| ▲ Show 20 Lines • Show All 126 Lines • ▼ Show 20 Lines | if (use_osl()) { | ||||
| kernel_features |= KERNEL_FEATURE_OSL; | kernel_features |= KERNEL_FEATURE_OSL; | ||||
| } | } | ||||
| return kernel_features; | return kernel_features; | ||||
| } | } | ||||
| void ShaderManager::free_memory() | void ShaderManager::free_memory() | ||||
| { | { | ||||
| beckmann_table.free_memory(); | |||||
| #ifdef WITH_OSL | #ifdef WITH_OSL | ||||
| OSLShaderManager::free_memory(); | OSLShaderManager::free_memory(); | ||||
| #endif | #endif | ||||
| ColorSpaceManager::free_memory(); | ColorSpaceManager::free_memory(); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 155 Lines • Show Last 20 Lines | |||||