diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2019-05-02 17:05:02 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2019-05-02 17:05:04 +0300 |
commit | 7daeb1f9aee284d958abe87622b43c70c21af967 (patch) | |
tree | 16f8a16137ee4c602e2a8dcc98dbbdb081920e78 /source/blender/draw/modes/shaders/common_hair_lib.glsl | |
parent | 807c8c6e17b9e553a440edc246e19b665d507012 (diff) | |
parent | 3076d95ba441cd32706a27d18922a30f8fd28b8a (diff) |
Merge 'master' into 'collada'
Diffstat (limited to 'source/blender/draw/modes/shaders/common_hair_lib.glsl')
-rw-r--r-- | source/blender/draw/modes/shaders/common_hair_lib.glsl | 188 |
1 files changed, 98 insertions, 90 deletions
diff --git a/source/blender/draw/modes/shaders/common_hair_lib.glsl b/source/blender/draw/modes/shaders/common_hair_lib.glsl index 14df29f2e94..02254908232 100644 --- a/source/blender/draw/modes/shaders/common_hair_lib.glsl +++ b/source/blender/draw/modes/shaders/common_hair_lib.glsl @@ -30,11 +30,11 @@ uniform mat4 hairDupliMatrix; /* -- Per control points -- */ uniform samplerBuffer hairPointBuffer; /* RGBA32F */ -#define point_position xyz -#define point_time w /* Position along the hair length */ +#define point_position xyz +#define point_time w /* Position along the hair length */ /* -- Per strands data -- */ -uniform usamplerBuffer hairStrandBuffer; /* R32UI */ +uniform usamplerBuffer hairStrandBuffer; /* R32UI */ uniform usamplerBuffer hairStrandSegBuffer; /* R16UI */ /* Not used, use one buffer per uv layer */ @@ -53,39 +53,40 @@ uniform usamplerBuffer hairStrandSegBuffer; /* R16UI */ #ifdef HAIR_PHASE_SUBDIV int hair_get_base_id(float local_time, int strand_segments, out float interp_time) { - float time_per_strand_seg = 1.0 / float(strand_segments); + float time_per_strand_seg = 1.0 / float(strand_segments); - float ratio = local_time / time_per_strand_seg; - interp_time = fract(ratio); + float ratio = local_time / time_per_strand_seg; + interp_time = fract(ratio); - return int(ratio); + return int(ratio); } -void hair_get_interp_attrs(out vec4 data0, out vec4 data1, out vec4 data2, out vec4 data3, out float interp_time) +void hair_get_interp_attrs( + out vec4 data0, out vec4 data1, out vec4 data2, out vec4 data3, out float interp_time) { - float local_time = float(gl_VertexID % hairStrandsRes) / float(hairStrandsRes - 1); + float local_time = float(gl_VertexID % hairStrandsRes) / float(hairStrandsRes - 1); - int hair_id = gl_VertexID / hairStrandsRes; - int strand_offset = int(texelFetch(hairStrandBuffer, hair_id).x); - int strand_segments = int(texelFetch(hairStrandSegBuffer, hair_id).x); + int hair_id = gl_VertexID / hairStrandsRes; + int strand_offset = int(texelFetch(hairStrandBuffer, hair_id).x); + int strand_segments = int(texelFetch(hairStrandSegBuffer, hair_id).x); - int id = hair_get_base_id(local_time, strand_segments, interp_time); + int id = hair_get_base_id(local_time, strand_segments, interp_time); - int ofs_id = id + strand_offset; + int ofs_id = id + strand_offset; - data0 = texelFetch(hairPointBuffer, ofs_id - 1); - data1 = texelFetch(hairPointBuffer, ofs_id); - data2 = texelFetch(hairPointBuffer, ofs_id + 1); - data3 = texelFetch(hairPointBuffer, ofs_id + 2); + data0 = texelFetch(hairPointBuffer, ofs_id - 1); + data1 = texelFetch(hairPointBuffer, ofs_id); + data2 = texelFetch(hairPointBuffer, ofs_id + 1); + data3 = texelFetch(hairPointBuffer, ofs_id + 2); - if (id <= 0) { - /* root points. Need to reconstruct previous data. */ - data0 = data1 * 2.0 - data2; - } - if (id + 1 >= strand_segments) { - /* tip points. Need to reconstruct next data. */ - data3 = data2 * 2.0 - data1; - } + if (id <= 0) { + /* root points. Need to reconstruct previous data. */ + data0 = data1 * 2.0 - data2; + } + if (id + 1 >= strand_segments) { + /* tip points. Need to reconstruct next data. */ + data3 = data2 * 2.0 - data1; + } } #endif @@ -97,102 +98,109 @@ void hair_get_interp_attrs(out vec4 data0, out vec4 data1, out vec4 data2, out v #ifndef HAIR_PHASE_SUBDIV int hair_get_strand_id(void) { - return gl_VertexID / (hairStrandsRes * hairThicknessRes); + return gl_VertexID / (hairStrandsRes * hairThicknessRes); } int hair_get_base_id(void) { - return gl_VertexID / hairThicknessRes; + return gl_VertexID / hairThicknessRes; } /* Copied from cycles. */ float hair_shaperadius(float shape, float root, float tip, float time) { - float radius = 1.0 - time; + float radius = 1.0 - time; - if (shape < 0.0) { - radius = pow(radius, 1.0 + shape); - } - else { - radius = pow(radius, 1.0 / (1.0 - shape)); - } + if (shape < 0.0) { + radius = pow(radius, 1.0 + shape); + } + else { + radius = pow(radius, 1.0 / (1.0 - shape)); + } - if (hairCloseTip && (time > 0.99)) { - return 0.0; - } + if (hairCloseTip && (time > 0.99)) { + return 0.0; + } - return (radius * (root - tip)) + tip; + return (radius * (root - tip)) + tip; } -#ifdef OS_MAC +# ifdef OS_MAC in float dummy; -#endif - -void hair_get_pos_tan_binor_time( - bool is_persp, mat4 invmodel_mat, vec3 camera_pos, vec3 camera_z, - out vec3 wpos, out vec3 wtan, out vec3 wbinor, out float time, out float thickness, out float thick_time) +# endif + +void hair_get_pos_tan_binor_time(bool is_persp, + mat4 invmodel_mat, + vec3 camera_pos, + vec3 camera_z, + out vec3 wpos, + out vec3 wtan, + out vec3 wbinor, + out float time, + out float thickness, + out float thick_time) { - int id = hair_get_base_id(); - vec4 data = texelFetch(hairPointBuffer, id); - wpos = data.point_position; - time = data.point_time; - -#ifdef OS_MAC - /* Generate a dummy read to avoid the driver bug with shaders having no - * vertex reads on macOS (T60171) */ - wpos.y += dummy * 0.0; -#endif - - if (time == 0.0) { - /* Hair root */ - wtan = texelFetch(hairPointBuffer, id + 1).point_position - wpos; - } - else { - wtan = wpos - texelFetch(hairPointBuffer, id - 1).point_position; - } - - wpos = (hairDupliMatrix * vec4(wpos, 1.0)).xyz; - wtan = mat3(hairDupliMatrix) * wtan; - - vec3 camera_vec = (is_persp) ? wpos - camera_pos : -camera_z; - wbinor = normalize(cross(camera_vec, wtan)); - - thickness = hair_shaperadius(hairRadShape, hairRadRoot, hairRadTip, time); - - if (hairThicknessRes > 1) { - thick_time = float(gl_VertexID % hairThicknessRes) / float(hairThicknessRes - 1); - thick_time = thickness * (thick_time * 2.0 - 1.0); - - /* Take object scale into account. - * NOTE: This only works fine with uniform scaling. */ - float scale = 1.0 / length(mat3(invmodel_mat) * wbinor); - - wpos += wbinor * thick_time * scale; - } + int id = hair_get_base_id(); + vec4 data = texelFetch(hairPointBuffer, id); + wpos = data.point_position; + time = data.point_time; + +# ifdef OS_MAC + /* Generate a dummy read to avoid the driver bug with shaders having no + * vertex reads on macOS (T60171) */ + wpos.y += dummy * 0.0; +# endif + + if (time == 0.0) { + /* Hair root */ + wtan = texelFetch(hairPointBuffer, id + 1).point_position - wpos; + } + else { + wtan = wpos - texelFetch(hairPointBuffer, id - 1).point_position; + } + + wpos = (hairDupliMatrix * vec4(wpos, 1.0)).xyz; + wtan = mat3(hairDupliMatrix) * wtan; + + vec3 camera_vec = (is_persp) ? wpos - camera_pos : -camera_z; + wbinor = normalize(cross(camera_vec, wtan)); + + thickness = hair_shaperadius(hairRadShape, hairRadRoot, hairRadTip, time); + + if (hairThicknessRes > 1) { + thick_time = float(gl_VertexID % hairThicknessRes) / float(hairThicknessRes - 1); + thick_time = thickness * (thick_time * 2.0 - 1.0); + + /* Take object scale into account. + * NOTE: This only works fine with uniform scaling. */ + float scale = 1.0 / length(mat3(invmodel_mat) * wbinor); + + wpos += wbinor * thick_time * scale; + } } vec2 hair_get_customdata_vec2(const samplerBuffer cd_buf) { - int id = hair_get_strand_id(); - return texelFetch(cd_buf, id).rg; + int id = hair_get_strand_id(); + return texelFetch(cd_buf, id).rg; } vec3 hair_get_customdata_vec3(const samplerBuffer cd_buf) { - int id = hair_get_strand_id(); - return texelFetch(cd_buf, id).rgb; + int id = hair_get_strand_id(); + return texelFetch(cd_buf, id).rgb; } vec4 hair_get_customdata_vec4(const samplerBuffer cd_buf) { - int id = hair_get_strand_id(); - return texelFetch(cd_buf, id).rgba; + int id = hair_get_strand_id(); + return texelFetch(cd_buf, id).rgba; } vec3 hair_get_strand_pos(void) { - int id = hair_get_strand_id() * hairStrandsRes; - return texelFetch(hairPointBuffer, id).point_position; + int id = hair_get_strand_id() * hairStrandsRes; + return texelFetch(hairPointBuffer, id).point_position; } #endif |