Welcome to mirror list, hosted at ThFree Co, Russian Federation.

eevee_lightprobe.hh « eevee « engines « draw « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 865339039fa59dd1d561c4b77fb15d7461635a4f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/*
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * Copyright 2018, Blender Foundation.
 */

/** \file
 * \ingroup eevee
 */

#pragma once

#include "eevee_lightcache.hh"
#include "eevee_view.hh"

#include "eevee_wrapper.hh"

namespace blender::eevee {

class Instance;

class LightProbeModule {
 private:
  Instance &inst_;

  LightProbeFilterDataBuf filter_data_;
  LightProbeInfoDataBuf info_data_;
  GridDataBuf grid_data_;
  CubemapDataBuf cube_data_;

  /* Either scene lightcache or lookdev lightcache */
  LightCache *lightcache_ = nullptr;
  /* Own lightcache used for lookdev lighting or as fallback. */
  LightCache *lightcache_lookdev_ = nullptr;
  /* Temporary cache used for baking. */
  LightCache *lightcache_baking_ = nullptr;

  /* Used for rendering probes. */
  /* OPTI(fclem) Share for the whole scene? Only allocate temporary? */
  Texture cube_depth_tx_ = {"CubemapDepth"};
  Texture cube_color_tx_ = {"CubemapColor"};
  LightProbeView probe_views_[6];

  Framebuffer cube_downsample_fb_ = {"cube_downsample"};
  Framebuffer filter_cube_fb_ = {"filter_cube"};
  Framebuffer filter_grid_fb_ = {"filter_grid"};

  std::array<DRWView *, 6> face_view_ = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};

  DRWPass *cube_downsample_ps_ = nullptr;
  DRWPass *filter_glossy_ps_ = nullptr;
  DRWPass *filter_diffuse_ps_ = nullptr;
  DRWPass *filter_visibility_ps_ = nullptr;

  DRWPass *display_ps_ = nullptr;

  /** Input texture to downsample cube pass. */
  GPUTexture *cube_downsample_input_tx_ = nullptr;
  /** Copy of actual textures from the lightcache_. */
  GPUTexture *active_grid_tx_ = nullptr;
  GPUTexture *active_cube_tx_ = nullptr;
  /** Constant values during baking. */
  float glossy_clamp_ = 0.0;
  float filter_quality_ = 0.0;

 public:
  LightProbeModule(Instance &inst)
      : inst_(inst),
        probe_views_{{inst, "posX_view", cubeface_mat[0], 0},
                     {inst, "negX_view", cubeface_mat[1], 1},
                     {inst, "posY_view", cubeface_mat[2], 2},
                     {inst, "negY_view", cubeface_mat[3], 3},
                     {inst, "posZ_view", cubeface_mat[4], 4},
                     {inst, "negZ_view", cubeface_mat[5], 5}}
  {
  }

  ~LightProbeModule()
  {
    MEM_delete(lightcache_lookdev_);
    MEM_delete(lightcache_baking_);
  }

  void init();

  void begin_sync();
  void end_sync();

  void set_view(const DRWView *view, const ivec2 extent);

  void set_world_dirty(void)
  {
    lightcache_->flag |= LIGHTCACHE_UPDATE_WORLD;
  }

  void swap_irradiance_cache(void)
  {
    if (lightcache_baking_ && lightcache_) {
      SWAP(GPUTexture *, lightcache_baking_->grid_tx.tex, lightcache_->grid_tx.tex);
    }
  }

  const GPUUniformBuf *grid_ubo_get() const
  {
    return grid_data_;
  }
  const GPUUniformBuf *cube_ubo_get() const
  {
    return cube_data_;
  }
  const GPUUniformBuf *info_ubo_get() const
  {
    return info_data_;
  }
  GPUTexture **grid_tx_ref_get()
  {
    return &active_grid_tx_;
  }
  GPUTexture **cube_tx_ref_get()
  {
    return &active_cube_tx_;
  }

  void bake(Depsgraph *depsgraph,
            int type,
            int index,
            int bounce,
            const float position[3],
            const LightProbe *probe = nullptr,
            float visibility_range = 0.0f);

  void draw_cache_display(void);

 private:
  void update_world_cache();

  void sync_world(const DRWView *view);
  void sync_grid(const DRWView *view, const struct LightGridCache &grid_cache, int grid_index);
  void sync_cubemap(const DRWView *view, const struct LightProbeCache &cube_cache, int cube_index);

  LightCache *baking_cache_get(void);

  void cubemap_prepare(vec3 position, float near, float far, bool background_only);

  void filter_glossy(int cube_index, float intensity);
  void filter_diffuse(int sample_index, float intensity);
  void filter_visibility(int sample_index, float visibility_blur, float visibility_range);

  float lod_bias_from_cubemap(void)
  {
    float target_size_sq = square_f(GPU_texture_width(cube_color_tx_));
    return 0.5f * logf(target_size_sq / filter_data_.sample_count) / logf(2);
  }

  static void cube_downsample_cb(void *thunk, int UNUSED(level))
  {
    DRW_draw_pass(reinterpret_cast<LightProbeModule *>(thunk)->cube_downsample_ps_);
  }

  void cubemap_render(void);
};

}  // namespace blender::eevee