diff options
Diffstat (limited to 'source/blender/draw/engines/eevee/eevee_gbuffer.hh')
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_gbuffer.hh | 227 |
1 files changed, 91 insertions, 136 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_gbuffer.hh b/source/blender/draw/engines/eevee/eevee_gbuffer.hh index 237a2ecaf31..dc217590038 100644 --- a/source/blender/draw/engines/eevee/eevee_gbuffer.hh +++ b/source/blender/draw/engines/eevee/eevee_gbuffer.hh @@ -33,110 +33,132 @@ enum eClosureBits { CLOSURE_SSS = 1 << 1, CLOSURE_REFLECTION = 1 << 2, CLOSURE_REFRACTION = 1 << 3, - CLOSURE_VOLUME = 1 << 4, - CLOSURE_EMISSION = 1 << 5, - CLOSURE_TRANSPARENCY = 1 << 6, + CLOSURE_AMBIENT_OCCLUSION = 1 << 5, + /* Non-stencil bits. */ + CLOSURE_TRANSPARENCY = 1 << 8, + CLOSURE_EMISSION = 1 << 9, + CLOSURE_HOLDOUT = 1 << 10, + CLOSURE_VOLUME = 1 << 11, }; +ENUM_OPERATORS(eClosureBits, CLOSURE_VOLUME); + +static inline eClosureBits extract_closure_mask(const GPUMaterial *gpumat) +{ + eClosureBits closure_bits = eClosureBits(0); + if (GPU_material_flag_get(gpumat, GPU_MATFLAG_DIFFUSE)) { + closure_bits |= CLOSURE_DIFFUSE; + } + if (GPU_material_flag_get(gpumat, GPU_MATFLAG_TRANSPARENT)) { + closure_bits |= CLOSURE_TRANSPARENCY; + } + if (GPU_material_flag_get(gpumat, GPU_MATFLAG_EMISSION)) { + closure_bits |= CLOSURE_EMISSION; + } + if (GPU_material_flag_get(gpumat, GPU_MATFLAG_GLOSSY)) { + closure_bits |= CLOSURE_REFLECTION; + } + if (GPU_material_flag_get(gpumat, GPU_MATFLAG_SUBSURFACE)) { + closure_bits |= CLOSURE_SSS; + } + if (GPU_material_flag_get(gpumat, GPU_MATFLAG_REFRACT)) { + closure_bits |= CLOSURE_REFRACTION; + } + if (GPU_material_flag_get(gpumat, GPU_MATFLAG_HOLDOUT)) { + closure_bits |= CLOSURE_HOLDOUT; + } + if (GPU_material_flag_get(gpumat, GPU_MATFLAG_AO)) { + closure_bits |= CLOSURE_AMBIENT_OCCLUSION; + } + return closure_bits; +} + struct GBuffer { + Instance &inst; + TextureFromPool transmit_color_tx = {"GbufferTransmitColor"}; TextureFromPool transmit_normal_tx = {"GbufferTransmitNormal"}; TextureFromPool transmit_data_tx = {"GbufferTransmitData"}; + TextureFromPool reflect_color_tx = {"GbufferReflectionColor"}; TextureFromPool reflect_normal_tx = {"GbufferReflectionNormal"}; - TextureFromPool volume_tx = {"GbufferVolume"}; - TextureFromPool emission_tx = {"GbufferEmission"}; - TextureFromPool transparency_tx = {"GbufferTransparency"}; - - Framebuffer gbuffer_fb = {"Gbuffer"}; - Framebuffer volume_fb = {"VolumeHeterogeneous"}; - - TextureFromPool holdout_tx = {"HoldoutRadiance"}; - TextureFromPool diffuse_tx = {"DiffuseRadiance"}; - Framebuffer radiance_fb = {"Radiance"}; - Framebuffer radiance_clear_fb = {"RadianceClear"}; - - Framebuffer holdout_fb = {"Holdout"}; - - TextureFromPool depth_behind_tx = {"DepthBehind"}; - - Framebuffer depth_behind_fb = {"DepthCopy"}; + TextureFromPool radiance_diffuse_tx = {"DiffuseRadiance"}; /** Raytracing. */ TextureFromPool ray_data_tx = {"RayData"}; TextureFromPool ray_radiance_tx = {"RayRadiance"}; TextureFromPool ray_variance_tx = {"RayVariance"}; - Framebuffer ray_data_fb = {"RayData"}; - Framebuffer ray_denoise_fb = {"RayDenoise"}; - /* Owner of this GBuffer. Used to query temp textures. */ - void *owner; + TextureFromPool rpass_emission_tx = {"PassEmission"}; + TextureFromPool rpass_diffuse_light_tx = {"PassDiffuseColor"}; + TextureFromPool rpass_specular_light_tx = {"PassSpecularColor"}; + TextureFromPool rpass_volume_light_tx = {"PassVolumeLight"}; + + /* Maximum texture size. Since we use imageLoad/Store instead of framebuffer, we only need to + * allocate the biggest texture. */ + int2 extent = int2(-1); - /* Pointer to the view's buffers. */ - GPUTexture *depth_tx = nullptr; - GPUTexture *combined_tx = nullptr; - int layer = -1; + GBuffer(Instance &inst_) : inst(inst_){}; - void sync(GPUTexture *depth_tx_, GPUTexture *combined_tx_, void *owner_, int layer_ = -1) + void begin_sync() { - owner = owner_; - depth_tx = depth_tx_; - combined_tx = combined_tx_; - layer = layer_; + extent = int2(-1); + transmit_color_tx.sync(); transmit_normal_tx.sync(); transmit_data_tx.sync(); reflect_color_tx.sync(); reflect_normal_tx.sync(); - volume_tx.sync(); - emission_tx.sync(); - transparency_tx.sync(); - holdout_tx.sync(); - diffuse_tx.sync(); - depth_behind_tx.sync(); + radiance_diffuse_tx.sync(); ray_data_tx.sync(); ray_radiance_tx.sync(); ray_variance_tx.sync(); + rpass_emission_tx.sync(); + rpass_diffuse_light_tx.sync(); + rpass_specular_light_tx.sync(); + rpass_volume_light_tx.sync(); } - void prepare(eClosureBits closures_used) + void view_sync(int2 view_extent) { - int2 extent = {GPU_texture_width(depth_tx), GPU_texture_height(depth_tx)}; + extent = math::max(extent, view_extent); + } + + void acquire(eClosureBits closures_used) + { + DrawEngineType *owner = (DrawEngineType *)&inst; - /* TODO Reuse for different config. */ if (closures_used & (CLOSURE_DIFFUSE | CLOSURE_SSS | CLOSURE_REFRACTION)) { transmit_color_tx.acquire(extent, GPU_R11F_G11F_B10F, owner); } + else { + transmit_color_tx.acquire(int2(1), GPU_R11F_G11F_B10F, owner); + } + if (closures_used & (CLOSURE_SSS | CLOSURE_REFRACTION)) { transmit_normal_tx.acquire(extent, GPU_RGBA16F, owner); transmit_data_tx.acquire(extent, GPU_R11F_G11F_B10F, owner); } else if (closures_used & CLOSURE_DIFFUSE) { transmit_normal_tx.acquire(extent, GPU_RG16F, owner); - } - if (closures_used & CLOSURE_SSS) { - diffuse_tx.acquire(extent, GPU_RGBA16F, owner); + transmit_data_tx.acquire(int2(1), GPU_R11F_G11F_B10F, owner); } if (closures_used & CLOSURE_REFLECTION) { reflect_color_tx.acquire(extent, GPU_R11F_G11F_B10F, owner); reflect_normal_tx.acquire(extent, GPU_RGBA16F, owner); } - - if (closures_used & CLOSURE_VOLUME) { - /* TODO(fclem): This is killing performance. - * Idea: use interleaved data pattern to fill only a 32bpp buffer. */ - volume_tx.acquire(extent, GPU_RGBA32UI, owner); + else { + reflect_color_tx.acquire(int2(1), GPU_R11F_G11F_B10F, owner); + reflect_normal_tx.acquire(int2(1), GPU_RGBA16F, owner); } - if (closures_used & CLOSURE_EMISSION) { - emission_tx.acquire(extent, GPU_R11F_G11F_B10F, owner); + if (closures_used & CLOSURE_SSS) { + radiance_diffuse_tx.acquire(extent, GPU_RGBA16F, owner); } - - if (closures_used & CLOSURE_TRANSPARENCY) { - /* TODO(fclem): Speedup by using Dithered holdout and GPU_RGB10_A2. */ - transparency_tx.acquire(extent, GPU_RGBA16, owner); + else { + radiance_diffuse_tx.acquire(int2(1), GPU_RGBA16F, owner); } if (closures_used & (CLOSURE_DIFFUSE | CLOSURE_REFLECTION | CLOSURE_REFRACTION)) { @@ -145,97 +167,30 @@ struct GBuffer { ray_variance_tx.acquire(extent, GPU_R8, owner); } - holdout_tx.acquire(extent, GPU_R11F_G11F_B10F, owner); - depth_behind_tx.acquire(extent, GPU_DEPTH24_STENCIL8, owner); - - /* Layer attachement also works with cubemap. */ - gbuffer_fb.ensure(GPU_ATTACHMENT_TEXTURE_LAYER(depth_tx, layer), - GPU_ATTACHMENT_TEXTURE(transmit_color_tx), - GPU_ATTACHMENT_TEXTURE(transmit_normal_tx), - GPU_ATTACHMENT_TEXTURE(transmit_data_tx), - GPU_ATTACHMENT_TEXTURE(reflect_color_tx), - GPU_ATTACHMENT_TEXTURE(reflect_normal_tx), - GPU_ATTACHMENT_TEXTURE(volume_tx), - GPU_ATTACHMENT_TEXTURE(emission_tx), - GPU_ATTACHMENT_TEXTURE(transparency_tx)); - } - - void bind(void) - { - GPU_framebuffer_bind(gbuffer_fb); - GPU_framebuffer_clear_stencil(gbuffer_fb, 0x0); - } - - void bind_radiance(void) - { - /* Layer attachement also works with cubemap. */ - radiance_fb.ensure(GPU_ATTACHMENT_TEXTURE_LAYER(depth_tx, layer), - GPU_ATTACHMENT_TEXTURE(combined_tx), - GPU_ATTACHMENT_TEXTURE(diffuse_tx)); - GPU_framebuffer_bind(radiance_fb); - } - - void bind_volume(void) - { - /* Layer attachement also works with cubemap. */ - volume_fb.ensure(GPU_ATTACHMENT_TEXTURE_LAYER(depth_tx, layer), - GPU_ATTACHMENT_TEXTURE(volume_tx), - GPU_ATTACHMENT_TEXTURE(transparency_tx)); - GPU_framebuffer_bind(volume_fb); - } - - void bind_tracing(void) - { - /* Layer attachement also works with cubemap. */ - /* Attach depth_stencil buffer to only trace the surfaces that need it. */ - ray_data_fb.ensure(GPU_ATTACHMENT_TEXTURE_LAYER(depth_tx, layer), - GPU_ATTACHMENT_TEXTURE(ray_data_tx), - GPU_ATTACHMENT_TEXTURE(ray_radiance_tx)); - GPU_framebuffer_bind(ray_data_fb); - - float color[4] = {0.0f}; - GPU_framebuffer_clear_color(ray_data_fb, color); - } - - void bind_holdout(void) - { - holdout_fb.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(holdout_tx)); - GPU_framebuffer_bind(holdout_fb); - } - - void copy_depth_behind(void) - { - depth_behind_fb.ensure(GPU_ATTACHMENT_TEXTURE(depth_behind_tx)); - GPU_framebuffer_bind(depth_behind_fb); - - GPU_framebuffer_blit(gbuffer_fb, 0, depth_behind_fb, 0, GPU_DEPTH_BIT); - } - - void clear_radiance(void) - { - radiance_clear_fb.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(diffuse_tx)); - GPU_framebuffer_bind(radiance_clear_fb); - - float color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - GPU_framebuffer_clear_color(radiance_clear_fb, color); + if (true) { + /* Dummies for everything for now. */ + rpass_emission_tx.acquire(int2(1), GPU_RGBA16F, owner); + rpass_diffuse_light_tx.acquire(int2(1), GPU_RGBA16F, owner); + rpass_specular_light_tx.acquire(int2(1), GPU_RGBA16F, owner); + rpass_volume_light_tx.acquire(int2(1), GPU_RGBA16F, owner); + } } - void render_end(void) + void release(void) { transmit_color_tx.release(); transmit_normal_tx.release(); transmit_data_tx.release(); reflect_color_tx.release(); reflect_normal_tx.release(); - volume_tx.release(); - emission_tx.release(); - transparency_tx.release(); - holdout_tx.release(); - diffuse_tx.release(); - depth_behind_tx.release(); + radiance_diffuse_tx.release(); ray_data_tx.release(); ray_radiance_tx.release(); ray_variance_tx.release(); + rpass_emission_tx.release(); + rpass_diffuse_light_tx.release(); + rpass_specular_light_tx.release(); + rpass_volume_light_tx.release(); } }; |