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
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/draw/engines/eevee/eevee_gbuffer.hh')
-rw-r--r--source/blender/draw/engines/eevee/eevee_gbuffer.hh227
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();
}
};