Blender V4.3
workbench_resources.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "../eevee_next/eevee_lut.hh" /* TODO: find somewhere to share blue noise Table. */
6#include "BKE_studiolight.h"
7#include "BLI_math_rotation.h"
8#include "IMB_imbuf_types.hh"
9
10#include "workbench_private.hh"
11
12namespace blender::workbench {
13
14static bool get_matcap_tx(Texture &matcap_tx, StudioLight &studio_light)
15{
16 BKE_studiolight_ensure_flag(&studio_light,
19 ImBuf *matcap_diffuse = studio_light.matcap_diffuse.ibuf;
20 ImBuf *matcap_specular = studio_light.matcap_specular.ibuf;
21 if (matcap_diffuse && matcap_diffuse->float_buffer.data) {
22 int layers = 1;
23 float *buffer = matcap_diffuse->float_buffer.data;
24 Vector<float> combined_buffer;
25
26 if (matcap_specular && matcap_specular->float_buffer.data) {
27 int size = matcap_diffuse->x * matcap_diffuse->y * 4;
28 combined_buffer.extend(matcap_diffuse->float_buffer.data, size);
29 combined_buffer.extend(matcap_specular->float_buffer.data, size);
30 buffer = combined_buffer.begin();
31 layers++;
32 }
33
34 matcap_tx = Texture(studio_light.name,
37 int2(matcap_diffuse->x, matcap_diffuse->y),
38 layers,
39 buffer);
40 return true;
41 }
42 return false;
43}
44
45static float4x4 get_world_shading_rotation_matrix(float studiolight_rot_z)
46{
47 /* TODO(@pragma37): C++ API? */
48 float V[4][4], R[4][4];
49 DRW_view_viewmat_get(nullptr, V, false);
50 axis_angle_to_mat4_single(R, 'Z', -studiolight_rot_z);
51 mul_m4_m4m4(R, V, R);
52 swap_v3_v3(R[2], R[1]);
53 negate_v3(R[2]);
54 return float4x4(R);
55}
56
58 const float4x4 &world_shading_rotation)
59{
60 LightData light = {};
61 if (sl && sl->flag) {
62 float3 direction = math::transform_direction(world_shading_rotation, float3(sl->vec));
63 light.direction = float4(direction, 0.0f);
64 /* We should pre-divide the power by PI but that makes the lights really dim. */
65 light.specular_color = float4(float3(sl->spec), 0.0f);
66 light.diffuse_color_wrap = float4(float3(sl->col), sl->smooth);
67 }
68 else {
69 light.direction = float4(1.0f, 0.0f, 0.0f, 0.0f);
70 light.specular_color = float4(0.0f);
71 light.diffuse_color_wrap = float4(0.0f);
72 }
73 return light;
74}
75
76void SceneResources::load_jitter_tx(int total_samples)
77{
79
80 const float total_samples_inv = 1.0f / total_samples;
81
82 /* Create blue noise jitter texture */
83 for (int x = 0; x < 64; x++) {
84 for (int y = 0; y < 64; y++) {
85 float phi = eevee::lut::blue_noise[y][x][0] * 2.0f * M_PI;
86 /* This rotate the sample per pixels */
87 jitter[y][x].x = math::cos(phi);
88 jitter[y][x].y = math::sin(phi);
89 /* This offset the sample along its direction axis (reduce banding) */
90 float bn = eevee::lut::blue_noise[y][x][1] - 0.5f;
91 bn = clamp_f(bn, -0.499f, 0.499f); /* fix fireflies */
92 jitter[y][x].z = bn * total_samples_inv;
93 jitter[y][x].w = eevee::lut::blue_noise[y][x][1];
94 }
95 }
96
100}
101
102void SceneResources::init(const SceneState &scene_state)
103{
104 const View3DShading &shading = scene_state.shading;
105
108 world_buf.xray_alpha = shading.xray_alpha;
110 world_buf.object_outline_color = float4(float3(shading.object_outline_color), 1.0f);
113
114 StudioLight *studio_light = nullptr;
115 if (U.edit_studio_light) {
116 studio_light = BKE_studiolight_studio_edit_get();
117 }
118 else {
119 if (shading.light == V3D_LIGHTING_MATCAP) {
120 studio_light = BKE_studiolight_find(shading.matcap, STUDIOLIGHT_TYPE_MATCAP);
121 if (studio_light && studio_light->name != current_matcap) {
122 if (get_matcap_tx(matcap_tx, *studio_light)) {
123 current_matcap = studio_light->name;
124 }
125 }
126 }
127 /* If matcaps are missing, use this as fallback. */
128 if (studio_light == nullptr) {
129 studio_light = BKE_studiolight_find(shading.studio_light, STUDIOLIGHT_TYPE_STUDIO);
130 }
131 }
132 if (!matcap_tx.is_valid()) {
134 }
135
136 float4x4 world_shading_rotation = float4x4::identity();
137 if (shading.flag & V3D_SHADING_WORLD_ORIENTATION) {
138 world_shading_rotation = get_world_shading_rotation_matrix(shading.studiolight_rot_z);
139 }
140
141 for (int i = 0; i < 4; i++) {
142 SolidLight *sl = (studio_light) ? &studio_light->light[i] : nullptr;
143 world_buf.lights[i] = get_light_data_from_studio_solidlight(sl, world_shading_rotation);
144 }
145
146 if (studio_light != nullptr) {
147 world_buf.ambient_color = float4(float3(studio_light->light_ambient), 0.0f);
150 }
151 else {
152 world_buf.ambient_color = float4(1.0f, 1.0f, 1.0f, 0.0f);
153 world_buf.use_specular = false;
154 }
155
156 /* TODO(@pragma37): volumes_do */
157
158 cavity.init(scene_state, *this);
159
160 if (scene_state.draw_dof && !jitter_tx.is_valid()) {
161 /* We don't care about total_samples in this case */
163 }
164
166
167 for (int i : IndexRange(6)) {
168 if (i < scene_state.clip_planes.size()) {
169 clip_planes_buf[i] = scene_state.clip_planes[i];
170 }
171 else {
172 clip_planes_buf[i] = float4(0);
173 }
174 }
175
176 clip_planes_buf.push_update();
177
179 GPU_RGBA8, int2(1), GPU_TEXTURE_USAGE_SHADER_READ, float4(1.0f, 0.0f, 1.0f, 1.0f));
181 missing_texture.name = "Missing Texture";
182
184 GPU_RGBA8, int2(1), GPU_TEXTURE_USAGE_SHADER_READ, float4(0.0f, 0.0f, 0.0f, 0.0f));
186 GPU_RGBA8, int2(1), 1, GPU_TEXTURE_USAGE_SHADER_READ, float4(0.0f, 0.0f, 0.0f, 0.0f));
188 GPU_RGBA8, 1, 1, GPU_TEXTURE_USAGE_SHADER_READ, float4(0.0f, 0.0f, 0.0f, 0.0f));
189}
190
191} // namespace blender::workbench
@ STUDIOLIGHT_MATCAP_SPECULAR_GPUTEXTURE
@ STUDIOLIGHT_MATCAP_DIFFUSE_GPUTEXTURE
@ STUDIOLIGHT_TYPE_MATCAP
@ STUDIOLIGHT_SPECULAR_HIGHLIGHT_PASS
@ STUDIOLIGHT_TYPE_STUDIO
struct StudioLight * BKE_studiolight_find(const char *name, int flag)
void BKE_studiolight_ensure_flag(StudioLight *sl, int flag)
StudioLight * BKE_studiolight_studio_edit_get(void)
MINLINE float clamp_f(float value, float min, float max)
#define M_PI
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
void axis_angle_to_mat4_single(float R[4][4], char axis, float angle)
MINLINE void negate_v3(float r[3])
MINLINE void swap_v3_v3(float a[3], float b[3])
@ V3D_LIGHTING_MATCAP
@ V3D_SHADING_SPECULAR_HIGHLIGHT
@ V3D_SHADING_WORLD_ORIENTATION
@ V3D_SHADING_MATCAP_FLIP_X
@ GPU_TEXTURE_USAGE_SHADER_READ
Contains defines and structs used throughout the imbuf module.
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Texture
unsigned int U
Definition btGjkEpa3.h:78
void extend(Span< T > array)
bool ensure_1d_array(eGPUTextureFormat format, int extent, int layers, eGPUTextureUsage usage=GPU_TEXTURE_USAGE_GENERAL, const float *data=nullptr, int mip_len=1)
bool ensure_2d_array(eGPUTextureFormat format, int2 extent, int layers, eGPUTextureUsage usage=GPU_TEXTURE_USAGE_GENERAL, const float *data=nullptr, int mip_len=1)
bool ensure_2d(eGPUTextureFormat format, int2 extent, eGPUTextureUsage usage=GPU_TEXTURE_USAGE_GENERAL, const float *data=nullptr, int mip_len=1)
void init(const SceneState &scene_state, SceneResources &resources)
DRW_Global G_draw
const float * DRW_viewport_invert_size_get()
const float * DRW_viewport_size_get()
bool DRW_state_is_image_render()
void DRW_view_viewmat_get(const DRWView *view, float mat[4][4], bool inverse)
RAYTRACE_GROUP_SIZE additional_info("eevee_shared", "eevee_gbuffer_data", "eevee_global_ubo", "eevee_sampling_data", "eevee_utility_texture", "eevee_hiz_data", "draw_view") .specialization_constant(Type RAYTRACE_GROUP_SIZE in_sh_0_tx in_sh_2_tx screen_normal_tx GPU_RGBA8
#define R
const float blue_noise[64][64][4]
T cos(const AngleRadianBase< T > &a)
T sin(const AngleRadianBase< T > &a)
VecBase< T, 3 > transform_direction(const MatBase< T, 3, 3 > &mat, const VecBase< T, 3 > &direction)
static bool get_matcap_tx(Texture &matcap_tx, StudioLight &studio_light)
static LightData get_light_data_from_studio_solidlight(const SolidLight *sl, const float4x4 &world_shading_rotation)
static float4x4 get_world_shading_rotation_matrix(float studiolight_rot_z)
MatBase< float, 4, 4 > float4x4
VecBase< float, 4 > float4
VecBase< int32_t, 2 > int2
VecBase< float, 3 > float3
GlobalsUboStorage block
ImBufFloatBuffer float_buffer
GPUTexture * texture
Definition BKE_image.hh:583
struct ImBuf * ibuf
StudioLightImage matcap_specular
SolidLight light[STUDIOLIGHT_MAX_LIGHT]
char name[FILE_MAXFILE]
StudioLightImage matcap_diffuse
float light_ambient[3]
LightData lights[4]
void init(const SceneState &scene_state)
UniformBuffer< WorldData > world_buf
UniformArrayBuffer< float4, 6 > clip_planes_buf
CCL_NAMESPACE_BEGIN struct Window V