diff options
author | Jeroen Bakker <j.bakker@atmind.nl> | 2018-05-31 14:32:53 +0300 |
---|---|---|
committer | Jeroen Bakker <j.bakker@atmind.nl> | 2018-06-01 12:01:55 +0300 |
commit | c450966e9562eb352b869f3b554d60a42dea2fa1 (patch) | |
tree | 8cdf507041087221dbf07c66f476b8618312872d /source | |
parent | 3b2d3a3cd11d07945b18252359378ffadddfe3bd (diff) |
Workbench: Material specific settings for the specular
- Uses the roughness setting of the basic eevee material
- renamed gloss_mir to roughness
- set default of roughness to 0.25
- renamed ray_mirror to metallic
- cleaned up material rna (BI mirror struct)
- use BLINN phong model
- normalize incoming/outgoing specular light
- when using camera oriented studiolight, the SolidLight will be used
for specular highlights
- EXPERIMENT: when in world oriented studiolight only the shadow direction will be used.
- change the settings of the internal light to make scenes more
readable
Diffstat (limited to 'source')
21 files changed, 253 insertions, 128 deletions
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 404761d2c36..c98e8ff109c 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -116,7 +116,7 @@ void BKE_material_init(Material *ma) ma->alpha = 1.0; ma->spec = 0.5; - ma->gloss_mir = 1.0; + ma->roughness = 0.25f; ma->pr_lamp = 3; /* two lamps, is bits */ ma->pr_type = MA_SPHERE; diff --git a/source/blender/blenkernel/intern/studiolight.c b/source/blender/blenkernel/intern/studiolight.c index 76b655f1fa5..fa8516a0a01 100644 --- a/source/blender/blenkernel/intern/studiolight.c +++ b/source/blender/blenkernel/intern/studiolight.c @@ -631,10 +631,10 @@ void BKE_studiolight_init(void) 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_POS], 0.8f); 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); + copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Z_POS], 0.2f); + copy_v3_fl(sl->diffuse_light[STUDIOLIGHT_Z_NEG], 0.1f); BLI_addtail(&studiolights, sl); studiolight_add_files_from_datafolder(BLENDER_SYSTEM_DATAFILES, STUDIOLIGHT_CAMERA_FOLDER, STUDIOLIGHT_ORIENTATION_CAMERA); diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 67f53d4d952..50ed9bfd146 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -1493,13 +1493,24 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main) part->rad_scale = 0.01f; } } - } + } { - if (!DNA_struct_elem_find(fd->filesdna, "SceneDisplay", "float", "roughness")) { - for (Scene *scene = main->scene.first; scene; scene = scene->id.next) { - scene->display.roughness = 0.5f; + if (!DNA_struct_elem_find(fd->filesdna, "Material", "float", "roughness")) { + for (Material *mat = main->mat.first; mat; mat = mat->id.next) { + if (mat->use_nodes) { + if (MAIN_VERSION_ATLEAST(main, 280, 0)) { + mat->roughness = mat->gloss_mir; + } else { + mat->roughness = 0.25f; + } + } + else { + mat->roughness = 1.0f - mat->gloss_mir; + } + mat->metallic = mat->ray_mirror; } + for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) { for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp index 89015f45e5a..47b720614ea 100644 --- a/source/blender/collada/DocumentImporter.cpp +++ b/source/blender/collada/DocumentImporter.cpp @@ -797,7 +797,7 @@ void DocumentImporter::write_profile_COMMON(COLLADAFW::EffectCommon *ef, Materia #endif } // reflectivity - ma->ray_mirror = ef->getReflectivity().getFloatValue(); + ma->metallic = ef->getReflectivity().getFloatValue(); // index of refraction #if 0 ma->ang = ef->getIndexOfRefraction().getFloatValue(); diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index 85c312d311c..42e81373914 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -1117,9 +1117,9 @@ static void material_opaque( EEVEE_LampsInfo *linfo = sldata->lamps; float *color_p = &ma->r; - float *metal_p = &ma->ray_mirror; + float *metal_p = &ma->metallic; float *spec_p = &ma->spec; - float *rough_p = &ma->gloss_mir; + float *rough_p = &ma->roughness; const bool use_gpumat = (ma->use_nodes && ma->nodetree); const bool use_refract = ((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) && @@ -1297,9 +1297,9 @@ static void material_transparent( ((stl->effects->enabled_effects & EFFECT_REFRACT) != 0) ); float *color_p = &ma->r; - float *metal_p = &ma->ray_mirror; + float *metal_p = &ma->metallic; float *spec_p = &ma->spec; - float *rough_p = &ma->gloss_mir; + float *rough_p = &ma->roughness; if (ma->use_nodes && ma->nodetree) { static float error_col[3] = {1.0f, 0.0f, 1.0f}; @@ -1605,9 +1605,9 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sld } float *color_p = &ma->r; - float *metal_p = &ma->ray_mirror; + float *metal_p = &ma->metallic; float *spec_p = &ma->spec; - float *rough_p = &ma->gloss_mir; + float *rough_p = &ma->roughness; shgrp = DRW_shgroup_hair_create( ob, psys, md, diff --git a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl index 88b715f55a8..39c6863e71c 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl @@ -1,5 +1,7 @@ #define NO_OBJECT_ID uint(0) #define EPSILON 0.00001 +#define M_PI 3.14159265358979323846 + /* 4x4 bayer matrix prepared for 8bit UNORM precision error. */ #define P(x) (((x + 0.5) * (1.0 / 16.0) - 0.5) * (1.0 / 255.0)) const vec4 dither_mat4x4[4] = vec4[4]( diff --git a/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl index c826a5b82fa..fc076ee8117 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl @@ -1,3 +1,8 @@ +struct LightData { + vec4 light_direction_vs; + vec4 specular_color; +}; + struct WorldData { vec4 diffuse_light_x_pos; vec4 diffuse_light_x_neg; @@ -9,5 +14,13 @@ struct WorldData { vec4 background_color_high; vec4 object_outline_color; vec4 light_direction_vs; - float specular_sharpness; + LightData lights[3]; + int num_lights; + int pad[3]; +}; + +struct MaterialData { + vec4 diffuse_color; + vec4 specular_color; + float roughness; }; diff --git a/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl index 7374dfbe79e..269911189fa 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl @@ -2,6 +2,7 @@ out vec4 fragColor; uniform usampler2D objectId; uniform sampler2D colorBuffer; +uniform sampler2D specularBuffer; uniform sampler2D normalBuffer; /* normalBuffer contains viewport normals */ uniform vec2 invertedViewportSize; @@ -54,6 +55,14 @@ void main() #endif /* WORKBENCH_ENCODE_NORMALS */ #endif +#ifdef V3D_SHADING_SPECULAR_HIGHLIGHT + /* XXX Should calculate the correct VS Incoming direction */ + vec3 I_vs = vec3(0.0, 0.0, 1.0); + vec4 specular_data = texelFetch(specularBuffer, texel, 0); + vec3 specular_color = get_world_specular_lights(world_data, specular_data, normal_viewport, I_vs); +#else + vec3 specular_color = vec3(0.0); +#endif #ifdef V3D_LIGHTING_STUDIO #ifdef STUDIOLIGHT_ORIENTATION_CAMERA @@ -64,20 +73,11 @@ void main() vec3 normal_world = normalWorldMatrix * normal_viewport; vec3 diffuse_light = get_world_diffuse_light(world_data, normal_world); #endif - - vec3 specular_color = get_world_specular_light(world_data, normal_viewport, vec3(0.0, 0.0, 1.0)); vec3 shaded_color = diffuse_light * diffuse_color.rgb + specular_color; #else /* V3D_LIGHTING_STUDIO */ - #ifdef V3D_SHADING_SPECULAR_HIGHLIGHT - vec3 specular_color = get_world_specular_light(world_data, normal_viewport, vec3(0.0, 0.0, 1.0)); vec3 shaded_color = diffuse_color.rgb + specular_color; - #else /* V3D_SHADING_SPECULAR_HIGHLIGHT */ - vec3 shaded_color = diffuse_color.rgb; - - #endif /* V3D_SHADING_SPECULAR_HIGHLIGHT */ - #endif /* V3D_LIGHTING_STUDIO */ #ifdef V3D_SHADING_SHADOW diff --git a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl index d0e3305cc70..88b32cb9b20 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl @@ -1,4 +1,3 @@ -uniform vec4 color = vec4(0.0, 0.0, 1.0, 1.0); #ifdef OB_TEXTURE uniform sampler2D image; #endif @@ -15,6 +14,10 @@ layout(std140) uniform world_block { WorldData world_data; }; +layout(std140) uniform material_block { + MaterialData material_data; +}; + layout(location=0) out vec4 transparentAccum; @@ -22,12 +25,18 @@ void main() { vec4 diffuse_color; #ifdef OB_SOLID - diffuse_color = color; + diffuse_color = material_data.diffuse_color; #endif /* OB_SOLID */ #ifdef OB_TEXTURE diffuse_color = texture(image, uv_interp); #endif /* OB_TEXTURE */ +#ifdef V3D_SHADING_SPECULAR_HIGHLIGHT + vec3 specular_color = get_world_specular_lights(world_data, vec4(material_data.specular_color.rgb, material_data.roughness), normal_viewport, vec3(0.0, 0.0, 1.0)); +#else + vec3 specular_color = vec3(0.0); +#endif + #ifdef V3D_LIGHTING_STUDIO #ifdef STUDIOLIGHT_ORIENTATION_CAMERA vec3 diffuse_light = get_camera_diffuse_light(world_data, normal_viewport); @@ -37,19 +46,11 @@ void main() vec3 diffuse_light = get_world_diffuse_light(world_data, normal_world); #endif - vec3 specular_color = get_world_specular_light(world_data, normal_viewport, vec3(0.0, 0.0, 1.0)); vec3 shaded_color = diffuse_light * diffuse_color.rgb + specular_color; #else /* V3D_LIGHTING_STUDIO */ - #ifdef V3D_SHADING_SPECULAR_HIGHLIGHT - vec3 specular_color = get_world_specular_light(world_data, normal_viewport, vec3(0.0, 0.0, 1.0)); vec3 shaded_color = diffuse_color.rgb + specular_color; - #else /* V3D_SHADING_SPECULAR_HIGHLIGHT */ - vec3 shaded_color = diffuse_color.rgb; - - #endif /* V3D_SHADING_SPECULAR_HIGHLIGHT */ - #endif /* V3D_LIGHTING_STUDIO */ float alpha = 0.5 ; diff --git a/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl index 2cc0ff3723d..c0f58271a8c 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl @@ -1,5 +1,9 @@ uniform int object_id = 0; -uniform vec3 object_color = vec3(1.0, 0.0, 1.0); + +layout(std140) uniform material_block { + MaterialData material_data; +}; + #ifdef OB_TEXTURE uniform sampler2D image; #endif @@ -13,11 +17,12 @@ in vec2 uv_interp; layout(location=0) out uint objectId; layout(location=1) out vec4 diffuseColor; +layout(location=2) out vec4 specularColor; #ifdef NORMAL_VIEWPORT_PASS_ENABLED #ifdef WORKBENCH_ENCODE_NORMALS -layout(location=2) out vec2 normalViewport; +layout(location=3) out vec2 normalViewport; #else /* WORKBENCH_ENCODE_NORMALS */ -layout(location=2) out vec3 normalViewport; +layout(location=3) out vec3 normalViewport; #endif /* WORKBENCH_ENCODE_NORMALS */ #endif /* NORMAL_VIEWPORT_PASS_ENABLED */ @@ -25,12 +30,16 @@ void main() { objectId = uint(object_id); #ifdef OB_SOLID - diffuseColor = vec4(object_color, 0.0); + diffuseColor = vec4(material_data.diffuse_color.rgb, 0.0); #endif /* OB_SOLID */ #ifdef OB_TEXTURE diffuseColor = texture(image, uv_interp); #endif /* OB_TEXTURE */ +#ifdef V3D_SHADING_SPECULAR_HIGHLIGHT + specularColor = vec4(material_data.specular_color.rgb, material_data.roughness); +#endif + #ifdef NORMAL_VIEWPORT_PASS_ENABLED #ifdef WORKBENCH_ENCODE_NORMALS if (!gl_FrontFacing) { diff --git a/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl index 7d1084c78b4..be124257c33 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl @@ -1,3 +1,5 @@ +#define BLINN + vec3 get_world_diffuse_light(WorldData world_data, vec3 N) { vec4 result = world_data.diffuse_light_x_pos * clamp(N.x, 0.0, 1.0); @@ -14,19 +16,33 @@ vec3 get_camera_diffuse_light(WorldData world_data, vec3 N) result = mix(result, world_data.diffuse_light_x_neg, clamp(-N.x, 0.0, 1.0)); result = mix(result, world_data.diffuse_light_z_pos, clamp( N.y, 0.0, 1.0)); result = mix(result, world_data.diffuse_light_z_neg, clamp(-N.y, 0.0, 1.0)); - result = mix(result, world_data.diffuse_light_y_pos, pow(clamp( N.z, 0.0, 1.0), 2.0)); + result = mix(result, world_data.diffuse_light_y_pos, clamp( N.z, 0.0, 1.0)); result = mix(result, world_data.diffuse_light_y_neg, clamp(-N.z, 0.0, 1.0)); return result.rgb; } /* N And I are in View Space. */ -vec3 get_world_specular_light(WorldData world_data, vec3 N, vec3 I) +vec3 get_world_specular_light(vec4 specular_data, LightData light_data, vec3 N, vec3 I) { #ifdef V3D_SHADING_SPECULAR_HIGHLIGHT + vec3 specular_light = specular_data.rgb * light_data.specular_color.rgb * light_data.specular_color.a; + + float shininess = exp2(10*(1.0-specular_data.a) + 1); + +#ifdef BLINN + float normalization_factor = (shininess + 8) / (8 * M_PI); + vec3 L = -light_data.light_direction_vs.xyz; + vec3 halfDir = normalize(L + I); + float specAngle = max(dot(halfDir, N), 0.0); + float NL = max(dot(L, N), 0.0); + float specular_influence = pow(specAngle, shininess) * NL * normalization_factor; + +#else vec3 reflection_vector = reflect(I, N); - vec3 specular_light = vec3(0.1); - /* Simple frontal specular highlights. */ - float specular_influence = pow(max(0.0, dot(world_data.light_direction_vs.xyz, reflection_vector)), world_data.specular_sharpness); + float specAngle = max(dot(light_data.light_direction_vs.xyz, reflection_vector), 0.0); + float specular_influence = pow(specAngle, shininess); +#endif + vec3 specular_color = specular_light * specular_influence; #else /* V3D_SHADING_SPECULAR_HIGHLIGHT */ @@ -34,3 +50,14 @@ vec3 get_world_specular_light(WorldData world_data, vec3 N, vec3 I) #endif /* V3D_SHADING_SPECULAR_HIGHLIGHT */ return specular_color; } + +vec3 get_world_specular_lights(WorldData world_data, vec4 specular_data, vec3 N, vec3 I) +{ + vec3 specular_light = vec3(0.0); + specular_light += get_world_specular_light(specular_data, world_data.lights[0], N, I); + for (int i = 0 ; i < world_data.num_lights ; i ++) { + specular_light += get_world_specular_light(specular_data, world_data.lights[i], N, I); + } + return specular_light; +} + diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c index 96e0e8ae18d..81cca2dcf5f 100644 --- a/source/blender/draw/engines/workbench/workbench_data.c +++ b/source/blender/draw/engines/workbench/workbench_data.c @@ -1,11 +1,14 @@ #include "workbench_private.h" +#include "DNA_userdef_types.h" + #include "UI_resources.h" + void workbench_private_data_init(WORKBENCH_PrivateData *wpd) { const DRWContextState *draw_ctx = DRW_context_state_get(); - Scene *scene = draw_ctx->scene; + const Scene *scene = draw_ctx->scene; wpd->material_hash = BLI_ghash_ptr_new(__func__); View3D *v3d = draw_ctx->v3d; @@ -46,7 +49,6 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd) copy_v3_v3(wd->object_outline_color, wpd->shading.object_outline_color); wd->object_outline_color[3] = 1.0f; - wd->specular_sharpness = 100.0f - scene->display.roughness * 100.0f; wpd->world_ubo = DRW_uniformbuffer_create(sizeof(WORKBENCH_UBO_World), &wpd->world_data); } @@ -55,6 +57,33 @@ void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd, floa { const DRWContextState *draw_ctx = DRW_context_state_get(); Scene *scene = draw_ctx->scene; + WORKBENCH_UBO_World *wd = &wpd->world_data; + float view_matrix[4][4]; + DRW_viewport_matrix_get(view_matrix, DRW_MAT_VIEW); + WORKBENCH_UBO_Light *light = &wd->lights[0]; + + mul_v3_mat3_m4v3(light->light_direction_vs, view_matrix, light_direction); + light->light_direction_vs[3] = 0.0f; + copy_v3_fl(light->specular_color, 1.0f); + light->energy = 1.0f; + copy_v4_v4(wd->light_direction_vs, light->light_direction_vs); + wd->num_lights = 1; + + if (STUDIOLIGHT_ORIENTATION_CAMERA_ENABLED(wpd)) { + int light_index = 0; + for (int index = 0 ; index < 3; index++) + { + SolidLight *sl = &U.light[index]; + if (sl->flag) { + WORKBENCH_UBO_Light *light = &wd->lights[light_index++]; + copy_v4_v4(light->light_direction_vs, sl->vec); + negate_v3(light->light_direction_vs); + copy_v4_v4(light->specular_color, sl->spec); + light->energy = 1.0f; + } + } + wd->num_lights = light_index; + } #if 0 if (STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) { @@ -71,15 +100,19 @@ void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd, floa negate_v3(light_direction); } - float view_matrix[4][4]; - DRW_viewport_matrix_get(view_matrix, DRW_MAT_VIEW); - mul_v3_mat3_m4v3(wpd->world_data.light_direction_vs, view_matrix, light_direction); - wpd->world_data.light_direction_vs[3] = 0.0; DRW_uniformbuffer_update(wpd->world_ubo, &wpd->world_data); } +static void workbench_private_material_free(void* data) +{ + WORKBENCH_MaterialData *material_data = (WORKBENCH_MaterialData*)data; + DRW_UBO_FREE_SAFE(material_data->material_ubo); + MEM_freeN(material_data); +} + void workbench_private_data_free(WORKBENCH_PrivateData *wpd) { - BLI_ghash_free(wpd->material_hash, NULL, MEM_freeN); + + BLI_ghash_free(wpd->material_hash, NULL, workbench_private_material_free); DRW_UBO_FREE_SAFE(wpd->world_ubo); } diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c index e7655eee940..47700c4bfd3 100644 --- a/source/blender/draw/engines/workbench/workbench_deferred.c +++ b/source/blender/draw/engines/workbench/workbench_deferred.c @@ -65,6 +65,7 @@ static struct { struct GPUTexture *object_id_tx; /* ref only, not alloced */ struct GPUTexture *color_buffer_tx; /* ref only, not alloced */ + struct GPUTexture *specular_buffer_tx; /* ref only, not alloced */ struct GPUTexture *normal_buffer_tx; /* ref only, not alloced */ struct GPUTexture *composite_buffer_tx; /* ref only, not alloced */ @@ -120,6 +121,7 @@ static char *workbench_build_prepass_frag(void) DynStr *ds = BLI_dynstr_new(); + BLI_dynstr_append(ds, datatoc_workbench_data_lib_glsl); BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl); BLI_dynstr_append(ds, datatoc_workbench_prepass_frag_glsl); @@ -231,6 +233,7 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata) const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]}; e_data.object_id_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_R32UI, &draw_engine_workbench_solid); e_data.color_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA8, &draw_engine_workbench_solid); + e_data.specular_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA8, &draw_engine_workbench_solid); e_data.composite_buffer_tx = DRW_texture_pool_query_2D( size[0], size[1], GPU_RGBA16F, &draw_engine_workbench_solid); @@ -247,6 +250,7 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata) GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_TEXTURE(e_data.object_id_tx), GPU_ATTACHMENT_TEXTURE(e_data.color_buffer_tx), + GPU_ATTACHMENT_TEXTURE(e_data.specular_buffer_tx), GPU_ATTACHMENT_TEXTURE(e_data.normal_buffer_tx), }); GPU_framebuffer_ensure_config(&fbl->composite_fb, { @@ -283,6 +287,28 @@ static void workbench_composite_uniforms(WORKBENCH_PrivateData *wpd, DRWShadingG if (NORMAL_VIEWPORT_PASS_ENABLED(wpd)) { DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &e_data.normal_buffer_tx); } + if (SPECULAR_HIGHLIGHT_ENABLED(wpd)) { + DRW_shgroup_uniform_texture_ref(grp, "specularBuffer", &e_data.specular_buffer_tx); + +#if 0 + float invwinmat[4][4]; + DRW_viewport_matrix_get(invwinmat, DRW_MAT_WININV); + + copy_v4_fl4(e_data.screenvecs[0], 1.0f, -1.0f, 0.0f, 1.0f); + copy_v4_fl4(e_data.screenvecs[1], -1.0f, 1.0f, 0.0f, 1.0f); + copy_v4_fl4(e_data.screenvecs[2], -1.0f, -1.0f, 0.0f, 1.0f); + for (int i = 0; i < 3; i++) { + mul_m4_v4(invwinmat, e_data.screenvecs[i]); + e_data.screenvecs[i][0] /= e_data.screenvecs[i][3]; /* perspective divide */ + e_data.screenvecs[i][1] /= e_data.screenvecs[i][3]; /* perspective divide */ + e_data.screenvecs[i][2] /= e_data.screenvecs[i][3]; /* perspective divide */ + e_data.screenvecs[i][3] = 1.0f; + } + sub_v3_v3(e_data.screenvecs[0], e_data.screenvecs[2]); + sub_v3_v3(e_data.screenvecs[1], e_data.screenvecs[2]); + DRW_shgroup_uniform_vec4(grp, "screenvecs[0]", e_data.screenvecs[0], 3); +#endif + } DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo); DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1); @@ -307,7 +333,7 @@ void workbench_deferred_cache_init(WORKBENCH_Data *vedata) workbench_private_data_get_light_direction(wpd, e_data.display.light_direction); e_data.display.shadow_shift = scene->display.shadow_shift; - copy_v3_v3(e_data.light_direction_vs, wpd->world_data.light_direction_vs); + copy_v3_v3(e_data.light_direction_vs, wpd->world_data.lights[0].light_direction_vs); if (SHADOW_ENABLED(wpd)) { psl->composite_pass = DRW_pass_create( @@ -385,7 +411,7 @@ static WORKBENCH_MaterialData *get_or_create_material_data( WORKBENCH_MaterialData material_template; /* Solid */ - workbench_material_get_solid_color(wpd, ob, mat, material_template.color); + workbench_material_update_data(wpd, ob, mat, &material_template); material_template.object_id = engine_object_data->object_id; material_template.drawtype = drawtype; material_template.ima = ima; @@ -398,10 +424,11 @@ static WORKBENCH_MaterialData *get_or_create_material_data( drawtype == OB_SOLID ? wpd->prepass_solid_sh : wpd->prepass_texture_sh, psl->prepass_pass); DRW_shgroup_stencil_mask(material->shgrp, 0xFF); material->object_id = engine_object_data->object_id; - copy_v4_v4(material->color, material_template.color); + copy_v4_v4(material->material_data.diffuse_color, material_template.material_data.diffuse_color); + copy_v4_v4(material->material_data.specular_color, material_template.material_data.specular_color); + material->material_data.roughness = material_template.material_data.roughness; switch (drawtype) { case OB_SOLID: - DRW_shgroup_uniform_vec3(material->shgrp, "object_color", material->color, 1); break; case OB_TEXTURE: @@ -412,6 +439,9 @@ static WORKBENCH_MaterialData *get_or_create_material_data( } } DRW_shgroup_uniform_int(material->shgrp, "object_id", &material->object_id, 1); + material->material_ubo = DRW_uniformbuffer_create(sizeof(WORKBENCH_UBO_Material), &material->material_data); + DRW_shgroup_uniform_block(material->shgrp, "material_block", material->material_ubo); + BLI_ghash_insert(wpd->material_hash, SET_UINT_IN_POINTER(hash), material); } return material; diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c index 4ba6ee3fdc9..279e6a745ee 100644 --- a/source/blender/draw/engines/workbench/workbench_forward.c +++ b/source/blender/draw/engines/workbench/workbench_forward.c @@ -163,7 +163,7 @@ static WORKBENCH_MaterialData *get_or_create_material_data( DRWShadingGroup *grp; /* Solid */ - workbench_material_get_solid_color(wpd, ob, mat, material_template.color); + workbench_material_update_data(wpd, ob, mat, &material_template); material_template.object_id = engine_object_data->object_id; material_template.drawtype = drawtype; material_template.ima = ima; @@ -179,10 +179,12 @@ static WORKBENCH_MaterialData *get_or_create_material_data( psl->transparent_accum_pass); DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo); workbench_material_set_normal_world_matrix(grp, wpd, e_data.normal_world_matrix); - copy_v4_v4(material->color, material_template.color); + material->object_id = engine_object_data->object_id; + copy_v4_v4(material->material_data.diffuse_color, material_template.material_data.diffuse_color); + copy_v4_v4(material->material_data.specular_color, material_template.material_data.specular_color); + material->material_data.roughness = material_template.material_data.roughness; switch (drawtype) { case OB_SOLID: - DRW_shgroup_uniform_vec4(grp, "color", material->color, 1); break; case OB_TEXTURE: @@ -192,6 +194,8 @@ static WORKBENCH_MaterialData *get_or_create_material_data( break; } } + material->material_ubo = DRW_uniformbuffer_create(sizeof(WORKBENCH_UBO_Material), &material->material_data); + DRW_shgroup_uniform_block(grp, "material_block", material->material_ubo); material->shgrp = grp; /* Depth */ diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c index fb9b73c48b0..55a97b99066 100644 --- a/source/blender/draw/engines/workbench/workbench_materials.c +++ b/source/blender/draw/engines/workbench/workbench_materials.c @@ -7,14 +7,18 @@ #define HSV_SATURATION 0.5 #define HSV_VALUE 0.9 -void workbench_material_get_solid_color(WORKBENCH_PrivateData *wpd, Object *ob, Material *mat, float *color) +void workbench_material_update_data(WORKBENCH_PrivateData *wpd, Object *ob, Material *mat, WORKBENCH_MaterialData *data) { /* When in OB_TEXTURE always uyse V3D_SHADING_MATERIAL_COLOR as fallback when no texture could be determined */ int color_type = wpd->drawtype == OB_SOLID ? wpd->shading.color_type : V3D_SHADING_MATERIAL_COLOR; - static float default_color[] = {0.8f, 0.8f, 0.8f, 1.0f}; - color[3] = 1.0f; + static float default_diffuse_color[] = {0.8f, 0.8f, 0.8f, 1.0f}; + static float default_specular_color[] = {1.0f, 1.0f, 1.0f, 1.0f}; + copy_v4_v4(data->material_data.diffuse_color, default_diffuse_color); + copy_v4_v4(data->material_data.specular_color, default_specular_color); + data->material_data.roughness = 0.25f; + if (DRW_object_is_paint_mode(ob) || color_type == V3D_SHADING_SINGLE_COLOR) { - copy_v3_v3(color, wpd->shading.single_color); + copy_v3_v3(data->material_data.diffuse_color, wpd->shading.single_color); } else if (color_type == V3D_SHADING_RANDOM_COLOR) { uint hash = BLI_ghashutil_strhash_p_murmur(ob->id.name); @@ -24,15 +28,14 @@ void workbench_material_get_solid_color(WORKBENCH_PrivateData *wpd, Object *ob, float offset = fmodf((hash / 100000.0) * M_GOLDEN_RATION_CONJUGATE, 1.0); float hsv[3] = {offset, HSV_SATURATION, HSV_VALUE}; - hsv_to_rgb_v(hsv, color); + hsv_to_rgb_v(hsv, data->material_data.diffuse_color); } else { /* V3D_SHADING_MATERIAL_COLOR */ if (mat) { - copy_v3_v3(color, &mat->r); - } - else { - copy_v3_v3(color, default_color); + copy_v3_v3(data->material_data.diffuse_color, &mat->r); + copy_v3_v3(data->material_data.specular_color, &mat->specr); + data->material_data.roughness = mat->roughness; } } } @@ -91,13 +94,20 @@ uint workbench_material_get_hash(WORKBENCH_MaterialData *material_template) /* TODO: make a C-string with settings and hash the string */ uint input[4]; uint result; - float *color = material_template->color; + float *color = material_template->material_data.diffuse_color; input[0] = (uint)(color[0] * 512); input[1] = (uint)(color[1] * 512); input[2] = (uint)(color[2] * 512); input[3] = material_template->object_id; result = BLI_ghashutil_uinthash_v4_murmur(input); + color = material_template->material_data.specular_color; + input[0] = (uint)(color[0] * 512); + input[1] = (uint)(color[1] * 512); + input[2] = (uint)(color[2] * 512); + input[3] = (uint)(material_template->material_data.roughness * 512); + result += BLI_ghashutil_uinthash_v4_murmur(input); + if (material_template->drawtype == OB_TEXTURE) { /* add texture reference */ result += BLI_ghashutil_inthash_p_murmur(material_template->ima); diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h index d40db7f248d..6fc3251a085 100644 --- a/source/blender/draw/engines/workbench/workbench_private.h +++ b/source/blender/draw/engines/workbench/workbench_private.h @@ -48,6 +48,7 @@ #define NORMAL_ENCODING_ENABLED() (true) #define WORKBENCH_REVEALAGE_ENABLED #define STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd) (wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_WORLD) +#define STUDIOLIGHT_ORIENTATION_CAMERA_ENABLED(wpd) (wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_CAMERA) typedef struct WORKBENCH_FramebufferList { @@ -98,6 +99,12 @@ typedef struct WORKBENCH_Data { WORKBENCH_StorageList *stl; } WORKBENCH_Data; +typedef struct WORKBENCH_UBO_Light { + float light_direction_vs[4]; + float specular_color[3]; + float energy; +} WORKBENCH_UBO_Light; + typedef struct WORKBENCH_UBO_World { float diffuse_light_x_pos[4]; float diffuse_light_x_neg[4]; @@ -109,11 +116,20 @@ typedef struct WORKBENCH_UBO_World { float background_color_high[4]; float object_outline_color[4]; float light_direction_vs[4]; - float specular_sharpness; - float pad[3]; + WORKBENCH_UBO_Light lights[3]; + int num_lights; + int pad[3]; } WORKBENCH_UBO_World; BLI_STATIC_ASSERT_ALIGN(WORKBENCH_UBO_World, 16) +typedef struct WORKBENCH_UBO_Material { + float diffuse_color[4]; + float specular_color[4]; + float roughness; + float pad[3]; +} WORKBENCH_UBO_Material; +BLI_STATIC_ASSERT_ALIGN(WORKBENCH_UBO_Material, 16) + typedef struct WORKBENCH_PrivateData { struct GHash *material_hash; struct GPUShader *prepass_solid_sh; @@ -144,7 +160,9 @@ typedef struct WORKBENCH_PrivateData { typedef struct WORKBENCH_MaterialData { /* Solid color */ - float color[4]; + WORKBENCH_UBO_Material material_data; + struct GPUUniformBuffer *material_ubo; + int object_id; int drawtype; Image *ima; @@ -199,7 +217,7 @@ void workbench_forward_cache_finish(WORKBENCH_Data *vedata); /* workbench_materials.c */ char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, int drawtype); -void workbench_material_get_solid_color(WORKBENCH_PrivateData *wpd, Object *ob, Material *mat, float *color); +void workbench_material_update_data(WORKBENCH_PrivateData *wpd, Object *ob, Material *mat, WORKBENCH_MaterialData *data); uint workbench_material_get_hash(WORKBENCH_MaterialData *material_template); int workbench_material_get_shader_index(WORKBENCH_PrivateData *wpd, int drawtype); void workbench_material_set_normal_world_matrix( diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp index 9cba1d03bd8..6cbdca756d5 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp @@ -546,7 +546,7 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id) if (mat) { tmpMat.setLine(mat->line_col[0], mat->line_col[1], mat->line_col[2], mat->line_col[3]); - tmpMat.setDiffuse(mat->r, mat->g, mat->b, mat->alpha); + tmpMat.setDiffuse(mat->r, mat->g, mat->b, 1.0f); tmpMat.setSpecular(mat->specr, mat->specg, mat->specb, 1.0f); tmpMat.setShininess(128.f); tmpMat.setPriority(mat->line_priority); diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index 564e6aee3fc..64c40cc3efa 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -73,7 +73,13 @@ typedef struct Material { /* Colors from Blender Internal that we are still using. */ float r, g, b; float specr, specg, specb; - float alpha, ray_mirror, spec, gloss_mir; + float alpha DNA_DEPRECATED; + float ray_mirror DNA_DEPRECATED; + float spec; + float gloss_mir DNA_DEPRECATED; /* renamed and inversed to roughness */ + float roughness; + float metallic; + float pad4[2]; /* Ror buttons and render. */ char pr_type, use_nodes; diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 3a7e6d0b4b1..ea6a34df3f5 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1371,7 +1371,6 @@ typedef struct DisplaySafeAreas { typedef struct SceneDisplay { float light_direction[3]; /* light direction for shadows/highlight */ float shadow_shift; - float roughness; /* Roughness for the specular highlights */ int matcap_icon; int matcap_type; @@ -1386,7 +1385,6 @@ typedef struct SceneDisplay { float matcap_hair_brightness_randomness; int matcap_ssao_samples; - int pad; } SceneDisplay; typedef struct SceneEEVEE { diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index a40606018e7..9f5b72ff13e 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -112,11 +112,6 @@ static void rna_Material_draw_update(Main *UNUSED(bmain), Scene *UNUSED(scene), WM_main_add_notifier(NC_MATERIAL | ND_SHADING_DRAW, ma); } -static PointerRNA rna_Material_mirror_get(PointerRNA *ptr) -{ - return rna_pointer_inherit_refine(ptr, &RNA_MaterialRaytraceMirror, ptr->id.data); -} - static void rna_Material_texpaint_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { Material *ma = (Material *)ptr->data; @@ -250,7 +245,7 @@ void rna_mtex_texture_slots_clear(ID *self_id, struct bContext *C, ReportList *r #else -static void rna_def_material_colors(StructRNA *srna) +static void rna_def_material_display(StructRNA *srna) { PropertyRNA *prop; @@ -265,17 +260,26 @@ static void rna_def_material_colors(StructRNA *srna) RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Specular Color", "Specular color of the material"); RNA_def_property_update(prop, 0, "rna_Material_draw_update"); + + prop = RNA_def_property(srna, "roughness", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "roughness"); + RNA_def_property_float_default(prop, 0.25f); + RNA_def_property_range(prop, 0, 1); + RNA_def_property_ui_text(prop, "Roughness", "Roughness of the material"); + RNA_def_property_update(prop, 0, "rna_Material_draw_update"); prop = RNA_def_property(srna, "specular_intensity", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "spec"); + RNA_def_property_float_default(prop, 0.5f); RNA_def_property_range(prop, 0, 1); - RNA_def_property_ui_text(prop, "Specular Intensity", "How intense (bright) the specular reflection is"); + RNA_def_property_ui_text(prop, "Specular", "How intense (bright) the specular reflection is"); RNA_def_property_update(prop, 0, "rna_Material_draw_update"); - prop = RNA_def_property(srna, "alpha", PROP_FLOAT, PROP_FACTOR); + prop = RNA_def_property(srna, "metallic", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "metallic"); RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Alpha", "Alpha transparency of the material"); - RNA_def_property_update(prop, 0, "rna_Material_draw_update"); + RNA_def_property_ui_text(prop, "Metallic", "Amount of mirror reflection for raytrace"); + RNA_def_property_update(prop, 0, "rna_Material_update"); /* Freestyle line color */ prop = RNA_def_property(srna, "line_color", PROP_FLOAT, PROP_COLOR); @@ -292,30 +296,6 @@ static void rna_def_material_colors(StructRNA *srna) RNA_def_property_update(prop, 0, "rna_Material_update"); } -static void rna_def_material_raymirror(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - srna = RNA_def_struct(brna, "MaterialRaytraceMirror", NULL); - RNA_def_struct_sdna(srna, "Material"); - RNA_def_struct_nested(brna, srna, "Material"); - RNA_def_struct_ui_text(srna, "Material Raytrace Mirror", "Raytraced reflection settings for a Material data-block"); - - prop = RNA_def_property(srna, "reflect_factor", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "ray_mirror"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Reflectivity", "Amount of mirror reflection for raytrace"); - RNA_def_property_update(prop, 0, "rna_Material_update"); - - prop = RNA_def_property(srna, "gloss_factor", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "gloss_mir"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Gloss Amount", - "The shininess of the reflection (values < 1.0 give diffuse, blurry reflections)"); - RNA_def_property_update(prop, 0, "rna_Material_update"); -} - void RNA_def_material(BlenderRNA *brna) { StructRNA *srna; @@ -412,13 +392,6 @@ void RNA_def_material(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Pass Index", "Index number for the \"Material Index\" render pass"); RNA_def_property_update(prop, NC_OBJECT, "rna_Material_update"); - /* nested structs */ - prop = RNA_def_property(srna, "raytrace_mirror", PROP_POINTER, PROP_NONE); - RNA_def_property_flag(prop, PROP_NEVER_NULL); - RNA_def_property_struct_type(prop, "MaterialRaytraceMirror"); - RNA_def_property_pointer_funcs(prop, "rna_Material_mirror_get", NULL, NULL, NULL); - RNA_def_property_ui_text(prop, "Raytrace Mirror", "Raytraced reflection settings for the material"); - /* nodetree */ prop = RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "nodetree"); @@ -435,8 +408,7 @@ void RNA_def_material(BlenderRNA *brna) rna_def_animdata_common(srna); rna_def_texpaint_slots(brna, srna); - rna_def_material_colors(srna); - rna_def_material_raymirror(brna); + rna_def_material_display(srna); RNA_api_material(srna); } diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index a8192e8c281..1530c7fc483 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -5726,15 +5726,6 @@ static void rna_def_scene_display(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, NC_SCENE | NA_EDITED, "rna_Scene_set_update"); - prop = RNA_def_property(srna, "roughness", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "roughness"); - RNA_def_property_float_default(prop, 0.0); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_range(prop, 0.00f, 1.0f, 1, 2); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text(prop, "Roughness", "Roughness for the specular highlights"); - RNA_def_property_update(prop, NC_SCENE | NA_EDITED, "rna_Scene_set_update"); - #ifdef WITH_CLAY_ENGINE /* Matcap. */ prop = RNA_def_property(srna, "matcap_icon", PROP_ENUM, PROP_NONE); |