diff options
Diffstat (limited to 'source/blender/gpu/shaders')
21 files changed, 867 insertions, 66 deletions
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_image_multi_rect_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_image_multi_rect_vert.glsl new file mode 100644 index 00000000000..9fdf8ececc5 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_image_multi_rect_vert.glsl @@ -0,0 +1,48 @@ +/** + * Simple shader that just draw multiple icons at the specified locations + * does not need any vertex input (producing less call to immBegin/End) + **/ + +/* Same as ICON_DRAW_CACHE_SIZE */ +#define MAX_CALLS 16 + +uniform vec4 calls_data[MAX_CALLS * 3]; + +out vec2 texCoord_interp; +flat out vec4 finalColor; + +void main() +{ + /* Rendering 2 triangle per icon. */ + int i = gl_VertexID / 6; + int v = gl_VertexID % 6; + + vec4 pos = calls_data[i*3]; + vec4 tex = calls_data[i*3+1]; + finalColor = calls_data[i*3+2]; + + /* TODO Remove this */ + if (v == 2) v = 4; + else if (v == 3) v = 0; + else if (v == 5) v = 2; + + if (v == 0) { + pos.xy = pos.xw; + tex.xy = tex.xw; + } + else if (v == 1) { + pos.xy = pos.xz; + tex.xy = tex.xz; + } + else if (v == 2) { + pos.xy = pos.yw; + tex.xy = tex.yw; + } + else { + pos.xy = pos.yz; + tex.xy = tex.yz; + } + + gl_Position = vec4(pos.xy, 0.0f, 1.0f); + texCoord_interp = tex.xy; +} diff --git a/source/blender/gpu/shaders/gpu_shader_2D_image_rect_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_image_rect_vert.glsl new file mode 100644 index 00000000000..118f4e3b187 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_image_rect_vert.glsl @@ -0,0 +1,35 @@ +/** + * Simple shader that just draw one icon at the specified location + * does not need any vertex input (producing less call to immBegin/End) + **/ + +uniform mat4 ModelViewProjectionMatrix; +uniform vec4 rect_icon; +uniform vec4 rect_geom; + +out vec2 texCoord_interp; + +void main() +{ + vec2 uv; + vec2 co; + if (gl_VertexID == 0) { + co = rect_geom.xw; + uv = rect_icon.xw; + } + else if (gl_VertexID == 1) { + co = rect_geom.xy; + uv = rect_icon.xy; + } + else if (gl_VertexID == 2) { + co = rect_geom.zw; + uv = rect_icon.zw; + } + else { + co = rect_geom.zy; + uv = rect_icon.zy; + } + + gl_Position = ModelViewProjectionMatrix * vec4(co, 0.0f, 1.0f); + texCoord_interp = uv; +} diff --git a/source/blender/gpu/shaders/gpu_shader_2D_nodelink_frag.glsl b/source/blender/gpu/shaders/gpu_shader_2D_nodelink_frag.glsl new file mode 100644 index 00000000000..8dda575107a --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_nodelink_frag.glsl @@ -0,0 +1,10 @@ + +in float colorGradient; +in vec4 finalColor; + +out vec4 fragColor; + +void main() { + fragColor = finalColor; + fragColor.a *= smoothstep(1.0, 0.1, abs(colorGradient)); +}
\ No newline at end of file diff --git a/source/blender/gpu/shaders/gpu_shader_2D_nodelink_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_nodelink_vert.glsl new file mode 100644 index 00000000000..4c295fcd72a --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_nodelink_vert.glsl @@ -0,0 +1,107 @@ +/** + * 2D Quadratic Bezier thick line drawing + **/ + +#define MID_VERTEX 57 + +/* u is position along the curve, defining the tangent space. + * v is "signed" distance (compressed to [0..1] range) from the pos in expand direction */ +in vec2 uv; +in vec2 pos; /* verts position in the curve tangent space */ +in vec2 expand; + +#ifdef USE_INSTANCE +/* Instance attrib */ +in vec2 P0; +in vec2 P1; +in vec2 P2; +in vec2 P3; +in ivec4 colid_doarrow; + +uniform vec4 colors[6]; + +#define colStart colors[colid_doarrow[0]] +#define colEnd colors[colid_doarrow[1]] +#define colShadow colors[colid_doarrow[2]] +#define doArrow (colid_doarrow[3] != 0) + +#else +/* Single curve drawcall, use uniform. */ +uniform vec2 bezierPts[4]; + +#define P0 bezierPts[0] +#define P1 bezierPts[1] +#define P2 bezierPts[2] +#define P3 bezierPts[3] + +uniform vec4 colors[3]; +uniform bool doArrow; + +#define colShadow colors[0] +#define colStart colors[1] +#define colEnd colors[2] + +#endif + +uniform float expandSize; +uniform float arrowSize; +uniform mat4 ModelViewProjectionMatrix; + +out float colorGradient; +out vec4 finalColor; + +void main(void) +{ + float t = uv.x; + float t2 = t * t; + float t2_3 = 3.0 * t2; + float one_minus_t = 1.0 - t; + float one_minus_t2 = one_minus_t * one_minus_t; + float one_minus_t2_3 = 3.0 * one_minus_t2; + + vec2 point = (P0 * one_minus_t2 * one_minus_t + + P1 * one_minus_t2_3 * t + + P2 * t2_3 * one_minus_t + + P3 * t2 * t); + + vec2 tangent = ((P1 - P0) * one_minus_t2_3 + + (P2 - P1) * 6.0 * (t - t2) + + (P3 - P2) * t2_3); + + /* tangent space at t */ + tangent = normalize(tangent); + vec2 normal = tangent.yx * vec2(-1.0, 1.0); + + /* Position vertex on the curve tangent space */ + point += (pos.x * tangent + pos.y * normal) * arrowSize; + + gl_Position = ModelViewProjectionMatrix * vec4(point, 0.0, 1.0); + + vec2 exp_axis = expand.x * tangent + expand.y * normal; + + /* rotate & scale the expand axis */ + exp_axis = ModelViewProjectionMatrix[0].xy * exp_axis.xx + + ModelViewProjectionMatrix[1].xy * exp_axis.yy; + + + float expand_dist = (uv.y * 2.0 - 1.0); + colorGradient = expand_dist; + + if (gl_VertexID < MID_VERTEX) { + /* Shadow pass */ + finalColor = colShadow; + } + else { + /* Second pass */ + finalColor = mix(colStart, colEnd, uv.x); + expand_dist *= 0.5; + } + + /* Expand into a line */ + gl_Position.xy += exp_axis * expandSize * expand_dist; + + /* if arrow */ + if (expand.y != 1.0 && !doArrow) { + gl_Position.xy *= 0.0; + } +}
\ No newline at end of file diff --git a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl new file mode 100644 index 00000000000..f660cae8d12 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl @@ -0,0 +1,35 @@ +uniform vec3 checkerColorAndSize; + +noperspective in vec4 finalColor; +noperspective in float butCo; + +out vec4 fragColor; + +vec4 do_checkerboard() +{ + float size = checkerColorAndSize.z; + vec2 phase = mod(gl_FragCoord.xy, size * 2.0); + + if ((phase.x > size && phase.y < size) || + (phase.x < size && phase.y > size)) + { + return vec4(checkerColorAndSize.xxx, 1.0); + } + else { + return vec4(checkerColorAndSize.yyy, 1.0); + } +} + +void main() +{ + fragColor = finalColor; + + if (butCo > 0.5) { + vec4 checker = do_checkerboard(); + fragColor = mix(checker, fragColor, fragColor.a); + } + + if (butCo > 0.0) { + fragColor.a = 1.0; + } +}
\ No newline at end of file diff --git a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl new file mode 100644 index 00000000000..0c351a3bce4 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl @@ -0,0 +1,186 @@ +#define BIT_RANGE(x) uint((1 << x) - 1) + +/* 2 bits for corner */ +/* Attention! Not the same order as in UI_interface.h! + * Ordered by drawing order. */ +#define BOTTOM_LEFT 0u +#define BOTTOM_RIGHT 1u +#define TOP_RIGHT 2u +#define TOP_LEFT 3u +#define CNR_FLAG_RANGE BIT_RANGE(2) + +/* 4bits for corner id */ +#define CORNER_VEC_OFS 2u +#define CORNER_VEC_RANGE BIT_RANGE(4) +const vec2 cornervec[36] = vec2[36]( + vec2(0.0, 1.0), vec2(0.02, 0.805), vec2(0.067, 0.617), vec2(0.169, 0.45), vec2(0.293, 0.293), vec2(0.45, 0.169), vec2(0.617, 0.076), vec2(0.805, 0.02), vec2(1.0, 0.0), + vec2(-1.0, 0.0), vec2(-0.805, 0.02), vec2(-0.617, 0.067), vec2(-0.45, 0.169), vec2(-0.293, 0.293), vec2(-0.169, 0.45), vec2(-0.076, 0.617), vec2(-0.02, 0.805), vec2(0.0, 1.0), + vec2(0.0, -1.0), vec2(-0.02, -0.805), vec2(-0.067, -0.617), vec2(-0.169, -0.45), vec2(-0.293, -0.293), vec2(-0.45, -0.169), vec2(-0.617, -0.076), vec2(-0.805, -0.02), vec2(-1.0, 0.0), + vec2(1.0, 0.0), vec2(0.805, -0.02), vec2(0.617, -0.067), vec2(0.45, -0.169), vec2(0.293, -0.293), vec2(0.169, -0.45), vec2(0.076, -0.617), vec2(0.02, -0.805), vec2(0.0, -1.0) +); + +/* 4bits for jitter id */ +#define JIT_OFS 6u +#define JIT_RANGE BIT_RANGE(4) +const vec2 jit[9] = vec2[9]( + vec2( 0.468813, -0.481430), vec2(-0.155755, -0.352820), + vec2( 0.219306, -0.238501), vec2(-0.393286, -0.110949), + vec2(-0.024699, 0.013908), vec2( 0.343805, 0.147431), + vec2(-0.272855, 0.269918), vec2( 0.095909, 0.388710), + vec2( 0.0, 0.0) +); + +/* 2bits for other flags */ +#define INNER_FLAG uint(1 << 10) /* is inner vert */ +#define EMBOSS_FLAG uint(1 << 11) /* is emboss vert */ + +/* 2bits for color */ +#define COLOR_OFS 12u +#define COLOR_RANGE BIT_RANGE(2) +#define COLOR_INNER 0u +#define COLOR_EDGE 1u +#define COLOR_EMBOSS 2u + +/* 2bits for trias type */ +#define TRIA_FLAG uint(1 << 14) /* is tria vert */ +#define TRIA_FIRST INNER_FLAG /* is first tria (reuse INNER_FLAG) */ + +/* We can reuse the CORNER_* bits for tria */ +#define TRIA_VEC_RANGE BIT_RANGE(6) +const vec2 triavec[34] = vec2[34]( + /* horizontal tria */ + vec2(-0.352077, 0.532607), vec2(-0.352077, -0.549313), vec2( 0.330000, -0.008353), + vec2( 0.352077, 0.532607), vec2( 0.352077, -0.549313), vec2(-0.330000, -0.008353), + /* circle tria (triangle strip) */ + vec2(0.000000, 1.000000), + vec2(0.382684, 0.923879), vec2(-0.382683, 0.923880), + vec2(0.707107, 0.707107), vec2(-0.707107, 0.707107), + vec2(0.923879, 0.382684), vec2(-0.923879, 0.382684), + vec2(1.000000, 0.000000), vec2(-1.000000, 0.000000), + vec2(0.923879, -0.382684), vec2(-0.923879, -0.382684), + vec2(0.707107, -0.707107), vec2(-0.707107, -0.707107), + vec2(0.382684, -0.923879), vec2(-0.382683, -0.923880), + vec2(0.000000, -1.000000), + /* menu arrow */ + vec2(-0.33, 0.16), vec2(0.33, 0.16), vec2(0.0, 0.82), + vec2(0.0, -0.82), vec2(-0.33, -0.16), vec2(0.33, -0.16), + /* check mark */ + vec2(-0.578579, 0.253369), vec2(-0.392773, 0.412794), vec2(-0.004241, -0.328551), + vec2(-0.003001, 0.034320), vec2(1.055313, 0.864744), vec2(0.866408, 1.026895) +); + +uniform mat4 ModelViewProjectionMatrix; + +#ifdef USE_INSTANCE +#define MAX_INSTANCE 6 +uniform vec4 parameters[11 * MAX_INSTANCE]; +#else +uniform vec4 parameters[11]; +#endif + +/* gl_InstanceID is 0 if not drawing instances. */ +#define recti parameters[gl_InstanceID * 11 + 0] +#define rect parameters[gl_InstanceID * 11 + 1] +#define radsi parameters[gl_InstanceID * 11 + 2].x +#define rads parameters[gl_InstanceID * 11 + 2].y +#define faci parameters[gl_InstanceID * 11 + 2].zw +#define roundCorners parameters[gl_InstanceID * 11 + 3] +#define colorInner1 parameters[gl_InstanceID * 11 + 4] +#define colorInner2 parameters[gl_InstanceID * 11 + 5] +#define colorEdge parameters[gl_InstanceID * 11 + 6] +#define colorEmboss parameters[gl_InstanceID * 11 + 7] +#define colorTria parameters[gl_InstanceID * 11 + 8] +#define tria1Center parameters[gl_InstanceID * 11 + 9].xy +#define tria2Center parameters[gl_InstanceID * 11 + 9].zw +#define tria1Size parameters[gl_InstanceID * 11 + 10].x +#define tria2Size parameters[gl_InstanceID * 11 + 10].y +#define shadeDir parameters[gl_InstanceID * 11 + 10].z +#define doAlphaCheck parameters[gl_InstanceID * 11 + 10].w + +in uint vflag; + +noperspective out vec4 finalColor; +noperspective out float butCo; + +vec2 do_widget(void) +{ + uint cflag = vflag & CNR_FLAG_RANGE; + uint vofs = (vflag >> CORNER_VEC_OFS) & CORNER_VEC_RANGE; + + vec2 v = cornervec[cflag * 9u + vofs]; + + bool is_inner = (vflag & INNER_FLAG) != 0u; + + /* Scale by corner radius */ + v *= roundCorners[cflag] * ((is_inner) ? radsi : rads); + + /* Position to corner */ + vec4 rct = (is_inner) ? recti : rect; + if (cflag == BOTTOM_LEFT) + v += rct.xz; + else if (cflag == BOTTOM_RIGHT) + v += rct.yz; + else if (cflag == TOP_RIGHT) + v += rct.yw; + else /* (cflag == TOP_LEFT) */ + v += rct.xw; + + /* compute uv and color gradient */ + uint color_id = (vflag >> COLOR_OFS) & COLOR_RANGE; + if (color_id == COLOR_INNER) { + vec2 uv = faci * (v - recti.xz); + float fac = clamp((shadeDir > 0.0) ? uv.y : uv.x, 0.0, 1.0); + if (doAlphaCheck != 0.0) { + finalColor = colorInner1; + butCo = uv.x; + } + else { + finalColor = mix(colorInner2, colorInner1, fac); + butCo = -1.0; + } + } + else if (color_id == COLOR_EDGE) { + finalColor = colorEdge; + butCo = -1.0; + } + else /* (color_id == COLOR_EMBOSS) */ { + finalColor = colorEmboss; + butCo = -1.0; + } + + bool is_emboss = (vflag & EMBOSS_FLAG) != 0u; + v.y -= (is_emboss) ? 1.0f : 0.0; + + return v; +} + +vec2 do_tria() +{ + uint vofs = vflag & TRIA_VEC_RANGE; + + vec2 v = triavec[vofs]; + + finalColor = colorTria; + butCo = -1.0; + + bool is_tria_first = (vflag & TRIA_FIRST) != 0u; + + if (is_tria_first) + v = v * tria1Size + tria1Center; + else + v = v * tria2Size + tria2Center; + + return v; +} + +void main() +{ + bool is_tria = (vflag & TRIA_FLAG) != 0u; + + vec2 v = (is_tria) ? do_tria() : do_widget(); + + /* Antialiasing offset */ + v += jit[(vflag >> JIT_OFS) & JIT_RANGE]; + + gl_Position = ModelViewProjectionMatrix * vec4(v, 0.0, 1.0); +}
\ No newline at end of file diff --git a/source/blender/gpu/shaders/gpu_shader_2D_widget_shadow_frag.glsl b/source/blender/gpu/shaders/gpu_shader_2D_widget_shadow_frag.glsl new file mode 100644 index 00000000000..7587b2fc18a --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_widget_shadow_frag.glsl @@ -0,0 +1,13 @@ + +in float shadowFalloff; + +out vec4 fragColor; + +uniform float alpha; + +void main() +{ + fragColor = vec4(0.0); + /* Manual curve fit of the falloff curve of previous drawing method. */ + fragColor.a = alpha * (shadowFalloff * shadowFalloff * 0.722 + shadowFalloff * 0.277); +}
\ No newline at end of file diff --git a/source/blender/gpu/shaders/gpu_shader_2D_widget_shadow_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_widget_shadow_vert.glsl new file mode 100644 index 00000000000..2f5353a7c86 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_widget_shadow_vert.glsl @@ -0,0 +1,64 @@ +#define BIT_RANGE(x) uint((1 << x) - 1) + +/* 2 bits for corner */ +/* Attention! Not the same order as in UI_interface.h! + * Ordered by drawing order. */ +#define BOTTOM_LEFT 0u +#define BOTTOM_RIGHT 1u +#define TOP_RIGHT 2u +#define TOP_LEFT 3u +#define CNR_FLAG_RANGE BIT_RANGE(2) + +/* 4bits for corner id */ +#define CORNER_VEC_OFS 2u +#define CORNER_VEC_RANGE BIT_RANGE(4) +const vec2 cornervec[36] = vec2[36]( + vec2(0.0, 1.0), vec2(0.02, 0.805), vec2(0.067, 0.617), vec2(0.169, 0.45), vec2(0.293, 0.293), vec2(0.45, 0.169), vec2(0.617, 0.076), vec2(0.805, 0.02), vec2(1.0, 0.0), + vec2(-1.0, 0.0), vec2(-0.805, 0.02), vec2(-0.617, 0.067), vec2(-0.45, 0.169), vec2(-0.293, 0.293), vec2(-0.169, 0.45), vec2(-0.076, 0.617), vec2(-0.02, 0.805), vec2(0.0, 1.0), + vec2(0.0, -1.0), vec2(-0.02, -0.805), vec2(-0.067, -0.617), vec2(-0.169, -0.45), vec2(-0.293, -0.293), vec2(-0.45, -0.169), vec2(-0.617, -0.076), vec2(-0.805, -0.02), vec2(-1.0, 0.0), + vec2(1.0, 0.0), vec2(0.805, -0.02), vec2(0.617, -0.067), vec2(0.45, -0.169), vec2(0.293, -0.293), vec2(0.169, -0.45), vec2(0.076, -0.617), vec2(0.02, -0.805), vec2(0.0, -1.0) +); + +#define INNER_FLAG uint(1 << 10) /* is inner vert */ + +uniform mat4 ModelViewProjectionMatrix; + +uniform vec4 parameters[4]; +/* radi and rad per corner */ +#define recti parameters[0] +#define rect parameters[1] +#define radsi parameters[2].x +#define rads parameters[2].y +#define roundCorners parameters[3] + +in uint vflag; + +out float shadowFalloff; + +void main() +{ + uint cflag = vflag & CNR_FLAG_RANGE; + uint vofs = (vflag >> CORNER_VEC_OFS) & CORNER_VEC_RANGE; + + vec2 v = cornervec[cflag * 9u + vofs]; + + bool is_inner = (vflag & INNER_FLAG) != 0u; + + shadowFalloff = (is_inner) ? 1.0 : 0.0; + + /* Scale by corner radius */ + v *= roundCorners[cflag] * ((is_inner) ? radsi : rads); + + /* Position to corner */ + vec4 rct = (is_inner) ? recti : rect; + if (cflag == BOTTOM_LEFT) + v += rct.xz; + else if (cflag == BOTTOM_RIGHT) + v += rct.yz; + else if (cflag == TOP_RIGHT) + v += rct.yw; + else /* (cflag == TOP_LEFT) */ + v += rct.xw; + + gl_Position = ModelViewProjectionMatrix * vec4(v, 0.0, 1.0); +}
\ No newline at end of file diff --git a/source/blender/gpu/shaders/gpu_shader_fullscreen_vert.glsl b/source/blender/gpu/shaders/gpu_shader_fullscreen_vert.glsl deleted file mode 100644 index fc5cc1cdcc3..00000000000 --- a/source/blender/gpu/shaders/gpu_shader_fullscreen_vert.glsl +++ /dev/null @@ -1,10 +0,0 @@ - -in vec2 pos; -in vec2 uvs; -out vec4 uvcoordsvar; - -void main() -{ - uvcoordsvar = vec4(uvs, 0.0, 0.0); - gl_Position = vec4(pos, 0.0, 1.0); -} diff --git a/source/blender/gpu/shaders/gpu_shader_image_depth_copy_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_depth_copy_frag.glsl new file mode 100644 index 00000000000..10f4dfd5a87 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_image_depth_copy_frag.glsl @@ -0,0 +1,12 @@ + +in vec2 texCoord_interp; +out vec4 fragColor; + +uniform sampler2D image; + +void main() +{ + float depth = texture(image, texCoord_interp).r; + fragColor = vec4(depth); + gl_FragDepth = depth; +} diff --git a/source/blender/gpu/shaders/gpu_shader_image_rect_modulate_alpha_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_frag.glsl index 7d9ce9d2003..6eeab8ca7e8 100644 --- a/source/blender/gpu/shaders/gpu_shader_image_rect_modulate_alpha_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_image_frag.glsl @@ -2,11 +2,9 @@ in vec2 texCoord_interp; out vec4 fragColor; -uniform float alpha; -uniform sampler2DRect image; +uniform sampler2D image; void main() { fragColor = texture(image, texCoord_interp); - fragColor.a *= alpha; } diff --git a/source/blender/gpu/shaders/gpu_shader_image_interlace_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_interlace_frag.glsl index 7f3e7df40ac..d95645f58e5 100644 --- a/source/blender/gpu/shaders/gpu_shader_image_interlace_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_image_interlace_frag.glsl @@ -8,8 +8,8 @@ in vec2 texCoord_interp; out vec4 fragColor; uniform int interlace_id; -uniform sampler2DRect image_a; -uniform sampler2DRect image_b; +uniform sampler2D image_a; +uniform sampler2D image_b; bool interlace() { diff --git a/source/blender/gpu/shaders/gpu_shader_image_varying_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_varying_color_frag.glsl new file mode 100644 index 00000000000..37686092700 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_image_varying_color_frag.glsl @@ -0,0 +1,11 @@ + +in vec2 texCoord_interp; +flat in vec4 finalColor; +out vec4 fragColor; + +uniform sampler2D image; + +void main() +{ + fragColor = texture(image, texCoord_interp) * finalColor; +} diff --git a/source/blender/gpu/shaders/gpu_shader_instance_mball_helpers_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_mball_handles_vert.glsl index 819199c26c7..819199c26c7 100644 --- a/source/blender/gpu/shaders/gpu_shader_instance_mball_helpers_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_instance_mball_handles_vert.glsl diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 780f4f59fb9..d3bc1f0ef8e 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -1,16 +1,9 @@ -uniform mat4 ModelViewMatrix; -#ifndef EEVEE_ENGINE -uniform mat4 ProjectionMatrix; -uniform mat4 ViewMatrixInverse; -uniform mat4 ViewMatrix; -#endif uniform mat4 ModelMatrix; uniform mat4 ModelMatrixInverse; +uniform mat4 ModelViewMatrix; uniform mat4 ModelViewMatrixInverse; -uniform mat4 ProjectionMatrixInverse; uniform mat3 NormalMatrix; -uniform vec4 CameraTexCoFactors; /* Old glsl mode compat. */ @@ -238,16 +231,18 @@ void geom( } void particle_info( - vec4 sprops, vec3 loc, vec3 vel, vec3 avel, - out float index, out float age, out float life_time, out vec3 location, + vec4 sprops, vec4 loc, vec3 vel, vec3 avel, + out float index, out float random, out float age, + out float life_time, out vec3 location, out float size, out vec3 velocity, out vec3 angular_velocity) { index = sprops.x; + random = loc.w; age = sprops.y; life_time = sprops.z; size = sprops.w; - location = loc; + location = loc.xyz; velocity = vel; angular_velocity = avel; } @@ -2533,8 +2528,7 @@ uint hash(int kx, int ky, int kz) float bits_to_01(uint bits) { - float x = float(bits) * (1.0 / float(0xffffffffu)); - return x; + return (float(bits) / 4294967295.0); } float cellnoise(vec3 p) @@ -2696,7 +2690,6 @@ void node_bsdf_glossy(vec4 color, float roughness, vec3 N, float ssr_id, out Clo { #ifdef EEVEE_ENGINE vec3 out_spec, ssr_spec; - roughness = sqrt(roughness); eevee_closure_glossy(N, vec3(1.0), int(ssr_id), roughness, 1.0, out_spec, ssr_spec); vec3 vN = normalize(mat3(ViewMatrix) * N); result = CLOSURE_DEFAULT; @@ -2718,7 +2711,8 @@ void node_bsdf_glossy(vec4 color, float roughness, vec3 N, float ssr_id, out Clo vec3 light_specular = glLightSource[i].specular.rgb; /* we mix in some diffuse so low roughness still shows up */ - float bsdf = 0.5 * pow(max(dot(N, H), 0.0), 1.0 / roughness); + float r2 = roughness * roughness; + float bsdf = 0.5 * pow(max(dot(N, H), 0.0), 1.0 / r2); bsdf += 0.5 * max(dot(N, light_position), 0.0); L += light_specular * bsdf; } @@ -2738,7 +2732,6 @@ void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, float ssr_i { #ifdef EEVEE_ENGINE vec3 out_spec, out_refr, ssr_spec; - roughness = sqrt(roughness); vec3 refr_color = (refractionDepth > 0.0) ? color.rgb * color.rgb : color.rgb; /* Simulate 2 transmission event */ eevee_closure_glass(N, vec3(1.0), int(ssr_id), roughness, 1.0, ior, out_spec, out_refr, ssr_spec); out_refr *= refr_color; @@ -2977,9 +2970,10 @@ void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out Cl #ifdef EEVEE_ENGINE vec3 out_refr; color.rgb *= (refractionDepth > 0.0) ? color.rgb : vec3(1.0); /* Simulate 2 absorption event. */ - roughness = sqrt(roughness); eevee_closure_refraction(N, roughness, ior, out_refr); + vec3 vN = normalize(mat3(ViewMatrix) * N); result = CLOSURE_DEFAULT; + result.ssr_normal = normal_encode(vN, viewCameraVec); result.radiance = out_refr * color.rgb; result.ssr_id = REFRACT_CLOSURE_FLAG; #else @@ -3004,7 +2998,7 @@ void node_ambient_occlusion(vec4 color, out Closure result) /* emission */ -void node_emission(vec4 color, float strength, vec3 N, out Closure result) +void node_emission(vec4 color, float strength, vec3 vN, out Closure result) { #ifndef VOLUMETRICS color *= strength; @@ -3012,7 +3006,7 @@ void node_emission(vec4 color, float strength, vec3 N, out Closure result) result = CLOSURE_DEFAULT; result.radiance = color.rgb; result.opacity = color.a; - result.ssr_normal = normal_encode(N, viewCameraVec); + result.ssr_normal = normal_encode(vN, viewCameraVec); #else result = Closure(color.rgb, color.a); #endif @@ -3072,6 +3066,86 @@ void node_volume_absorption(vec4 color, float density, out Closure result) #endif } +void node_blackbody(float temperature, sampler2D spectrummap, out vec4 color) +{ + if(temperature >= 12000.0) { + color = vec4(0.826270103, 0.994478524, 1.56626022, 1.0); + } + else if(temperature < 965.0) { + color = vec4(4.70366907, 0.0, 0.0, 1.0); + } + else { + float t = (temperature - 965.0) / (12000.0 - 965.0); + color = vec4(texture(spectrummap, vec2(t, 0.0)).rgb, 1.0); + } +} + +void node_volume_principled( + vec4 color, + float density, + float anisotropy, + vec4 absorption_color, + float emission_strength, + vec4 emission_color, + float blackbody_intensity, + vec4 blackbody_tint, + float temperature, + float density_attribute, + vec4 color_attribute, + float temperature_attribute, + sampler2D spectrummap, + out Closure result) +{ +#ifdef VOLUMETRICS + vec3 absorption_coeff = vec3(0.0); + vec3 scatter_coeff = vec3(0.0); + vec3 emission_coeff = vec3(0.0); + + /* Compute density. */ + density = max(density, 0.0); + + if(density > 1e-5) { + density = max(density * density_attribute, 0.0); + } + + if(density > 1e-5) { + /* Compute scattering and absorption coefficients. */ + vec3 scatter_color = color.rgb * color_attribute.rgb; + + scatter_coeff = scatter_color * density; + absorption_color.rgb = sqrt(max(absorption_color.rgb, 0.0)); + absorption_coeff = max(1.0 - scatter_color, 0.0) * max(1.0 - absorption_color.rgb, 0.0) * density; + } + + /* Compute emission. */ + emission_strength = max(emission_strength, 0.0); + + if(emission_strength > 1e-5) { + emission_coeff += emission_strength * emission_color.rgb; + } + + if(blackbody_intensity > 1e-3) { + /* Add temperature from attribute. */ + float T = max(temperature * max(temperature_attribute, 0.0), 0.0); + + /* Stefan-Boltzman law. */ + float T4 = (T * T) * (T * T); + float sigma = 5.670373e-8 * 1e-6 / M_PI; + float intensity = sigma * mix(1.0, T4, blackbody_intensity); + + if(intensity > 1e-5) { + vec4 bb; + node_blackbody(T, spectrummap, bb); + emission_coeff += bb.rgb * blackbody_tint.rgb * intensity; + } + } + + result = Closure(absorption_coeff, scatter_coeff, emission_coeff, anisotropy); +#else + result = CLOSURE_DEFAULT; +#endif +} + /* closures */ void node_mix_shader(float fac, Closure shader1, Closure shader2, out Closure shader) @@ -3150,7 +3224,13 @@ void node_attribute_volume_color(sampler3D tex, out vec4 outcol, out vec3 outvec #else vec3 cos = vec3(0.0); #endif - outvec = texture(tex, cos).rgb; + + vec4 value = texture(tex, cos).rgba; + /* Density is premultiplied for interpolation, divide it out here. */ + if (value.a > 1e-8) + value.rgb /= value.a; + + outvec = value.rgb; outcol = vec4(outvec, 1.0); outf = dot(vec3(1.0 / 3.0), outvec); } @@ -3162,9 +3242,23 @@ void node_attribute_volume_flame(sampler3D tex, out vec4 outcol, out vec3 outvec #else vec3 cos = vec3(0.0); #endif - outvec = texture(tex, cos).rrr; - outcol = vec4(outvec, 1.0); - outf = dot(vec3(1.0 / 3.0), outvec); + outf = texture(tex, cos).r; + outvec = vec3(outf, outf, outf); + outcol = vec4(outf, outf, outf, 1.0); +} + +void node_attribute_volume_temperature(sampler3D tex, vec2 temperature, out vec4 outcol, out vec3 outvec, out float outf) +{ +#if defined(EEVEE_ENGINE) && defined(MESH_SHADER) && defined(VOLUMETRICS) + vec3 cos = volumeObjectLocalCoord; +#else + vec3 cos = vec3(0.0); +#endif + float flame = texture(tex, cos).r; + + outf = (flame > 0.01) ? temperature.x + flame * (temperature.y - temperature.x): 0.0; + outvec = vec3(outf, outf, outf); + outcol = vec4(outf, outf, outf, 1.0); } void node_attribute(vec3 attr, out vec4 outcol, out vec3 outvec, out float outf) @@ -3657,17 +3751,29 @@ float noise_perlin(float x, float y, float z) float v = noise_fade(fy); float w = noise_fade(fz); - float result; + float noise_u[2], noise_v[2]; + + noise_u[0] = noise_nerp(u, + noise_grad(hash(X, Y, Z), fx, fy, fz), + noise_grad(hash(X + 1, Y, Z), fx - 1.0, fy, fz)); + + noise_u[1] = noise_nerp(u, + noise_grad(hash(X, Y + 1, Z), fx, fy - 1.0, fz), + noise_grad(hash(X + 1, Y + 1, Z), fx - 1.0, fy - 1.0, fz)); + + noise_v[0] = noise_nerp(v, noise_u[0], noise_u[1]); - result = noise_nerp(w, noise_nerp(v, noise_nerp(u, noise_grad(hash(X, Y, Z), fx, fy, fz), - noise_grad(hash(X + 1, Y, Z), fx - 1.0, fy, fz)), - noise_nerp(u, noise_grad(hash(X, Y + 1, Z), fx, fy - 1.0, fz), - noise_grad(hash(X + 1, Y + 1, Z), fx - 1.0, fy - 1.0, fz))), - noise_nerp(v, noise_nerp(u, noise_grad(hash(X, Y, Z + 1), fx, fy, fz - 1.0), - noise_grad(hash(X + 1, Y, Z + 1), fx - 1.0, fy, fz - 1.0)), - noise_nerp(u, noise_grad(hash(X, Y + 1, Z + 1), fx, fy - 1.0, fz - 1.0), - noise_grad(hash(X + 1, Y + 1, Z + 1), fx - 1.0, fy - 1.0, fz - 1.0)))); - return noise_scale3(result); + noise_u[0] = noise_nerp(u, + noise_grad(hash(X, Y, Z + 1), fx, fy, fz - 1.0), + noise_grad(hash(X + 1, Y, Z + 1), fx - 1.0, fy, fz - 1.0)); + + noise_u[1] = noise_nerp(u, + noise_grad(hash(X, Y + 1, Z + 1), fx, fy - 1.0, fz - 1.0), + noise_grad(hash(X + 1, Y + 1, Z + 1), fx - 1.0, fy - 1.0, fz - 1.0)); + + noise_v[1] = noise_nerp(v, noise_u[0], noise_u[1]); + + return noise_scale3(noise_nerp(w, noise_v[0], noise_v[1])); } float noise(vec3 p) @@ -4135,9 +4241,38 @@ void node_bevel(float radius, vec3 N, out vec3 result) result = N; } -void node_displacement(float height, float dist, vec3 N, out vec3 result) +void node_displacement_object(float height, float midlevel, float scale, vec3 N, mat4 obmat, out vec3 result) +{ + N = (vec4(N, 0.0) * obmat).xyz; + result = (height - midlevel) * scale * normalize(N); + result = (obmat * vec4(result, 0.0)).xyz; +} + +void node_displacement_world(float height, float midlevel, float scale, vec3 N, out vec3 result) +{ + result = (height - midlevel) * scale * normalize(N); +} + +void node_vector_displacement_tangent(vec4 vector, float midlevel, float scale, vec4 tangent, vec3 normal, mat4 obmat, mat4 viewmat, out vec3 result) +{ + vec3 N_object = normalize(((vec4(normal, 0.0) * viewmat) * obmat).xyz); + vec3 T_object = normalize(((vec4(tangent.xyz, 0.0) * viewmat) * obmat).xyz); + vec3 B_object = tangent.w * normalize(cross(N_object, T_object)); + + vec3 offset = (vector.xyz - vec3(midlevel)) * scale; + result = offset.x * T_object + offset.y * N_object + offset.z * B_object; + result = (obmat * vec4(result, 0.0)).xyz; +} + +void node_vector_displacement_object(vec4 vector, float midlevel, float scale, mat4 obmat, out vec3 result) +{ + result = (vector.xyz - vec3(midlevel)) * scale; + result = (obmat * vec4(result, 0.0)).xyz; +} + +void node_vector_displacement_world(vec4 vector, float midlevel, float scale, out vec3 result) { - result = height * dist * N; + result = (vector.xyz - vec3(midlevel)) * scale; } /* output */ diff --git a/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_vert.glsl b/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_vert.glsl index 1319e386c65..fca39852c2a 100644 --- a/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_vert.glsl @@ -1,12 +1,14 @@ -uniform mat4 ModelViewProjectionMatrix; - -in vec2 pos; -in vec2 uvs; out vec2 texCoord_interp; void main() { - gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0); - texCoord_interp = uvs; + const vec4 vert[3] = vec4[3]( + vec3(-1.0, -1.0, 0.0, 0.0), + vec3( 3.0, -1.0, 2.0, 0.0), + vec3(-1.0, 3.0, 0.0, 2.0) + ); + + gl_Position = vec4(vert[gl_VertexID].xy, 0.0, 1.0); + texCoord_interp = vert[gl_VertexID].zw; } diff --git a/source/blender/gpu/shaders/gpu_shader_text_frag.glsl b/source/blender/gpu/shaders/gpu_shader_text_frag.glsl index 7ff90ad4f21..fbfa4cfcc9d 100644 --- a/source/blender/gpu/shaders/gpu_shader_text_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_text_frag.glsl @@ -1,15 +1,74 @@ flat in vec4 color_flat; +flat in vec4 texCoord_rect; noperspective in vec2 texCoord_interp; out vec4 fragColor; uniform sampler2D glyph; +const vec2 offsets4[4] = vec2[4]( + vec2(-0.5, 0.5), vec2( 0.5, 0.5), + vec2(-0.5, -0.5), vec2(-0.5, -0.5) +); + +const vec2 offsets16[16] = vec2[16]( + vec2(-1.5, 1.5), vec2(-0.5, 1.5), vec2( 0.5, 1.5), vec2( 1.5, 1.5), + vec2(-1.5, 0.5), vec2(-0.5, 0.5), vec2( 0.5, 0.5), vec2( 1.5, 0.5), + vec2(-1.5, -0.5), vec2(-0.5, -0.5), vec2( 0.5, -0.5), vec2( 1.5, -0.5), + vec2(-1.5, -1.5), vec2(-0.5, -1.5), vec2( 0.5, -1.5), vec2( 1.5, -1.5) +); + +#define sample_glyph_offset(texco, texel, ofs) texture(glyph, texco + ofs * texel).r + void main() { // input color replaces texture color fragColor.rgb = color_flat.rgb; + vec2 texel = 1.0 / vec2(textureSize(glyph, 0)); + vec2 texco = mix(abs(texCoord_rect.xy), abs(texCoord_rect.zw), texCoord_interp); + // modulate input alpha & texture alpha - fragColor.a = color_flat.a * texture(glyph, texCoord_interp).r; + if (texCoord_rect.x > 0) { + fragColor.a = texture(glyph, texco).r; + } + else { + fragColor.a = 0.0; + + if (texCoord_rect.w > 0) { + /* 3x3 blur */ + /* Manual unroll for perf. (stupid glsl compiler) */ + fragColor.a += sample_glyph_offset(texco, texel, offsets4[0]); + fragColor.a += sample_glyph_offset(texco, texel, offsets4[1]); + fragColor.a += sample_glyph_offset(texco, texel, offsets4[2]); + fragColor.a += sample_glyph_offset(texco, texel, offsets4[3]); + fragColor.a *= (1.0 / 4.0); + } + else { + /* 5x5 blur */ + /* Manual unroll for perf. (stupid glsl compiler) */ + fragColor.a += sample_glyph_offset(texco, texel, offsets16[ 0]); + fragColor.a += sample_glyph_offset(texco, texel, offsets16[ 1]); + fragColor.a += sample_glyph_offset(texco, texel, offsets16[ 2]); + fragColor.a += sample_glyph_offset(texco, texel, offsets16[ 3]); + + fragColor.a += sample_glyph_offset(texco, texel, offsets16[ 4]); + fragColor.a += sample_glyph_offset(texco, texel, offsets16[ 5]) * 2.0; + fragColor.a += sample_glyph_offset(texco, texel, offsets16[ 6]) * 2.0; + fragColor.a += sample_glyph_offset(texco, texel, offsets16[ 7]); + + fragColor.a += sample_glyph_offset(texco, texel, offsets16[ 8]); + fragColor.a += sample_glyph_offset(texco, texel, offsets16[ 9]) * 2.0; + fragColor.a += sample_glyph_offset(texco, texel, offsets16[10]) * 2.0; + fragColor.a += sample_glyph_offset(texco, texel, offsets16[11]); + + fragColor.a += sample_glyph_offset(texco, texel, offsets16[12]); + fragColor.a += sample_glyph_offset(texco, texel, offsets16[13]); + fragColor.a += sample_glyph_offset(texco, texel, offsets16[14]); + fragColor.a += sample_glyph_offset(texco, texel, offsets16[15]); + fragColor.a *= (1.0 / 20.0); + } + } + + fragColor.a *= color_flat.a; } diff --git a/source/blender/gpu/shaders/gpu_shader_text_geom.glsl b/source/blender/gpu/shaders/gpu_shader_text_geom.glsl new file mode 100644 index 00000000000..0acd2106f7a --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_text_geom.glsl @@ -0,0 +1,37 @@ + +uniform mat4 ModelViewProjectionMatrix; + +layout(points) in; +layout(triangle_strip, max_vertices = 4) out; + +in vec4 pos_rect[]; +in vec4 tex_rect[]; +in vec4 color[]; + +flat out vec4 color_flat; +flat out vec4 texCoord_rect; +noperspective out vec2 texCoord_interp; + +void main() +{ + color_flat = color[0]; + texCoord_rect = tex_rect[0]; + + gl_Position = (ModelViewProjectionMatrix * vec4(pos_rect[0].xy, 0.0, 1.0)); + texCoord_interp = vec2(0.0, 0.0); + EmitVertex(); + + gl_Position = (ModelViewProjectionMatrix * vec4(pos_rect[0].zy, 0.0, 1.0)); + texCoord_interp = vec2(1.0, 0.0); + EmitVertex(); + + gl_Position = (ModelViewProjectionMatrix * vec4(pos_rect[0].xw, 0.0, 1.0)); + texCoord_interp = vec2(0.0, 1.0); + EmitVertex(); + + gl_Position = (ModelViewProjectionMatrix * vec4(pos_rect[0].zw, 0.0, 1.0)); + texCoord_interp = vec2(1.0, 1.0); + EmitVertex(); + + EndPrimitive(); +} diff --git a/source/blender/gpu/shaders/gpu_shader_text_simple_geom.glsl b/source/blender/gpu/shaders/gpu_shader_text_simple_geom.glsl new file mode 100644 index 00000000000..8903fd1df57 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_text_simple_geom.glsl @@ -0,0 +1,36 @@ + +layout(points) in; +layout(triangle_strip, max_vertices = 4) out; + +in vec4 pos_rect[]; +in vec4 tex_rect[]; +in vec4 color[]; + +flat out vec4 color_flat; +flat out vec4 texCoord_rect; +noperspective out vec2 texCoord_interp; + +void main() +{ + color_flat = color[0]; + texCoord_rect = tex_rect[0]; + gl_Position.zw = vec2(0.0, 1.0); + + gl_Position.xy = pos_rect[0].xy; + texCoord_interp = vec2(0.0, 0.0); + EmitVertex(); + + gl_Position.xy = pos_rect[0].zy; + texCoord_interp = vec2(1.0, 0.0); + EmitVertex(); + + gl_Position.xy = pos_rect[0].xw; + texCoord_interp = vec2(0.0, 1.0); + EmitVertex(); + + gl_Position.xy = pos_rect[0].zw; + texCoord_interp = vec2(1.0, 1.0); + EmitVertex(); + + EndPrimitive(); +} diff --git a/source/blender/gpu/shaders/gpu_shader_text_simple_vert.glsl b/source/blender/gpu/shaders/gpu_shader_text_simple_vert.glsl new file mode 100644 index 00000000000..4a2cde71e07 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_text_simple_vert.glsl @@ -0,0 +1,22 @@ + +/* Simpler version of gpu_shader_text_vert that supports only 2D translation. */ + +uniform mat4 ModelViewProjectionMatrix; + +in vec4 pos; /* rect */ +in vec4 tex; /* rect */ +in vec4 col; + +out vec4 pos_rect; +out vec4 tex_rect; +out vec4 color; + +void main() +{ + /* Manual mat4*vec2 */ + pos_rect = ModelViewProjectionMatrix[0].xyxy * pos.xxzz; + pos_rect += ModelViewProjectionMatrix[1].xyxy * pos.yyww; + pos_rect += ModelViewProjectionMatrix[3].xyxy; + tex_rect = tex; + color = col; +} diff --git a/source/blender/gpu/shaders/gpu_shader_text_vert.glsl b/source/blender/gpu/shaders/gpu_shader_text_vert.glsl index 6129f49ce22..338156f5b68 100644 --- a/source/blender/gpu/shaders/gpu_shader_text_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_text_vert.glsl @@ -1,16 +1,17 @@ uniform mat4 ModelViewProjectionMatrix; -in vec2 pos; -in vec2 texCoord; -in vec4 color; -flat out vec4 color_flat; -noperspective out vec2 texCoord_interp; +in vec4 pos; /* rect */ +in vec4 tex; /* rect */ +in vec4 col; + +out vec4 pos_rect; +out vec4 tex_rect; +out vec4 color; void main() { - gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0); - - color_flat = color; - texCoord_interp = texCoord; + pos_rect = pos; + tex_rect = tex; + color = col; } |