Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/blender/addon/properties.py13
-rw-r--r--intern/cycles/blender/addon/ui.py1
-rw-r--r--intern/cycles/blender/blender_shader.cpp3
-rw-r--r--intern/cycles/blender/blender_sync.cpp8
-rw-r--r--intern/cycles/device/device_cpu.cpp116
-rw-r--r--intern/cycles/device/device_optix.cpp14
-rw-r--r--intern/cycles/device/device_task.h16
-rw-r--r--intern/cycles/kernel/shaders/node_sky_texture.osl39
-rw-r--r--intern/cycles/kernel/svm/svm_sky.h15
-rw-r--r--intern/cycles/render/image_sky.cpp10
-rw-r--r--intern/cycles/render/image_sky.h4
-rw-r--r--intern/cycles/render/light.cpp14
-rw-r--r--intern/cycles/render/nodes.cpp45
-rw-r--r--intern/cycles/render/nodes.h3
-rw-r--r--intern/ghost/GHOST_C-api.h4
-rw-r--r--intern/ghost/GHOST_IWindow.h4
-rw-r--r--intern/ghost/intern/GHOST_Window.h4
-rw-r--r--intern/mantaflow/intern/MANTA_main.cpp14
-rw-r--r--intern/mantaflow/intern/strings/fluid_script.h8
-rw-r--r--intern/sky/include/sky_model.h61
-rw-r--r--intern/sky/source/sky_model.cpp10
-rw-r--r--intern/sky/source/sky_nishita.cpp84
22 files changed, 302 insertions, 188 deletions
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 6d28c14e12a..45d25720aff 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -212,7 +212,7 @@ def enum_denoiser(self, context):
items += enum_openimagedenoise_denoiser(self, context)
return items
-enum_denoising_optix_input_passes = (
+enum_denoising_input_passes = (
('RGB', "Color", "Use only color as input", 1),
('RGB_ALBEDO', "Color + Albedo", "Use color and albedo data as input", 2),
('RGB_ALBEDO_NORMAL', "Color + Albedo + Normal", "Use color, albedo and normal data as input", 3),
@@ -1451,11 +1451,18 @@ class CyclesRenderLayerSettings(bpy.types.PropertyGroup):
denoising_optix_input_passes: EnumProperty(
name="Input Passes",
- description="Passes handed over to the OptiX denoiser (this can have different effects on the denoised image)",
- items=enum_denoising_optix_input_passes,
+ description="Passes used by the denoiser to distinguish noise from shader and geometry detail",
+ items=enum_denoising_input_passes,
default='RGB_ALBEDO',
)
+ denoising_openimagedenoise_input_passes: EnumProperty(
+ name="Input Passes",
+ description="Passes used by the denoiser to distinguish noise from shader and geometry detail",
+ items=enum_denoising_input_passes,
+ default='RGB_ALBEDO_NORMAL',
+ )
+
use_pass_crypto_object: BoolProperty(
name="Cryptomatte Object",
description="Render cryptomatte object pass, for isolating objects in compositing",
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 3d0b2f721b4..03b1675c309 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -1008,6 +1008,7 @@ class CYCLES_RENDER_PT_denoising(CyclesButtonsPanel, Panel):
col.prop(cycles_view_layer, "denoising_optix_input_passes")
return
elif denoiser == 'OPENIMAGEDENOISE':
+ col.prop(cycles_view_layer, "denoising_openimagedenoise_input_passes")
return
col.prop(cycles_view_layer, "denoising_radius", text="Radius")
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index 19d2730dc93..33e73b5a4b9 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -815,9 +815,10 @@ static ShaderNode *add_node(Scene *scene,
sky->ground_albedo = b_sky_node.ground_albedo();
sky->sun_disc = b_sky_node.sun_disc();
sky->sun_size = b_sky_node.sun_size();
+ sky->sun_intensity = b_sky_node.sun_intensity();
sky->sun_elevation = b_sky_node.sun_elevation();
sky->sun_rotation = b_sky_node.sun_rotation();
- sky->altitude = b_sky_node.altitude();
+ sky->altitude = 1000.0f * b_sky_node.altitude();
sky->air_density = b_sky_node.air_density();
sky->dust_density = b_sky_node.dust_density();
sky->ozone_density = b_sky_node.ozone_density();
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index ee2445e44c4..d509f2fc786 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -954,7 +954,13 @@ DenoiseParams BlenderSync::get_denoise_params(BL::Scene &b_scene,
denoising.strength = get_float(clayer, "denoising_strength");
denoising.feature_strength = get_float(clayer, "denoising_feature_strength");
denoising.relative_pca = get_boolean(clayer, "denoising_relative_pca");
- denoising.optix_input_passes = get_enum(clayer, "denoising_optix_input_passes");
+
+ denoising.input_passes = (DenoiserInput)get_enum(
+ clayer,
+ (denoising.type == DENOISER_OPTIX) ? "denoising_optix_input_passes" :
+ "denoising_openimagedenoise_input_passes",
+ DENOISER_INPUT_NUM,
+ DENOISER_INPUT_RGB_ALBEDO_NORMAL);
denoising.store_passes = get_boolean(clayer, "denoising_store_passes");
}
diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp
index af8db5b75b8..ee3a3ddea64 100644
--- a/intern/cycles/device/device_cpu.cpp
+++ b/intern/cycles/device/device_cpu.cpp
@@ -951,12 +951,13 @@ class CPUDevice : public Device {
void denoise_openimagedenoise_buffer(DeviceTask &task,
float *buffer,
- size_t offset,
- size_t stride,
- size_t x,
- size_t y,
- size_t w,
- size_t h)
+ const size_t offset,
+ const size_t stride,
+ const size_t x,
+ const size_t y,
+ const size_t w,
+ const size_t h,
+ const float scale)
{
#ifdef WITH_OPENIMAGEDENOISE
assert(openimagedenoise_supported());
@@ -982,31 +983,65 @@ class CPUDevice : public Device {
}
/* Set images with appropriate stride for our interleaved pass storage. */
- const struct {
+ struct {
const char *name;
- int offset;
- } passes[] = {{"color", task.pass_denoising_data + DENOISING_PASS_COLOR},
- {"normal", task.pass_denoising_data + DENOISING_PASS_NORMAL},
- {"albedo", task.pass_denoising_data + DENOISING_PASS_ALBEDO},
- {"output", 0},
+ const int offset;
+ const bool scale;
+ const bool use;
+ array<float> scaled_buffer;
+ } passes[] = {{"color", task.pass_denoising_data + DENOISING_PASS_COLOR, false, true},
+ {"albedo",
+ task.pass_denoising_data + DENOISING_PASS_ALBEDO,
+ true,
+ task.denoising.input_passes >= DENOISER_INPUT_RGB_ALBEDO},
+ {"normal",
+ task.pass_denoising_data + DENOISING_PASS_NORMAL,
+ true,
+ task.denoising.input_passes >= DENOISER_INPUT_RGB_ALBEDO_NORMAL},
+ {"output", 0, false, true},
{ NULL,
0 }};
for (int i = 0; passes[i].name; i++) {
+ if (!passes[i].use) {
+ continue;
+ }
+
const int64_t pixel_offset = offset + x + y * stride;
- const int64_t buffer_offset = (pixel_offset * task.pass_stride + passes[i].offset) *
- sizeof(float);
- const int64_t pixel_stride = task.pass_stride * sizeof(float);
+ const int64_t buffer_offset = (pixel_offset * task.pass_stride + passes[i].offset);
+ const int64_t pixel_stride = task.pass_stride;
const int64_t row_stride = stride * pixel_stride;
- oidn_filter.setImage(passes[i].name,
- (char *)buffer + buffer_offset,
- oidn::Format::Float3,
- w,
- h,
- 0,
- pixel_stride,
- row_stride);
+ if (passes[i].scale && scale != 1.0f) {
+ /* Normalize albedo and normal passes as they are scaled by the number of samples.
+ * For the color passes OIDN will perform auto-exposure making it unnecessary. */
+ array<float> &scaled_buffer = passes[i].scaled_buffer;
+ scaled_buffer.resize(w * h * 3);
+
+ for (int y = 0; y < h; y++) {
+ const float *pass_row = buffer + buffer_offset + y * row_stride;
+ float *scaled_row = scaled_buffer.data() + y * w * 3;
+
+ for (int x = 0; x < w; x++) {
+ scaled_row[x * 3 + 0] = pass_row[x * pixel_stride + 0] * scale;
+ scaled_row[x * 3 + 1] = pass_row[x * pixel_stride + 1] * scale;
+ scaled_row[x * 3 + 2] = pass_row[x * pixel_stride + 2] * scale;
+ }
+ }
+
+ oidn_filter.setImage(
+ passes[i].name, scaled_buffer.data(), oidn::Format::Float3, w, h, 0, 0, 0);
+ }
+ else {
+ oidn_filter.setImage(passes[i].name,
+ buffer + buffer_offset,
+ oidn::Format::Float3,
+ w,
+ h,
+ 0,
+ pixel_stride * sizeof(float),
+ row_stride * sizeof(float));
+ }
}
/* Execute filter. */
@@ -1021,6 +1056,7 @@ class CPUDevice : public Device {
(void)y;
(void)w;
(void)h;
+ (void)scale;
#endif
}
@@ -1037,7 +1073,8 @@ class CPUDevice : public Device {
rtile.x,
rtile.y,
rtile.w,
- rtile.h);
+ rtile.h,
+ 1.0f / rtile.sample);
/* todo: it may be possible to avoid this copy, but we have to ensure that
* when other code copies data from the device it doesn't overwrite the
@@ -1047,6 +1084,9 @@ class CPUDevice : public Device {
else {
/* Per-tile denoising. */
rtile.sample = rtile.start_sample + rtile.num_samples;
+ const float scale = 1.0f / rtile.sample;
+ const float invscale = rtile.sample;
+ const size_t pass_stride = task.pass_stride;
/* Map neighboring tiles into one buffer for denoising. */
RenderTileNeighbors neighbors(rtile);
@@ -1075,22 +1115,24 @@ class CPUDevice : public Device {
const int ymax = min(ntile.y + ntile.h, rect.w);
const size_t tile_offset = ntile.offset + xmin + ymin * ntile.stride;
- const float *tile_buffer = (float *)ntile.buffer + tile_offset * task.pass_stride;
+ const float *tile_buffer = (float *)ntile.buffer + tile_offset * pass_stride;
const size_t merged_stride = rect_size.x;
const size_t merged_offset = (xmin - rect.x) + (ymin - rect.y) * merged_stride;
- float *merged_buffer = merged.data() + merged_offset * task.pass_stride;
+ float *merged_buffer = merged.data() + merged_offset * pass_stride;
for (int y = ymin; y < ymax; y++) {
- memcpy(merged_buffer, tile_buffer, sizeof(float) * task.pass_stride * (xmax - xmin));
- tile_buffer += ntile.stride * task.pass_stride;
- merged_buffer += merged_stride * task.pass_stride;
+ for (int x = 0; x < pass_stride * (xmax - xmin); x++) {
+ merged_buffer[x] = tile_buffer[x] * scale;
+ }
+ tile_buffer += ntile.stride * pass_stride;
+ merged_buffer += merged_stride * pass_stride;
}
}
/* Denoise */
denoise_openimagedenoise_buffer(
- task, merged.data(), 0, rect_size.x, 0, 0, rect_size.x, rect_size.y);
+ task, merged.data(), 0, rect_size.x, 0, 0, rect_size.x, rect_size.y, 1.0f);
/* Copy back result from merged buffer. */
RenderTile &ntile = neighbors.target;
@@ -1101,16 +1143,20 @@ class CPUDevice : public Device {
const int ymax = min(ntile.y + ntile.h, rect.w);
const size_t tile_offset = ntile.offset + xmin + ymin * ntile.stride;
- float *tile_buffer = (float *)ntile.buffer + tile_offset * task.pass_stride;
+ float *tile_buffer = (float *)ntile.buffer + tile_offset * pass_stride;
const size_t merged_stride = rect_size.x;
const size_t merged_offset = (xmin - rect.x) + (ymin - rect.y) * merged_stride;
- const float *merged_buffer = merged.data() + merged_offset * task.pass_stride;
+ const float *merged_buffer = merged.data() + merged_offset * pass_stride;
for (int y = ymin; y < ymax; y++) {
- memcpy(tile_buffer, merged_buffer, sizeof(float) * task.pass_stride * (xmax - xmin));
- tile_buffer += ntile.stride * task.pass_stride;
- merged_buffer += merged_stride * task.pass_stride;
+ for (int x = 0; x < pass_stride * (xmax - xmin); x += pass_stride) {
+ tile_buffer[x + 0] = merged_buffer[x + 0] * invscale;
+ tile_buffer[x + 1] = merged_buffer[x + 1] * invscale;
+ tile_buffer[x + 2] = merged_buffer[x + 2] * invscale;
+ }
+ tile_buffer += ntile.stride * pass_stride;
+ merged_buffer += merged_stride * pass_stride;
}
}
diff --git a/intern/cycles/device/device_optix.cpp b/intern/cycles/device/device_optix.cpp
index 35856f48213..1cc45983565 100644
--- a/intern/cycles/device/device_optix.cpp
+++ b/intern/cycles/device/device_optix.cpp
@@ -877,7 +877,7 @@ class OptiXDevice : public CUDADevice {
# if OPTIX_DENOISER_NO_PIXEL_STRIDE
device_only_memory<float> input_rgb(this, "denoiser input rgb");
- input_rgb.alloc_to_device(rect_size.x * rect_size.y * 3 * task.denoising.optix_input_passes);
+ input_rgb.alloc_to_device(rect_size.x * rect_size.y * 3 * task.denoising.input_passes);
void *input_args[] = {&input_rgb.device_pointer,
&input_ptr,
@@ -886,7 +886,7 @@ class OptiXDevice : public CUDADevice {
&input_stride,
&task.pass_stride,
const_cast<int *>(pass_offset),
- &task.denoising.optix_input_passes,
+ &task.denoising.input_passes,
&rtile.sample};
launch_filter_kernel(
"kernel_cuda_filter_convert_to_rgb", rect_size.x, rect_size.y, input_args);
@@ -897,7 +897,7 @@ class OptiXDevice : public CUDADevice {
# endif
const bool recreate_denoiser = (denoiser == NULL) ||
- (task.denoising.optix_input_passes != denoiser_input_passes);
+ (task.denoising.input_passes != denoiser_input_passes);
if (recreate_denoiser) {
// Destroy existing handle before creating new one
if (denoiser != NULL) {
@@ -906,9 +906,9 @@ class OptiXDevice : public CUDADevice {
// Create OptiX denoiser handle on demand when it is first used
OptixDenoiserOptions denoiser_options;
- assert(task.denoising.optix_input_passes >= 1 && task.denoising.optix_input_passes <= 3);
+ assert(task.denoising.input_passes >= 1 && task.denoising.input_passes <= 3);
denoiser_options.inputKind = static_cast<OptixDenoiserInputKind>(
- OPTIX_DENOISER_INPUT_RGB + (task.denoising.optix_input_passes - 1));
+ OPTIX_DENOISER_INPUT_RGB + (task.denoising.input_passes - 1));
# if OPTIX_ABI_VERSION < 28
denoiser_options.pixelFormat = OPTIX_PIXEL_FORMAT_FLOAT3;
# endif
@@ -917,7 +917,7 @@ class OptiXDevice : public CUDADevice {
optixDenoiserSetModel(denoiser, OPTIX_DENOISER_MODEL_KIND_HDR, NULL, 0));
// OptiX denoiser handle was created with the requested number of input passes
- denoiser_input_passes = task.denoising.optix_input_passes;
+ denoiser_input_passes = task.denoising.input_passes;
}
OptixDenoiserSizes sizes = {};
@@ -992,7 +992,7 @@ class OptiXDevice : public CUDADevice {
denoiser_state.device_pointer,
scratch_offset,
input_layers,
- task.denoising.optix_input_passes,
+ task.denoising.input_passes,
overlap_offset.x,
overlap_offset.y,
output_layers,
diff --git a/intern/cycles/device/device_task.h b/intern/cycles/device/device_task.h
index 21da55d50d4..fd380788282 100644
--- a/intern/cycles/device/device_task.h
+++ b/intern/cycles/device/device_task.h
@@ -42,6 +42,14 @@ enum DenoiserType {
DENOISER_ALL = ~0,
};
+enum DenoiserInput {
+ DENOISER_INPUT_RGB = 1,
+ DENOISER_INPUT_RGB_ALBEDO = 2,
+ DENOISER_INPUT_RGB_ALBEDO_NORMAL = 3,
+
+ DENOISER_INPUT_NUM,
+};
+
typedef int DenoiserTypeMask;
class DenoiseParams {
@@ -73,10 +81,10 @@ class DenoiseParams {
/* Clamp the input to the range of +-1e8. Should be enough for any legitimate data. */
bool clamp_input;
- /** Optix Denoiser **/
+ /** OIDN/Optix Denoiser **/
- /* Passes handed over to the OptiX denoiser (default to color + albedo). */
- int optix_input_passes;
+ /* Passes handed over to the OIDN/OptiX denoiser (default to color + albedo). */
+ DenoiserInput input_passes;
DenoiseParams()
{
@@ -92,7 +100,7 @@ class DenoiseParams {
neighbor_frames = 2;
clamp_input = true;
- optix_input_passes = 2;
+ input_passes = DENOISER_INPUT_RGB_ALBEDO_NORMAL;
start_sample = 0;
}
diff --git a/intern/cycles/kernel/shaders/node_sky_texture.osl b/intern/cycles/kernel/shaders/node_sky_texture.osl
index 20d379939ab..acb198a9852 100644
--- a/intern/cycles/kernel/shaders/node_sky_texture.osl
+++ b/intern/cycles/kernel/shaders/node_sky_texture.osl
@@ -127,12 +127,13 @@ float precise_angle(vector a, vector b)
return 2.0 * atan2(length(a - b), length(a + b));
}
-color sky_radiance_nishita(vector dir, float nishita_data[9], string filename)
+color sky_radiance_nishita(vector dir, float nishita_data[10], string filename)
{
/* definitions */
float sun_elevation = nishita_data[6];
float sun_rotation = nishita_data[7];
float angular_diameter = nishita_data[8];
+ float sun_intensity = nishita_data[9];
int sun_disc = angular_diameter > 0;
float alpha = 1.0;
color xyz;
@@ -149,7 +150,7 @@ color sky_radiance_nishita(vector dir, float nishita_data[9], string filename)
/* if ray inside sun disc render it, otherwise render sky */
if (sun_dir_angle < half_angular && sun_disc == 1) {
- /* get 3 pixels data */
+ /* get 2 pixels data */
color pixel_bottom = color(nishita_data[0], nishita_data[1], nishita_data[2]);
color pixel_top = color(nishita_data[3], nishita_data[4], nishita_data[5]);
float y;
@@ -158,13 +159,13 @@ color sky_radiance_nishita(vector dir, float nishita_data[9], string filename)
if (sun_elevation - half_angular > 0.0) {
if ((sun_elevation + half_angular) > 0.0) {
y = ((dir_elevation - sun_elevation) / angular_diameter) + 0.5;
- xyz = mix(pixel_bottom, pixel_top, y);
+ xyz = mix(pixel_bottom, pixel_top, y) * sun_intensity;
}
}
else {
if (sun_elevation + half_angular > 0.0) {
y = dir_elevation / (sun_elevation + half_angular);
- xyz = mix(pixel_bottom, pixel_top, y);
+ xyz = mix(pixel_bottom, pixel_top, y) * sun_intensity;
}
}
/* limb darkening, coefficient is 0.6f */
@@ -176,7 +177,8 @@ color sky_radiance_nishita(vector dir, float nishita_data[9], string filename)
else {
/* sky interpolation */
float x = (direction[1] + M_PI + sun_rotation) / M_2PI;
- float y = 1.0 - (dir_elevation / M_PI_2);
+ /* more pixels toward horizon compensation */
+ float y = 1.0 - sqrt(dir_elevation / M_PI_2);
if (x > 1.0) {
x = x - 1.0;
}
@@ -206,19 +208,20 @@ color sky_radiance_nishita(vector dir, float nishita_data[9], string filename)
return xyz_to_rgb(xyz[0], xyz[1], xyz[2]) * 120000.0;
}
-shader node_sky_texture(int use_mapping = 0,
- matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- vector Vector = P,
- string type = "hosek_wilkie",
- float theta = 0.0,
- float phi = 0.0,
- string filename = "",
- color radiance = color(0.0, 0.0, 0.0),
- float config_x[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
- float config_y[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
- float config_z[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
- float nishita_data[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
- output color Color = color(0.0, 0.0, 0.0))
+shader node_sky_texture(
+ int use_mapping = 0,
+ matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+ vector Vector = P,
+ string type = "hosek_wilkie",
+ float theta = 0.0,
+ float phi = 0.0,
+ string filename = "",
+ color radiance = color(0.0, 0.0, 0.0),
+ float config_x[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ float config_y[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ float config_z[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ float nishita_data[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ output color Color = color(0.0, 0.0, 0.0))
{
vector p = Vector;
diff --git a/intern/cycles/kernel/svm/svm_sky.h b/intern/cycles/kernel/svm/svm_sky.h
index 214c0cd1a9a..be2c8ccdacf 100644
--- a/intern/cycles/kernel/svm/svm_sky.h
+++ b/intern/cycles/kernel/svm/svm_sky.h
@@ -136,6 +136,7 @@ ccl_device float3 sky_radiance_nishita(KernelGlobals *kg,
float sun_elevation = nishita_data[6];
float sun_rotation = nishita_data[7];
float angular_diameter = nishita_data[8];
+ float sun_intensity = nishita_data[9];
bool sun_disc = (angular_diameter > 0.0f);
float3 xyz;
/* convert dir to spherical coordinates */
@@ -151,7 +152,7 @@ ccl_device float3 sky_radiance_nishita(KernelGlobals *kg,
/* if ray inside sun disc render it, otherwise render sky */
if (sun_disc && sun_dir_angle < half_angular) {
- /* get 3 pixels data */
+ /* get 2 pixels data */
float3 pixel_bottom = make_float3(nishita_data[0], nishita_data[1], nishita_data[2]);
float3 pixel_top = make_float3(nishita_data[3], nishita_data[4], nishita_data[5]);
float y;
@@ -160,13 +161,13 @@ ccl_device float3 sky_radiance_nishita(KernelGlobals *kg,
if (sun_elevation - half_angular > 0.0f) {
if (sun_elevation + half_angular > 0.0f) {
y = ((dir_elevation - sun_elevation) / angular_diameter) + 0.5f;
- xyz = interp(pixel_bottom, pixel_top, y);
+ xyz = interp(pixel_bottom, pixel_top, y) * sun_intensity;
}
}
else {
if (sun_elevation + half_angular > 0.0f) {
y = dir_elevation / (sun_elevation + half_angular);
- xyz = interp(pixel_bottom, pixel_top, y);
+ xyz = interp(pixel_bottom, pixel_top, y) * sun_intensity;
}
}
/* limb darkening, coefficient is 0.6f */
@@ -178,7 +179,8 @@ ccl_device float3 sky_radiance_nishita(KernelGlobals *kg,
else {
/* sky interpolation */
float x = (direction.y + M_PI_F + sun_rotation) / M_2PI_F;
- float y = dir_elevation / M_PI_2_F;
+ /* more pixels toward horizon compensation */
+ float y = safe_sqrtf(dir_elevation / M_PI_2_F);
if (x > 1.0f) {
x -= 1.0f;
}
@@ -301,7 +303,7 @@ ccl_device void svm_node_tex_sky(
/* Nishita */
else {
/* Define variables */
- float nishita_data[9];
+ float nishita_data[10];
float4 data = read_node_float(kg, offset);
nishita_data[0] = data.x;
@@ -317,7 +319,8 @@ ccl_device void svm_node_tex_sky(
data = read_node_float(kg, offset);
nishita_data[8] = data.x;
- uint texture_id = __float_as_uint(data.y);
+ nishita_data[9] = data.y;
+ uint texture_id = __float_as_uint(data.z);
/* Compute Sky */
f = sky_radiance_nishita(kg, dir, nishita_data, texture_id);
diff --git a/intern/cycles/render/image_sky.cpp b/intern/cycles/render/image_sky.cpp
index 24d4834c2fa..0560907c63e 100644
--- a/intern/cycles/render/image_sky.cpp
+++ b/intern/cycles/render/image_sky.cpp
@@ -25,8 +25,11 @@
CCL_NAMESPACE_BEGIN
-SkyLoader::SkyLoader(
- float sun_elevation, int altitude, float air_density, float dust_density, float ozone_density)
+SkyLoader::SkyLoader(float sun_elevation,
+ float altitude,
+ float air_density,
+ float dust_density,
+ float ozone_density)
: sun_elevation(sun_elevation),
altitude(altitude),
air_density(air_density),
@@ -57,7 +60,6 @@ bool SkyLoader::load_pixels(const ImageMetaData &metadata,
int width = metadata.width;
int height = metadata.height;
float *pixel_data = (float *)pixels;
- float altitude_f = (float)altitude;
/* precompute sky texture */
const int rows_per_task = divide_up(1024, width);
@@ -70,7 +72,7 @@ bool SkyLoader::load_pixels(const ImageMetaData &metadata,
width,
height,
sun_elevation,
- altitude_f,
+ altitude,
air_density,
dust_density,
ozone_density);
diff --git a/intern/cycles/render/image_sky.h b/intern/cycles/render/image_sky.h
index cf4a3e8942c..686f4e5b885 100644
--- a/intern/cycles/render/image_sky.h
+++ b/intern/cycles/render/image_sky.h
@@ -21,14 +21,14 @@ CCL_NAMESPACE_BEGIN
class SkyLoader : public ImageLoader {
private:
float sun_elevation;
- int altitude;
+ float altitude;
float air_density;
float dust_density;
float ozone_density;
public:
SkyLoader(float sun_elevation,
- int altitude,
+ float altitude,
float air_density,
float dust_density,
float ozone_density);
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index c0615c6217b..183c02cb6b9 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -625,13 +625,19 @@ void LightManager::device_update_background(Device *device,
}
}
+ /* Determine sun direction from lat/long and texture mapping. */
float latitude = sky->sun_elevation;
float longitude = M_2PI_F - sky->sun_rotation + M_PI_2_F;
+ float3 sun_direction = make_float3(
+ cosf(latitude) * cosf(longitude), cosf(latitude) * sinf(longitude), sinf(latitude));
+ Transform sky_transform = transform_inverse(sky->tex_mapping.compute_transform());
+ sun_direction = transform_direction(&sky_transform, sun_direction);
+
+ /* Pack sun direction and size. */
float half_angle = sky->sun_size * 0.5f;
- kbackground->sun = make_float4(cosf(latitude) * cosf(longitude),
- cosf(latitude) * sinf(longitude),
- sinf(latitude),
- half_angle);
+ kbackground->sun = make_float4(
+ sun_direction.x, sun_direction.y, sun_direction.z, half_angle);
+
kbackground->sun_weight = 4.0f;
environment_res.x = max(environment_res.x, 512);
environment_res.y = max(environment_res.y, 256);
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 1e09b71b340..1a29663ec5e 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -632,7 +632,7 @@ typedef struct SunSky {
/* Parameter */
float radiance_x, radiance_y, radiance_z;
- float config_x[9], config_y[9], config_z[9], nishita_data[9];
+ float config_x[9], config_y[9], config_z[9], nishita_data[10];
} SunSky;
/* Preetham model */
@@ -749,18 +749,24 @@ static void sky_texture_precompute_hosek(SunSky *sunsky,
static void sky_texture_precompute_nishita(SunSky *sunsky,
bool sun_disc,
float sun_size,
+ float sun_intensity,
float sun_elevation,
float sun_rotation,
- int altitude,
+ float altitude,
float air_density,
float dust_density)
{
/* sample 2 sun pixels */
float pixel_bottom[3];
float pixel_top[3];
- float altitude_f = (float)altitude;
SKY_nishita_skymodel_precompute_sun(
- sun_elevation, sun_size, altitude_f, air_density, dust_density, pixel_bottom, pixel_top);
+ sun_elevation, sun_size, altitude, air_density, dust_density, pixel_bottom, pixel_top);
+ /* limit sun rotation between 0 and 360 degrees */
+ sun_rotation = fmodf(sun_rotation, M_2PI_F);
+ if (sun_rotation < 0.0f) {
+ sun_rotation += M_2PI_F;
+ }
+ sun_rotation = M_2PI_F - sun_rotation;
/* send data to svm_sky */
sunsky->nishita_data[0] = pixel_bottom[0];
sunsky->nishita_data[1] = pixel_bottom[1];
@@ -769,8 +775,9 @@ static void sky_texture_precompute_nishita(SunSky *sunsky,
sunsky->nishita_data[4] = pixel_top[1];
sunsky->nishita_data[5] = pixel_top[2];
sunsky->nishita_data[6] = sun_elevation;
- sunsky->nishita_data[7] = M_2PI_F - sun_rotation;
+ sunsky->nishita_data[7] = sun_rotation;
sunsky->nishita_data[8] = sun_disc ? sun_size : 0.0f;
+ sunsky->nishita_data[9] = sun_intensity;
}
NODE_DEFINE(SkyTextureNode)
@@ -790,9 +797,10 @@ NODE_DEFINE(SkyTextureNode)
SOCKET_FLOAT(ground_albedo, "Ground Albedo", 0.3f);
SOCKET_BOOLEAN(sun_disc, "Sun Disc", true);
SOCKET_FLOAT(sun_size, "Sun Size", 0.009512f);
+ SOCKET_FLOAT(sun_intensity, "Sun Intensity", 1.0f);
SOCKET_FLOAT(sun_elevation, "Sun Elevation", M_PI_2_F);
SOCKET_FLOAT(sun_rotation, "Sun Rotation", 0.0f);
- SOCKET_INT(altitude, "Altitude", 0);
+ SOCKET_FLOAT(altitude, "Altitude", 1.0f);
SOCKET_FLOAT(air_density, "Air", 1.0f);
SOCKET_FLOAT(dust_density, "Dust", 1.0f);
SOCKET_FLOAT(ozone_density, "Ozone", 1.0f);
@@ -820,12 +828,17 @@ void SkyTextureNode::compile(SVMCompiler &compiler)
else if (type == NODE_SKY_HOSEK)
sky_texture_precompute_hosek(&sunsky, sun_direction, turbidity, ground_albedo);
else if (type == NODE_SKY_NISHITA) {
+ /* Clamp altitude to reasonable values.
+ * Below 1m causes numerical issues and above 60km is space. */
+ float clamped_altitude = clamp(altitude, 1.0f, 59999.0f);
+
sky_texture_precompute_nishita(&sunsky,
sun_disc,
sun_size,
+ sun_intensity,
sun_elevation,
sun_rotation,
- altitude,
+ clamped_altitude,
air_density,
dust_density);
/* precomputed texture image parameters */
@@ -837,7 +850,7 @@ void SkyTextureNode::compile(SVMCompiler &compiler)
/* precompute sky texture */
if (handle.empty()) {
SkyLoader *loader = new SkyLoader(
- sun_elevation, altitude, air_density, dust_density, ozone_density);
+ sun_elevation, clamped_altitude, air_density, dust_density, ozone_density);
handle = image_manager->add_image(loader, impar);
}
}
@@ -892,7 +905,10 @@ void SkyTextureNode::compile(SVMCompiler &compiler)
__float_as_uint(sunsky.nishita_data[5]),
__float_as_uint(sunsky.nishita_data[6]),
__float_as_uint(sunsky.nishita_data[7]));
- compiler.add_node(__float_as_uint(sunsky.nishita_data[8]), handle.svm_slot(), 0, 0);
+ compiler.add_node(__float_as_uint(sunsky.nishita_data[8]),
+ __float_as_uint(sunsky.nishita_data[9]),
+ handle.svm_slot(),
+ 0);
}
tex_mapping.compile_end(compiler, vector_in, vector_offset);
@@ -908,12 +924,17 @@ void SkyTextureNode::compile(OSLCompiler &compiler)
else if (type == NODE_SKY_HOSEK)
sky_texture_precompute_hosek(&sunsky, sun_direction, turbidity, ground_albedo);
else if (type == NODE_SKY_NISHITA) {
+ /* Clamp altitude to reasonable values.
+ * Below 1m causes numerical issues and above 60km is space. */
+ float clamped_altitude = clamp(altitude, 1.0f, 59999.0f);
+
sky_texture_precompute_nishita(&sunsky,
sun_disc,
sun_size,
+ sun_intensity,
sun_elevation,
sun_rotation,
- altitude,
+ clamped_altitude,
air_density,
dust_density);
/* precomputed texture image parameters */
@@ -925,7 +946,7 @@ void SkyTextureNode::compile(OSLCompiler &compiler)
/* precompute sky texture */
if (handle.empty()) {
SkyLoader *loader = new SkyLoader(
- sun_elevation, altitude, air_density, dust_density, ozone_density);
+ sun_elevation, clamped_altitude, air_density, dust_density, ozone_density);
handle = image_manager->add_image(loader, impar);
}
}
@@ -940,7 +961,7 @@ void SkyTextureNode::compile(OSLCompiler &compiler)
compiler.parameter_array("config_x", sunsky.config_x, 9);
compiler.parameter_array("config_y", sunsky.config_y, 9);
compiler.parameter_array("config_z", sunsky.config_z, 9);
- compiler.parameter_array("nishita_data", sunsky.nishita_data, 9);
+ compiler.parameter_array("nishita_data", sunsky.nishita_data, 10);
/* nishita texture */
if (type == NODE_SKY_NISHITA) {
compiler.parameter_texture("filename", handle.svm_slot());
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 846ba7423e5..326f1d14168 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -170,9 +170,10 @@ class SkyTextureNode : public TextureNode {
float ground_albedo;
bool sun_disc;
float sun_size;
+ float sun_intensity;
float sun_elevation;
float sun_rotation;
- int altitude;
+ float altitude;
float air_density;
float dust_density;
float ozone_density;
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index c7737392e7b..92061f55128 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -362,8 +362,8 @@ extern GHOST_TSuccess GHOST_HasCursorShape(GHOST_WindowHandle windowhandle,
* \param mask The mask data for the cursor.
* \param sizex The width of the cursor
* \param sizey The height of the cursor
- * \param hotX The X coordinate of the cursor hotspot.
- * \param hotY The Y coordinate of the cursor hotspot.
+ * \param hotX The X coordinate of the cursor hot-spot.
+ * \param hotY The Y coordinate of the cursor hot-spot.
* \param canInvertColor Let macOS invert cursor color to match platform convention.
* \return Indication of success.
*/
diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h
index 62290d20f1c..9c72b6f07f9 100644
--- a/intern/ghost/GHOST_IWindow.h
+++ b/intern/ghost/GHOST_IWindow.h
@@ -287,8 +287,8 @@ class GHOST_IWindow {
* Set the shape of the cursor to a custom cursor.
* \param bitmap The bitmap data for the cursor.
* \param mask The mask data for the cursor.
- * \param hotX The X coordinate of the cursor hotspot.
- * \param hotY The Y coordinate of the cursor hotspot.
+ * \param hotX The X coordinate of the cursor hot-spot.
+ * \param hotY The Y coordinate of the cursor hot-spot.
* \return Indication of success.
*/
virtual GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 *bitmap,
diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h
index 6738aa850ce..7cfea5110c5 100644
--- a/intern/ghost/intern/GHOST_Window.h
+++ b/intern/ghost/intern/GHOST_Window.h
@@ -124,8 +124,8 @@ class GHOST_Window : public GHOST_IWindow {
* Set the shape of the cursor to a custom cursor.
* \param bitmap The bitmap data for the cursor.
* \param mask The mask data for the cursor.
- * \param hotX The X coordinate of the cursor hotspot.
- * \param hotY The Y coordinate of the cursor hotspot.
+ * \param hotX The X coordinate of the cursor hot-spot.
+ * \param hotY The Y coordinate of the cursor hot-spot.
* \return Indication of success.
*/
GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 *bitmap,
diff --git a/intern/mantaflow/intern/MANTA_main.cpp b/intern/mantaflow/intern/MANTA_main.cpp
index 43121f08f2d..676a2fd785e 100644
--- a/intern/mantaflow/intern/MANTA_main.cpp
+++ b/intern/mantaflow/intern/MANTA_main.cpp
@@ -870,9 +870,9 @@ void MANTA::initializeRNAMap(FluidModifierData *fmd)
mRNAMap["GUIDING_ALPHA"] = to_string(fds->guide_alpha);
mRNAMap["GUIDING_BETA"] = to_string(fds->guide_beta);
mRNAMap["GUIDING_FACTOR"] = to_string(fds->guide_vel_factor);
- mRNAMap["GRAVITY_X"] = to_string(fds->gravity[0]);
- mRNAMap["GRAVITY_Y"] = to_string(fds->gravity[1]);
- mRNAMap["GRAVITY_Z"] = to_string(fds->gravity[2]);
+ mRNAMap["GRAVITY_X"] = to_string(fds->gravity_final[0]);
+ mRNAMap["GRAVITY_Y"] = to_string(fds->gravity_final[1]);
+ mRNAMap["GRAVITY_Z"] = to_string(fds->gravity_final[2]);
mRNAMap["CACHE_DIR"] = cacheDirectory;
mRNAMap["COMPRESSION_OPENVDB"] = vdbCompressionMethod;
mRNAMap["PRECISION_OPENVDB"] = vdbPrecisionHalf;
@@ -1256,6 +1256,7 @@ bool MANTA::readData(FluidModifierData *fmd, int framenr, bool resumable)
<< ", '" << volume_format << "', " << resumable_cache << ")";
pythonCommands.push_back(ss.str());
result &= runPythonString(pythonCommands);
+ return (mSmokeFromFile = result);
}
if (mUsingLiquid) {
ss.str("");
@@ -1263,6 +1264,7 @@ bool MANTA::readData(FluidModifierData *fmd, int framenr, bool resumable)
<< ", '" << volume_format << "', " << resumable_cache << ")";
pythonCommands.push_back(ss.str());
result &= runPythonString(pythonCommands);
+ return (mFlipFromFile = result);
}
return result;
}
@@ -1296,7 +1298,7 @@ bool MANTA::readNoise(FluidModifierData *fmd, int framenr, bool resumable)
<< ", '" << volume_format << "', " << resumable_cache << ")";
pythonCommands.push_back(ss.str());
- return runPythonString(pythonCommands);
+ return (mNoiseFromFile = runPythonString(pythonCommands));
}
bool MANTA::readMesh(FluidModifierData *fmd, int framenr)
@@ -1331,7 +1333,7 @@ bool MANTA::readMesh(FluidModifierData *fmd, int framenr)
pythonCommands.push_back(ss.str());
}
- return runPythonString(pythonCommands);
+ return (mMeshFromFile = runPythonString(pythonCommands));
}
bool MANTA::readParticles(FluidModifierData *fmd, int framenr, bool resumable)
@@ -1365,7 +1367,7 @@ bool MANTA::readParticles(FluidModifierData *fmd, int framenr, bool resumable)
<< framenr << ", '" << volume_format << "', " << resumable_cache << ")";
pythonCommands.push_back(ss.str());
- return runPythonString(pythonCommands);
+ return (mParticlesFromFile = runPythonString(pythonCommands));
}
bool MANTA::readGuiding(FluidModifierData *fmd, int framenr, bool sourceDomain)
diff --git a/intern/mantaflow/intern/strings/fluid_script.h b/intern/mantaflow/intern/strings/fluid_script.h
index 977b99e7759..4ee3ae59957 100644
--- a/intern/mantaflow/intern/strings/fluid_script.h
+++ b/intern/mantaflow/intern/strings/fluid_script.h
@@ -146,19 +146,19 @@ mantaMsg('1 Mantaflow cell is ' + str(ratioMetersToRes_s$ID$) + ' Blender length
ratioResToBLength_s$ID$ = float(res_s$ID$) / float(domainSize_s$ID$) # [cells / blength] (blength: cm, m, or km, ... )\n\
mantaMsg('1 Blender length unit is ' + str(ratioResToBLength_s$ID$) + ' Mantaflow cells long.')\n\
\n\
-ratioBTimeToTimstep_s$ID$ = float(1) / float(frameLengthRaw_s$ID$) # the time within 1 blender time unit, see also fluid.c\n\
-mantaMsg('1 Blender time unit is ' + str(ratioBTimeToTimstep_s$ID$) + ' Mantaflow time units long.')\n\
+ratioBTimeToTimestep_s$ID$ = float(1) / float(frameLengthRaw_s$ID$) # the time within 1 blender time unit, see also fluid.c\n\
+mantaMsg('1 Blender time unit is ' + str(ratioBTimeToTimestep_s$ID$) + ' Mantaflow time units long.')\n\
\n\
ratioFrameToFramelength_s$ID$ = float(1) / float(frameLengthUnscaled_s$ID$ ) # the time within 1 frame\n\
mantaMsg('frame / frameLength is ' + str(ratioFrameToFramelength_s$ID$) + ' Mantaflow time units long.')\n\
\n\
-scaleAcceleration_s$ID$ = ratioResToBLength_s$ID$ * (ratioBTimeToTimstep_s$ID$**2)# [meters/btime^2] to [cells/timestep^2] (btime: sec, min, or h, ...)\n\
+scaleAcceleration_s$ID$ = ratioResToBLength_s$ID$ * (ratioBTimeToTimestep_s$ID$**2)# [meters/btime^2] to [cells/timestep^2] (btime: sec, min, or h, ...)\n\
mantaMsg('scaleAcceleration is ' + str(scaleAcceleration_s$ID$))\n\
\n\
scaleSpeedFrames_s$ID$ = ratioResToBLength_s$ID$ * ratioFrameToFramelength_s$ID$ # [blength/frame] to [cells/frameLength]\n\
mantaMsg('scaleSpeed is ' + str(scaleSpeedFrames_s$ID$))\n\
\n\
-scaleSpeedTime_s$ID$ = ratioResToBLength_s$ID$ * ratioBTimeToTimstep_s$ID$ # [blength/btime] to [cells/frameLength]\n\
+scaleSpeedTime_s$ID$ = ratioResToBLength_s$ID$ * ratioBTimeToTimestep_s$ID$ # [blength/btime] to [cells/frameLength]\n\
mantaMsg('scaleSpeedTime is ' + str(scaleSpeedTime_s$ID$))\n\
\n\
gravity_s$ID$ *= scaleAcceleration_s$ID$ # scale from world acceleration to cell based acceleration\n\
diff --git a/intern/sky/include/sky_model.h b/intern/sky/include/sky_model.h
index 9e7700f3042..021086e1e02 100644
--- a/intern/sky/include/sky_model.h
+++ b/intern/sky/include/sky_model.h
@@ -356,8 +356,8 @@ typedef struct SKY_ArHosekSkyModelState {
---------------------------------------------------------------------------- */
SKY_ArHosekSkyModelState *SKY_arhosekskymodelstate_alloc_init(const double solar_elevation,
- const double atmospheric_turbidity,
- const double ground_albedo);
+ const double atmospheric_turbidity,
+ const double ground_albedo);
/* ----------------------------------------------------------------------------
@@ -398,56 +398,55 @@ SKY_ArHosekSkyModelState *SKY_arhosekskymodelstate_alienworld_alloc_init(
void SKY_arhosekskymodelstate_free(SKY_ArHosekSkyModelState *state);
double SKY_arhosekskymodel_radiance(SKY_ArHosekSkyModelState *state,
- double theta,
- double gamma,
- double wavelength);
+ double theta,
+ double gamma,
+ double wavelength);
// CIE XYZ and RGB versions
SKY_ArHosekSkyModelState *SKY_arhosek_xyz_skymodelstate_alloc_init(const double turbidity,
- const double albedo,
- const double elevation);
+ const double albedo,
+ const double elevation);
SKY_ArHosekSkyModelState *SKY_arhosek_rgb_skymodelstate_alloc_init(const double turbidity,
- const double albedo,
- const double elevation);
+ const double albedo,
+ const double elevation);
double SKY_arhosek_tristim_skymodel_radiance(SKY_ArHosekSkyModelState *state,
- double theta,
- double gamma,
- int channel);
+ double theta,
+ double gamma,
+ int channel);
// Delivers the complete function: sky + sun, including limb darkening.
// Please read the above description before using this - there are several
// caveats!
double SKY_arhosekskymodel_solar_radiance(SKY_ArHosekSkyModelState *state,
- double theta,
- double gamma,
- double wavelength);
-
+ double theta,
+ double gamma,
+ double wavelength);
/* Nishita improved sky model */
void SKY_nishita_skymodel_precompute_texture(float *pixels,
- int stride,
- int start_y,
- int end_y,
- int width,
- int height,
- float sun_elevation,
+ int stride,
+ int start_y,
+ int end_y,
+ int width,
+ int height,
+ float sun_elevation,
+ float altitude,
+ float air_density,
+ float dust_density,
+ float ozone_density);
+
+void SKY_nishita_skymodel_precompute_sun(float sun_elevation,
+ float angular_diameter,
float altitude,
float air_density,
float dust_density,
- float ozone_density);
-
-void SKY_nishita_skymodel_precompute_sun(float sun_elevation,
- float angular_diameter,
- float altitude,
- float air_density,
- float dust_density,
- float *pixel_bottom,
- float *pixel_top);
+ float *r_pixel_bottom,
+ float *r_pixel_top);
#ifdef __cplusplus
}
diff --git a/intern/sky/source/sky_model.cpp b/intern/sky/source/sky_model.cpp
index 3eca68e076c..64cf14ec030 100644
--- a/intern/sky/source/sky_model.cpp
+++ b/intern/sky/source/sky_model.cpp
@@ -292,9 +292,9 @@ void SKY_arhosekskymodelstate_free(SKY_ArHosekSkyModelState *state)
}
double SKY_arhosekskymodel_radiance(SKY_ArHosekSkyModelState *state,
- double theta,
- double gamma,
- double wavelength)
+ double theta,
+ double gamma,
+ double wavelength)
{
int low_wl = (int)((wavelength - 320.0) / 40.0);
@@ -323,8 +323,8 @@ double SKY_arhosekskymodel_radiance(SKY_ArHosekSkyModelState *state,
// xyz and rgb versions
SKY_ArHosekSkyModelState *SKY_arhosek_xyz_skymodelstate_alloc_init(const double turbidity,
- const double albedo,
- const double elevation)
+ const double albedo,
+ const double elevation)
{
SKY_ArHosekSkyModelState *state = ALLOC(SKY_ArHosekSkyModelState);
diff --git a/intern/sky/source/sky_nishita.cpp b/intern/sky/source/sky_nishita.cpp
index 27286ddecac..eae95dc73fe 100644
--- a/intern/sky/source/sky_nishita.cpp
+++ b/intern/sky/source/sky_nishita.cpp
@@ -14,19 +14,23 @@
* limitations under the License.
*/
-#include "sky_model.h"
#include "sky_float3.h"
+#include "sky_model.h"
/* Constants */
static const float rayleigh_scale = 8000.0f; // Rayleigh scale height (m)
static const float mie_scale = 1200.0f; // Mie scale height (m)
static const float mie_coeff = 2e-5f; // Mie scattering coefficient
static const float mie_G = 0.76f; // aerosols anisotropy
+static const float sqr_G = mie_G * mie_G; // squared aerosols anisotropy
static const float earth_radius = 6360000.0f; // radius of Earth (m)
static const float atmosphere_radius = 6420000.0f; // radius of atmosphere (m)
static const int steps = 32; // segments per primary ray
static const int steps_light = 16; // segments per sun connection ray
static const int num_wavelengths = 21; // number of wavelengths
+static const int max_luminous_efficacy = 683; // maximum luminous efficacy
+static const float step_lambda = (num_wavelengths - 1) *
+ 1e-9f; // step between each sampled wavelength
/* irradiance at top of atmosphere */
static const float irradiance[] = {
1.45756829855592995315f, 1.56596305559738380175f, 1.65148449067670455293f,
@@ -90,7 +94,7 @@ static float3 spec_to_xyz(float *spectrum)
xyz.y += cmf_xyz[i][1] * spectrum[i];
xyz.z += cmf_xyz[i][2] * spectrum[i];
}
- return xyz * (20 * 683 * 1e-9f);
+ return xyz * step_lambda * max_luminous_efficacy;
}
/* Atmosphere volume models */
@@ -122,8 +126,6 @@ static float phase_rayleigh(float mu)
static float phase_mie(float mu)
{
- static const float sqr_G = mie_G * mie_G;
-
return (3.0f * (1.0f - sqr_G) * (1.0f + sqr(mu))) /
(8.0f * M_PI_F * (2.0f + sqr_G) * powf((1.0f + sqr_G - 2.0f * mie_G * mu), 1.5));
}
@@ -167,6 +169,7 @@ static float3 ray_optical_depth(float3 ray_origin, float3 ray_dir)
/* The density of each segment is evaluated at its middle. */
float3 P = ray_origin + 0.5f * segment;
+
for (int i = 0; i < steps_light; i++) {
/* Compute height above sea level. */
float height = len(P) - earth_radius;
@@ -174,13 +177,13 @@ static float3 ray_optical_depth(float3 ray_origin, float3 ray_dir)
/* Accumulate optical depth of this segment (density is assumed to be constant along it). */
float3 density = make_float3(
density_rayleigh(height), density_mie(height), density_ozone(height));
- optical_depth += segment_length * density;
+ optical_depth += density;
/* Advance along ray. */
P += segment;
}
- return optical_depth;
+ return optical_depth * segment_length;
}
/* Single Scattering implementation */
@@ -219,6 +222,7 @@ static void single_scattering(float3 ray_dir,
/* The density and in-scattering of each segment is evaluated at its middle. */
float3 P = ray_origin + 0.5f * segment;
+
for (int i = 0; i < steps; i++) {
/* Compute height above sea level. */
float height = len(P) - earth_radius;
@@ -268,16 +272,16 @@ static void single_scattering(float3 ray_dir,
/* calculate texture array */
void SKY_nishita_skymodel_precompute_texture(float *pixels,
- int stride,
- int start_y,
- int end_y,
- int width,
- int height,
- float sun_elevation,
- float altitude,
- float air_density,
- float dust_density,
- float ozone_density)
+ int stride,
+ int start_y,
+ int end_y,
+ int width,
+ int height,
+ float sun_elevation,
+ float altitude,
+ float air_density,
+ float dust_density,
+ float ozone_density)
{
/* calculate texture pixels */
float spectrum[num_wavelengths];
@@ -287,11 +291,13 @@ void SKY_nishita_skymodel_precompute_texture(float *pixels,
float latitude_step = M_PI_2_F / height;
float longitude_step = M_2PI_F / width;
+ float half_lat_step = latitude_step / 2.0f;
for (int y = start_y; y < end_y; y++) {
- float latitude = latitude_step * y;
+ /* sample more pixels toward the horizon */
+ float latitude = (M_PI_2_F + half_lat_step) * sqr((float)y / height);
- float *pixel_row = pixels + (y * width) * stride;
+ float *pixel_row = pixels + (y * width * stride);
for (int x = 0; x < half_width; x++) {
float longitude = longitude_step * x - M_PI_F;
@@ -299,13 +305,15 @@ void SKY_nishita_skymodel_precompute_texture(float *pixels,
single_scattering(dir, sun_dir, cam_pos, air_density, dust_density, ozone_density, spectrum);
float3 xyz = spec_to_xyz(spectrum);
- pixel_row[x * stride + 0] = xyz.x;
- pixel_row[x * stride + 1] = xyz.y;
- pixel_row[x * stride + 2] = xyz.z;
- int mirror_x = width - x - 1;
- pixel_row[mirror_x * stride + 0] = xyz.x;
- pixel_row[mirror_x * stride + 1] = xyz.y;
- pixel_row[mirror_x * stride + 2] = xyz.z;
+ int pos_x = x * stride;
+ pixel_row[pos_x] = xyz.x;
+ pixel_row[pos_x + 1] = xyz.y;
+ pixel_row[pos_x + 2] = xyz.z;
+ /* mirror sky */
+ int mirror_x = (width - x - 1) * stride;
+ pixel_row[mirror_x] = xyz.x;
+ pixel_row[mirror_x + 1] = xyz.y;
+ pixel_row[mirror_x + 2] = xyz.z;
}
}
}
@@ -326,17 +334,17 @@ static void sun_radiation(float3 cam_dir,
/* Combine spectra and the optical depth into transmittance. */
float transmittance = rayleigh_coeff[i] * optical_depth.x * air_density +
1.11f * mie_coeff * optical_depth.y * dust_density;
- r_spectrum[i] = (irradiance[i] / solid_angle) * expf(-transmittance);
+ r_spectrum[i] = irradiance[i] * expf(-transmittance) / solid_angle;
}
}
void SKY_nishita_skymodel_precompute_sun(float sun_elevation,
- float angular_diameter,
- float altitude,
- float air_density,
- float dust_density,
- float *pixel_bottom,
- float *pixel_top)
+ float angular_diameter,
+ float altitude,
+ float air_density,
+ float dust_density,
+ float *r_pixel_bottom,
+ float *r_pixel_top)
{
/* definitions */
float half_angular = angular_diameter / 2.0f;
@@ -358,10 +366,10 @@ void SKY_nishita_skymodel_precompute_sun(float sun_elevation,
pix_top = spec_to_xyz(spectrum);
/* store pixels */
- pixel_bottom[0] = pix_bottom.x;
- pixel_bottom[1] = pix_bottom.y;
- pixel_bottom[2] = pix_bottom.z;
- pixel_top[0] = pix_top.x;
- pixel_top[1] = pix_top.y;
- pixel_top[2] = pix_top.z;
+ r_pixel_bottom[0] = pix_bottom.x;
+ r_pixel_bottom[1] = pix_bottom.y;
+ r_pixel_bottom[2] = pix_bottom.z;
+ r_pixel_top[0] = pix_top.x;
+ r_pixel_top[1] = pix_top.y;
+ r_pixel_top[2] = pix_top.z;
}