This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/source/blender/draw/engines/eevee_next/eevee_sampling.hh
Clément Foucault f4fe3fb09b EEVEE-Next: Depth Of Field: Port implementation to compute shader
This is a port of the previous implementation but using compute
shaders instead of using the raster pipeline for every steps.

Only the scatter passes is kept as a raster pass for obvious performance
reasons.

Many steps have been rewritten to take advantage of LDS which allows faster
and simpler downsampling and filtering for some passes.

A new stabilize phase has been separated from another setup pass in order
to improve it in the future with better stabilization.

The scatter pass shaders and pipeline also changed. We now use indirect
drawcall to draw quads using triangle strips primitives. This reduces
fragment shader invocation count & overdraw compared to a bounding
triangle. This also reduces the amount of vertex shader invocation
drastically to the bare minimum instead of having always 3 verts per
4 pixels (for each ground).
2022-08-02 21:53:17 +02:00

190 lines
5.6 KiB
C++

/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2021 Blender Foundation.
*/
/** \file
* \ingroup eevee
*
* Random number generator, contains persistent state and sample count logic.
*/
#pragma once
#include "BKE_colortools.h"
#include "BLI_system.h"
#include "BLI_vector.hh"
#include "DNA_scene_types.h"
#include "DRW_render.h"
#include "eevee_shader_shared.hh"
namespace blender::eevee {
class Instance;
class Sampling {
private:
Instance &inst_;
/* Number of samples in the first ring of jittered depth of field. */
static constexpr uint64_t dof_web_density_ = 6;
/* High number of sample for viewport infinite rendering. */
static constexpr uint64_t infinite_sample_count_ = 0xFFFFFFu;
/* During interactive rendering, loop over the first few samples. */
static constexpr uint64_t interactive_sample_max_ = 8;
/** 0 based current sample. Might not increase sequentially in viewport. */
uint64_t sample_ = 0;
/** Target sample count. */
uint64_t sample_count_ = 64;
/** Number of ring in the web pattern of the jittered Depth of Field. */
uint64_t dof_ring_count_ = 0;
/** Number of samples in the web pattern of the jittered Depth of Field. */
uint64_t dof_sample_count_ = 1;
/** Motion blur steps. */
uint64_t motion_blur_steps_ = 1;
/** Increases if the view and the scene is static. Does increase sequentially. */
int64_t viewport_sample_ = 0;
/** Tag to reset sampling for the next sample. */
bool reset_ = false;
/**
* Switch between interactive and static accumulation.
* In interactive mode, image stability is prioritized over quality.
*/
bool interactive_mode_ = false;
/**
* Sample count after which we use the static accumulation.
* Interactive sampling from sample 0 to (interactive_mode_threshold - 1).
* Accumulation sampling from sample interactive_mode_threshold to sample_count_.
*/
static constexpr int interactive_mode_threshold = 3;
SamplingDataBuf data_;
public:
Sampling(Instance &inst) : inst_(inst){};
~Sampling(){};
void init(const Scene *scene);
void end_sync();
void step();
/* Viewport Only: Function to call to notify something in the scene changed.
* This will reset accumulation. Do not call after end_sync() or during sample rendering. */
void reset()
{
reset_ = true;
}
/* Viewport Only: true if an update happened in the scene and accumulation needs reset. */
bool is_reset() const
{
return reset_;
}
void bind_resources(DRWShadingGroup *grp)
{
DRW_shgroup_storage_block_ref(grp, "sampling_buf", &data_);
}
/* Returns a pseudo random number in [0..1] range. Each dimension are de-correlated. */
float rng_get(eSamplingDimension dimension) const
{
return data_.dimensions[dimension];
}
/* Returns a pseudo random number in [0..1] range. Each dimension are de-correlated. */
float2 rng_2d_get(eSamplingDimension starting_dimension) const
{
return *reinterpret_cast<const float2 *>(&data_.dimensions[starting_dimension]);
}
/* Returns a pseudo random number in [0..1] range. Each dimension are de-correlated. */
float3 rng_3d_get(eSamplingDimension starting_dimension) const
{
return *reinterpret_cast<const float3 *>(&data_.dimensions[starting_dimension]);
}
/* Returns true if rendering has finished. */
bool finished() const
{
return (sample_ >= sample_count_);
}
/* Returns true if viewport smoothing and sampling has finished. */
bool finished_viewport() const
{
return (viewport_sample_ >= sample_count_) && !interactive_mode_;
}
/* Returns true if viewport renderer is in interactive mode and should use TAA. */
bool interactive_mode() const
{
return interactive_mode_;
}
uint64_t sample_count() const
{
return sample_count_;
}
/* Return true if we are starting a new motion blur step. We need to run sync again since
* depsgraph was updated by MotionBlur::step(). */
bool do_render_sync() const
{
return ((sample_ % (sample_count_ / motion_blur_steps_)) == 0);
}
/**
* Special ball distribution:
* Point are distributed in a way that when they are orthogonally
* projected into any plane, the resulting distribution is (close to)
* a uniform disc distribution.
* \a rand is 3 random float in the [0..1] range.
* Returns point in a ball of radius 1 and centered on the origin.
*/
static float3 sample_ball(const float3 &rand);
/**
* Uniform disc distribution.
* \a rand is 2 random float in the [0..1] range.
* Returns point in a disk of radius 1 and centered on the origin.
*/
static float2 sample_disk(const float2 &rand);
/**
* Uniform disc distribution using Fibonacci spiral sampling.
* \a rand is 2 random float in the [0..1] range.
* Returns point in a disk of radius 1 and centered on the origin.
*/
static float2 sample_spiral(const float2 &rand);
/**
* Special RNG for depth of field.
* Returns \a radius and \a theta angle offset to apply to the web sampling pattern.
*/
void dof_disk_sample_get(float *r_radius, float *r_theta) const;
/**
* Returns sample count inside the jittered depth of field web pattern.
*/
uint64_t dof_ring_count_get() const
{
return dof_ring_count_;
}
/**
* Returns sample count inside the jittered depth of field web pattern.
*/
uint64_t dof_sample_count_get() const
{
return dof_sample_count_;
}
/* Cumulative Distribution Function Utils. */
static void cdf_from_curvemapping(const CurveMapping &curve, Vector<float> &cdf);
static void cdf_invert(Vector<float> &cdf, Vector<float> &inverted_cdf);
};
} // namespace blender::eevee