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
|
/*
* 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 2020, Blender Foundation.
*/
/** \file
* \ingroup draw_engine
*
* EEVEE LUT generation:
*
* Routine to generate the LUT used by eevee stored in eevee_lut.h
* These functions are not to be used in the final executable.
*/
#include "DRW_render.h"
#include "BLI_fileops.h"
#include "BLI_rand.h"
#include "BLI_string_utils.h"
#include "eevee_private.h"
#define DO_FILE_OUTPUT 0
float *EEVEE_lut_update_ggx_brdf(int lut_size)
{
DRWPass *pass = DRW_pass_create(__func__, DRW_STATE_WRITE_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(EEVEE_shaders_ggx_lut_sh_get(), pass);
DRW_shgroup_uniform_float_copy(grp, "sampleCount", 64.0f); /* Actual sample count is squared. */
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
GPUTexture *tex = DRW_texture_create_2d(lut_size, lut_size, GPU_RG16F, 0, NULL);
GPUFrameBuffer *fb = NULL;
GPU_framebuffer_ensure_config(&fb,
{
GPU_ATTACHMENT_NONE,
GPU_ATTACHMENT_TEXTURE(tex),
});
GPU_framebuffer_bind(fb);
DRW_draw_pass(pass);
GPU_FRAMEBUFFER_FREE_SAFE(fb);
float *data = GPU_texture_read(tex, GPU_DATA_FLOAT, 0);
GPU_texture_free(tex);
#if DO_FILE_OUTPUT
/* Content is to be put inside eevee_lut.c */
FILE *f = BLI_fopen("bsdf_split_sum_ggx.h", "w");
fprintf(f, "const float bsdf_split_sum_ggx[%d * %d * 2] = {", lut_size, lut_size);
for (int i = 0; i < lut_size * lut_size * 2;) {
fprintf(f, "\n ");
for (int j = 0; j < 4; j++, i += 2) {
fprintf(f, "%ff, %ff, ", data[i], data[i + 1]);
}
}
fprintf(f, "\n};\n");
fclose(f);
#endif
return data;
}
float *EEVEE_lut_update_ggx_btdf(int lut_size, int lut_depth)
{
float roughness;
DRWPass *pass = DRW_pass_create(__func__, DRW_STATE_WRITE_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(EEVEE_shaders_ggx_refraction_lut_sh_get(), pass);
DRW_shgroup_uniform_float_copy(grp, "sampleCount", 64.0f); /* Actual sample count is squared. */
DRW_shgroup_uniform_float(grp, "z", &roughness, 1);
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
GPUTexture *tex = DRW_texture_create_2d_array(lut_size, lut_size, lut_depth, GPU_RG16F, 0, NULL);
GPUFrameBuffer *fb = NULL;
for (int i = 0; i < lut_depth; i++) {
GPU_framebuffer_ensure_config(&fb,
{
GPU_ATTACHMENT_NONE,
GPU_ATTACHMENT_TEXTURE_LAYER(tex, i),
});
GPU_framebuffer_bind(fb);
roughness = i / (lut_depth - 1.0f);
DRW_draw_pass(pass);
}
GPU_FRAMEBUFFER_FREE_SAFE(fb);
float *data = GPU_texture_read(tex, GPU_DATA_FLOAT, 0);
GPU_texture_free(tex);
#if DO_FILE_OUTPUT
/* Content is to be put inside eevee_lut.c. Don't forget to format the output. */
FILE *f = BLI_fopen("btdf_split_sum_ggx.h", "w");
fprintf(f, "const float btdf_split_sum_ggx[%d][%d * %d * 2] = {", lut_depth, lut_size, lut_size);
fprintf(f, "\n ");
int ofs = 0;
for (int d = 0; d < lut_depth; d++) {
fprintf(f, "{\n");
for (int i = 0; i < lut_size * lut_size * 2;) {
for (int j = 0; j < 4; j++, i += 2, ofs += 2) {
fprintf(f, "%ff, %ff, ", data[ofs], data[ofs + 1]);
}
fprintf(f, "\n ");
}
fprintf(f, "},\n");
}
fprintf(f, "};\n");
fclose(f);
#endif
return data;
}
|