Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Tönne <lukas.toenne@gmail.com>2017-08-03 10:11:48 +0300
committerLukas Tönne <lukas.toenne@gmail.com>2017-08-03 10:11:48 +0300
commite34ba9fb7a91ef9be9109eaae5242cd4b3d7a22c (patch)
treea4a7dc27c038dcd6d67bc4e1c20b06740c97658a /source/blender/draw/engines/eevee
parentc92457a87ab0866111f2cdc8ad1e6b1777465675 (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.c64
-rw-r--r--source/blender/draw/engines/eevee/shaders/hair_lib.glsl40
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*/