mirror of
https://github.com/blender/blender
synced 2026-09-29 04:37:17 +03:00
We are running out of bits. Split the original `ShaderDataFlag` into `ShaderRuntimeFlag`, which is determined by closures in the shader and set up during rendering, and `ShaderDataFlag`, which is the same for the whole shader graph and hence determined during shader compilation The size of `ShaderData` did not change due to padding Pull Request: https://projects.blender.org/blender/blender/pulls/161856
119 lines
4 KiB
C
119 lines
4 KiB
C
/* SPDX-FileCopyrightText: 2011-2026 Blender Foundation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0 */
|
|
|
|
#pragma once
|
|
|
|
#include "kernel/integrator/mnee.h"
|
|
#include "kernel/integrator/shade_surface.h"
|
|
|
|
CCL_NAMESPACE_BEGIN
|
|
|
|
#ifdef __MNEE__
|
|
|
|
/* Sample a light and run the MNEE manifold walk for a caustic receiver. On a successful walk
|
|
* the result is written to a shadow slot for integrator_shade_surface, otherwise nothing is
|
|
* written and direct light is sampled there. */
|
|
ccl_device_forceinline ShaderEvalResult
|
|
integrate_surface_mnee(KernelGlobals kg,
|
|
IntegratorState state,
|
|
ccl_private ShaderData *sd,
|
|
const ccl_private RNGState *rng_state)
|
|
{
|
|
/* Kernel must only be scheduled for caustic receivers. */
|
|
kernel_assert(sd->object_flag & SD_OBJECT_CAUSTICS_RECEIVER);
|
|
|
|
if (!kernel_data.integrator.use_direct_light) {
|
|
return SHADER_EVAL_OK;
|
|
}
|
|
|
|
/* Sample position on a light. */
|
|
LightSample ls ccl_optional_struct_init;
|
|
{
|
|
const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
|
|
const uint bounce = INTEGRATOR_STATE(state, path, bounce);
|
|
const float3 rand_light = path_state_rng_3D(kg, rng_state, PRNG_LIGHT);
|
|
|
|
if (!light_sample_from_position(kg,
|
|
rand_light,
|
|
sd->time,
|
|
sd->P,
|
|
sd->N,
|
|
light_link_receiver_nee(kg, sd),
|
|
sd->runtime_flag,
|
|
bounce,
|
|
path_flag,
|
|
&ls))
|
|
{
|
|
return SHADER_EVAL_OK;
|
|
}
|
|
}
|
|
|
|
kernel_assert(ls.pdf != 0.0f);
|
|
|
|
/* The manifold walk connects a caustic light to the receiver across reflection; transmission
|
|
* caustics and triangle lights are not handled. */
|
|
if (ls.type == LIGHT_TRIANGLE || dot(ls.D, sd->N) < 0.0f) {
|
|
return SHADER_EVAL_OK;
|
|
}
|
|
|
|
if (!kernel_data_fetch(lights, ls.prim).use_caustics) {
|
|
return SHADER_EVAL_OK;
|
|
}
|
|
|
|
ShaderDataCausticsStorage emission_sd_storage;
|
|
ccl_private ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage);
|
|
|
|
Spectrum mnee_throughput = zero_spectrum();
|
|
float3 mnee_wo = zero_float3();
|
|
int mnee_vertex_count = 0;
|
|
const ShaderEvalResult result = kernel_path_mnee_sample(
|
|
kg, state, sd, emission_sd, rng_state, &ls, &mnee_throughput, &mnee_wo, mnee_vertex_count);
|
|
if (result == SHADER_EVAL_CACHE_MISS) {
|
|
return SHADER_EVAL_CACHE_MISS;
|
|
}
|
|
|
|
/* Store MNEE state in a shadow state, to avoid increasing path state size.
|
|
* This is then turned into an actual shadow ray state in shade_surface, or discarded. */
|
|
if (mnee_vertex_count > 0) {
|
|
Ray ray ccl_optional_struct_init;
|
|
light_sample_to_surface_shadow_ray(kg, emission_sd, &ls, &ray);
|
|
|
|
IntegratorShadowState shadow_state = integrator_shadow_path_init(
|
|
kg, state, DEVICE_KERNEL_INTEGRATOR_SHADOW_PATH_MNEE_PENDING, false);
|
|
integrator_state_write_mnee(
|
|
state, shadow_state, &ls, &ray, mnee_vertex_count, mnee_throughput, mnee_wo);
|
|
}
|
|
|
|
return SHADER_EVAL_OK;
|
|
}
|
|
|
|
#endif /* __MNEE__ */
|
|
|
|
ccl_device void integrator_intersect_mnee(KernelGlobals kg, IntegratorState state)
|
|
{
|
|
PROFILING_INIT(kg, PROFILING_SHADE_SURFACE_DIRECT_LIGHT);
|
|
|
|
ShaderData sd;
|
|
integrate_surface_shader_setup(kg, state, &sd);
|
|
const int shader = sd.shader & SHADER_MASK;
|
|
|
|
#ifdef __MNEE__
|
|
RNGState rng_state;
|
|
path_state_rng_load(state, &rng_state);
|
|
|
|
const ShaderEvalResult result = integrate_surface_mnee(kg, state, &sd, &rng_state);
|
|
if (result == SHADER_EVAL_CACHE_MISS) {
|
|
integrator_path_cache_miss(state, DEVICE_KERNEL_INTEGRATOR_INTERSECT_MNEE);
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
integrator_path_next_sorted(kg,
|
|
state,
|
|
DEVICE_KERNEL_INTEGRATOR_INTERSECT_MNEE,
|
|
DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE,
|
|
shader);
|
|
}
|
|
|
|
CCL_NAMESPACE_END
|