mirror of
https://github.com/blender/blender
synced 2026-09-29 04:37:17 +03:00
EEVEE: Add support for Transparent BSDF through Shader To RGB
This PR adds to possibility to get the radiance behind an object using the Shader To RGB workflow. The result of this operation depends on the type of material. - Dithered Material with Raytraced Transmission **off** will sample the nearest probe. - Dithered Material with Raytraced Transmission **on** will show Dithered Materials with transmission **off** or fallback to nearest probe. - Blended Material will show all Dithered Material materials or fallback to nearest probe. This covers some workflows that were possible before 4.2 (which were relying on the refraction BSDF). This removes the `use_combined_lightprobe_eval` optimization which was defaulting all Dithered Material to be in the same layer when raytracing was off. We cannot do that anymore since this transparency feature requires clear separation between the two material types (Raytraced Transmission on/off). We could eventually reintroduce it by changing the way the submission is done when there is no shader to rgb in the scene. Pull Request: https://projects.blender.org/blender/blender/pulls/149723
This commit is contained in:
parent
fa2e224625
commit
dd12ff0af5
20 changed files with 172 additions and 21 deletions
|
|
@ -235,9 +235,11 @@
|
|||
#define SPHERE_PROBE_TEX_SLOT 7
|
||||
#define VOLUME_SCATTERING_TEX_SLOT 8
|
||||
#define VOLUME_TRANSMITTANCE_TEX_SLOT 9
|
||||
#define HIZ_PREVIOUS_LAYER_TEX_SLOT 10
|
||||
#define RADIANCE_PREVIOUS_LAYER_TEX_SLOT 11
|
||||
/* Currently only used by ray-tracing, but might become used by forward too. */
|
||||
#define PLANAR_PROBE_DEPTH_TEX_SLOT 10
|
||||
#define PLANAR_PROBE_RADIANCE_TEX_SLOT 11
|
||||
#define PLANAR_PROBE_DEPTH_TEX_SLOT 12
|
||||
#define PLANAR_PROBE_RADIANCE_TEX_SLOT 13
|
||||
|
||||
/* Images. */
|
||||
#define RBUFS_COLOR_SLOT 0
|
||||
|
|
|
|||
|
|
@ -92,6 +92,9 @@ void HiZBuffer::update()
|
|||
return;
|
||||
}
|
||||
|
||||
/* After this, the front buffer become valid. */
|
||||
front.ref_tx_ = hiz_tx_.current();
|
||||
|
||||
src_tx_ = *src_tx_ptr_;
|
||||
for (const int i : IndexRange(HIZ_MIP_COUNT)) {
|
||||
hiz_mip_ref_[i] = hiz_tx_.current().mip_view(i);
|
||||
|
|
|
|||
|
|
@ -14,10 +14,16 @@
|
|||
|
||||
#include "DRW_render.hh"
|
||||
|
||||
#include "DRW_gpu_wrapper.hh"
|
||||
|
||||
#include "draw_pass.hh"
|
||||
#include "eevee_defines.hh"
|
||||
#include "eevee_hizbuffer_shared.hh"
|
||||
|
||||
namespace blender::eevee {
|
||||
|
||||
using namespace draw;
|
||||
|
||||
class Instance;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
@ -33,6 +39,9 @@ class HiZBuffer {
|
|||
/** References to the mip views of the current (front) HiZ texture. */
|
||||
std::array<gpu::Texture *, HIZ_MIP_COUNT> hiz_mip_ref_;
|
||||
|
||||
/** Dummy texture cleared to max depth to be used before the first hiz update. */
|
||||
draw::Texture dummy_empty_hiz_tx_ = {"dummy_empty_hiz_tx_"};
|
||||
|
||||
/**
|
||||
* Atomic counter counting the number of tile that have finished down-sampling.
|
||||
* The last one will process the last few mip level.
|
||||
|
|
@ -57,6 +66,9 @@ class HiZBuffer {
|
|||
HiZBuffer(Instance &inst, HiZData &data) : inst_(inst), data_(data)
|
||||
{
|
||||
atomic_tile_counter_.clear_to_zero();
|
||||
float value = 1.0f;
|
||||
dummy_empty_hiz_tx_.ensure_2d(
|
||||
gpu::TextureFormat::SFLOAT_32, int2(1), GPU_TEXTURE_USAGE_SHADER_READ, &value);
|
||||
};
|
||||
|
||||
void sync();
|
||||
|
|
@ -71,6 +83,9 @@ class HiZBuffer {
|
|||
src_tx_ptr_ = texture;
|
||||
layer_id_ = layer;
|
||||
swap_layer();
|
||||
/* Both layer becomes undefined. Replace by dummy texture. */
|
||||
back.ref_tx_ = dummy_empty_hiz_tx_;
|
||||
front.ref_tx_ = dummy_empty_hiz_tx_;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -82,7 +97,7 @@ class HiZBuffer {
|
|||
void swap_layer()
|
||||
{
|
||||
hiz_tx_.swap();
|
||||
back.ref_tx_ = hiz_tx_.previous();
|
||||
back.ref_tx_ = front.ref_tx_;
|
||||
front.ref_tx_ = hiz_tx_.current();
|
||||
set_dirty();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -320,6 +320,7 @@ void ForwardPipeline::sync()
|
|||
{
|
||||
/* Common resources. */
|
||||
opaque_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
|
||||
opaque_ps_.bind_texture(RADIANCE_PREVIOUS_LAYER_TEX_SLOT, &inst_.render_buffers.combined_tx);
|
||||
opaque_ps_.bind_resources(inst_.uniform_data);
|
||||
opaque_ps_.bind_resources(inst_.lights);
|
||||
opaque_ps_.bind_resources(inst_.shadows);
|
||||
|
|
@ -348,6 +349,7 @@ void ForwardPipeline::sync()
|
|||
|
||||
/* Textures. */
|
||||
sub.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
|
||||
sub.bind_texture(RADIANCE_PREVIOUS_LAYER_TEX_SLOT, &inst_.render_buffers.combined_tx);
|
||||
|
||||
sub.bind_resources(inst_.uniform_data);
|
||||
sub.bind_resources(inst_.lights);
|
||||
|
|
@ -429,6 +431,13 @@ PassMain::Sub *ForwardPipeline::prepass_transparent_add(const Object *ob,
|
|||
PassMain::Sub *pass = &transparent_ps_.sub(GPU_material_get_name(gpumat), sorting_value);
|
||||
pass->state_set(state);
|
||||
pass->material_set(*inst_.manager, gpumat, true);
|
||||
|
||||
if (GPU_material_flag_get(gpumat, GPU_MATFLAG_SHADER_TO_RGBA) &&
|
||||
GPU_material_flag_get(gpumat, GPU_MATFLAG_TRANSPARENT))
|
||||
{
|
||||
pass->bind_texture(HIZ_PREVIOUS_LAYER_TEX_SLOT, &inst_.hiz_buffer.back.ref_tx_);
|
||||
pass->bind_texture(RADIANCE_PREVIOUS_LAYER_TEX_SLOT, &inst_.render_buffers.combined_tx);
|
||||
}
|
||||
return pass;
|
||||
}
|
||||
|
||||
|
|
@ -449,6 +458,13 @@ PassMain::Sub *ForwardPipeline::material_transparent_add(const Object *ob,
|
|||
PassMain::Sub *pass = &transparent_ps_.sub(GPU_material_get_name(gpumat), sorting_value);
|
||||
pass->state_set(state);
|
||||
pass->material_set(*inst_.manager, gpumat, true);
|
||||
|
||||
if (GPU_material_flag_get(gpumat, GPU_MATFLAG_SHADER_TO_RGBA) &&
|
||||
GPU_material_flag_get(gpumat, GPU_MATFLAG_TRANSPARENT))
|
||||
{
|
||||
pass->bind_texture(HIZ_PREVIOUS_LAYER_TEX_SLOT, &inst_.hiz_buffer.back.ref_tx_);
|
||||
pass->bind_texture(RADIANCE_PREVIOUS_LAYER_TEX_SLOT, &inst_.render_buffers.combined_tx);
|
||||
}
|
||||
return pass;
|
||||
}
|
||||
|
||||
|
|
@ -496,12 +512,15 @@ void ForwardPipeline::render(View &view,
|
|||
return;
|
||||
}
|
||||
|
||||
inst_.hiz_buffer.swap_layer();
|
||||
|
||||
GPU_debug_group_begin("Forward.Opaque");
|
||||
|
||||
prepass_fb.bind();
|
||||
inst_.manager->submit(prepass_ps_, view);
|
||||
|
||||
inst_.hiz_buffer.set_dirty();
|
||||
inst_.hiz_buffer.update();
|
||||
|
||||
inst_.shadows.set_view(view, extent);
|
||||
inst_.volume_probes.set_view(view);
|
||||
|
|
@ -576,32 +595,44 @@ void DeferredLayerBase::gbuffer_pass_sync(Instance &inst)
|
|||
gbuffer_ps_.bind_resources(inst.uniform_data);
|
||||
gbuffer_ps_.bind_resources(inst.sampling);
|
||||
gbuffer_ps_.bind_resources(inst.hiz_buffer.front);
|
||||
gbuffer_ps_.bind_resources(inst.hiz_buffer.front);
|
||||
gbuffer_ps_.bind_resources(inst.cryptomatte);
|
||||
|
||||
gbuffer_ps_.bind_texture(HIZ_PREVIOUS_LAYER_TEX_SLOT, &inst.hiz_buffer.back.ref_tx_);
|
||||
gbuffer_ps_.bind_texture(RADIANCE_PREVIOUS_LAYER_TEX_SLOT, &radiance_behind_tx_);
|
||||
|
||||
/* Bind light resources for the NPR materials that gets rendered first.
|
||||
* Non-NPR shaders will override these resource bindings. */
|
||||
gbuffer_ps_.bind_resources(inst.lights);
|
||||
gbuffer_ps_.bind_resources(inst.shadows);
|
||||
gbuffer_ps_.bind_resources(inst.sphere_probes);
|
||||
gbuffer_ps_.bind_resources(inst.volume_probes);
|
||||
gbuffer_ps_.bind_texture(RADIANCE_PREVIOUS_LAYER_TEX_SLOT, &radiance_behind_tx_);
|
||||
|
||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_WRITE_STENCIL |
|
||||
DRW_STATE_CLIP_CONTROL_UNIT_RANGE | DRW_STATE_STENCIL_ALWAYS;
|
||||
|
||||
gbuffer_single_sided_hybrid_ps_ = &gbuffer_ps_.sub("DoubleSided");
|
||||
gbuffer_single_sided_hybrid_ps_->bind_texture(RADIANCE_PREVIOUS_LAYER_TEX_SLOT,
|
||||
&radiance_behind_tx_);
|
||||
gbuffer_single_sided_hybrid_ps_->state_set(state | DRW_STATE_CULL_BACK);
|
||||
|
||||
gbuffer_double_sided_hybrid_ps_ = &gbuffer_ps_.sub("SingleSided");
|
||||
gbuffer_double_sided_hybrid_ps_->bind_texture(RADIANCE_PREVIOUS_LAYER_TEX_SLOT,
|
||||
&radiance_behind_tx_);
|
||||
gbuffer_double_sided_hybrid_ps_->state_set(state);
|
||||
|
||||
gbuffer_double_sided_ps_ = &gbuffer_ps_.sub("DoubleSided");
|
||||
gbuffer_double_sided_ps_->bind_texture(RADIANCE_PREVIOUS_LAYER_TEX_SLOT, &radiance_behind_tx_);
|
||||
gbuffer_double_sided_ps_->state_set(state);
|
||||
|
||||
gbuffer_single_sided_ps_ = &gbuffer_ps_.sub("SingleSided");
|
||||
gbuffer_single_sided_ps_->bind_texture(RADIANCE_PREVIOUS_LAYER_TEX_SLOT, &radiance_behind_tx_);
|
||||
gbuffer_single_sided_ps_->state_set(state | DRW_STATE_CULL_BACK);
|
||||
|
||||
closure_bits_ = CLOSURE_NONE;
|
||||
closure_count_ = 0;
|
||||
radiance_behind_tx_ = nullptr;
|
||||
}
|
||||
|
||||
void DeferredLayer::begin_sync()
|
||||
|
|
@ -666,6 +697,8 @@ void DeferredLayer::end_sync(bool is_first_pass,
|
|||
const bool is_layer_refracted = (next_layer_has_transmission && has_any_closure);
|
||||
const bool has_transmit_closure = (closure_bits_ & (CLOSURE_REFRACTION | CLOSURE_TRANSLUCENT));
|
||||
const bool has_reflect_closure = (closure_bits_ & (CLOSURE_REFLECTION | CLOSURE_DIFFUSE));
|
||||
const bool has_transparent_shader_to_rgba = (closure_bits_ & CLOSURE_TRANSPARENCY) &&
|
||||
(closure_bits_ & CLOSURE_SHADER_TO_RGBA);
|
||||
use_raytracing_ = (has_transmit_closure || has_reflect_closure) &&
|
||||
inst_.raytracing.use_raytracing();
|
||||
use_clamp_direct_ = inst_.sampling.use_clamp_direct();
|
||||
|
|
@ -675,7 +708,9 @@ void DeferredLayer::end_sync(bool is_first_pass,
|
|||
|
||||
/* The first pass will never have any surfaces behind it. Nothing is refracted except the
|
||||
* environment. So in this case, disable tracing and fallback to probe. */
|
||||
use_screen_transmission_ = use_raytracing_ && has_transmit_closure && !is_first_pass;
|
||||
use_screen_transmission_ = use_raytracing_ &&
|
||||
(has_transmit_closure || has_transparent_shader_to_rgba) &&
|
||||
!is_first_pass;
|
||||
use_screen_reflection_ = use_raytracing_ && has_reflect_closure;
|
||||
|
||||
use_feedback_output_ = (use_raytracing_ || is_layer_refracted) &&
|
||||
|
|
@ -925,9 +960,11 @@ gpu::Texture *DeferredLayer::render(View &main_view,
|
|||
gpu::Texture *radiance_behind_tx)
|
||||
{
|
||||
if (closure_count_ == 0) {
|
||||
return nullptr;
|
||||
return radiance_behind_tx;
|
||||
}
|
||||
|
||||
radiance_behind_tx_ = radiance_behind_tx ? radiance_behind_tx : dummy_black;
|
||||
|
||||
RenderBuffers &rb = inst_.render_buffers;
|
||||
|
||||
constexpr eGPUTextureUsage usage_read = GPU_TEXTURE_USAGE_SHADER_READ;
|
||||
|
|
@ -1013,11 +1050,6 @@ gpu::Texture *DeferredLayer::render(View &main_view,
|
|||
|
||||
void DeferredPipeline::begin_sync()
|
||||
{
|
||||
Instance &inst = opaque_layer_.inst_;
|
||||
|
||||
const bool use_raytracing = (inst.scene->eevee.flag & SCE_EEVEE_SSR_ENABLED) != 0;
|
||||
use_combined_lightprobe_eval = !use_raytracing;
|
||||
|
||||
opaque_layer_.begin_sync();
|
||||
refraction_layer_.begin_sync();
|
||||
}
|
||||
|
|
@ -1083,7 +1115,7 @@ PassMain::Sub *DeferredPipeline::prepass_add(::Material *blender_mat,
|
|||
GPUMaterial *gpumat,
|
||||
bool has_motion)
|
||||
{
|
||||
if (!use_combined_lightprobe_eval && (blender_mat->blend_flag & MA_BL_SS_REFRACTION)) {
|
||||
if (blender_mat->blend_flag & MA_BL_SS_REFRACTION) {
|
||||
return refraction_layer_.prepass_add(blender_mat, gpumat, has_motion);
|
||||
}
|
||||
return opaque_layer_.prepass_add(blender_mat, gpumat, has_motion);
|
||||
|
|
@ -1091,7 +1123,7 @@ PassMain::Sub *DeferredPipeline::prepass_add(::Material *blender_mat,
|
|||
|
||||
PassMain::Sub *DeferredPipeline::material_add(::Material *blender_mat, GPUMaterial *gpumat)
|
||||
{
|
||||
if (!use_combined_lightprobe_eval && (blender_mat->blend_flag & MA_BL_SS_REFRACTION)) {
|
||||
if (blender_mat->blend_flag & MA_BL_SS_REFRACTION) {
|
||||
return refraction_layer_.material_add(blender_mat, gpumat);
|
||||
}
|
||||
return opaque_layer_.material_add(blender_mat, gpumat);
|
||||
|
|
@ -1445,6 +1477,8 @@ void DeferredProbePipeline::render(View &view,
|
|||
{
|
||||
GPU_debug_group_begin("Probe.Render");
|
||||
|
||||
opaque_layer_.radiance_behind_tx_ = dummy_black;
|
||||
|
||||
GPU_framebuffer_bind(prepass_fb);
|
||||
inst_.manager->submit(opaque_layer_.prepass_ps_, view);
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "DRW_render.hh"
|
||||
|
||||
#include "eevee_defines.hh"
|
||||
#include "eevee_lut.hh"
|
||||
#include "eevee_material.hh"
|
||||
#include "eevee_raytrace.hh"
|
||||
|
|
@ -181,7 +182,7 @@ class ForwardPipeline {
|
|||
} transp_buffer_;
|
||||
|
||||
public:
|
||||
ForwardPipeline(Instance &inst) : inst_(inst) {};
|
||||
ForwardPipeline(Instance &inst) : inst_(inst) {}
|
||||
|
||||
void sync();
|
||||
void end_sync();
|
||||
|
|
@ -227,6 +228,8 @@ struct DeferredLayerBase {
|
|||
PassMain::Sub *gbuffer_single_sided_ps_ = nullptr;
|
||||
PassMain::Sub *gbuffer_double_sided_ps_ = nullptr;
|
||||
|
||||
gpu::Texture *radiance_behind_tx_ = nullptr;
|
||||
|
||||
/* Closures bits from the materials in this pass. */
|
||||
eClosureBits closure_bits_ = CLOSURE_NONE;
|
||||
/* Maximum closure count considering all material in this pass. */
|
||||
|
|
@ -362,7 +365,8 @@ class DeferredLayer : DeferredLayerBase {
|
|||
|
||||
bool has_transmission() const
|
||||
{
|
||||
return closure_bits_ & CLOSURE_TRANSMISSION;
|
||||
return (closure_bits_ & CLOSURE_TRANSMISSION) ||
|
||||
((closure_bits_ & CLOSURE_TRANSPARENCY) && (closure_bits_ & CLOSURE_SHADER_TO_RGBA));
|
||||
}
|
||||
|
||||
/* Do we compute indirect lighting inside the light eval pass. */
|
||||
|
|
@ -393,8 +397,6 @@ class DeferredPipeline {
|
|||
|
||||
PassSimple debug_draw_ps_ = {"debug_gbuffer"};
|
||||
|
||||
bool use_combined_lightprobe_eval;
|
||||
|
||||
public:
|
||||
DeferredPipeline(Instance &inst)
|
||||
: opaque_layer_(inst), refraction_layer_(inst), volumetric_layer_(inst) {};
|
||||
|
|
@ -572,8 +574,16 @@ class DeferredProbePipeline {
|
|||
|
||||
PassSimple eval_light_ps_ = {"EvalLights"};
|
||||
|
||||
/* Used when there is no feedback radiance buffer. */
|
||||
Texture dummy_black = {"dummy_black"};
|
||||
|
||||
public:
|
||||
DeferredProbePipeline(Instance &inst) : inst_(inst) {};
|
||||
DeferredProbePipeline(Instance &inst) : inst_(inst)
|
||||
{
|
||||
float4 data(0.0f);
|
||||
dummy_black.ensure_2d(
|
||||
gpu::TextureFormat::SFLOAT_16_16_16_16, int2(1), GPU_TEXTURE_USAGE_SHADER_READ, data);
|
||||
}
|
||||
|
||||
void begin_sync();
|
||||
void end_sync();
|
||||
|
|
|
|||
|
|
@ -857,6 +857,17 @@ void ShaderModule::material_create_info_amend(GPUMaterial *gpumat, GPUCodegenOut
|
|||
info.additional_info("eevee_cryptomatte_out");
|
||||
}
|
||||
|
||||
if (GPU_material_flag_get(gpumat, GPU_MATFLAG_SHADER_TO_RGBA)) {
|
||||
info.define("MAT_SHADER_TO_RGBA");
|
||||
}
|
||||
|
||||
if (ELEM(pipeline_type, MAT_PIPE_DEFERRED, MAT_PIPE_FORWARD) &&
|
||||
GPU_material_flag_get(gpumat, GPU_MATFLAG_SHADER_TO_RGBA))
|
||||
{
|
||||
info.additional_info("eevee_hiz_prev_data");
|
||||
info.additional_info("eevee_previous_layer_radiance");
|
||||
}
|
||||
|
||||
if (GPU_material_flag_get(gpumat, GPU_MATFLAG_DIFFUSE)) {
|
||||
info.define("MAT_DIFFUSE");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,22 @@ float4 closure_to_rgba(Closure cl_unused)
|
|||
float closure_rand = fract(noise + sampling_rng_1D_get(SAMPLING_CLOSURE));
|
||||
closure_weights_reset(closure_rand);
|
||||
|
||||
#if defined(MAT_TRANSPARENT) && defined(MAT_SHADER_TO_RGBA)
|
||||
float3 V = -drw_world_incident_vector(g_data.P);
|
||||
LightProbeSample samp = lightprobe_load(g_data.P, g_data.Ng, V);
|
||||
float3 radiance_behind = lightprobe_spherical_sample_normalized_with_parallax(
|
||||
samp, g_data.P, V, 0.0);
|
||||
|
||||
# ifndef MAT_FIRST_LAYER
|
||||
int2 texel = int2(gl_FragCoord.xy);
|
||||
if (texelFetchExtend(hiz_prev_tx, texel, 0).x != 1.0f) {
|
||||
radiance_behind = texelFetch(previous_layer_radiance_tx, texel, 0).xyz;
|
||||
}
|
||||
# endif
|
||||
|
||||
radiance += radiance_behind * saturate(transmittance);
|
||||
#endif
|
||||
|
||||
return float4(radiance, saturate(1.0f - average(transmittance)));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,22 @@ float4 closure_to_rgba(Closure cl_unused)
|
|||
float closure_rand = fract(noise + sampling_rng_1D_get(SAMPLING_CLOSURE));
|
||||
closure_weights_reset(closure_rand);
|
||||
|
||||
#if defined(MAT_TRANSPARENT) && defined(MAT_SHADER_TO_RGBA)
|
||||
float3 V = -drw_world_incident_vector(g_data.P);
|
||||
LightProbeSample samp = lightprobe_load(g_data.P, g_data.Ng, V);
|
||||
float3 radiance_behind = lightprobe_spherical_sample_normalized_with_parallax(
|
||||
samp, g_data.P, V, 0.0);
|
||||
|
||||
# ifndef MAT_FIRST_LAYER
|
||||
int2 texel = int2(gl_FragCoord.xy);
|
||||
if (texelFetchExtend(hiz_prev_tx, texel, 0).x != 1.0f) {
|
||||
radiance_behind = texelFetch(previous_layer_radiance_tx, texel, 0).xyz;
|
||||
}
|
||||
# endif
|
||||
|
||||
radiance += radiance_behind * saturate(transmittance);
|
||||
#endif
|
||||
|
||||
return float4(radiance, saturate(1.0f - average(transmittance)));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,15 @@ SAMPLER(HIZ_TEX_SLOT, sampler2D, hiz_tx)
|
|||
ADDITIONAL_INFO(eevee_global_ubo)
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(eevee_hiz_prev_data)
|
||||
SAMPLER(HIZ_PREVIOUS_LAYER_TEX_SLOT, sampler2D, hiz_prev_tx)
|
||||
ADDITIONAL_INFO(eevee_global_ubo)
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(eevee_previous_layer_radiance)
|
||||
SAMPLER(RADIANCE_PREVIOUS_LAYER_TEX_SLOT, sampler2D, previous_layer_radiance_tx)
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(eevee_utility_texture)
|
||||
SAMPLER(RBUFS_UTILITY_TEX_SLOT, sampler2DArray, utility_tx)
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
|
@ -51,9 +60,9 @@ GPU_SHADER_CREATE_END()
|
|||
|
||||
GPU_SHADER_CREATE_INFO(eevee_gbuffer_data)
|
||||
DEFINE("GBUFFER_LOAD")
|
||||
SAMPLER(12, usampler2DArray, gbuf_header_tx)
|
||||
SAMPLER(13, sampler2DArray, gbuf_closure_tx)
|
||||
SAMPLER(14, sampler2DArray, gbuf_normal_tx)
|
||||
SAMPLER(11, usampler2DArray, gbuf_header_tx)
|
||||
SAMPLER(14, sampler2DArray, gbuf_closure_tx)
|
||||
SAMPLER(15, sampler2DArray, gbuf_normal_tx)
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
||||
GPU_SHADER_CREATE_INFO(eevee_render_pass_out)
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ FRAGMENT_SOURCE("eevee_surf_forward_frag.glsl")
|
|||
/* Optionally added depending on the material. */
|
||||
// ADDITIONAL_INFO(eevee_render_pass_out)
|
||||
// ADDITIONAL_INFO(eevee_cryptomatte_out)
|
||||
// ADDITIONAL_INFO(eevee_hiz_prev_data)
|
||||
// ADDITIONAL_INFO(eevee_previous_layer_radiance)
|
||||
ADDITIONAL_INFO(eevee_global_ubo)
|
||||
ADDITIONAL_INFO(eevee_light_data)
|
||||
ADDITIONAL_INFO(eevee_lightprobe_data)
|
||||
|
|
|
|||
|
|
@ -33,4 +33,7 @@ ADDITIONAL_INFO(eevee_surf_deferred_base)
|
|||
ADDITIONAL_INFO(eevee_light_data)
|
||||
ADDITIONAL_INFO(eevee_lightprobe_data)
|
||||
ADDITIONAL_INFO(eevee_shadow_data)
|
||||
/* Optionally added depending on the material. */
|
||||
// ADDITIONAL_INFO(eevee_hiz_prev_data)
|
||||
// ADDITIONAL_INFO(eevee_previous_layer_radiance)
|
||||
GPU_SHADER_CREATE_END()
|
||||
|
|
|
|||
|
|
@ -184,6 +184,12 @@ RESHAPE(float3x3, mat3x3, mat3x4)
|
|||
#define thread
|
||||
#define threadgroup
|
||||
|
||||
float4 texelFetchExtend(sampler2D samp, int2 texel, int lvl)
|
||||
{
|
||||
texel = clamp(texel, int2(0), textureSize(samp, lvl).xy - 1);
|
||||
return texelFetch(samp, texel, lvl);
|
||||
}
|
||||
|
||||
/* Stage agnostic builtin function.
|
||||
* GLSL doesn't allow mixing shader stages inside the same source file.
|
||||
* Make sure builtin functions are stubbed when used in an invalid stage. */
|
||||
|
|
|
|||
|
|
@ -103,6 +103,12 @@
|
|||
#define _shared_sta (&
|
||||
#define _shared_end )
|
||||
|
||||
float4 texelFetchExtend(sampler2D samp, int2 texel, int lvl)
|
||||
{
|
||||
texel = clamp(texel, int2(0), textureSize(samp, lvl).xy - 1);
|
||||
return texelFetch(samp, texel, lvl);
|
||||
}
|
||||
|
||||
/* Resource accessor. */
|
||||
#define specialization_constant_get(create_info, _res) _res
|
||||
#define shared_variable_get(create_info, _res) _res
|
||||
|
|
|
|||
|
|
@ -107,6 +107,8 @@ float4 texelFetch(samplerBuffer, int) RET;
|
|||
int4 texelFetch(isamplerBuffer, int) RET;
|
||||
uint4 texelFetch(usamplerBuffer, int) RET;
|
||||
|
||||
float4 texelFetchExtend(sampler2D samp, int2 texel, int lvl) RET;
|
||||
|
||||
/** \} */
|
||||
|
||||
#undef RET
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:44e80108906894adc7928c5e5682746faaad776faea0110864ec44dfea2266a3
|
||||
size 131665
|
||||
3
tests/files/render/bsdf/shader_to_rgb_transparent.blend
Normal file
3
tests/files/render/bsdf/shader_to_rgb_transparent.blend
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:8dad9271062cb7a9e27e0d204c1a0f72e55bf326675cd7a639594a9a9fc59776
|
||||
size 161383
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b459673d7d8d793285240b78eba12d4a989e5acd0829e9cb9a8ff9088908acd0
|
||||
size 95771
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:1b0cb91715ca216cf3b9a5d4589ad21fbe7b37bd98e26b16ef6dc30852ee0bc7
|
||||
size 28201
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c35ba2d18c8d16fe405ef55fbed7b269b4164676a9b76c1179dabdd013dd9eb5
|
||||
size 108184
|
||||
|
|
@ -26,7 +26,8 @@ BLOCKLIST_ALL = [
|
|||
"camera_depth_of_field_jittered.blend",
|
||||
"shadow_resolution.blend",
|
||||
"shadow_min_pool_size.blend",
|
||||
"shadow_resolution_scale.blend"
|
||||
"shadow_resolution_scale.blend",
|
||||
"shader_to_rgb_transparent.blend",
|
||||
]
|
||||
|
||||
# Blocklist for device + build configuration that does not support OSL at all.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue