EEvEE: LookDev
This commit is contained in:
parent
ce5fa2deca
commit
765fd29d68
@ -3545,6 +3545,11 @@ class VIEW3D_PT_shading(Panel):
|
||||
sub.active = shading.show_object_outline
|
||||
sub.prop(shading, "object_outline_color", text="")
|
||||
|
||||
elif shading.type in ('MATERIAL'):
|
||||
col.row().template_icon_view(shading, "studio_light")
|
||||
if shading.studio_light_orientation == 'WORLD':
|
||||
col.row().prop(shading, "studiolight_rot_z")
|
||||
|
||||
|
||||
class VIEW3D_PT_overlay(Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
|
@ -160,7 +160,7 @@ struct ImBuf *BKE_icon_geom_rasterize(
|
||||
const struct Icon_Geom *geom,
|
||||
const unsigned int size_x, const unsigned int size_y);
|
||||
|
||||
int BKE_icon_ensure_studio_light(struct StudioLight *sl);
|
||||
int BKE_icon_ensure_studio_light(struct StudioLight *sl, int id_type);
|
||||
|
||||
#define ICON_RENDER_DEFAULT_HEIGHT 32
|
||||
|
||||
|
@ -51,6 +51,10 @@
|
||||
#define STUDIOLIGHT_Y_NEG 3
|
||||
#define STUDIOLIGHT_Z_POS 4
|
||||
#define STUDIOLIGHT_Z_NEG 5
|
||||
#define STUDIOLIGHT_ICON_ID_TYPE_RADIANCE 0
|
||||
#define STUDIOLIGHT_ICON_ID_TYPE_IRRADIANCE 1
|
||||
|
||||
struct GPUTexture;
|
||||
|
||||
enum StudioLightFlag {
|
||||
STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED = (1 << 0),
|
||||
@ -58,7 +62,9 @@ enum StudioLightFlag {
|
||||
STUDIOLIGHT_EXTERNAL_FILE = (1 << 2),
|
||||
STUDIOLIGHT_ORIENTATION_CAMERA = (1 << 3),
|
||||
STUDIOLIGHT_ORIENTATION_WORLD = (1 << 4),
|
||||
STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED = (1 << 5),
|
||||
STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED = (1 << 5),
|
||||
STUDIOLIGHT_EQUIRECTANGULAR_GPUTEXTURE = (1 << 6),
|
||||
STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED = (1 << 7),
|
||||
} StudioLightFlag;
|
||||
|
||||
typedef struct StudioLight {
|
||||
@ -66,18 +72,21 @@ typedef struct StudioLight {
|
||||
int flag;
|
||||
char name[FILE_MAXFILE];
|
||||
char path[FILE_MAX];
|
||||
int icon_id;
|
||||
int irradiance_icon_id;
|
||||
int radiance_icon_id;
|
||||
int index;
|
||||
float diffuse_light[6][3];
|
||||
float light_direction[3];
|
||||
ImBuf *equirectangular_buffer;
|
||||
ImBuf *radiance_buffers[6];
|
||||
struct GPUTexture *equirectangular_gputexture;
|
||||
} StudioLight;
|
||||
|
||||
void BKE_studiolight_init(void);
|
||||
void BKE_studiolight_free(void);
|
||||
struct StudioLight *BKE_studiolight_find(const char *name);
|
||||
struct StudioLight *BKE_studiolight_find(const char *name, int flag);
|
||||
struct StudioLight *BKE_studiolight_findindex(int index);
|
||||
unsigned int *BKE_studiolight_preview(StudioLight *sl, int icon_size);
|
||||
unsigned int *BKE_studiolight_preview(StudioLight *sl, int icon_size, int icon_id_type);
|
||||
const struct ListBase *BKE_studiolight_listbase(void);
|
||||
void BKE_studiolight_ensure_flag(StudioLight *sl, int flag);
|
||||
|
||||
|
@ -806,10 +806,11 @@ struct Icon_Geom *BKE_icon_geom_from_file(const char *filename)
|
||||
|
||||
/** \name Studio Light Icon
|
||||
* \{ */
|
||||
int BKE_icon_ensure_studio_light(struct StudioLight *sl)
|
||||
int BKE_icon_ensure_studio_light(struct StudioLight *sl, int id_type)
|
||||
{
|
||||
int icon_id = get_next_free_id();
|
||||
icon_create(icon_id, ICON_DATA_STUDIOLIGHT, sl);
|
||||
Icon *icon = icon_create(icon_id, ICON_DATA_STUDIOLIGHT, sl);
|
||||
icon->id_type = id_type;
|
||||
return icon_id;
|
||||
}
|
||||
/** \} */
|
||||
|
@ -48,6 +48,8 @@
|
||||
#include "IMB_imbuf.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
|
||||
#include "GPU_texture.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
|
||||
@ -67,6 +69,16 @@ static void studiolight_free(struct StudioLight *sl)
|
||||
IMB_freeImBuf(sl->radiance_buffers[index]);
|
||||
sl->radiance_buffers[index] = NULL;
|
||||
}
|
||||
|
||||
if (sl->equirectangular_gputexture) {
|
||||
GPU_texture_free(sl->equirectangular_gputexture);
|
||||
sl->equirectangular_gputexture = NULL;
|
||||
}
|
||||
|
||||
if (sl->equirectangular_buffer) {
|
||||
IMB_freeImBuf(sl->equirectangular_buffer);
|
||||
sl->equirectangular_buffer = NULL;
|
||||
}
|
||||
}
|
||||
MEM_freeN(sl);
|
||||
}
|
||||
@ -78,7 +90,8 @@ static struct StudioLight *studiolight_create(void)
|
||||
sl->name[0] = 0x00;
|
||||
sl->flag = 0;
|
||||
sl->index = BLI_listbase_count(&studiolights);
|
||||
sl->icon_id = BKE_icon_ensure_studio_light(sl);
|
||||
sl->radiance_icon_id = BKE_icon_ensure_studio_light(sl, STUDIOLIGHT_ICON_ID_TYPE_RADIANCE);
|
||||
sl->irradiance_icon_id = BKE_icon_ensure_studio_light(sl, STUDIOLIGHT_ICON_ID_TYPE_IRRADIANCE);
|
||||
|
||||
for (int index = 0 ; index < 6 ; index ++) {
|
||||
sl->radiance_buffers[index] = NULL;
|
||||
@ -133,13 +146,38 @@ static void studiolight_calculate_radiance_buffer(
|
||||
}
|
||||
}
|
||||
|
||||
static void studiolight_calculate_radiance_buffers(StudioLight *sl)
|
||||
static void studiolight_load_equierectangular_image(StudioLight *sl)
|
||||
{
|
||||
if (sl->flag & STUDIOLIGHT_EXTERNAL_FILE) {
|
||||
ImBuf *ibuf = NULL;
|
||||
ibuf = IMB_loadiffname(sl->path, 0, NULL);
|
||||
if (ibuf) {
|
||||
IMB_float_from_rect(ibuf);
|
||||
sl->equirectangular_buffer = ibuf;
|
||||
}
|
||||
}
|
||||
sl->flag |= STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED;
|
||||
}
|
||||
|
||||
static void studiolight_create_equierectangular_gputexture(StudioLight *sl)
|
||||
{
|
||||
if (sl->flag & STUDIOLIGHT_EXTERNAL_FILE) {
|
||||
char error[256];
|
||||
BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED);
|
||||
ImBuf *ibuf = sl->equirectangular_buffer;
|
||||
sl->equirectangular_gputexture = GPU_texture_create_2D(ibuf->x, ibuf->y, GPU_RGBA16F, ibuf->rect_float, error);
|
||||
}
|
||||
sl->flag |= STUDIOLIGHT_EQUIRECTANGULAR_GPUTEXTURE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void studiolight_calculate_radiance_buffers(StudioLight *sl)
|
||||
{
|
||||
if (sl->flag & STUDIOLIGHT_EXTERNAL_FILE) {
|
||||
BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED);
|
||||
ImBuf* ibuf = sl->equirectangular_buffer;
|
||||
if (ibuf) {
|
||||
float *colbuf = MEM_mallocN(SQUARE(STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE) * sizeof(float[4]), __func__);
|
||||
const float add = 1.0f / (STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE + 1);
|
||||
const float start = ((1.0f / STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE) * 0.5f) - 0.5f;
|
||||
@ -183,7 +221,6 @@ static void studiolight_calculate_radiance_buffers(StudioLight *sl)
|
||||
IMB_saveiff(sl->radiance_buffers[STUDIOLIGHT_Z_NEG], "/tmp/studiolight_radiance_top.png", IB_rectfloat);
|
||||
#endif
|
||||
MEM_freeN(colbuf);
|
||||
IMB_freeImBuf(ibuf);
|
||||
}
|
||||
}
|
||||
sl->flag |= STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED;
|
||||
@ -451,70 +488,63 @@ static int studiolight_cmp(const void *a, const void *b)
|
||||
return BLI_strcasecmp(sl1->name, sl2->name);
|
||||
}
|
||||
}
|
||||
/* API */
|
||||
void BKE_studiolight_init(void)
|
||||
|
||||
/* icons */
|
||||
static unsigned int* studiolight_radiance_preview(StudioLight *sl, int icon_size)
|
||||
{
|
||||
StudioLight *sl;
|
||||
/* go over the preset folder and add a studiolight for every image with its path */
|
||||
/* order studio lights by name */
|
||||
/* Also reserve icon space for it. */
|
||||
/* Add default studio light */
|
||||
sl = studiolight_create();
|
||||
BLI_strncpy(sl->name, "INTERNAL_01", FILE_MAXFILE);
|
||||
sl->flag = STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED | STUDIOLIGHT_ORIENTATION_CAMERA;
|
||||
copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_X_POS], 0.0f);
|
||||
copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_X_NEG], 0.0f);
|
||||
copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Y_POS], 1.0f);
|
||||
copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Y_NEG], 0.0f);
|
||||
copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Z_POS], 0.0f);
|
||||
copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Z_NEG], 0.0f);
|
||||
BLI_addtail(&studiolights, sl);
|
||||
BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED);
|
||||
|
||||
studiolight_add_files_from_datafolder(BLENDER_SYSTEM_DATAFILES, STUDIOLIGHT_CAMERA_FOLDER, STUDIOLIGHT_ORIENTATION_CAMERA);
|
||||
studiolight_add_files_from_datafolder(BLENDER_USER_DATAFILES, STUDIOLIGHT_CAMERA_FOLDER, STUDIOLIGHT_ORIENTATION_CAMERA);
|
||||
studiolight_add_files_from_datafolder(BLENDER_SYSTEM_DATAFILES, STUDIOLIGHT_WORLD_FOLDER, STUDIOLIGHT_ORIENTATION_WORLD);
|
||||
studiolight_add_files_from_datafolder(BLENDER_USER_DATAFILES, STUDIOLIGHT_WORLD_FOLDER, STUDIOLIGHT_ORIENTATION_WORLD);
|
||||
uint *rect = MEM_mallocN(icon_size * icon_size * sizeof(uint), __func__);
|
||||
int icon_center = icon_size / 2;
|
||||
float sphere_radius = icon_center * 0.9;
|
||||
|
||||
/* sort studio lights on filename. */
|
||||
BLI_listbase_sort(&studiolights, studiolight_cmp);
|
||||
}
|
||||
int offset = 0;
|
||||
for (int y = 0; y < icon_size; y++) {
|
||||
float dy = y - icon_center;
|
||||
for (int x = 0; x < icon_size; x++) {
|
||||
float dx = x - icon_center;
|
||||
/* calculate aliasing */
|
||||
float alias = 0;
|
||||
const float alias_step = 0.333;
|
||||
for (float ay = dy - 0.5; ay < dy + 0.5; ay += alias_step) {
|
||||
for (float ax = dx - 0.5; ax < dx + 0.5; ax += alias_step) {
|
||||
if (sqrt(ay * ay + ax * ax) < sphere_radius) {
|
||||
alias += alias_step * alias_step;
|
||||
}
|
||||
}
|
||||
}
|
||||
uint pixelresult = 0x0;
|
||||
uint alias_i = clamp_i(alias * 256, 0, 255);
|
||||
if (alias_i != 0) {
|
||||
/* calculate normal */
|
||||
uint alias_mask = alias_i << 24;
|
||||
float incoming[3];
|
||||
copy_v3_fl3(incoming, 0.0, 1.0, 0.0);
|
||||
|
||||
void BKE_studiolight_free(void)
|
||||
{
|
||||
struct StudioLight *sl;
|
||||
while ((sl = BLI_pophead(&studiolights))) {
|
||||
studiolight_free(sl);
|
||||
}
|
||||
}
|
||||
float normal[3];
|
||||
normal[0] = dx / sphere_radius;
|
||||
normal[2] = dy / sphere_radius;
|
||||
normal[1] = -sqrt(-(normal[0] * normal[0]) - (normal[2] * normal[2]) + 1);
|
||||
normalize_v3(normal);
|
||||
|
||||
struct StudioLight *BKE_studiolight_find(const char *name)
|
||||
{
|
||||
LISTBASE_FOREACH(StudioLight *, sl, &studiolights) {
|
||||
if (STREQLEN(sl->name, name, FILE_MAXFILE)) {
|
||||
return sl;
|
||||
float direction[3];
|
||||
reflect_v3_v3v3(direction, incoming, normal);
|
||||
|
||||
float color[4];
|
||||
studiolight_calculate_radiance(sl->equirectangular_buffer, color, direction);
|
||||
|
||||
pixelresult = rgb_to_cpack(
|
||||
linearrgb_to_srgb(color[0]),
|
||||
linearrgb_to_srgb(color[1]),
|
||||
linearrgb_to_srgb(color[2])) | alias_mask;
|
||||
}
|
||||
rect[offset++] = pixelresult;
|
||||
}
|
||||
}
|
||||
/* When not found, use the default studio light */
|
||||
return studiolights.first;
|
||||
return rect;
|
||||
}
|
||||
|
||||
struct StudioLight *BKE_studiolight_findindex(int index)
|
||||
{
|
||||
LISTBASE_FOREACH(StudioLight *, sl, &studiolights) {
|
||||
if (sl->index == index) {
|
||||
return sl;
|
||||
}
|
||||
}
|
||||
/* When not found, use the default studio light */
|
||||
return studiolights.first;
|
||||
}
|
||||
|
||||
const struct ListBase *BKE_studiolight_listbase(void)
|
||||
{
|
||||
return &studiolights;
|
||||
}
|
||||
|
||||
unsigned int *BKE_studiolight_preview(StudioLight *sl, int icon_size)
|
||||
static unsigned int* studiolight_irradiance_preview(StudioLight *sl, int icon_size)
|
||||
{
|
||||
BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED);
|
||||
|
||||
@ -566,18 +596,101 @@ unsigned int *BKE_studiolight_preview(StudioLight *sl, int icon_size)
|
||||
return rect;
|
||||
}
|
||||
|
||||
/* API */
|
||||
void BKE_studiolight_init(void)
|
||||
{
|
||||
StudioLight *sl;
|
||||
/* go over the preset folder and add a studiolight for every image with its path */
|
||||
/* order studio lights by name */
|
||||
/* Also reserve icon space for it. */
|
||||
/* Add default studio light */
|
||||
sl = studiolight_create();
|
||||
BLI_strncpy(sl->name, "INTERNAL_01", FILE_MAXFILE);
|
||||
sl->flag = STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED | STUDIOLIGHT_ORIENTATION_CAMERA;
|
||||
copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_X_POS], 0.0f);
|
||||
copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_X_NEG], 0.0f);
|
||||
copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Y_POS], 1.0f);
|
||||
copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Y_NEG], 0.0f);
|
||||
copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Z_POS], 0.0f);
|
||||
copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Z_NEG], 0.0f);
|
||||
BLI_addtail(&studiolights, sl);
|
||||
|
||||
studiolight_add_files_from_datafolder(BLENDER_SYSTEM_DATAFILES, STUDIOLIGHT_CAMERA_FOLDER, STUDIOLIGHT_ORIENTATION_CAMERA);
|
||||
studiolight_add_files_from_datafolder(BLENDER_USER_DATAFILES, STUDIOLIGHT_CAMERA_FOLDER, STUDIOLIGHT_ORIENTATION_CAMERA);
|
||||
studiolight_add_files_from_datafolder(BLENDER_SYSTEM_DATAFILES, STUDIOLIGHT_WORLD_FOLDER, STUDIOLIGHT_ORIENTATION_WORLD);
|
||||
studiolight_add_files_from_datafolder(BLENDER_USER_DATAFILES, STUDIOLIGHT_WORLD_FOLDER, STUDIOLIGHT_ORIENTATION_WORLD);
|
||||
|
||||
/* sort studio lights on filename. */
|
||||
BLI_listbase_sort(&studiolights, studiolight_cmp);
|
||||
}
|
||||
|
||||
void BKE_studiolight_free(void)
|
||||
{
|
||||
struct StudioLight *sl;
|
||||
while ((sl = BLI_pophead(&studiolights))) {
|
||||
studiolight_free(sl);
|
||||
}
|
||||
}
|
||||
|
||||
struct StudioLight *BKE_studiolight_find(const char *name, int flag)
|
||||
{
|
||||
LISTBASE_FOREACH(StudioLight *, sl, &studiolights) {
|
||||
if (STREQLEN(sl->name, name, FILE_MAXFILE)) {
|
||||
if ((sl->flag & flag) == flag) {
|
||||
return sl;
|
||||
} else {
|
||||
/* flags do not match, so use default */
|
||||
return studiolights.first;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* When not found, use the default studio light */
|
||||
return studiolights.first;
|
||||
}
|
||||
|
||||
struct StudioLight *BKE_studiolight_findindex(int index)
|
||||
{
|
||||
LISTBASE_FOREACH(StudioLight *, sl, &studiolights) {
|
||||
if (sl->index == index) {
|
||||
return sl;
|
||||
}
|
||||
}
|
||||
/* When not found, use the default studio light */
|
||||
return studiolights.first;
|
||||
}
|
||||
|
||||
const struct ListBase *BKE_studiolight_listbase(void)
|
||||
{
|
||||
return &studiolights;
|
||||
}
|
||||
|
||||
unsigned int *BKE_studiolight_preview(StudioLight *sl, int icon_size, int icon_id_type)
|
||||
{
|
||||
if (icon_id_type == STUDIOLIGHT_ICON_ID_TYPE_IRRADIANCE) {
|
||||
return studiolight_irradiance_preview(sl, icon_size);
|
||||
} else {
|
||||
return studiolight_radiance_preview(sl, icon_size);
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_studiolight_ensure_flag(StudioLight *sl, int flag)
|
||||
{
|
||||
if ((sl->flag & flag) == flag) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((flag & STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED)) {
|
||||
studiolight_load_equierectangular_image(sl);
|
||||
}
|
||||
if ((flag & STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED)) {
|
||||
studiolight_calculate_radiance_buffers(sl);
|
||||
}
|
||||
if ((flag & STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED)) {
|
||||
studiolight_calculate_diffuse_light(sl);
|
||||
}
|
||||
if ((flag & STUDIOLIGHT_EQUIRECTANGULAR_GPUTEXTURE)) {
|
||||
studiolight_create_equierectangular_gputexture(sl);
|
||||
}
|
||||
if ((flag & STUDIOLIGHT_LIGHT_DIRECTION_CALCULATED)) {
|
||||
studiolight_calculate_light_direction(sl);
|
||||
}
|
||||
|
@ -97,6 +97,7 @@ set(SRC
|
||||
engines/eevee/eevee_engine.c
|
||||
engines/eevee/eevee_lightprobes.c
|
||||
engines/eevee/eevee_lights.c
|
||||
engines/eevee/eevee_lookdev.c
|
||||
engines/eevee/eevee_materials.c
|
||||
engines/eevee/eevee_mist.c
|
||||
engines/eevee/eevee_motion_blur.c
|
||||
|
@ -511,6 +511,13 @@ void EEVEE_draw_effects(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
|
||||
/* Save the final texture and framebuffer for final transformation or read. */
|
||||
effects->final_tx = effects->source_buffer;
|
||||
effects->final_fb = (effects->target_buffer != fbl->main_color_fb) ? fbl->main_fb : fbl->effect_fb;
|
||||
if ((effects->enabled_effects & EFFECT_TAA) && (effects->enabled_effects & (EFFECT_BLOOM | EFFECT_DOF | EFFECT_MOTION_BLUR)) == 0) {
|
||||
if (!effects->swap_double_buffer) {
|
||||
effects->final_fb = fbl->double_buffer_fb;
|
||||
} else {
|
||||
effects->final_fb = fbl->main_fb;
|
||||
}
|
||||
}
|
||||
|
||||
/* If no post processes is enabled, buffers are still not swapped, do it now. */
|
||||
SWAP_DOUBLE_BUFFERS();
|
||||
|
@ -187,7 +187,6 @@ static void eevee_draw_background(void *vedata)
|
||||
/* Default framebuffer and texture */
|
||||
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
||||
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
|
||||
|
||||
/* Sort transparents before the loop. */
|
||||
DRW_pass_sort_shgroup_z(psl->transparent_pass);
|
||||
|
||||
@ -310,6 +309,11 @@ static void eevee_draw_background(void *vedata)
|
||||
}
|
||||
}
|
||||
|
||||
/* LookDev */
|
||||
EEVEE_lookdev_draw_background(vedata);
|
||||
/* END */
|
||||
|
||||
|
||||
/* Tonemapping and transfer result to default framebuffer. */
|
||||
GPU_framebuffer_bind(dfbl->default_fb);
|
||||
DRW_transform_to_display(stl->effects->final_tx);
|
||||
|
@ -71,6 +71,7 @@
|
||||
|
||||
static struct {
|
||||
struct GPUShader *probe_default_sh;
|
||||
struct GPUShader *probe_default_studiolight_sh;
|
||||
struct GPUShader *probe_filter_glossy_sh;
|
||||
struct GPUShader *probe_filter_diffuse_sh;
|
||||
struct GPUShader *probe_filter_visibility_sh;
|
||||
@ -214,6 +215,9 @@ static void lightprobe_shaders_init(void)
|
||||
e_data.probe_default_sh = DRW_shader_create(
|
||||
datatoc_background_vert_glsl, NULL, datatoc_default_world_frag_glsl, NULL);
|
||||
|
||||
e_data.probe_default_studiolight_sh = DRW_shader_create(
|
||||
datatoc_background_vert_glsl, NULL, datatoc_default_world_frag_glsl, "#define LOOKDEV\n");
|
||||
|
||||
MEM_freeN(shader_str);
|
||||
|
||||
shader_str = BLI_string_joinN(
|
||||
@ -411,7 +415,11 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
|
||||
World *wo = scene->world;
|
||||
|
||||
float *col = ts.colorBackground;
|
||||
if (wo) {
|
||||
|
||||
/* LookDev */
|
||||
EEVEE_lookdev_cache_init(vedata, &grp, e_data.probe_default_studiolight_sh, psl->probe_background, pinfo);
|
||||
/* END */
|
||||
if (!grp && wo) {
|
||||
col = &wo->horr;
|
||||
bool wo_sh_compiled = true;
|
||||
|
||||
@ -445,6 +453,7 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
|
||||
|
||||
if (wo->update_flag != 0 || pinfo->prev_world != wo || pinfo->prev_wo_sh_compiled != wo_sh_compiled) {
|
||||
pinfo->update_world |= PROBE_UPDATE_ALL;
|
||||
pinfo->studiolight_index = 0;
|
||||
pinfo->prev_wo_sh_compiled = wo_sh_compiled;
|
||||
pinfo->prev_world = wo;
|
||||
}
|
||||
@ -452,6 +461,7 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
|
||||
}
|
||||
else if (pinfo->prev_world) {
|
||||
pinfo->update_world |= PROBE_UPDATE_ALL;
|
||||
pinfo->studiolight_index = 0;
|
||||
pinfo->prev_wo_sh_compiled = false;
|
||||
pinfo->prev_world = NULL;
|
||||
}
|
||||
@ -1830,6 +1840,7 @@ void EEVEE_lightprobes_free(void)
|
||||
MEM_SAFE_FREE(e_data.format_probe_display_cube);
|
||||
MEM_SAFE_FREE(e_data.format_probe_display_planar);
|
||||
DRW_SHADER_FREE_SAFE(e_data.probe_default_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.probe_default_studiolight_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.probe_filter_glossy_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.probe_filter_diffuse_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.probe_filter_visibility_sh);
|
||||
|
130
source/blender/draw/engines/eevee/eevee_lookdev.c
Normal file
130
source/blender/draw/engines/eevee/eevee_lookdev.c
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright 2016, Blender Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Contributor(s): Blender Institute
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file eevee_lookdev.c
|
||||
* \ingroup draw_engine
|
||||
*/
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "BKE_camera.h"
|
||||
#include "BKE_studiolight.h"
|
||||
|
||||
#include "DNA_screen_types.h"
|
||||
|
||||
#include "eevee_private.h"
|
||||
|
||||
void EEVEE_lookdev_cache_init(EEVEE_Data *vedata, DRWShadingGroup **grp, GPUShader *shader, DRWPass *pass, EEVEE_LightProbesInfo *pinfo)
|
||||
{
|
||||
EEVEE_StorageList *stl = vedata->stl;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
View3D *v3d = draw_ctx->v3d;
|
||||
if (v3d && v3d->drawtype == OB_MATERIAL)
|
||||
{
|
||||
StudioLight *sl = BKE_studiolight_find(v3d->shading.studio_light, STUDIOLIGHT_ORIENTATION_WORLD);
|
||||
if ((sl->flag & STUDIOLIGHT_ORIENTATION_WORLD)) {
|
||||
struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
|
||||
|
||||
BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECTANGULAR_GPUTEXTURE);
|
||||
*grp = DRW_shgroup_create(shader, pass);
|
||||
GPUTexture *tex = sl->equirectangular_gputexture;
|
||||
DRW_shgroup_uniform_texture(*grp, "image", tex);
|
||||
|
||||
axis_angle_to_mat3_single(stl->studiolight_matrix, 'Z', v3d->shading.studiolight_rot_z);
|
||||
DRW_shgroup_uniform_mat3(*grp, "StudioLightMatrix", stl->studiolight_matrix);
|
||||
|
||||
DRW_shgroup_uniform_float(*grp, "backgroundAlpha", &stl->g_data->background_alpha, 1);
|
||||
DRW_shgroup_call_add(*grp, geom, NULL);
|
||||
|
||||
/* Do we need to recalc the lightprobes? */
|
||||
if (pinfo && (pinfo->studiolight_index != sl->index || pinfo->studiolight_rot_z != v3d->shading.studiolight_rot_z)) {
|
||||
pinfo->update_world |= PROBE_UPDATE_ALL;
|
||||
pinfo->studiolight_index = sl->index;
|
||||
pinfo->studiolight_rot_z = v3d->shading.studiolight_rot_z;
|
||||
pinfo->prev_wo_sh_compiled = false;
|
||||
pinfo->prev_world = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EEVEE_lookdev_draw_background(EEVEE_Data *vedata)
|
||||
{
|
||||
EEVEE_PassList *psl = vedata->psl;
|
||||
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
|
||||
EEVEE_EffectsInfo *effects = stl->effects;
|
||||
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
|
||||
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
|
||||
if (psl->lookdev_pass && draw_ctx->v3d) {
|
||||
DRW_stats_group_start("Look Dev");
|
||||
CameraParams params;
|
||||
BKE_camera_params_init(¶ms);
|
||||
View3D *v3d = draw_ctx->v3d;
|
||||
RegionView3D *rv3d = draw_ctx->rv3d;
|
||||
ARegion *ar = draw_ctx->ar;
|
||||
|
||||
BKE_camera_params_from_view3d(¶ms, draw_ctx->depsgraph, v3d, rv3d);
|
||||
params.is_ortho = true;
|
||||
params.ortho_scale = 4.0;
|
||||
params.zoom = CAMERA_PARAM_ZOOM_INIT_PERSP;
|
||||
BKE_camera_params_compute_viewplane(¶ms, ar->winx, ar->winy, 1.0f, 1.0f);
|
||||
BKE_camera_params_compute_matrix(¶ms);
|
||||
|
||||
const float *viewport_size = DRW_viewport_size_get();
|
||||
int viewport_inset_x = viewport_size[0]/4;
|
||||
int viewport_inset_y = viewport_size[1]/4;
|
||||
|
||||
EEVEE_CommonUniformBuffer *common = &sldata->common_data;
|
||||
common->la_num_light = 0;
|
||||
common->prb_num_planar = 0;
|
||||
common->prb_num_render_cube = 1;
|
||||
common->prb_num_render_grid = 1;
|
||||
common->ao_dist = 0.0f;
|
||||
common->ao_factor = 0.0f;
|
||||
common->ao_settings = 0.0f;
|
||||
DRW_uniformbuffer_update(sldata->common_ubo, common);
|
||||
|
||||
/* override matrices */
|
||||
float winmat[4][4];
|
||||
float winmat_inv[4][4];
|
||||
copy_m4_m4(winmat, params.winmat);
|
||||
invert_m4_m4(winmat_inv, winmat);
|
||||
DRW_viewport_matrix_override_set(winmat, DRW_MAT_WIN);
|
||||
DRW_viewport_matrix_override_set(winmat_inv, DRW_MAT_WININV);
|
||||
float viewmat[4][4];
|
||||
DRW_viewport_matrix_get(viewmat, DRW_MAT_VIEW);
|
||||
float persmat[4][4];
|
||||
float persmat_inv[4][4];
|
||||
mul_m4_m4m4(persmat, winmat, viewmat);
|
||||
invert_m4_m4(persmat_inv, persmat);
|
||||
DRW_viewport_matrix_override_set(persmat, DRW_MAT_PERS);
|
||||
DRW_viewport_matrix_override_set(persmat_inv, DRW_MAT_PERSINV);
|
||||
|
||||
GPUFrameBuffer *fb = effects->final_fb;
|
||||
GPU_framebuffer_bind(fb);
|
||||
GPU_framebuffer_viewport_set(fb, viewport_size[0]-viewport_inset_x, 0, viewport_inset_x, viewport_inset_y);
|
||||
DRW_draw_pass(psl->lookdev_pass);
|
||||
|
||||
DRW_viewport_matrix_override_unset_all();
|
||||
DRW_stats_group_end();
|
||||
}
|
||||
}
|
@ -34,6 +34,7 @@
|
||||
#include "BKE_particle.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_pbvh.h"
|
||||
#include "BKE_studiolight.h"
|
||||
|
||||
#include "DNA_world_types.h"
|
||||
#include "DNA_modifier_types.h"
|
||||
@ -54,6 +55,7 @@ static struct {
|
||||
struct GPUShader *default_prepass_clip_sh;
|
||||
struct GPUShader *default_lit[VAR_MAT_MAX];
|
||||
struct GPUShader *default_background;
|
||||
struct GPUShader *default_studiolight_background;
|
||||
struct GPUShader *update_noise_sh;
|
||||
|
||||
/* 64*64 array texture containing all LUTs and other utilitarian arrays.
|
||||
@ -320,6 +322,9 @@ static char *eevee_get_defines(int options)
|
||||
if (((options & VAR_MAT_VOLUME) != 0) && ((options & VAR_MAT_BLEND) != 0)) {
|
||||
BLI_dynstr_appendf(ds, "#define USE_ALPHA_BLEND_VOLUMETRICS\n");
|
||||
}
|
||||
if ((options & VAR_MAT_LOOKDEV) != 0) {
|
||||
BLI_dynstr_appendf(ds, "#define LOOKDEV\n");
|
||||
}
|
||||
|
||||
str = BLI_dynstr_get_cstring(ds);
|
||||
BLI_dynstr_free(ds);
|
||||
@ -578,6 +583,10 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata, EEVEE_StorageList *stl, E
|
||||
datatoc_background_vert_glsl, NULL, datatoc_default_world_frag_glsl,
|
||||
NULL);
|
||||
|
||||
e_data.default_studiolight_background = DRW_shader_create(
|
||||
datatoc_background_vert_glsl, NULL, datatoc_default_world_frag_glsl,
|
||||
"#define LOOKDEV\n");
|
||||
|
||||
e_data.default_prepass_sh = DRW_shader_create(
|
||||
datatoc_prepass_vert_glsl, NULL, datatoc_prepass_frag_glsl,
|
||||
NULL);
|
||||
@ -861,6 +870,35 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_get(
|
||||
return DRW_shgroup_create(e_data.default_lit[options], vedata->psl->default_pass[options]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a default shading group inside the lookdev pass without standard uniforms.
|
||||
**/
|
||||
static struct DRWShadingGroup *EEVEE_lookdev_shading_group_get(
|
||||
EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata,
|
||||
bool use_ssr, int shadow_method)
|
||||
{
|
||||
static int ssr_id;
|
||||
ssr_id = (use_ssr) ? 1 : -1;
|
||||
int options = VAR_MAT_MESH | VAR_MAT_LOOKDEV;
|
||||
|
||||
options |= eevee_material_shadow_option(shadow_method);
|
||||
|
||||
if (e_data.default_lit[options] == NULL) {
|
||||
create_default_shader(options);
|
||||
}
|
||||
|
||||
if (vedata->psl->lookdev_pass == NULL) {
|
||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_CULL_BACK;
|
||||
vedata->psl->lookdev_pass = DRW_pass_create("LookDev Pass", state);
|
||||
|
||||
DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], vedata->psl->lookdev_pass);
|
||||
/* XXX / WATCH: This creates non persistent binds for the ubos and textures.
|
||||
* But it's currently OK because the following shgroups does not add any bind. */
|
||||
add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, false, false);
|
||||
}
|
||||
|
||||
return DRW_shgroup_create(e_data.default_lit[options], vedata->psl->lookdev_pass);
|
||||
}
|
||||
void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
|
||||
{
|
||||
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
|
||||
@ -884,7 +922,11 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
|
||||
|
||||
float *col = ts.colorBackground;
|
||||
|
||||
if (wo) {
|
||||
/* LookDev */
|
||||
EEVEE_lookdev_cache_init(vedata, &grp, e_data.default_studiolight_background, psl->background_pass, NULL);
|
||||
/* END */
|
||||
|
||||
if (!grp && wo) {
|
||||
col = &wo->horr;
|
||||
|
||||
if (wo->use_nodes && wo->nodetree) {
|
||||
@ -1588,6 +1630,43 @@ void EEVEE_materials_cache_finish(EEVEE_Data *vedata)
|
||||
{
|
||||
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
|
||||
|
||||
/* Look-Dev */
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
const View3D *v3d = draw_ctx->v3d;
|
||||
if (v3d && v3d->drawtype == OB_MATERIAL) {
|
||||
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
|
||||
EEVEE_LampsInfo *linfo = sldata->lamps;
|
||||
struct Gwn_Batch *sphere = DRW_cache_sphere_get();
|
||||
static float mat1[4][4];
|
||||
static float color[3] = {1.0, 1.0, 1.0};
|
||||
static float metallic_on = 1.0f;
|
||||
static float metallic_off = 0.00f;
|
||||
static float specular = 1.0f;
|
||||
static float roughness = 0.05f;
|
||||
|
||||
float view_mat[4][4];
|
||||
DRW_viewport_matrix_get(view_mat, DRW_MAT_VIEWINV);
|
||||
|
||||
DRWShadingGroup *shgrp = EEVEE_lookdev_shading_group_get(sldata, vedata, false, linfo->shadow_method);
|
||||
DRW_shgroup_uniform_vec3(shgrp, "basecol", color, 1);
|
||||
DRW_shgroup_uniform_float(shgrp, "metallic", &metallic_on, 1);
|
||||
DRW_shgroup_uniform_float(shgrp, "specular", &specular, 1);
|
||||
DRW_shgroup_uniform_float(shgrp, "roughness", &roughness, 1);
|
||||
unit_m4(mat1);
|
||||
mul_m4_m4m4(mat1, mat1, view_mat);
|
||||
translate_m4(mat1, -1.5f, 0.0f, -5.0f);
|
||||
DRW_shgroup_call_add(shgrp, sphere, mat1);
|
||||
|
||||
shgrp = EEVEE_lookdev_shading_group_get(sldata, vedata, false, linfo->shadow_method);
|
||||
DRW_shgroup_uniform_vec3(shgrp, "basecol", color, 1);
|
||||
DRW_shgroup_uniform_float(shgrp, "metallic", &metallic_off, 1);
|
||||
DRW_shgroup_uniform_float(shgrp, "specular", &specular, 1);
|
||||
DRW_shgroup_uniform_float(shgrp, "roughness", &roughness, 1);
|
||||
translate_m4(mat1, 3.0f, 0.0f, 0.0f);
|
||||
DRW_shgroup_call_add(shgrp, sphere, mat1);
|
||||
}
|
||||
/* END */
|
||||
|
||||
BLI_ghash_free(stl->g_data->material_hash, NULL, MEM_freeN);
|
||||
BLI_ghash_free(stl->g_data->hair_material_hash, NULL, NULL);
|
||||
}
|
||||
@ -1603,6 +1682,7 @@ void EEVEE_materials_free(void)
|
||||
DRW_SHADER_FREE_SAFE(e_data.default_prepass_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.default_prepass_clip_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.default_background);
|
||||
DRW_SHADER_FREE_SAFE(e_data.default_studiolight_background);
|
||||
DRW_SHADER_FREE_SAFE(e_data.update_noise_sh);
|
||||
DRW_TEXTURE_FREE_SAFE(e_data.util_tex);
|
||||
DRW_TEXTURE_FREE_SAFE(e_data.noise_tex);
|
||||
|
@ -101,28 +101,29 @@ enum {
|
||||
|
||||
/* Material shader variations */
|
||||
enum {
|
||||
VAR_MAT_MESH = (1 << 0),
|
||||
VAR_MAT_PROBE = (1 << 1),
|
||||
VAR_MAT_HAIR = (1 << 2),
|
||||
VAR_MAT_FLAT = (1 << 3),
|
||||
VAR_MAT_BLEND = (1 << 4),
|
||||
VAR_MAT_VSM = (1 << 5),
|
||||
VAR_MAT_ESM = (1 << 6),
|
||||
VAR_MAT_VOLUME = (1 << 7),
|
||||
VAR_MAT_MESH = (1 << 0),
|
||||
VAR_MAT_PROBE = (1 << 1),
|
||||
VAR_MAT_HAIR = (1 << 2),
|
||||
VAR_MAT_FLAT = (1 << 3),
|
||||
VAR_MAT_BLEND = (1 << 4),
|
||||
VAR_MAT_VSM = (1 << 5),
|
||||
VAR_MAT_ESM = (1 << 6),
|
||||
VAR_MAT_VOLUME = (1 << 7),
|
||||
VAR_MAT_LOOKDEV = (1 << 8),
|
||||
/* Max number of variation */
|
||||
/* IMPORTANT : Leave it last and set
|
||||
* it's value accordingly. */
|
||||
VAR_MAT_MAX = (1 << 8),
|
||||
VAR_MAT_MAX = (1 << 9),
|
||||
/* These are options that are not counted in VAR_MAT_MAX
|
||||
* because they are not cumulative with the others above. */
|
||||
VAR_MAT_CLIP = (1 << 9),
|
||||
VAR_MAT_HASH = (1 << 10),
|
||||
VAR_MAT_MULT = (1 << 11),
|
||||
VAR_MAT_SHADOW = (1 << 12),
|
||||
VAR_MAT_REFRACT = (1 << 13),
|
||||
VAR_MAT_SSS = (1 << 14),
|
||||
VAR_MAT_TRANSLUC = (1 << 15),
|
||||
VAR_MAT_SSSALBED = (1 << 16),
|
||||
VAR_MAT_CLIP = (1 << 10),
|
||||
VAR_MAT_HASH = (1 << 11),
|
||||
VAR_MAT_MULT = (1 << 12),
|
||||
VAR_MAT_SHADOW = (1 << 13),
|
||||
VAR_MAT_REFRACT = (1 << 14),
|
||||
VAR_MAT_SSS = (1 << 15),
|
||||
VAR_MAT_TRANSLUC = (1 << 16),
|
||||
VAR_MAT_SSSALBED = (1 << 17),
|
||||
};
|
||||
|
||||
typedef struct EEVEE_BoundSphere {
|
||||
@ -205,6 +206,7 @@ typedef struct EEVEE_PassList {
|
||||
struct DRWPass *transparent_pass;
|
||||
struct DRWPass *background_pass;
|
||||
struct DRWPass *update_noise_pass;
|
||||
struct DRWPass *lookdev_pass;
|
||||
} EEVEE_PassList;
|
||||
|
||||
typedef struct EEVEE_FramebufferList {
|
||||
@ -277,6 +279,8 @@ typedef struct EEVEE_StorageList {
|
||||
struct EEVEE_EffectsInfo *effects;
|
||||
|
||||
struct EEVEE_PrivateData *g_data;
|
||||
/* XXX: move to better place */
|
||||
float studiolight_matrix[3][3];
|
||||
} EEVEE_StorageList;
|
||||
|
||||
/* ************ LIGHT UBO ************* */
|
||||
@ -452,6 +456,8 @@ typedef struct EEVEE_LightProbesInfo {
|
||||
float visibility_blur;
|
||||
float intensity_fac;
|
||||
int shres;
|
||||
int studiolight_index;
|
||||
float studiolight_rot_z;
|
||||
/* List of probes in the scene. */
|
||||
/* XXX This is fragile, can get out of sync quickly. */
|
||||
struct Object *probes_cube_ref[MAX_PROBE];
|
||||
@ -929,6 +935,10 @@ void EEVEE_render_cache(void *vedata, struct Object *ob, struct RenderEngine *en
|
||||
void EEVEE_render_draw(EEVEE_Data *vedata, struct RenderEngine *engine, struct RenderLayer *render_layer, const struct rcti *rect);
|
||||
void EEVEE_render_update_passes(struct RenderEngine *engine, struct Scene *scene, struct ViewLayer *view_layer);
|
||||
|
||||
/** eevee_lookdev.c */
|
||||
void EEVEE_lookdev_cache_init(EEVEE_Data *vedata, DRWShadingGroup **grp, GPUShader *shader, DRWPass *pass, EEVEE_LightProbesInfo *pinfo);
|
||||
void EEVEE_lookdev_draw_background(EEVEE_Data *vedata);
|
||||
|
||||
/* Shadow Matrix */
|
||||
static const float texcomat[4][4] = { /* From NDC to TexCo */
|
||||
{0.5f, 0.0f, 0.0f, 0.0f},
|
||||
|
@ -15,5 +15,9 @@ Closure nodetree_exec(void)
|
||||
|
||||
Closure result = Closure(out_spec + out_diff * albedo, 1.0, vec4(ssr_spec, roughness), normal_encode(normalize(viewNormal), viewCameraVec), 0);
|
||||
|
||||
#ifdef LOOKDEV
|
||||
gl_FragDepth = 0.0;
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -1,9 +1,57 @@
|
||||
#define M_PI 3.14159265358979323846
|
||||
|
||||
uniform float backgroundAlpha;
|
||||
uniform mat4 ProjectionMatrix;
|
||||
uniform mat4 ProjectionMatrixInverse;
|
||||
uniform mat4 ViewMatrixInverse;
|
||||
#ifdef LOOKDEV
|
||||
uniform mat3 StudioLightMatrix;
|
||||
uniform sampler2D image;
|
||||
in vec3 viewPosition;
|
||||
#else
|
||||
uniform vec3 color;
|
||||
#endif
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main() {
|
||||
FragColor = vec4(color, backgroundAlpha);
|
||||
void background_transform_to_world(vec3 viewvec, out vec3 worldvec)
|
||||
{
|
||||
vec4 v = (ProjectionMatrix[3][3] == 0.0) ? vec4(viewvec, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
|
||||
vec4 co_homogenous = (ProjectionMatrixInverse * v);
|
||||
|
||||
vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
|
||||
worldvec = (ViewMatrixInverse * co).xyz;
|
||||
}
|
||||
|
||||
float hypot(float x, float y)
|
||||
{
|
||||
return sqrt(x * x + y * y);
|
||||
}
|
||||
|
||||
void node_tex_environment_equirectangular(vec3 co, sampler2D ima, out vec4 color)
|
||||
{
|
||||
vec3 nco = normalize(co);
|
||||
float u = -atan(nco.y, nco.x) / (2.0 * M_PI) + 0.5;
|
||||
float v = atan(nco.z, hypot(nco.x, nco.y)) / M_PI + 0.5;
|
||||
|
||||
/* Fix pole bleeding */
|
||||
float half_width = 0.5 / float(textureSize(ima, 0).x);
|
||||
v = clamp(v, half_width, 1.0 - half_width);
|
||||
|
||||
/* Fix u = 0 seam */
|
||||
/* This is caused by texture filtering, since uv don't have smooth derivatives
|
||||
* at u = 0 or 2PI, hardware filtering is using the smallest mipmap for certain
|
||||
* texels. So we force the highest mipmap and don't do anisotropic filtering. */
|
||||
color = textureLod(ima, vec2(u, v), 0.0);
|
||||
}
|
||||
|
||||
void main() {
|
||||
#ifdef LOOKDEV
|
||||
vec3 worldvec;
|
||||
vec4 color;
|
||||
background_transform_to_world(viewPosition, worldvec);
|
||||
node_tex_environment_equirectangular(StudioLightMatrix * worldvec, image, color);
|
||||
#endif
|
||||
|
||||
FragColor = vec4(clamp(color.rgb, vec3(0.0), vec3(1e10)), backgroundAlpha);
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd)
|
||||
if (v3d) {
|
||||
wpd->shading = v3d->shading;
|
||||
wpd->drawtype = v3d->drawtype;
|
||||
wpd->studio_light = BKE_studiolight_find(wpd->shading.studio_light);
|
||||
wpd->studio_light = BKE_studiolight_find(wpd->shading.studio_light, 0);
|
||||
}
|
||||
else {
|
||||
memset(&wpd->shading, 0, sizeof(wpd->shading));
|
||||
|
@ -783,7 +783,7 @@ static DrawInfo *icon_create_drawinfo(Icon *icon)
|
||||
IconImage *img = MEM_mallocN(sizeof(IconImage), __func__);
|
||||
img->w = STUDIOLIGHT_SIZE;
|
||||
img->h = STUDIOLIGHT_SIZE;
|
||||
img->rect = BKE_studiolight_preview(sl, STUDIOLIGHT_SIZE);
|
||||
img->rect = BKE_studiolight_preview(sl, STUDIOLIGHT_SIZE, icon->id_type);
|
||||
di->data.buffer.image = img;
|
||||
}
|
||||
else {
|
||||
|
@ -655,12 +655,7 @@ static int rna_3DViewShading_type_get(PointerRNA *ptr)
|
||||
RenderEngineType *type = RE_engines_find(scene->r.engine);
|
||||
View3D *v3d = (View3D *)ptr->data;
|
||||
|
||||
if (BKE_scene_uses_blender_eevee(scene)) {
|
||||
if (v3d->drawtype == OB_MATERIAL) {
|
||||
return OB_RENDER;
|
||||
}
|
||||
}
|
||||
else if (v3d->drawtype == OB_RENDER) {
|
||||
if (!BKE_scene_uses_blender_eevee(scene) && v3d->drawtype == OB_RENDER) {
|
||||
if (!(type && type->render_to_view)) {
|
||||
return OB_MATERIAL;
|
||||
}
|
||||
@ -693,6 +688,7 @@ static const EnumPropertyItem *rna_3DViewShading_type_itemf(
|
||||
RNA_enum_items_add_value(&item, &totitem, rna_enum_shading_type_items, OB_TEXTURE);
|
||||
|
||||
if (BKE_scene_uses_blender_eevee(scene)) {
|
||||
RNA_enum_items_add_value(&item, &totitem, rna_enum_shading_type_items, OB_MATERIAL);
|
||||
RNA_enum_items_add_value(&item, &totitem, rna_enum_shading_type_items, OB_RENDER);
|
||||
}
|
||||
else {
|
||||
@ -711,7 +707,7 @@ static const EnumPropertyItem *rna_3DViewShading_type_itemf(
|
||||
static int rna_View3DShading_studio_light_orientation_get(PointerRNA *ptr)
|
||||
{
|
||||
View3D *v3d = (View3D *)ptr->data;
|
||||
StudioLight *sl = BKE_studiolight_find(v3d->shading.studio_light);
|
||||
StudioLight *sl = BKE_studiolight_find(v3d->shading.studio_light, 0);
|
||||
return sl->flag & (STUDIOLIGHT_ORIENTATION_WORLD | STUDIOLIGHT_ORIENTATION_CAMERA);
|
||||
}
|
||||
static void rna_View3DShading_studio_light_orientation_set(PointerRNA *UNUSED(ptr), int UNUSED(value))
|
||||
@ -721,7 +717,9 @@ static void rna_View3DShading_studio_light_orientation_set(PointerRNA *UNUSED(pt
|
||||
static int rna_View3DShading_studio_light_get(PointerRNA *ptr)
|
||||
{
|
||||
View3D *v3d = (View3D *)ptr->data;
|
||||
StudioLight *sl = BKE_studiolight_find(v3d->shading.studio_light);
|
||||
const int flag = v3d->drawtype == OB_MATERIAL? STUDIOLIGHT_ORIENTATION_WORLD: 0;
|
||||
StudioLight *sl = BKE_studiolight_find(v3d->shading.studio_light, flag);
|
||||
BLI_strncpy(v3d->shading.studio_light, sl->name, FILE_MAXFILE);
|
||||
return sl->index;
|
||||
}
|
||||
|
||||
@ -733,19 +731,40 @@ static void rna_View3DShading_studio_light_set(PointerRNA *ptr, int value)
|
||||
}
|
||||
|
||||
static const EnumPropertyItem *rna_View3DShading_studio_light_itemf(
|
||||
bContext *UNUSED(C), PointerRNA *UNUSED(ptr),
|
||||
bContext *UNUSED(C), PointerRNA *ptr,
|
||||
PropertyRNA *UNUSED(prop), bool *r_free)
|
||||
{
|
||||
View3D *v3d = (View3D *)ptr->data;
|
||||
EnumPropertyItem *item = NULL;
|
||||
EnumPropertyItem *lastitem;
|
||||
int totitem = 0;
|
||||
bool show_studiolight;
|
||||
|
||||
LISTBASE_FOREACH(StudioLight *, sl, BKE_studiolight_listbase()) {
|
||||
if (totitem < NUM_STUDIOLIGHT_ITEMS) {
|
||||
RNA_enum_items_add_value(&item, &totitem, rna_enum_studio_light_items, totitem);
|
||||
show_studiolight = false;
|
||||
int icon_id = sl->irradiance_icon_id;
|
||||
|
||||
if ((sl->flag & STUDIOLIGHT_EXTERNAL_FILE) == 0) {
|
||||
/* always show internal lights */
|
||||
show_studiolight = true;
|
||||
} else {
|
||||
switch (v3d->drawtype) {
|
||||
case OB_SOLID:
|
||||
case OB_TEXTURE:
|
||||
show_studiolight = true;
|
||||
break;
|
||||
case OB_MATERIAL:
|
||||
show_studiolight = (sl->flag & STUDIOLIGHT_ORIENTATION_WORLD) > 0;
|
||||
icon_id = sl->radiance_icon_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (show_studiolight && totitem < NUM_STUDIOLIGHT_ITEMS) {
|
||||
RNA_enum_items_add_value(&item, &totitem, rna_enum_studio_light_items, sl->index);
|
||||
lastitem = &item[totitem - 1];
|
||||
lastitem->value = sl->index;
|
||||
lastitem->icon = sl->icon_id;
|
||||
lastitem->icon = icon_id;
|
||||
lastitem->name = sl->name;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user