diff options
author | Lukas Tönne <lukas.toenne@gmail.com> | 2017-08-03 10:11:48 +0300 |
---|---|---|
committer | Lukas Tönne <lukas.toenne@gmail.com> | 2017-08-03 10:11:48 +0300 |
commit | e34ba9fb7a91ef9be9109eaae5242cd4b3d7a22c (patch) | |
tree | a4a7dc27c038dcd6d67bc4e1c20b06740c97658a /source/blender/draw/engines/eevee | |
parent | c92457a87ab0866111f2cdc8ad1e6b1777465675 (diff) |
Use a 2D texture for the hair interpolation data instead of 1D for larger number of hairs.
It turns out that 1D textures have the same size limit on their 1 axis as 2D textures.
This limits the potential number of hair dramatically, even though the actual size of
the texture is very small. Using a 2D texture and wrapping the index avoids this problem.
Diffstat (limited to 'source/blender/draw/engines/eevee')
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_materials.c | 64 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/shaders/hair_lib.glsl | 40 |
2 files changed, 45 insertions, 59 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index 1c937cac92e..a50b5b62e62 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -196,7 +196,7 @@ static char *eevee_get_defines(int options) BLI_dynstr_appendf(ds, "#define HAIR_SHADER\n"); } if ((options & VAR_MAT_HAIR_FIBERS) != 0) { - BLI_dynstr_appendf(ds, "#define HAIR_SHADER_FIBERS\n"); + BLI_dynstr_append(ds, DRW_hair_shader_defines()); } if ((options & VAR_MAT_PROBE) != 0) { BLI_dynstr_appendf(ds, "#define PROBE_CAPTURE\n"); @@ -381,12 +381,15 @@ void EEVEE_materials_init(EEVEE_StorageList *stl) "#define CLIP_PLANES\n"); e_data.default_prepass_hair_fiber_sh = DRW_shader_create( - hair_fiber_vert_str, NULL, datatoc_prepass_frag_glsl, - "#define HAIR_SHADER\n#define HAIR_SHADER_FIBERS\n"); + hair_fiber_vert_str, NULL, datatoc_prepass_frag_glsl, DRW_hair_shader_defines()); - e_data.default_prepass_hair_fiber_clip_sh = DRW_shader_create( - hair_fiber_vert_str, NULL, datatoc_prepass_frag_glsl, - "#define HAIR_SHADER\n#define HAIR_SHADER_FIBERS\n#define CLIP_PLANES\n"); + { + char defines[256]; + BLI_snprintf(defines, sizeof(defines), "#define CLIP_PLANES\n%s", + DRW_hair_shader_defines()); + e_data.default_prepass_hair_fiber_clip_sh = DRW_shader_create( + hair_fiber_vert_str, NULL, datatoc_prepass_frag_glsl, defines); + } MEM_freeN(frag_str); MEM_freeN(hair_fiber_vert_str); @@ -1122,11 +1125,8 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl bool use_fibers = false; float mat[4][4]; struct Gwn_Batch *hair_geom = NULL; + const DRWHairFiberTextureBuffer *fiber_buffer = NULL; GPUTexture **fiber_texture = NULL; - const float *ribbon_width = NULL; - const int *strand_map_start = NULL; - const int *strand_vertex_start = NULL; - const int *fiber_start = NULL; if (ob->mode & OB_MODE_HAIR_EDIT) { BMEditStrands *edit = psys->hairedit; @@ -1136,16 +1136,12 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl use_fibers = true; copy_m4_m4(mat, ob->obmat); - const DRWHairFiberTextureBuffer *buffer = NULL; - hair_geom = DRW_cache_editstrands_get_hair_fibers(edit, true, &buffer); + hair_geom = DRW_cache_editstrands_get_hair_fibers(edit, true, &fiber_buffer); + if (!edit->texture) { - edit->texture = DRW_texture_create_1D(buffer->size, DRW_TEX_RG_32, 0, buffer->data); + edit->texture = DRW_texture_create_2D(fiber_buffer->width, fiber_buffer->height, + DRW_TEX_RG_32, 0, fiber_buffer->data); } - - ribbon_width = &tsettings->hair_draw_size; - strand_map_start = &buffer->strand_map_start; - strand_vertex_start = &buffer->strand_vertex_start; - fiber_start = &buffer->fiber_start; fiber_texture = (GPUTexture **)(&edit->texture); } } @@ -1169,24 +1165,13 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl DRW_shgroup_call_add(stl->g_data->depth_shgrp_clip, hair_geom, mat); } else { - DRWShadingGroup *depth_shgrp = stl->g_data->depth_shgrp_hair_fibers; - DRWShadingGroup *depth_clip_shgrp = stl->g_data->depth_shgrp_hair_fibers_clip; - DRW_shgroup_call_add(depth_shgrp, hair_geom, mat); - DRW_shgroup_call_add(depth_clip_shgrp, hair_geom, mat); - - DRW_shgroup_uniform_vec2(depth_shgrp, "viewport_size", DRW_viewport_size_get(), 1); - DRW_shgroup_uniform_vec2(depth_clip_shgrp, "viewport_size", DRW_viewport_size_get(), 1); - DRW_shgroup_uniform_float(depth_shgrp, "ribbon_width", ribbon_width, 1); - DRW_shgroup_uniform_float(depth_clip_shgrp, "ribbon_width", ribbon_width, 1); + DRW_shgroup_call_add(stl->g_data->depth_shgrp_hair_fibers, hair_geom, mat); + DRW_hair_shader_uniforms(stl->g_data->depth_shgrp_hair_fibers, scene, + fiber_texture, fiber_buffer); - DRW_shgroup_uniform_buffer(depth_shgrp, "strand_data", fiber_texture); - DRW_shgroup_uniform_buffer(depth_clip_shgrp, "strand_data", fiber_texture); - DRW_shgroup_uniform_int(depth_shgrp, "strand_map_start", strand_map_start, 1); - DRW_shgroup_uniform_int(depth_clip_shgrp, "strand_map_start", strand_map_start, 1); - DRW_shgroup_uniform_int(depth_shgrp, "strand_vertex_start", strand_vertex_start, 1); - DRW_shgroup_uniform_int(depth_clip_shgrp, "strand_vertex_start", strand_vertex_start, 1); - DRW_shgroup_uniform_int(depth_shgrp, "fiber_start", fiber_start, 1); - DRW_shgroup_uniform_int(depth_clip_shgrp, "fiber_start", fiber_start, 1); + DRW_shgroup_call_add(stl->g_data->depth_shgrp_hair_fibers_clip, hair_geom, mat); + DRW_hair_shader_uniforms(stl->g_data->depth_shgrp_hair_fibers_clip, scene, + fiber_texture, fiber_buffer); } DRWShadingGroup *shgrp = BLI_ghash_lookup(material_hash, (const void *)ma); @@ -1233,13 +1218,8 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl DRW_shgroup_call_add(shgrp, hair_geom, mat); if (use_fibers) { - DRW_shgroup_uniform_vec2(shgrp, "viewport_size", DRW_viewport_size_get(), 1); - DRW_shgroup_uniform_float(shgrp, "ribbon_width", ribbon_width, 1); - - DRW_shgroup_uniform_buffer(shgrp, "strand_data", fiber_texture); - DRW_shgroup_uniform_int(shgrp, "strand_map_start", strand_map_start, 1); - DRW_shgroup_uniform_int(shgrp, "strand_vertex_start", strand_vertex_start, 1); - DRW_shgroup_uniform_int(shgrp, "fiber_start", fiber_start, 1); + DRW_hair_shader_uniforms(shgrp, scene, + fiber_texture, fiber_buffer); } } } diff --git a/source/blender/draw/engines/eevee/shaders/hair_lib.glsl b/source/blender/draw/engines/eevee/shaders/hair_lib.glsl index 430fee1bc2c..4cbf69e1074 100644 --- a/source/blender/draw/engines/eevee/shaders/hair_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/hair_lib.glsl @@ -1,8 +1,8 @@ -#ifdef HAIR_SHADER +#ifdef HAIR_SHADER_FIBERS #define FIBER_RIBBON -uniform sampler1D strand_data; +uniform sampler2D strand_data; uniform int strand_map_start; uniform int strand_vertex_start; uniform int fiber_start; @@ -13,6 +13,12 @@ uniform vec2 viewport_size; #define INDEX_INVALID -1 +vec2 read_texdata(int offset) +{ + ivec2 offset2 = ivec2(offset % HAIR_SHADER_TEX_WIDTH, offset / HAIR_SHADER_TEX_WIDTH); + return texelFetch(strand_data, offset2, 0).rg; +} + mat3 mat3_from_vectors(vec3 nor, vec3 tang) { tang = normalize(tang); @@ -23,7 +29,7 @@ mat3 mat3_from_vectors(vec3 nor, vec3 tang) void get_strand_data(int index, out int start, out int count) { int offset = strand_map_start + index; - vec4 a = texelFetch(strand_data, offset, 0); + vec2 a = read_texdata(offset); start = floatBitsToInt(a.r); count = floatBitsToInt(a.g); @@ -32,11 +38,11 @@ void get_strand_data(int index, out int start, out int count) void get_strand_vertex(int index, out vec3 co, out vec3 nor, out vec3 tang) { int offset = strand_vertex_start + index * 5; - vec4 a = texelFetch(strand_data, offset, 0); - vec4 b = texelFetch(strand_data, offset + 1, 0); - vec4 c = texelFetch(strand_data, offset + 2, 0); - vec4 d = texelFetch(strand_data, offset + 3, 0); - vec4 e = texelFetch(strand_data, offset + 4, 0); + vec2 a = read_texdata(offset); + vec2 b = read_texdata(offset + 1); + vec2 c = read_texdata(offset + 2); + vec2 d = read_texdata(offset + 3); + vec2 e = read_texdata(offset + 4); co = vec3(a.rg, b.r); nor = vec3(b.g, c.rg); @@ -46,8 +52,8 @@ void get_strand_vertex(int index, out vec3 co, out vec3 nor, out vec3 tang) void get_strand_root(int index, out vec3 co) { int offset = strand_vertex_start + index * 5; - vec4 a = texelFetch(strand_data, offset, 0); - vec4 b = texelFetch(strand_data, offset + 1, 0); + vec2 a = read_texdata(offset); + vec2 b = read_texdata(offset + 1); co = vec3(a.rg, b.r); } @@ -55,12 +61,12 @@ void get_strand_root(int index, out vec3 co) void get_fiber_data(int fiber_index, out ivec4 parent_index, out vec4 parent_weight, out vec3 pos) { int offset = fiber_start + fiber_index * 6; - vec4 a = texelFetch(strand_data, offset, 0); - vec4 b = texelFetch(strand_data, offset + 1, 0); - vec4 c = texelFetch(strand_data, offset + 2, 0); - vec4 d = texelFetch(strand_data, offset + 3, 0); - vec4 e = texelFetch(strand_data, offset + 4, 0); - vec4 f = texelFetch(strand_data, offset + 5, 0); + vec2 a = read_texdata(offset); + vec2 b = read_texdata(offset + 1); + vec2 c = read_texdata(offset + 2); + vec2 d = read_texdata(offset + 3); + vec2 e = read_texdata(offset + 4); + vec2 f = read_texdata(offset + 5); parent_index = ivec4(floatBitsToInt(a.rg), floatBitsToInt(b.rg)); parent_weight = vec4(c.rg, d.rg); @@ -168,4 +174,4 @@ void hair_fiber_get_vertex(int fiber_index, float curve_param, mat4 ModelViewMat #endif } -#endif /*HAIR_SHADER*/ +#endif /*HAIR_SHADER_FIBERS*/ |