diff options
Diffstat (limited to 'source/blender/gpu/shaders')
116 files changed, 3695 insertions, 2168 deletions
diff --git a/source/blender/gpu/shaders/gpu_shader_2D_flat_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_flat_color_vert.glsl new file mode 100644 index 00000000000..769e2b0e37c --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_flat_color_vert.glsl @@ -0,0 +1,13 @@ + +uniform mat4 ModelViewProjectionMatrix; + +in vec2 pos; +in vec4 color; + +flat out vec4 finalColor; + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0); + finalColor = color; +} 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_image_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_image_vert.glsl new file mode 100644 index 00000000000..228f3f1da19 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_image_vert.glsl @@ -0,0 +1,13 @@ + +uniform mat4 ModelViewProjectionMatrix; + +/* Keep in sync with intern/opencolorio/gpu_shader_display_transform_vertex.glsl */ +in vec2 texCoord; +in vec2 pos; +out vec2 texCoord_interp; + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4(pos.xy, 0.0f, 1.0f); + texCoord_interp = texCoord; +} diff --git a/source/blender/gpu/shaders/gpu_shader_2D_line_dashed_frag.glsl b/source/blender/gpu/shaders/gpu_shader_2D_line_dashed_frag.glsl new file mode 100644 index 00000000000..3c5b0d1ca0a --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_line_dashed_frag.glsl @@ -0,0 +1,54 @@ + +/* + * Fragment Shader for dashed lines, with uniform multi-color(s), or any single-color, and any thickness. + * + * Dashed is performed in screen space. + */ + +uniform float dash_width; + +/* Simple mode, discarding non-dash parts (so no need for blending at all). */ +uniform float dash_factor; /* if > 1.0, solid line. */ + +/* More advanced mode, allowing for complex, multi-colored patterns. Enabled when colors_len > 0. */ +/* Note: max number of steps/colors in pattern is 32! */ +uniform int colors_len; /* Enabled if > 0, 1 for solid line. */ +uniform vec4 colors[32]; + +noperspective in float distance_along_line; +noperspective in vec4 color_geom; + +out vec4 fragColor; + +void main() +{ + /* Multi-color option. */ + if (colors_len > 0) { + /* Solid line case, simple. */ + if (colors_len == 1) { + fragColor = colors[0]; + } + /* Actually dashed line... */ + else { + float normalized_distance = fract(distance_along_line / dash_width); + fragColor = colors[int(normalized_distance * colors_len)]; + } + } + /* Single color option. */ + else { + /* Solid line case, simple. */ + if (dash_factor >= 1.0f) { + fragColor = color_geom; + } + /* Actually dashed line... */ + else { + float normalized_distance = fract(distance_along_line / dash_width); + if (normalized_distance <= dash_factor) { + fragColor = color_geom; + } + else { + discard; + } + } + } +} diff --git a/source/blender/gpu/shaders/gpu_shader_2D_line_dashed_geom.glsl b/source/blender/gpu/shaders/gpu_shader_2D_line_dashed_geom.glsl new file mode 100644 index 00000000000..8fa19f94b39 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_line_dashed_geom.glsl @@ -0,0 +1,56 @@ + +/* + * Geometry Shader for dashed lines, with uniform multi-color(s), or any single-color, and unary thickness. + * + * Dashed is performed in screen space. + */ + + +/* Make to be used with dynamic batching so no Model Matrix needed */ +uniform mat4 ModelViewProjectionMatrix; +uniform vec2 viewport_size; + +/* Uniforms from fragment shader, used here to optimize out useless computation in case of solid line. */ +uniform float dash_factor; /* if > 1.0, solid line. */ +uniform int colors_len; /* Enabled if > 0, 1 for solid line. */ + +layout(lines) in; + +in vec4 color_vert[]; + +layout(line_strip, max_vertices = 2) out; +noperspective out float distance_along_line; +noperspective out vec4 color_geom; + +void main() +{ + vec4 v1 = gl_in[0].gl_Position; + vec4 v2 = gl_in[1].gl_Position; + + gl_Position = v1; + color_geom = color_vert[0]; + distance_along_line = 0.0f; + EmitVertex(); + + gl_Position = v2; + color_geom = color_vert[1]; + if ((colors_len == 1) || (dash_factor >= 1.0f)) { + /* Solid line, optimize out distance computation! */ + distance_along_line = 0.0f; + } + else { + vec2 p1 = (v1.xy / v1.w) * 0.5 + 0.5; // <- device coordinates in [0..1] range. + p1 = p1 * viewport_size; // <- 'virtual' screen coordinates. + + vec2 p2 = (v2.xy / v2.w) * 0.5 + 0.5; // <- device coordinates in [0..1] range. + p2 = p2 * viewport_size; // <- 'virtual' screen coordinates. + + distance_along_line = distance(p1, p2); + } + EmitVertex(); + + EndPrimitive(); + + /* Note: we could also use similar approach as diag_stripes_frag, but this would give us dashed 'anchored' + * to the screen, and not to one end of the line... */ +} diff --git a/source/blender/gpu/shaders/gpu_shader_2D_line_dashed_uniform_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_line_dashed_uniform_color_vert.glsl new file mode 100644 index 00000000000..f5c611586aa --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_line_dashed_uniform_color_vert.glsl @@ -0,0 +1,21 @@ + +/* + * Vertex Shader for dashed lines with 2D coordinates, with uniform multi-colors or uniform single-color, + * and unary thickness. + * + * Dashed is performed in screen space. + */ + +uniform mat4 ModelViewProjectionMatrix; + +uniform vec4 color; + +in vec2 pos; + +out vec4 color_vert; + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0); + color_vert = color; +} diff --git a/source/blender/gpu/shaders/gpu_shader_2D_line_dashed_width_geom.glsl b/source/blender/gpu/shaders/gpu_shader_2D_line_dashed_width_geom.glsl new file mode 100644 index 00000000000..5a4da5cc9d4 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_line_dashed_width_geom.glsl @@ -0,0 +1,59 @@ + +// Draw dashed lines, perforated in screen space, with non-unary width. + +/* Make to be used with dynamic batching so no Model Matrix needed */ +uniform mat4 ModelViewProjectionMatrix; +uniform vec2 viewport_size; + +/* Width of the generated 'line'. */ +uniform float width; /* in pixels, screen space. */ + +/* Uniforms from fragment shader, used here to optimize out useless computation in case of solid line. */ +uniform float dash_factor; /* if > 1.0, solid line. */ +uniform int colors_len; /* Enabled if > 0, 1 for solid line. */ + +layout(lines) in; + +layout(triangle_strip, max_vertices = 4) out; +noperspective out float distance_along_line; + +void main() +{ + vec4 v1 = gl_in[0].gl_Position; + vec4 v2 = gl_in[1].gl_Position; + + /* Width, from 2D screen space in pixels, to ModelViewProjection space of each input vertices. */ + float w1 = (width / viewport_size) * v1.w * 2.0; + float w2 = (width / viewport_size) * v2.w * 2.0; + + /* Normalized vector parallel to screen and orthogonal to line. */ + vec4 wdir = normalize(vec4(v1.y - v2.y, v2.x - v1.x, 0.0, 0.0)) + + distance_along_line = 0.0f; + gl_Position = v1 + (wdir * w1); + EmitVertex(); + + gl_Position = v1 - (wdir * w1); + EmitVertex(); + + if ((colors_len == 1) || (dash_factor >= 1.0f)) { + /* Solid line, optimize out distance computation! */ + distance_along_line = 0.0f; + } + else { + vec2 p1 = (v1.xy / v1.w) * 0.5 + 0.5; // <- device coordinates in [0..1] range. + p1 = p1 * viewport_size; // <- 'virtual' screen coordinates. + + vec2 p2 = (v2.xy / v2.w) * 0.5 + 0.5; // <- device coordinates in [0..1] range. + p2 = p2 * viewport_size; // <- 'virtual' screen coordinates. + + distance_along_line = distance(p1, p2); + } + gl_Position = v2 + (wdir * w2); + EmitVertex(); + + gl_Position = v2 - (wdir * w2); + EmitVertex(); + + EndPrimitive(); +} 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..1497f9eeeb1 --- /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)); +} 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..4a9f5f94321 --- /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; + } +} diff --git a/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_aa_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_aa_vert.glsl new file mode 100644 index 00000000000..1f833cfb7be --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_aa_vert.glsl @@ -0,0 +1,21 @@ + +uniform mat4 ModelViewProjectionMatrix; +uniform float size; + +in vec2 pos; +out vec2 radii; + +void main() { + gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0); + gl_PointSize = size; + + // calculate concentric radii in pixels + float radius = 0.5 * size; + + // start at the outside and progress toward the center + radii[0] = radius; + radii[1] = radius - 1.0; + + // convert to PointCoord units + radii /= size; +} diff --git a/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_outline_aa_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_outline_aa_vert.glsl new file mode 100644 index 00000000000..99bdeb22904 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_outline_aa_vert.glsl @@ -0,0 +1,24 @@ + +uniform mat4 ModelViewProjectionMatrix; +uniform float size; +uniform float outlineWidth; + +in vec2 pos; +out vec4 radii; + +void main() { + gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0); + gl_PointSize = size; + + // calculate concentric radii in pixels + float radius = 0.5 * size; + + // start at the outside and progress toward the center + radii[0] = radius; + radii[1] = radius - 1.0; + radii[2] = radius - outlineWidth; + radii[3] = radius - outlineWidth - 1.0; + + // convert to PointCoord units + radii /= size; +} diff --git a/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_varying_color_outline_aa_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_varying_color_outline_aa_vert.glsl new file mode 100644 index 00000000000..5fad95236df --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_point_uniform_size_varying_color_outline_aa_vert.glsl @@ -0,0 +1,27 @@ + +uniform mat4 ModelViewProjectionMatrix; +uniform float size; +uniform float outlineWidth; + +in vec2 pos; +in vec4 color; +out vec4 radii; +out vec4 fillColor; + +void main() { + gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0); + gl_PointSize = size; + fillColor = color; + + // calculate concentric radii in pixels + float radius = 0.5 * size; + + // start at the outside and progress toward the center + radii[0] = radius; + radii[1] = radius - 1.0; + radii[2] = radius - outlineWidth; + radii[3] = radius - outlineWidth - 1.0; + + // convert to PointCoord units + radii /= size; +} diff --git a/source/blender/gpu/shaders/gpu_shader_2D_point_varying_size_varying_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_point_varying_size_varying_color_vert.glsl new file mode 100644 index 00000000000..d6aacf0cdc5 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_point_varying_size_varying_color_vert.glsl @@ -0,0 +1,14 @@ + +uniform mat4 ModelViewProjectionMatrix; + +in vec2 pos; +in float size; +in vec4 color; +out vec4 finalColor; + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0); + gl_PointSize = size; + finalColor = color; +} diff --git a/source/blender/gpu/shaders/gpu_shader_2D_smooth_color_dithered_frag.glsl b/source/blender/gpu/shaders/gpu_shader_2D_smooth_color_dithered_frag.glsl new file mode 100644 index 00000000000..145ed16248a --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_smooth_color_dithered_frag.glsl @@ -0,0 +1,20 @@ + +noperspective in vec4 finalColor; +out vec4 fragColor; + +/* 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]( + vec4( P(0.0), P(8.0), P(2.0), P(10.0)), + vec4(P(12.0), P(4.0), P(14.0), P(6.0)), + vec4( P(3.0), P(11.0), P(1.0), P(9.0)), + vec4(P(15.0), P(7.0), P(13.0), P(5.0)) +); + +void main() +{ + ivec2 tx1 = ivec2(gl_FragCoord.xy) % 4; + ivec2 tx2 = ivec2(gl_FragCoord.xy) % 2; + float dither_noise = dither_mat4x4[tx1.x][tx1.y]; + fragColor = finalColor + dither_noise; +} diff --git a/source/blender/gpu/shaders/gpu_shader_2D_smooth_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_2D_smooth_color_frag.glsl new file mode 100644 index 00000000000..4a4bfb6a616 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_smooth_color_frag.glsl @@ -0,0 +1,8 @@ + +noperspective in vec4 finalColor; +out vec4 fragColor; + +void main() +{ + fragColor = finalColor; +} diff --git a/source/blender/gpu/shaders/gpu_shader_2D_smooth_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_smooth_color_vert.glsl new file mode 100644 index 00000000000..fe91f4d0902 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_smooth_color_vert.glsl @@ -0,0 +1,13 @@ + +uniform mat4 ModelViewProjectionMatrix; + +in vec2 pos; +in vec4 color; + +noperspective out vec4 finalColor; + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0); + finalColor = color; +} diff --git a/source/blender/gpu/shaders/gpu_shader_2D_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_vert.glsl new file mode 100644 index 00000000000..89e3c52f9f8 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_vert.glsl @@ -0,0 +1,9 @@ + +uniform mat4 ModelViewProjectionMatrix; + +in vec2 pos; + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0); +} 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..a356014d025 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl @@ -0,0 +1,40 @@ +uniform vec3 checkerColorAndSize; + +noperspective in vec4 finalColor; +noperspective in float butCo; +flat in float discardFac; + +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() +{ + if (min(1.0, -butCo) > discardFac) { + discard; + } + + fragColor = finalColor; + + if (butCo > 0.5) { + vec4 checker = do_checkerboard(); + fragColor = mix(checker, fragColor, fragColor.a); + } + + if (butCo > 0.0) { + fragColor.a = 1.0; + } +} 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..9b63952db5c --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl @@ -0,0 +1,208 @@ +#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[43] = vec2[43]( + + /* ROUNDBOX_TRIA_ARROWS */ + vec2(-0.170000, 0.400000), vec2(-0.050000, 0.520000), vec2( 0.250000, 0.000000), vec2( 0.470000, -0.000000), vec2(-0.170000, -0.400000), vec2(-0.050000, -0.520000), + vec2( 0.170000, 0.400000), vec2( 0.050000, 0.520000), vec2(-0.250000, 0.000000), vec2(-0.470000, -0.000000), vec2( 0.170000, -0.400000), vec2( 0.050000, -0.520000), + + /* ROUNDBOX_TRIA_SCROLL - 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), + + /* ROUNDBOX_TRIA_MENU - menu arrows */ + vec2(-0.51, 0.08), vec2(-0.41, 0.20), vec2(-0.05, -0.39), + vec2(-0.05, -0.18), vec2(0.41, 0.08), vec2(0.3, 0.20), + + + /* ROUNDBOX_TRIA_CHECK - check mark */ + vec2(-0.67000, 0.020000), vec2(-0.500000, 0.190000), vec2(-0.130000, -0.520000), + vec2(-0.130000, -0.170000), vec2(0.720000, 0.430000), vec2(0.530000, 0.590000), + + /* ROUNDBOX_TRIA_HOLD_ACTION_ARROW - hold action arrows */ +#define OY (-0.2 / 2) +#define SC (0.35 * 2) +// vec2(-0.5 + SC, 1.0 + OY), vec2( 0.5, 1.0 + OY), vec2( 0.5, 0.0 + OY + SC), + vec2( 0.5 - SC, 1.0 + OY), vec2(-0.5, 1.0 + OY), vec2(-0.5, 0.0 + OY + SC) +#undef OY +#undef SC +); + +uniform mat4 ModelViewProjectionMatrix; + +#define MAX_PARAM 11 +#ifdef USE_INSTANCE +#define MAX_INSTANCE 6 +uniform vec4 parameters[MAX_PARAM * MAX_INSTANCE]; +#else +uniform vec4 parameters[MAX_PARAM]; +#endif + +/* gl_InstanceID is 0 if not drawing instances. */ +#define recti parameters[gl_InstanceID * MAX_PARAM + 0] +#define rect parameters[gl_InstanceID * MAX_PARAM + 1] +#define radsi parameters[gl_InstanceID * MAX_PARAM + 2].x +#define rads parameters[gl_InstanceID * MAX_PARAM + 2].y +#define faci parameters[gl_InstanceID * MAX_PARAM + 2].zw +#define roundCorners parameters[gl_InstanceID * MAX_PARAM + 3] +#define colorInner1 parameters[gl_InstanceID * MAX_PARAM + 4] +#define colorInner2 parameters[gl_InstanceID * MAX_PARAM + 5] +#define colorEdge parameters[gl_InstanceID * MAX_PARAM + 6] +#define colorEmboss parameters[gl_InstanceID * MAX_PARAM + 7] +#define colorTria parameters[gl_InstanceID * MAX_PARAM + 8] +#define tria1Center parameters[gl_InstanceID * MAX_PARAM + 9].xy +#define tria2Center parameters[gl_InstanceID * MAX_PARAM + 9].zw +#define tria1Size parameters[gl_InstanceID * MAX_PARAM + 10].x +#define tria2Size parameters[gl_InstanceID * MAX_PARAM + 10].y +#define shadeDir parameters[gl_InstanceID * MAX_PARAM + 10].z +#define alphaDiscard parameters[gl_InstanceID * MAX_PARAM + 10].w + +/* We encode alpha check and discard factor together. */ +#define doAlphaCheck (alphaDiscard < 0.0) +#define discardFactor abs(alphaDiscard) + +in uint vflag; + +noperspective out vec4 finalColor; +noperspective out float butCo; +flat out float discardFac; + +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; + + vec2 uv = faci * (v - recti.xz); + + /* compute uv and color gradient */ + uint color_id = (vflag >> COLOR_OFS) & COLOR_RANGE; + if (color_id == COLOR_INNER) { + float fac = clamp((shadeDir > 0.0) ? uv.y : uv.x, 0.0, 1.0); + + if (doAlphaCheck) { + finalColor = colorInner1; + butCo = uv.x; + } + else { + finalColor = mix(colorInner2, colorInner1, fac); + butCo = -abs(uv.x); + } + } + else if (color_id == COLOR_EDGE) { + finalColor = colorEdge; + butCo = -abs(uv.x); + } + else /* (color_id == COLOR_EMBOSS) */ { + finalColor = colorEmboss; + butCo = -abs(uv.x); + } + + 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() +{ + discardFac = discardFactor; + 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); +} 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..fc4d055a903 --- /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); +} 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..f6be496ac4f --- /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); +} diff --git a/source/blender/gpu/shaders/gpu_shader_3D_clipped_uniform_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_clipped_uniform_color_vert.glsl new file mode 100644 index 00000000000..84e44837264 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_3D_clipped_uniform_color_vert.glsl @@ -0,0 +1,12 @@ + +uniform mat4 ModelViewProjectionMatrix; +uniform mat4 ModelMatrix; +uniform vec4 ClipPlane; + +in vec3 pos; + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); + gl_ClipDistance[0] = dot(ModelMatrix * vec4(pos, 1.0), ClipPlane); +} diff --git a/source/blender/gpu/shaders/gpu_shader_3D_flat_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_flat_color_vert.glsl new file mode 100644 index 00000000000..7db7e28d8e6 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_3D_flat_color_vert.glsl @@ -0,0 +1,26 @@ + +uniform mat4 ModelViewProjectionMatrix; + +in vec3 pos; +#if defined(USE_COLOR_U32) +in uint color; +#else +in vec4 color; +#endif + +flat out vec4 finalColor; + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); + +#if defined(USE_COLOR_U32) + finalColor = vec4( + ((color ) & uint(0xFF)) * (1.0f / 255.0f), + ((color >> 8) & uint(0xFF)) * (1.0f / 255.0f), + ((color >> 16) & uint(0xFF)) * (1.0f / 255.0f), + ((color >> 24) ) * (1.0f / 255.0f)); +#else + finalColor = color; +#endif +} diff --git a/source/blender/gpu/shaders/gpu_shader_3D_groundline_geom.glsl b/source/blender/gpu/shaders/gpu_shader_3D_groundline_geom.glsl new file mode 100644 index 00000000000..f16fa21b342 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_3D_groundline_geom.glsl @@ -0,0 +1,16 @@ + +/* Make to be used with dynamic batching so no Model Matrix needed */ +uniform mat4 ViewProjectionMatrix; + +layout(points) in; +layout(line_strip, max_vertices = 2) out; + +void main() +{ + vec3 vert = gl_in[0].gl_Position.xyz; + gl_Position = ViewProjectionMatrix * vec4(vert.xyz, 1.0); + EmitVertex(); + gl_Position = ViewProjectionMatrix * vec4(vert.xy, 0.0, 1.0); + EmitVertex(); + EndPrimitive(); +} diff --git a/source/blender/gpu/shaders/gpu_shader_3D_groundpoint_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_groundpoint_vert.glsl new file mode 100644 index 00000000000..55f410eb25d --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_3D_groundpoint_vert.glsl @@ -0,0 +1,11 @@ + +/* Made to be used with dynamic batching so no Model Matrix needed */ +uniform mat4 ViewProjectionMatrix; + +in vec3 pos; + +void main() +{ + gl_Position = ViewProjectionMatrix * vec4(pos.xy, 0.0, 1.0); + gl_PointSize = 2.0; +} diff --git a/source/blender/gpu/shaders/gpu_shader_3D_image_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_image_vert.glsl new file mode 100644 index 00000000000..eb877ab20b6 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_3D_image_vert.glsl @@ -0,0 +1,12 @@ + +uniform mat4 ModelViewProjectionMatrix; + +in vec2 texCoord; +in vec3 pos; +out vec2 texCoord_interp; + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4(pos.xyz, 1.0f); + texCoord_interp = texCoord; +} diff --git a/source/blender/gpu/shaders/gpu_shader_3D_line_dashed_uniform_color_legacy_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_line_dashed_uniform_color_legacy_vert.glsl new file mode 100644 index 00000000000..84fbf977846 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_3D_line_dashed_uniform_color_legacy_vert.glsl @@ -0,0 +1,26 @@ + +/* + * Vertex Shader for dashed lines with 3D coordinates, with uniform multi-colors or uniform single-color, + * and unary thickness. + * + * Legacy version, without geometry shader support, always produce solid lines! + */ + +uniform mat4 ModelViewProjectionMatrix; +uniform vec2 viewport_size; + +uniform vec4 color; + +in vec3 pos; +noperspective out float distance_along_line; +noperspective out vec4 color_geom; + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); + + /* Hack - prevent stupid GLSL compiler to optimize out unused viewport_size uniform, which gives crash! */ + distance_along_line = viewport_size.x * 0.000001f - viewport_size.x * 0.0000009f; + + color_geom = color; +} diff --git a/source/blender/gpu/shaders/gpu_shader_3D_line_dashed_uniform_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_line_dashed_uniform_color_vert.glsl new file mode 100644 index 00000000000..2fe08896585 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_3D_line_dashed_uniform_color_vert.glsl @@ -0,0 +1,21 @@ + +/* + * Vertex Shader for dashed lines with 3D coordinates, with uniform multi-colors or uniform single-color, + * and unary thickness. + * + * Dashed is performed in screen space. + */ + +uniform mat4 ModelViewProjectionMatrix; + +uniform vec4 color; + +in vec3 pos; + +out vec4 color_vert; + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); + color_vert = color; +} diff --git a/source/blender/gpu/shaders/gpu_shader_3D_normal_smooth_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_normal_smooth_color_vert.glsl new file mode 100644 index 00000000000..e6b8fed7265 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_3D_normal_smooth_color_vert.glsl @@ -0,0 +1,22 @@ + +uniform mat4 ModelViewProjectionMatrix; +uniform mat3 NormalMatrix; + +in vec3 pos; +in vec3 nor; +in vec4 color; + +#ifdef USE_FLAT_NORMAL +flat out vec3 normal; +flat out vec4 finalColor; +#else +out vec3 normal; +out vec4 finalColor; +#endif + +void main() +{ + normal = normalize(NormalMatrix * nor); + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); + finalColor = color; +} diff --git a/source/blender/gpu/shaders/gpu_shader_3D_normal_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_normal_vert.glsl new file mode 100644 index 00000000000..a3f447a85f9 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_3D_normal_vert.glsl @@ -0,0 +1,13 @@ + +uniform mat4 ModelViewProjectionMatrix; +uniform mat3 NormalMatrix; + +in vec3 pos; +in vec3 nor; +out vec3 normal; + +void main() +{ + normal = normalize(NormalMatrix * nor); + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); +} diff --git a/source/blender/gpu/shaders/gpu_shader_3D_passthrough_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_passthrough_vert.glsl new file mode 100644 index 00000000000..60793bf56b6 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_3D_passthrough_vert.glsl @@ -0,0 +1,8 @@ + +/* Does Nothing */ +in vec3 pos; + +void main() +{ + gl_Position = vec4(pos, 1.0); +} diff --git a/source/blender/gpu/shaders/gpu_shader_3D_point_fixed_size_varying_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_point_fixed_size_varying_color_vert.glsl new file mode 100644 index 00000000000..2fe9c0623fa --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_3D_point_fixed_size_varying_color_vert.glsl @@ -0,0 +1,12 @@ + +uniform mat4 ModelViewProjectionMatrix; + +in vec3 pos; +in vec4 color; +out vec4 finalColor; + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); + finalColor = color; +} diff --git a/source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_aa_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_aa_vert.glsl new file mode 100644 index 00000000000..ebc945fcf35 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_aa_vert.glsl @@ -0,0 +1,21 @@ + +uniform mat4 ModelViewProjectionMatrix; +uniform float size; + +in vec3 pos; +out vec2 radii; + +void main() { + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); + gl_PointSize = size; + + // calculate concentric radii in pixels + float radius = 0.5 * size; + + // start at the outside and progress toward the center + radii[0] = radius; + radii[1] = radius - 1.0; + + // convert to PointCoord units + radii /= size; +} diff --git a/source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_outline_aa_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_outline_aa_vert.glsl new file mode 100644 index 00000000000..0d6b90cfba4 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_3D_point_uniform_size_outline_aa_vert.glsl @@ -0,0 +1,24 @@ + +uniform mat4 ModelViewProjectionMatrix; +uniform float size; +uniform float outlineWidth; + +in vec3 pos; +out vec4 radii; + +void main() { + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); + gl_PointSize = size; + + // calculate concentric radii in pixels + float radius = 0.5 * size; + + // start at the outside and progress toward the center + radii[0] = radius; + radii[1] = radius - 1.0; + radii[2] = radius - outlineWidth; + radii[3] = radius - outlineWidth - 1.0; + + // convert to PointCoord units + radii /= size; +} diff --git a/source/blender/gpu/shaders/gpu_shader_3D_point_varying_size_varying_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_point_varying_size_varying_color_vert.glsl new file mode 100644 index 00000000000..e14b9535c89 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_3D_point_varying_size_varying_color_vert.glsl @@ -0,0 +1,14 @@ + +uniform mat4 ModelViewProjectionMatrix; + +in vec3 pos; +in float size; +in vec4 color; +out vec4 finalColor; + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); + gl_PointSize = size; + finalColor = color; +} diff --git a/source/blender/gpu/shaders/gpu_shader_3D_point_varying_size_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_point_varying_size_vert.glsl new file mode 100644 index 00000000000..e4f173ab617 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_3D_point_varying_size_vert.glsl @@ -0,0 +1,11 @@ + +uniform mat4 ModelViewProjectionMatrix; + +in vec3 pos; +in float size; + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); + gl_PointSize = size; +} diff --git a/source/blender/gpu/shaders/gpu_shader_3D_smooth_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_3D_smooth_color_frag.glsl new file mode 100644 index 00000000000..41fdefd22e8 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_3D_smooth_color_frag.glsl @@ -0,0 +1,8 @@ + +in vec4 finalColor; +out vec4 fragColor; + +void main() +{ + fragColor = finalColor; +} diff --git a/source/blender/gpu/shaders/gpu_shader_3D_smooth_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_smooth_color_vert.glsl new file mode 100644 index 00000000000..a1feb2f75b7 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_3D_smooth_color_vert.glsl @@ -0,0 +1,13 @@ + +uniform mat4 ModelViewProjectionMatrix; + +in vec3 pos; +in vec4 color; + +out vec4 finalColor; + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); + finalColor = color; +} diff --git a/source/blender/gpu/shaders/gpu_shader_3D_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_vert.glsl new file mode 100644 index 00000000000..059473ebb74 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_3D_vert.glsl @@ -0,0 +1,9 @@ + +uniform mat4 ModelViewProjectionMatrix; + +in vec3 pos; + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); +} diff --git a/source/blender/gpu/shaders/gpu_shader_basic_frag.glsl b/source/blender/gpu/shaders/gpu_shader_basic_frag.glsl index a030756e992..c4657bb7f66 100644 --- a/source/blender/gpu/shaders/gpu_shader_basic_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_basic_frag.glsl @@ -20,12 +20,10 @@ #define STIPPLE_HEXAGON 3 #define STIPPLE_DIAG_STRIPES 4 #define STIPPLE_DIAG_STRIPES_SWAP 5 -#define STIPPLE_S3D_INTERLACE_ROW 6 -#define STIPPLE_S3D_INTERLACE_ROW_SWAP 7 -#define STIPPLE_S3D_INTERLACE_COLUMN 8 -#define STIPPLE_S3D_INTERLACE_COLUMN_SWAP 9 -#define STIPPLE_S3D_INTERLACE_CHECKERBOARD 10 -#define STIPPLE_S3D_INTERLACE_CHECKERBOARD_SWAP 11 + +#ifndef NO_SPECULAR +uniform mat4 ProjectionMatrix; +#endif #if defined(USE_SOLID_LIGHTING) || defined(USE_SCENE_LIGHTING) #if defined(USE_FLAT_NORMAL) @@ -58,7 +56,7 @@ uniform sampler2D_default texture_map; #ifdef USE_STIPPLE uniform int stipple_id; #if defined(DRAW_LINE) -varying in float t; +varying float t; uniform int stipple_pattern; #endif #endif @@ -74,14 +72,9 @@ void main() /* We have to use mod function and integer casting. * This can be optimized further with the bitwise operations * when GLSL 1.3 is supported. */ - if (stipple_id == STIPPLE_HALFTONE || - stipple_id == STIPPLE_S3D_INTERLACE_CHECKERBOARD || - stipple_id == STIPPLE_S3D_INTERLACE_CHECKERBOARD_SWAP) - { + if (stipple_id == STIPPLE_HALFTONE) { int result = int(mod(gl_FragCoord.x + gl_FragCoord.y, 2)); bool dis = result == 0; - if (stipple_id == STIPPLE_S3D_INTERLACE_CHECKERBOARD_SWAP) - dis = !dis; if (dis) discard; } @@ -116,22 +109,6 @@ void main() if (!((16 - modx > mody && mody > 8 - modx) || mody > 24 - modx)) discard; } - else if (stipple_id == STIPPLE_S3D_INTERLACE_ROW || stipple_id == STIPPLE_S3D_INTERLACE_ROW_SWAP) { - int result = int(mod(gl_FragCoord.y, 2)); - bool dis = result == 0; - if (stipple_id == STIPPLE_S3D_INTERLACE_ROW_SWAP) - dis = !dis; - if (dis) - discard; - } - else if (stipple_id == STIPPLE_S3D_INTERLACE_COLUMN || stipple_id == STIPPLE_S3D_INTERLACE_COLUMN_SWAP) { - int result = int(mod(gl_FragCoord.x, 2)); - bool dis = result != 0; - if (stipple_id == STIPPLE_S3D_INTERLACE_COLUMN_SWAP) - dis = !dis; - if (dis) - discard; - } else if (stipple_id == STIPPLE_HEXAGON) { int mody = int(mod(gl_FragCoord.y, 2)); int modx = int(mod(gl_FragCoord.x, 4)); @@ -190,7 +167,7 @@ void main() #ifndef NO_SPECULAR /* view vector computation, depends on orthographics or perspective */ - vec3 V = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(varying_position) : vec3(0.0, 0.0, -1.0); + vec3 V = (ProjectionMatrix[3][3] == 0.0) ? normalize(varying_position) : vec3(0.0, 0.0, -1.0); #endif for (int i = 0; i < NUM_SCENE_LIGHTS; i++) { diff --git a/source/blender/gpu/shaders/gpu_shader_basic_geom.glsl b/source/blender/gpu/shaders/gpu_shader_basic_geom.glsl index a88681a5fd3..13f05b340bf 100644 --- a/source/blender/gpu/shaders/gpu_shader_basic_geom.glsl +++ b/source/blender/gpu/shaders/gpu_shader_basic_geom.glsl @@ -14,9 +14,9 @@ layout(line_strip, max_vertices = 10) out; layout(triangle_strip, max_vertices = 6) out; #endif -varying out float t; -varying in vec4 varying_vertex_color_line[]; -varying out vec4 varying_vertex_color; +out float t; +in vec4 varying_vertex_color_line[]; +out vec4 varying_vertex_color; uniform ivec4 viewport; uniform float line_width; diff --git a/source/blender/gpu/shaders/gpu_shader_basic_vert.glsl b/source/blender/gpu/shaders/gpu_shader_basic_vert.glsl index c29a39b4e34..4fdaf809cd1 100644 --- a/source/blender/gpu/shaders/gpu_shader_basic_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_basic_vert.glsl @@ -1,4 +1,8 @@ +uniform mat4 ModelViewMatrix; +uniform mat4 ProjectionMatrix; +uniform mat3 NormalMatrix; + #if defined(USE_SOLID_LIGHTING) || defined(USE_SCENE_LIGHTING) #if defined(USE_FLAT_NORMAL) varying vec3 eyespace_vert_pos; @@ -29,15 +33,15 @@ varying float gl_ClipDistance[6]; void main() { - vec4 co = gl_ModelViewMatrix * gl_Vertex; + vec4 co = ModelViewMatrix * gl_Vertex; #if defined(USE_SOLID_LIGHTING) || defined(USE_SCENE_LIGHTING) #if !defined(USE_FLAT_NORMAL) - varying_normal = normalize(gl_NormalMatrix * gl_Normal); + varying_normal = normalize(NormalMatrix * gl_Normal); #endif #if defined(USE_FLAT_NORMAL) /* transform vertex into eyespace */ - eyespace_vert_pos = (gl_ModelViewMatrix * gl_Vertex).xyz; + eyespace_vert_pos = (ModelViewMatrix * gl_Vertex).xyz; #endif #ifndef USE_SOLID_LIGHTING @@ -45,7 +49,7 @@ void main() #endif #endif - gl_Position = gl_ProjectionMatrix * co; + gl_Position = ProjectionMatrix * co; #ifdef CLIP_WORKAROUND int i; diff --git a/source/blender/gpu/shaders/gpu_shader_checker_frag.glsl b/source/blender/gpu/shaders/gpu_shader_checker_frag.glsl new file mode 100644 index 00000000000..545f6d19e21 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_checker_frag.glsl @@ -0,0 +1,20 @@ + +uniform vec4 color1; +uniform vec4 color2; +uniform int size; + +out vec4 fragColor; + +void main() +{ + vec2 phase = mod(gl_FragCoord.xy, (size*2)); + + if ((phase.x > size && phase.y < size) || + (phase.x < size && phase.y > size)) + { + fragColor = color1; + } + else { + fragColor = color2; + } +} diff --git a/source/blender/gpu/shaders/gpu_shader_depth_only_frag.glsl b/source/blender/gpu/shaders/gpu_shader_depth_only_frag.glsl new file mode 100644 index 00000000000..60e71e19004 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_depth_only_frag.glsl @@ -0,0 +1,6 @@ + +void main() +{ + // no color output, only depth (line below is implicit) + // gl_FragDepth = gl_FragCoord.z; +} diff --git a/source/blender/gpu/shaders/gpu_shader_diag_stripes_frag.glsl b/source/blender/gpu/shaders/gpu_shader_diag_stripes_frag.glsl new file mode 100644 index 00000000000..beb71c58100 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_diag_stripes_frag.glsl @@ -0,0 +1,20 @@ + +uniform vec4 color1; +uniform vec4 color2; +uniform int size1; +uniform int size2; + +out vec4 fragColor; + +void main() +{ + float phase = mod((gl_FragCoord.x + gl_FragCoord.y), (size1 + size2)); + + if (phase < size1) + { + fragColor = color1; + } + else { + fragColor = color2; + } +} diff --git a/source/blender/gpu/shaders/gpu_shader_edges_front_back_ortho_vert.glsl b/source/blender/gpu/shaders/gpu_shader_edges_front_back_ortho_vert.glsl new file mode 100644 index 00000000000..4ed7ed56c11 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_edges_front_back_ortho_vert.glsl @@ -0,0 +1,54 @@ + +// Draw "fancy" wireframe, displaying front-facing, back-facing and +// silhouette lines differently. +// Mike Erwin, April 2015 + +uniform bool drawFront = true; +uniform bool drawBack = true; +uniform bool drawSilhouette = true; + +uniform vec4 frontColor; +uniform vec4 backColor; +uniform vec4 silhouetteColor; + +uniform vec3 eye; // direction we are looking + +uniform mat4 ModelViewProjectionMatrix; + +in vec3 pos; + +// normals of faces this edge joins (object coords) +in vec3 N1; +in vec3 N2; + +flat out vec4 finalColor; + +// TODO: in float angle; // [-pi .. +pi], + peak, 0 flat, - valley + +// to discard an entire line, set both endpoints to nowhere +// and it won't produce any fragments +const vec4 nowhere = vec4(vec3(0.0), 1.0); + +void main() +{ + bool face_1_front = dot(N1, eye) > 0.0; + bool face_2_front = dot(N2, eye) > 0.0; + + vec4 position = ModelViewProjectionMatrix * vec4(pos, 1.0); + + if (face_1_front && face_2_front) { + // front-facing edge + gl_Position = drawFront ? position : nowhere; + finalColor = frontColor; + } + else if (face_1_front || face_2_front) { + // exactly one face is front-facing, silhouette edge + gl_Position = drawSilhouette ? position : nowhere; + finalColor = silhouetteColor; + } + else { + // back-facing edge + gl_Position = drawBack ? position : nowhere; + finalColor = backColor; + } +} diff --git a/source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_geom.glsl b/source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_geom.glsl new file mode 100644 index 00000000000..e7632fcad15 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_geom.glsl @@ -0,0 +1,60 @@ + +// Draw "fancy" wireframe, displaying front-facing, back-facing and +// silhouette lines differently. +// Mike Erwin, April 2015 + +// After working with this shader a while, convinced we should make +// separate shaders for perpective & ortho. (Oct 2016) + +// Due to perspective, the line segment's endpoints might disagree on +// whether the adjacent faces are front facing. This geometry shader +// decides which edge type to use if endpoints disagree. + +uniform mat4 ProjectionMatrix; + +uniform bool drawFront = true; +uniform bool drawBack = true; +uniform bool drawSilhouette = true; + +uniform vec4 frontColor; +uniform vec4 backColor; +uniform vec4 silhouetteColor; + +layout(lines) in; +layout(line_strip, max_vertices = 2) out; + +in vec4 MV_pos[]; +in float edgeClass[]; + +flat out vec4 finalColor; + +void emitLine(vec4 color) +{ + gl_Position = ProjectionMatrix * MV_pos[0]; + EmitVertex(); + gl_Position = ProjectionMatrix * MV_pos[1]; + finalColor = color; + EmitVertex(); + EndPrimitive(); +} + +void main() +{ + float finalEdgeClass = max(edgeClass[0], edgeClass[1]); + + if (finalEdgeClass > 0.0f) { + // front-facing edge + if (drawFront) + emitLine(frontColor); + } + else if (finalEdgeClass < 0.0f) { + // back-facing edge + if (drawBack) + emitLine(backColor); + } + else { + // exactly one face is front-facing, silhouette edge + if (drawSilhouette) + emitLine(silhouetteColor); + } +} diff --git a/source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_legacy_vert.glsl b/source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_legacy_vert.glsl new file mode 100644 index 00000000000..30b3bdb890d --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_legacy_vert.glsl @@ -0,0 +1,68 @@ + +// Draw "fancy" wireframe, displaying front-facing, back-facing and +// silhouette lines differently. +// Mike Erwin, April 2015 + +// After working with this shader a while, convinced we should make +// separate shaders for perpective & ortho. (Oct 2016) + +// This shader is an imperfect stepping stone until all platforms are +// ready for geometry shaders. + +// Due to perspective, the line segment's endpoints might disagree on +// whether the adjacent faces are front facing. Need to use a geometry +// shader or pass in an extra position attribute (the other endpoint) +// to do this properly. + +uniform bool drawFront = true; +uniform bool drawBack = true; +uniform bool drawSilhouette = true; + +uniform vec4 frontColor; +uniform vec4 backColor; +uniform vec4 silhouetteColor; + +uniform mat4 ModelViewMatrix; +uniform mat4 ModelViewProjectionMatrix; +uniform mat3 NormalMatrix; + +in vec3 pos; + +// normals of faces this edge joins (object coords) +in vec3 N1; +in vec3 N2; + +flat out vec4 finalColor; + +// TODO: in float angle; // [-pi .. +pi], + peak, 0 flat, - valley + +// to discard an entire line, set its color to invisible +// (must have GL_BLEND enabled, or discard in fragment shader) +const vec4 invisible = vec4(0.0); + +bool front(vec3 N) +{ + vec4 xformed = ModelViewMatrix * vec4(pos, 1.0); + return dot(NormalMatrix * N, normalize(-xformed.xyz)) > 0.0; +} + +void main() +{ + bool face_1_front = front(N1); + bool face_2_front = front(N2); + + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); + + if (face_1_front && face_2_front) { + // front-facing edge + finalColor = drawFront ? frontColor : invisible; + } + else if (face_1_front || face_2_front) { + // exactly one face is front-facing, silhouette edge + finalColor = drawSilhouette ? silhouetteColor : invisible; + } + else { + // back-facing edge + finalColor = drawBack ? backColor : invisible; + } +} diff --git a/source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_vert.glsl b/source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_vert.glsl new file mode 100644 index 00000000000..e1fb78dd1a9 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_edges_front_back_persp_vert.glsl @@ -0,0 +1,44 @@ + +// Draw "fancy" wireframe, displaying front-facing, back-facing and +// silhouette lines differently. +// Mike Erwin, April 2015 + +// After working with this shader a while, convinced we should make +// separate shaders for perpective & ortho. (Oct 2016) + +// Due to perspective, the line segment's endpoints might disagree on +// whether the adjacent faces are front facing. We use a geometry +// shader to resolve this properly. + +uniform mat4 ModelViewMatrix; +uniform mat3 NormalMatrix; + +in vec3 pos; +in vec3 N1, N2; // normals of faces this edge joins (object coords) + +out vec4 MV_pos; +out float edgeClass; + +// TODO: in float angle; // [-pi .. +pi], + peak, 0 flat, - valley + +bool front(vec3 N, vec3 eye) +{ + return dot(NormalMatrix * N, eye) > 0.0; +} + +void main() +{ + MV_pos = ModelViewMatrix * vec4(pos, 1.0); + + vec3 eye = normalize(-MV_pos.xyz); + + bool face_1_front = front(N1, eye); + bool face_2_front = front(N2, eye); + + if (face_1_front && face_2_front) + edgeClass = 1.0; // front-facing edge + else if (face_1_front || face_2_front) + edgeClass = 0.0; // exactly one face is front-facing, silhouette edge + else + edgeClass = -1.0; // back-facing edge +} diff --git a/source/blender/gpu/shaders/gpu_shader_edges_overlay_frag.glsl b/source/blender/gpu/shaders/gpu_shader_edges_overlay_frag.glsl new file mode 100644 index 00000000000..0538c037dcf --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_edges_overlay_frag.glsl @@ -0,0 +1,20 @@ + +#define SMOOTH 1 + +const float transitionWidth = 1.0; + +uniform vec4 fillColor = vec4(0); +uniform vec4 outlineColor = vec4(0,0,0,1); + +noperspective in vec3 distanceToOutline; + +out vec4 FragColor; + +void main() { + float edgeness = min(min(distanceToOutline.x, distanceToOutline.y), distanceToOutline.z); +#if SMOOTH + FragColor = mix(outlineColor, fillColor, smoothstep(0, transitionWidth, edgeness)); +#else + FragColor = (edgeness <= 0) ? outlineColor : fillColor; +#endif +} diff --git a/source/blender/gpu/shaders/gpu_shader_edges_overlay_geom.glsl b/source/blender/gpu/shaders/gpu_shader_edges_overlay_geom.glsl new file mode 100644 index 00000000000..ad0dccb6c81 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_edges_overlay_geom.glsl @@ -0,0 +1,67 @@ +layout(triangles) in; +layout(triangle_strip, max_vertices=3) out; + +uniform float outlineWidth = 1.0; +uniform vec2 viewportSize; + +in vec4 pos_xformed[]; +in float widthModulator[]; + +noperspective out vec3 distanceToOutline; + +// project to screen space +vec2 proj(int axis) { + vec4 pos = pos_xformed[axis]; + return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize; +} + +float dist(vec2 pos[3], int v) { + // current vertex position + vec2 vpos = pos[v]; + // endpoints of opposite edge + vec2 e1 = pos[(v + 1) % 3]; + vec2 e2 = pos[(v + 2) % 3]; + + float abs_det = length(cross(vec3(vpos - e1, 0), vec3(vpos - e2, 0))); // could simplify + return abs_det / distance(e2, e1); +} + +vec3 distance[3]; + +void clearEdge(int v) { + float distant = 10 * outlineWidth; + for (int i = 0; i < 3; ++i) + distance[i][v] += distant; +} + +void modulateEdge(int v) { + float offset = min(widthModulator[v],1) * outlineWidth; + for (int i = 0; i < 3; ++i) + distance[i][v] -= offset; +} + +void main() { + vec2 pos[3] = vec2[3](proj(0), proj(1), proj(2)); + + for (int v = 0; v < 3; ++v) + distance[v] = vec3(0); + + for (int v = 0; v < 3; ++v) { + if (widthModulator[v] > 0) { + distance[v][v] = dist(pos, v); + modulateEdge(v); + } + } + + for (int v = 0; v < 3; ++v) + if (widthModulator[v] <= 0) + clearEdge(v); + + for (int v = 0; v < 3; ++v) { + gl_Position = pos_xformed[v]; + distanceToOutline = distance[v]; + EmitVertex(); + } + + EndPrimitive(); +} diff --git a/source/blender/gpu/shaders/gpu_shader_edges_overlay_simple_geom.glsl b/source/blender/gpu/shaders/gpu_shader_edges_overlay_simple_geom.glsl new file mode 100644 index 00000000000..ec692e210c2 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_edges_overlay_simple_geom.glsl @@ -0,0 +1,52 @@ +layout(triangles) in; +layout(triangle_strip, max_vertices=3) out; + +uniform float outlineWidth = 1.0; +uniform vec2 viewportSize; + +noperspective out vec3 distanceToOutline; + +// project to screen space +vec2 proj(int axis) { + vec4 pos = gl_in[axis].gl_Position; + return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize; +} + +float dist(vec2 pos[3], int v) { + // current vertex position + vec2 vpos = pos[v]; + // endpoints of opposite edge + vec2 e1 = pos[(v + 1) % 3]; + vec2 e2 = pos[(v + 2) % 3]; + + float abs_det = length(cross(vec3(vpos - e1, 0), vec3(vpos - e2, 0))); // could simplify + return abs_det / distance(e2, e1); +} + +vec3 distance[3]; + +void modulateEdge(int v) { + float offset = 0.5 * outlineWidth; + for (int i = 0; i < 3; ++i) + distance[i][v] -= offset; +} + +void main() { + vec2 pos[3] = vec2[3](proj(0), proj(1), proj(2)); + + for (int v = 0; v < 3; ++v) + distance[v] = vec3(0); + + for (int v = 0; v < 3; ++v) { + distance[v][v] = dist(pos, v); + modulateEdge(v); + } + + for (int v = 0; v < 3; ++v) { + gl_Position = gl_in[v].gl_Position; + distanceToOutline = distance[v]; + EmitVertex(); + } + + EndPrimitive(); +} diff --git a/source/blender/gpu/shaders/gpu_shader_edges_overlay_vert.glsl b/source/blender/gpu/shaders/gpu_shader_edges_overlay_vert.glsl new file mode 100644 index 00000000000..fb1d0aafe05 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_edges_overlay_vert.glsl @@ -0,0 +1,13 @@ + +uniform mat4 ModelViewProjectionMatrix; + +in vec3 pos; +in float edgeWidthModulator; + +out vec4 pos_xformed; +out float widthModulator; + +void main() { + pos_xformed = ModelViewProjectionMatrix * vec4(pos, 1.0); + widthModulator = edgeWidthModulator; +} diff --git a/source/blender/gpu/shaders/gpu_shader_fire_frag.glsl b/source/blender/gpu/shaders/gpu_shader_fire_frag.glsl index 3819203bcd9..fc9cafb6b02 100644 --- a/source/blender/gpu/shaders/gpu_shader_fire_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_fire_frag.glsl @@ -1,17 +1,15 @@ -varying vec3 coords; +in vec3 coords; +out vec4 fragColor; uniform sampler3D flame_texture; uniform sampler1D spectrum_texture; void main() { - float flame = texture3D(flame_texture, coords).r; - vec4 emission = texture1D(spectrum_texture, flame); + float flame = texture(flame_texture, coords).r; + vec4 emission = texture(spectrum_texture, flame); - vec4 color; - color.rgb = emission.a * emission.rgb; - color.a = emission.a; - - gl_FragColor = color; + fragColor.rgb = emission.a * emission.rgb; + fragColor.a = emission.a; } diff --git a/source/blender/gpu/shaders/gpu_shader_flat_color_alpha_test_0_frag.glsl b/source/blender/gpu/shaders/gpu_shader_flat_color_alpha_test_0_frag.glsl new file mode 100644 index 00000000000..cefae1021d2 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_flat_color_alpha_test_0_frag.glsl @@ -0,0 +1,11 @@ + +flat in vec4 finalColor; +out vec4 fragColor; + +void main() +{ + if (finalColor.a > 0.0) + fragColor = finalColor; + else + discard; +} diff --git a/source/blender/gpu/shaders/gpu_shader_flat_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_flat_color_frag.glsl new file mode 100644 index 00000000000..d738ed5ddb2 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_flat_color_frag.glsl @@ -0,0 +1,8 @@ + +flat in vec4 finalColor; +out vec4 fragColor; + +void main() +{ + fragColor = finalColor; +} diff --git a/source/blender/gpu/shaders/gpu_shader_flat_id_frag.glsl b/source/blender/gpu/shaders/gpu_shader_flat_id_frag.glsl new file mode 100644 index 00000000000..aa6f30531ae --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_flat_id_frag.glsl @@ -0,0 +1,8 @@ + +flat in uint finalId; +out uint fragId; + +void main() +{ + fragId = finalId; +} diff --git a/source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl b/source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl index e04cd7d3306..c4e7cff2b0b 100644 --- a/source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl +++ b/source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl @@ -1,9 +1,10 @@ uniform sampler2D depthbuffer; -varying vec4 uvcoordsvar; + +in vec4 uvcoordsvar; void main(void) { - float depth = texture2D(depthbuffer, uvcoordsvar.xy).r; + float depth = texture(depthbuffer, uvcoordsvar.xy).r; /* XRay background, discard */ if (depth >= 1.0) { diff --git a/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl b/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl index 338ef6d51a7..15d30e75969 100644 --- a/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl @@ -17,17 +17,18 @@ uniform vec4 dof_params; uniform vec4 viewvecs[3]; // coordinates on framebuffer in normalized (0.0-1.0) uv space -varying vec4 uvcoordsvar; +in vec4 uvcoordsvar; /* color texture coordinates, offset by a small amount */ -varying vec2 color_uv1; -varying vec2 color_uv2; +in vec2 color_uv1; +in vec2 color_uv2; -varying vec2 depth_uv1; -varying vec2 depth_uv2; -varying vec2 depth_uv3; -varying vec2 depth_uv4; +in vec2 depth_uv1; +in vec2 depth_uv2; +in vec2 depth_uv3; +in vec2 depth_uv4; +out vec4 FragColor; float calculate_far_coc(in float zdepth) { @@ -63,85 +64,85 @@ void first_pass() offset_row[2] = 3.0 * offset_row[0]; /* heavily blur the image */ - vec4 color = texture2D(colorbuffer, color_uv1); - color += texture2D(colorbuffer, color_uv1 + offset_row[1]); - color += texture2D(colorbuffer, color_uv2); - color += texture2D(colorbuffer, color_uv2 + offset_row[1]); + vec4 color = texture(colorbuffer, color_uv1); + color += texture(colorbuffer, color_uv1 + offset_row[1]); + color += texture(colorbuffer, color_uv2); + color += texture(colorbuffer, color_uv2 + offset_row[1]); color /= 4.0; - depth.r = texture2D(depthbuffer, depth_uv1).r; - depth.g = texture2D(depthbuffer, depth_uv2).r; - depth.b = texture2D(depthbuffer, depth_uv3).r; - depth.a = texture2D(depthbuffer, depth_uv4).r; + depth.r = texture(depthbuffer, depth_uv1).r; + depth.g = texture(depthbuffer, depth_uv2).r; + depth.b = texture(depthbuffer, depth_uv3).r; + depth.a = texture(depthbuffer, depth_uv4).r; zdepth = get_view_space_z_from_depth(vec4(viewvecs[0].z), vec4(viewvecs[1].z), depth); coc = calculate_near_coc(zdepth); - depth.r = texture2D(depthbuffer, depth_uv1 + offset_row[0]).r; - depth.g = texture2D(depthbuffer, depth_uv2 + offset_row[0]).r; - depth.b = texture2D(depthbuffer, depth_uv3 + offset_row[0]).r; - depth.a = texture2D(depthbuffer, depth_uv4 + offset_row[0]).r; + depth.r = texture(depthbuffer, depth_uv1 + offset_row[0]).r; + depth.g = texture(depthbuffer, depth_uv2 + offset_row[0]).r; + depth.b = texture(depthbuffer, depth_uv3 + offset_row[0]).r; + depth.a = texture(depthbuffer, depth_uv4 + offset_row[0]).r; zdepth = get_view_space_z_from_depth(vec4(viewvecs[0].z), vec4(viewvecs[1].z), depth); coc = max(calculate_near_coc(zdepth), coc); - depth.r = texture2D(depthbuffer, depth_uv1 + offset_row[1]).r; - depth.g = texture2D(depthbuffer, depth_uv2 + offset_row[1]).r; - depth.b = texture2D(depthbuffer, depth_uv3 + offset_row[1]).r; - depth.a = texture2D(depthbuffer, depth_uv4 + offset_row[1]).r; + depth.r = texture(depthbuffer, depth_uv1 + offset_row[1]).r; + depth.g = texture(depthbuffer, depth_uv2 + offset_row[1]).r; + depth.b = texture(depthbuffer, depth_uv3 + offset_row[1]).r; + depth.a = texture(depthbuffer, depth_uv4 + offset_row[1]).r; zdepth = get_view_space_z_from_depth(vec4(viewvecs[0].z), vec4(viewvecs[1].z), depth); coc = max(calculate_near_coc(zdepth), coc); - depth.r = texture2D(depthbuffer, depth_uv1 + offset_row[2]).r; - depth.g = texture2D(depthbuffer, depth_uv2 + offset_row[2]).r; - depth.b = texture2D(depthbuffer, depth_uv3 + offset_row[2]).r; - depth.a = texture2D(depthbuffer, depth_uv4 + offset_row[2]).r; + depth.r = texture(depthbuffer, depth_uv1 + offset_row[2]).r; + depth.g = texture(depthbuffer, depth_uv2 + offset_row[2]).r; + depth.b = texture(depthbuffer, depth_uv3 + offset_row[2]).r; + depth.a = texture(depthbuffer, depth_uv4 + offset_row[2]).r; zdepth = get_view_space_z_from_depth(vec4(viewvecs[0].z), vec4(viewvecs[1].z), depth); coc = max(calculate_near_coc(zdepth), coc); final_coc = max(max(coc.x, coc.y), max(coc.z, coc.w)); - gl_FragColor = vec4(color.rgb, final_coc); + FragColor = vec4(color.rgb, final_coc); } /* second pass, gaussian blur the downsampled image */ void second_pass() { - vec4 depth = vec4(texture2D(depthbuffer, uvcoordsvar.xy).r); + vec4 depth = vec4(texture(depthbuffer, uvcoordsvar.xy).r); /* clever sampling to sample 2 pixels at once. Of course it's not real gaussian sampling this way */ - vec4 color = texture2D(colorbuffer, uvcoordsvar.xy) * 0.3125; - color += texture2D(colorbuffer, uvcoordsvar.xy + invrendertargetdim) * 0.234375; - color += texture2D(colorbuffer, uvcoordsvar.xy + 2.5 * invrendertargetdim) * 0.09375; - color += texture2D(colorbuffer, uvcoordsvar.xy + 4.5 * invrendertargetdim) * 0.015625; - color += texture2D(colorbuffer, uvcoordsvar.xy - invrendertargetdim) * 0.234375; - color += texture2D(colorbuffer, uvcoordsvar.xy - 2.5 * invrendertargetdim) * 0.09375; - color += texture2D(colorbuffer, uvcoordsvar.xy - 4.5 * invrendertargetdim) * 0.015625; - - gl_FragColor = color; + vec4 color = texture(colorbuffer, uvcoordsvar.xy) * 0.3125; + color += texture(colorbuffer, uvcoordsvar.xy + invrendertargetdim) * 0.234375; + color += texture(colorbuffer, uvcoordsvar.xy + 2.5 * invrendertargetdim) * 0.09375; + color += texture(colorbuffer, uvcoordsvar.xy + 4.5 * invrendertargetdim) * 0.015625; + color += texture(colorbuffer, uvcoordsvar.xy - invrendertargetdim) * 0.234375; + color += texture(colorbuffer, uvcoordsvar.xy - 2.5 * invrendertargetdim) * 0.09375; + color += texture(colorbuffer, uvcoordsvar.xy - 4.5 * invrendertargetdim) * 0.015625; + + FragColor = color; } /* third pass, calculate the final coc from blurred and unblurred images */ void third_pass() { - vec4 color = texture2D(colorbuffer, uvcoordsvar.xy); - vec4 color_blurred = texture2D(blurredcolorbuffer, uvcoordsvar.xy); + vec4 color = texture(colorbuffer, uvcoordsvar.xy); + vec4 color_blurred = texture(blurredcolorbuffer, uvcoordsvar.xy); float coc = 2.0 * max(color_blurred.a, color.a); -color.a; - gl_FragColor = vec4(color.rgb, coc); + FragColor = vec4(color.rgb, coc); } /* fourth pass, blur the final coc once to get rid of discontinuities */ void fourth_pass() { - vec4 color = texture2D(colorbuffer, uvcoordsvar.xz); - color += texture2D(colorbuffer, uvcoordsvar.yz); - color += texture2D(colorbuffer, uvcoordsvar.xw); - color += texture2D(colorbuffer, uvcoordsvar.yw); + vec4 color = texture(colorbuffer, uvcoordsvar.xz); + color += texture(colorbuffer, uvcoordsvar.yz); + color += texture(colorbuffer, uvcoordsvar.xw); + color += texture(colorbuffer, uvcoordsvar.yw); - gl_FragColor = color / 4.0; + FragColor = color / 4.0; } vec4 small_sample_blur(in sampler2D colorbuffer, in vec2 uv, in vec4 color) @@ -150,10 +151,10 @@ vec4 small_sample_blur(in sampler2D colorbuffer, in vec2 uv, in vec4 color) vec4 result = weight * color; weight *= 4.0; - result += weight * texture2D(colorbuffer, uv + color_uv1.xy); - result += weight * texture2D(colorbuffer, uv - color_uv1.xy); - result += weight * texture2D(colorbuffer, uv + color_uv1.yx); - result += weight * texture2D(colorbuffer, uv - color_uv1.yx); + result += weight * texture(colorbuffer, uv + color_uv1.xy); + result += weight * texture(colorbuffer, uv - color_uv1.xy); + result += weight * texture(colorbuffer, uv + color_uv1.yx); + result += weight * texture(colorbuffer, uv - color_uv1.yx); return result; } @@ -163,11 +164,11 @@ vec4 small_sample_blur(in sampler2D colorbuffer, in vec2 uv, in vec4 color) void fifth_pass() { vec4 factors; - vec4 color_orig = texture2D(colorbuffer, uvcoordsvar.xy); - vec4 highblurred = texture2D(blurredcolorbuffer, uvcoordsvar.xy); - vec4 mediumblurred = texture2D(mblurredcolorbuffer, uvcoordsvar.xy); + vec4 color_orig = texture(colorbuffer, uvcoordsvar.xy); + vec4 highblurred = texture(blurredcolorbuffer, uvcoordsvar.xy); + vec4 mediumblurred = texture(mblurredcolorbuffer, uvcoordsvar.xy); vec4 smallblurred = small_sample_blur(colorbuffer, uvcoordsvar.xy, color_orig); - float depth = texture2D(depthbuffer, uvcoordsvar.xy).r; + float depth = texture(depthbuffer, uvcoordsvar.xy).r; float zdepth = get_view_space_z_from_depth(vec4(viewvecs[0].z), vec4(viewvecs[1].z), vec4(depth)).r; float coc_far = clamp(calculate_far_coc(zdepth), 0.0, 1.0); @@ -188,7 +189,7 @@ void fifth_pass() color /= dot(factors, vec4(1.0)); /* using original color is not correct, but use that for now because alpha of * blurred buffers uses CoC instead */ - gl_FragColor = vec4(color.rgb, color_orig.a); + FragColor = vec4(color.rgb, color_orig.a); } diff --git a/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_frag.glsl b/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_frag.glsl index 182113367d3..c41c1d0820b 100644 --- a/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_frag.glsl @@ -14,24 +14,28 @@ uniform sampler2D depthbuffer; uniform sampler2D cocbuffer; -/* this includes focal distance in x and aperture size in y */ +/* this includes aperture size in x and focal distance in y */ uniform vec4 dof_params; /* viewvectors for reconstruction of world space */ uniform vec4 viewvecs[3]; /* initial uv coordinate */ -varying vec2 uvcoord; +in vec2 uvcoord; /* coordinate used for calculating radius et al set in geometry shader */ -varying vec2 particlecoord; -varying vec4 color; +in vec2 particlecoord; +flat in vec4 color; /* downsampling coordinates */ -varying vec2 downsample1; -varying vec2 downsample2; -varying vec2 downsample3; -varying vec2 downsample4; +in vec2 downsample1; +in vec2 downsample2; +in vec2 downsample3; +in vec2 downsample4; + +layout(location = 0) out vec4 fragData0; +layout(location = 1) out vec4 fragData1; +layout(location = 2) out vec4 fragData2; #define M_PI 3.1415926535897932384626433832795 @@ -55,15 +59,15 @@ void downsample_pass() float far_coc, near_coc; /* custom downsampling. We need to be careful to sample nearest here to avoid leaks */ - vec4 color1 = texture2D(colorbuffer, downsample1); - vec4 color2 = texture2D(colorbuffer, downsample2); - vec4 color3 = texture2D(colorbuffer, downsample3); - vec4 color4 = texture2D(colorbuffer, downsample4); + vec4 color1 = texture(colorbuffer, downsample1); + vec4 color2 = texture(colorbuffer, downsample2); + vec4 color3 = texture(colorbuffer, downsample3); + vec4 color4 = texture(colorbuffer, downsample4); - depth.r = texture2D(depthbuffer, downsample1).r; - depth.g = texture2D(depthbuffer, downsample2).r; - depth.b = texture2D(depthbuffer, downsample3).r; - depth.a = texture2D(depthbuffer, downsample4).r; + depth.r = texture(depthbuffer, downsample1).r; + depth.g = texture(depthbuffer, downsample2).r; + depth.b = texture(depthbuffer, downsample3).r; + depth.a = texture(depthbuffer, downsample4).r; zdepth = get_view_space_z_from_depth(vec4(viewvecs[0].z), vec4(viewvecs[1].z), depth); coc = calculate_coc(zdepth); @@ -82,16 +86,16 @@ void downsample_pass() float norm_far = dot(far_weights, vec4(1.0)); /* now write output to weighted buffers. */ - gl_FragData[0] = color1 * near_weights.x + color2 * near_weights.y + color3 * near_weights.z + + fragData0 = color1 * near_weights.x + color2 * near_weights.y + color3 * near_weights.z + color4 * near_weights.w; - gl_FragData[1] = color1 * far_weights.x + color2 * far_weights.y + color3 * far_weights.z + + fragData1 = color1 * far_weights.x + color2 * far_weights.y + color3 * far_weights.z + color4 * far_weights.w; if (norm_near > 0.0) - gl_FragData[0] /= norm_near; + fragData0 /= norm_near; if (norm_far > 0.0) - gl_FragData[1] /= norm_far; - gl_FragData[2] = vec4(near_coc, far_coc, 0.0, 1.0); + fragData1 /= norm_far; + fragData2 = vec4(near_coc, far_coc, 0.0, 1.0); } /* accumulate color in the near/far blur buffers */ @@ -102,36 +106,36 @@ void accumulate_pass(void) { if (dof_params.w == 0.0) r = 1.0; else - r = cos(M_PI / dof_params.w) / - (cos(theta - (2.0 * M_PI / dof_params.w) * floor((dof_params.w * theta + M_PI) / (2.0 * M_PI)))); + r = cos(M_PI / dof_params.w) / + (cos(theta - (2.0 * M_PI / dof_params.w) * floor((dof_params.w * theta + M_PI) / (2.0 * M_PI)))); if (dot(particlecoord, particlecoord) > r * r) discard; - gl_FragData[0] = color; + fragData0 = color; } -#define MERGE_THRESHOLD 4.0 +#define MERGE_THRESHOLD 4.0 /* combine the passes, */ void final_pass(void) { vec4 finalcolor; float totalweight; - float depth = texture2D(depthbuffer, uvcoord).r; + float depth = texture(depthbuffer, uvcoord).r; vec4 zdepth = get_view_space_z_from_depth(vec4(viewvecs[0].z), vec4(viewvecs[1].z), vec4(depth)); float coc_near = calculate_coc(zdepth).r; float coc_far = max(-coc_near, 0.0); coc_near = max(coc_near, 0.0); - vec4 farcolor = texture2D(farbuffer, uvcoord); + vec4 farcolor = texture(farbuffer, uvcoord); float farweight = farcolor.a; if (farweight > 0.0) farcolor /= farweight; - vec4 nearcolor = texture2D(nearbuffer, uvcoord); + vec4 nearcolor = texture(nearbuffer, uvcoord); - vec4 srccolor = texture2D(colorbuffer, uvcoord); + vec4 srccolor = texture(colorbuffer, uvcoord); - vec4 coc = texture2D(cocbuffer, uvcoord); + vec4 coc = texture(cocbuffer, uvcoord); float mixfac = smoothstep(1.0, MERGE_THRESHOLD, coc_far); finalcolor = mix(srccolor, farcolor, mixfac); @@ -152,7 +156,9 @@ void final_pass(void) { finalcolor = mix(finalcolor, nearcolor, nearweight / totalweight); } - gl_FragData[0] = finalcolor; + fragData0 = finalcolor; + // fragData0 = vec4(nearweight, farweight, 0.0, 1.0); + // fragData0 = vec4(nearcolor.rgb, 1.0); } void main() diff --git a/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_geo.glsl b/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_geo.glsl index 4c650e7695f..52d0a9be499 100644 --- a/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_geo.glsl +++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_geo.glsl @@ -5,27 +5,14 @@ uniform vec2 layerselection; uniform sampler2D cocbuffer; -#if __VERSION__ >= 150 - layout(points) in; - layout(triangle_strip, max_vertices = 4) out; - - #define POS gl_in[0].gl_Position -#else - /* use the EXT_geometry_shader4 way */ - #define POS gl_PositionIn[0] -#endif - -/* initial uv coordinate */ -#if __VERSION__ < 130 - varying in vec2 uvcoord[]; - varying out vec2 particlecoord; - varying out vec4 color; - #define textureLod texture2DLod -#else - in vec2 uvcoord[]; - out vec2 particlecoord; - out vec4 color; -#endif +layout(points) in; +layout(triangle_strip, max_vertices = 4) out; + +#define POS gl_in[0].gl_Position + +in vec2 uvcoord[]; +out vec2 particlecoord; +flat out vec4 color; #define M_PI 3.1415926535897932384626433832795 @@ -46,21 +33,23 @@ void main() vec2 offset_far = vec2(offset_val * 0.5) / vec2(rendertargetdim.x, rendertargetdim.y); - gl_Position = POS + vec4(-offset_far.x, -offset_far.y, 0.0, 0.0); color = colortex; + + gl_Position = POS + vec4(-offset_far.x, -offset_far.y, 0.0, 0.0); particlecoord = vec2(-1.0, -1.0); EmitVertex(); + gl_Position = POS + vec4(-offset_far.x, offset_far.y, 0.0, 0.0); particlecoord = vec2(-1.0, 1.0); - color = colortex; EmitVertex(); + gl_Position = POS + vec4(offset_far.x, -offset_far.y, 0.0, 0.0); particlecoord = vec2(1.0, -1.0); - color = colortex; EmitVertex(); + gl_Position = POS + vec4(offset_far.x, offset_far.y, 0.0, 0.0); particlecoord = vec2(1.0, 1.0); - color = colortex; EmitVertex(); + EndPrimitive(); } diff --git a/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_vert.glsl b/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_vert.glsl index eea4385578f..86b338e528e 100644 --- a/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_vert.glsl @@ -1,27 +1,31 @@ -uniform vec2 invrendertargetdim; -uniform ivec2 rendertargetdim; + +in vec2 pos; +in vec2 uvs; /* initial uv coordinate */ -varying vec2 uvcoord; +out vec2 uvcoord; /* coordinate used for calculating radius et al set in geometry shader */ -varying vec2 particlecoord; +out vec2 particlecoord; /* downsampling coordinates */ -varying vec2 downsample1; -varying vec2 downsample2; -varying vec2 downsample3; -varying vec2 downsample4; +out vec2 downsample1; +out vec2 downsample2; +out vec2 downsample3; +out vec2 downsample4; + +uniform vec2 invrendertargetdim; +uniform ivec2 rendertargetdim; void vert_dof_downsample() { /* gather pixels from neighbors. half dimensions means we offset half a pixel to * get this right though it's possible we may lose a pixel at some point */ - downsample1 = gl_MultiTexCoord0.xy + vec2(-0.5, -0.5) * invrendertargetdim; - downsample2 = gl_MultiTexCoord0.xy + vec2(-0.5, 0.5) * invrendertargetdim; - downsample3 = gl_MultiTexCoord0.xy + vec2(0.5, 0.5) * invrendertargetdim; - downsample4 = gl_MultiTexCoord0.xy + vec2(0.5, -0.5) * invrendertargetdim; + downsample1 = uvs.xy + vec2(-0.5, -0.5) * invrendertargetdim; + downsample2 = uvs.xy + vec2(-0.5, 0.5) * invrendertargetdim; + downsample3 = uvs.xy + vec2(0.5, 0.5) * invrendertargetdim; + downsample4 = uvs.xy + vec2(0.5, -0.5) * invrendertargetdim; - gl_Position = gl_Vertex; + gl_Position = vec4(pos, 0.0, 1.0); } /* geometry shading pass, calculate a texture coordinate based on the indexed id */ @@ -42,8 +46,8 @@ void vert_dof_coc_scatter_pass() void vert_dof_final() { - uvcoord = gl_MultiTexCoord0.xy; - gl_Position = gl_Vertex; + uvcoord = uvs; + gl_Position = vec4(pos, 0.0, 1.0); } void main() diff --git a/source/blender/gpu/shaders/gpu_shader_fx_dof_vert.glsl b/source/blender/gpu/shaders/gpu_shader_fx_dof_vert.glsl index 221dd7e68df..b4576f75d19 100644 --- a/source/blender/gpu/shaders/gpu_shader_fx_dof_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_vert.glsl @@ -1,51 +1,54 @@ uniform vec2 invrendertargetdim; -//texture coordinates for framebuffer read -varying vec4 uvcoordsvar; +in vec2 pos; +in vec2 uvs; + +/* texture coordinates for framebuffer read */ +out vec4 uvcoordsvar; /* color texture coordinates, offset by a small amount */ -varying vec2 color_uv1; -varying vec2 color_uv2; +out vec2 color_uv1; +out vec2 color_uv2; -varying vec2 depth_uv1; -varying vec2 depth_uv2; -varying vec2 depth_uv3; -varying vec2 depth_uv4; +out vec2 depth_uv1; +out vec2 depth_uv2; +out vec2 depth_uv3; +out vec2 depth_uv4; //very simple shader for gull screen FX, just pass values on void vert_generic() { - uvcoordsvar = gl_MultiTexCoord0; - gl_Position = gl_Vertex; + uvcoordsvar = vec4(uvs, 0.0, 0.0); + gl_Position = vec4(pos, 0.0, 1.0); } void vert_dof_first_pass() { /* we offset the texture coordinates by 1.5 pixel, * then we reuse that to sample the surrounding pixels */ - color_uv1 = gl_MultiTexCoord0.xy + vec2(-1.5, -1.5) * invrendertargetdim; - color_uv2 = gl_MultiTexCoord0.xy + vec2(0.5, -1.5) * invrendertargetdim; + color_uv1 = uvs.xy + vec2(-1.5, -1.5) * invrendertargetdim; + color_uv2 = uvs.xy + vec2(0.5, -1.5) * invrendertargetdim; - depth_uv1 = gl_MultiTexCoord0.xy + vec2(-1.5, -1.5) * invrendertargetdim; - depth_uv2 = gl_MultiTexCoord0.xy + vec2(-0.5, -1.5) * invrendertargetdim; - depth_uv3 = gl_MultiTexCoord0.xy + vec2(0.5, -1.5) * invrendertargetdim; - depth_uv4 = gl_MultiTexCoord0.xy + vec2(1.5, -1.5) * invrendertargetdim; + depth_uv1 = uvs.xy + vec2(-1.5, -1.5) * invrendertargetdim; + depth_uv2 = uvs.xy + vec2(-0.5, -1.5) * invrendertargetdim; + depth_uv3 = uvs.xy + vec2(0.5, -1.5) * invrendertargetdim; + depth_uv4 = uvs.xy + vec2(1.5, -1.5) * invrendertargetdim; - gl_Position = gl_Vertex; + gl_Position = vec4(pos, 0.0, 1.0); } void vert_dof_fourth_pass() { vec4 halfpixel = vec4(-0.5, 0.5, -0.5, 0.5); - uvcoordsvar = gl_MultiTexCoord0.xxyy + + uvcoordsvar = uvs.xxyy + halfpixel * vec4(invrendertargetdim.x, invrendertargetdim.x, invrendertargetdim.y, invrendertargetdim.y); - gl_Position = gl_Vertex; + gl_Position = vec4(pos, 0.0, 1.0); } void vert_dof_fifth_pass() @@ -53,8 +56,8 @@ void vert_dof_fifth_pass() vec4 halfpixel = vec4(-0.5, 0.5, -0.5, 0.5); color_uv1 = vec2(0.5, 1.5) * invrendertargetdim; - uvcoordsvar = gl_MultiTexCoord0; - gl_Position = gl_Vertex; + uvcoordsvar = vec4(uvs, 0.0, 0.0); + gl_Position = vec4(pos, 0.0, 1.0); } void main() diff --git a/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl b/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl index 1dc49b52be1..7aa6786d292 100644 --- a/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl +++ b/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl @@ -1,14 +1,17 @@ +uniform mat4 ProjectionMatrix; + /* simple depth reconstruction, see http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer * we change the factors from the article to fit the OpennGL model. */ #ifdef PERSP_MATRIX + /* perspective camera code */ vec3 get_view_space_from_depth(in vec2 uvcoords, in vec3 viewvec_origin, in vec3 viewvec_diff, in float depth) { float d = 2.0 * depth - 1.0; - float zview = -gl_ProjectionMatrix[3][2] / (d + gl_ProjectionMatrix[2][2]); + float zview = -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]); return zview * (viewvec_origin + vec3(uvcoords, 0.0) * viewvec_diff); } @@ -18,7 +21,7 @@ vec4 get_view_space_z_from_depth(in vec4 near, in vec4 range, in vec4 depth) vec4 d = 2.0 * depth - vec4(1.0); /* return positive value, so sign differs! */ - return vec4(gl_ProjectionMatrix[3][2]) / (d + vec4(gl_ProjectionMatrix[2][2])); + return vec4(ProjectionMatrix[3][2]) / (d + vec4(ProjectionMatrix[2][2])); } #else diff --git a/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl b/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl index f19ff4ec65a..4904010c841 100644 --- a/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl @@ -1,3 +1,4 @@ + // color buffer uniform sampler2D colorbuffer; @@ -9,8 +10,10 @@ uniform sampler1D ssao_concentric_tex; // depth buffer uniform sampler2D depthbuffer; + // coordinates on framebuffer in normalized (0.0-1.0) uv space -varying vec4 uvcoordsvar; +in vec4 uvcoordsvar; +out vec4 FragColor; /* ssao_params.x : pixel scale for the ssao radious */ /* ssao_params.y : factor for the ssao darkening */ @@ -33,7 +36,7 @@ vec3 calculate_view_space_normal(in vec3 viewposition) float calculate_ssao_factor(float depth) { /* take the normalized ray direction here */ - vec2 rotX = texture2D(jitter_tex, uvcoordsvar.xy * ssao_sample_params.yz).rg; + vec2 rotX = texture(jitter_tex, uvcoordsvar.xy * ssao_sample_params.yz).rg; vec2 rotY = vec2(-rotX.y, rotX.x); /* occlusion is zero in full depth */ @@ -46,9 +49,9 @@ float calculate_ssao_factor(float depth) /* find the offset in screen space by multiplying a point * in camera space at the depth of the point by the projection matrix. */ vec2 offset; - float homcoord = gl_ProjectionMatrix[2][3] * position.z + gl_ProjectionMatrix[3][3]; - offset.x = gl_ProjectionMatrix[0][0] * ssao_params.x / homcoord; - offset.y = gl_ProjectionMatrix[1][1] * ssao_params.x / homcoord; + float homcoord = ProjectionMatrix[2][3] * position.z + ProjectionMatrix[3][3]; + offset.x = ProjectionMatrix[0][0] * ssao_params.x / homcoord; + offset.y = ProjectionMatrix[1][1] * ssao_params.x / homcoord; /* convert from -1.0...1.0 range to 0.0..1.0 for easy use with texture coordinates */ offset *= 0.5; @@ -57,7 +60,7 @@ float calculate_ssao_factor(float depth) int num_samples = int(ssao_sample_params.x); for (x = 0; x < num_samples; x++) { - vec2 dir_sample = texture1D(ssao_concentric_tex, (float(x) + 0.5) / ssao_sample_params.x).rg; + vec2 dir_sample = texture(ssao_concentric_tex, (float(x) + 0.5) / ssao_sample_params.x).rg; /* rotate with random direction to get jittered result */ vec2 dir_jittered = vec2(dot(dir_sample, rotX), dot(dir_sample, rotY)); @@ -67,7 +70,7 @@ float calculate_ssao_factor(float depth) if (uvcoords.x > 1.0 || uvcoords.x < 0.0 || uvcoords.y > 1.0 || uvcoords.y < 0.0) continue; - float depth_new = texture2D(depthbuffer, uvcoords).r; + float depth_new = texture(depthbuffer, uvcoords).r; if (depth_new != 1.0) { vec3 pos_new = get_view_space_from_depth(uvcoords, viewvecs[0].xyz, viewvecs[1].xyz, depth_new); vec3 dir = pos_new - position; @@ -87,8 +90,8 @@ float calculate_ssao_factor(float depth) void main() { - float depth = texture2D(depthbuffer, uvcoordsvar.xy).r; - vec4 scene_col = texture2D(colorbuffer, uvcoordsvar.xy); + float depth = texture(depthbuffer, uvcoordsvar.xy).r; + vec4 scene_col = texture(colorbuffer, uvcoordsvar.xy); vec3 final_color = mix(scene_col.rgb, ssao_color.rgb, calculate_ssao_factor(depth)); - gl_FragColor = vec4(final_color.rgb, scene_col.a); + FragColor = vec4(final_color.rgb, scene_col.a); } diff --git a/source/blender/gpu/shaders/gpu_shader_fx_vert.glsl b/source/blender/gpu/shaders/gpu_shader_fx_vert.glsl deleted file mode 100644 index 5194e414520..00000000000 --- a/source/blender/gpu/shaders/gpu_shader_fx_vert.glsl +++ /dev/null @@ -1,9 +0,0 @@ -varying vec4 uvcoordsvar; - -//very simple shader for full screen FX, just pass values on - -void main() -{ - uvcoordsvar = gl_MultiTexCoord0; - gl_Position = gl_Vertex; -} diff --git a/source/blender/gpu/shaders/gpu_shader_geometry.glsl b/source/blender/gpu/shaders/gpu_shader_geometry.glsl index fe630dbeddb..705b79cbf56 100644 --- a/source/blender/gpu/shaders/gpu_shader_geometry.glsl +++ b/source/blender/gpu/shaders/gpu_shader_geometry.glsl @@ -1,10 +1,11 @@ + +uniform mat4 ProjectionMatrix; + uniform int PrimitiveIdBase; uniform int osd_active_uv_offset; -#if __VERSION__ >= 150 - layout(lines_adjacency) in; - layout(triangle_strip, max_vertices = 4) out; -#endif +layout(lines_adjacency) in; +layout(triangle_strip, max_vertices = 4) out; in block { VertexData v; @@ -31,17 +32,12 @@ uniform int osd_fvar_count; tessCoord.t); \ } -#ifdef USE_NEW_SHADING # define INTERP_FACE_VARYING_ATT_2(result, fvarOffset, tessCoord) \ { \ vec2 tmp; \ INTERP_FACE_VARYING_2(tmp, fvarOffset, tessCoord); \ result = vec3(tmp, 0); \ } -#else -# define INTERP_FACE_VARYING_ATT_2(result, fvarOffset, tessCoord) \ - INTERP_FACE_VARYING_2(result, fvarOffset, tessCoord) -#endif uniform samplerBuffer FVarDataBuffer; uniform isamplerBuffer FVarDataOffsetBuffer; @@ -69,7 +65,7 @@ void emit_flat(int index, vec3 normal) set_mtface_vertex_attrs(st); - gl_Position = gl_ProjectionMatrix * inpt[index].v.position; + gl_Position = ProjectionMatrix * inpt[index].v.position; EmitVertex(); } @@ -90,7 +86,7 @@ void emit_smooth(int index) set_mtface_vertex_attrs(st); - gl_Position = gl_ProjectionMatrix * inpt[index].v.position; + gl_Position = ProjectionMatrix * inpt[index].v.position; EmitVertex(); } diff --git a/source/blender/gpu/shaders/gpu_shader_image_alpha_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_alpha_color_frag.glsl new file mode 100644 index 00000000000..727c3c0a832 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_image_alpha_color_frag.glsl @@ -0,0 +1,11 @@ + +in vec2 texCoord_interp; +out vec4 fragColor; + +uniform vec4 color; +uniform sampler2D image; + +void main() +{ + fragColor = texture(image, texCoord_interp).r * color; +} diff --git a/source/blender/gpu/shaders/gpu_shader_image_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_color_frag.glsl new file mode 100644 index 00000000000..ef8935cc7ba --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_image_color_frag.glsl @@ -0,0 +1,11 @@ + +in vec2 texCoord_interp; +out vec4 fragColor; + +uniform vec4 color; +uniform sampler2D image; + +void main() +{ + fragColor = texture(image, texCoord_interp) * color; +} 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_depth_linear_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_depth_linear_frag.glsl new file mode 100644 index 00000000000..bcbe1f577fd --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_image_depth_linear_frag.glsl @@ -0,0 +1,16 @@ + +in vec2 texCoord_interp; +out vec4 fragColor; + +uniform float znear; +uniform float zfar; +uniform sampler2D image; + +void main() +{ + float depth = texture(image, texCoord_interp).r; + + /* normalize */ + fragColor.rgb = vec3((2.0f * znear) / (zfar + znear - (depth * (zfar - znear)))); + fragColor.a = 1.0f; +} diff --git a/source/blender/gpu/shaders/gpu_shader_image_desaturate_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_desaturate_frag.glsl new file mode 100644 index 00000000000..1ac0d68b35f --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_image_desaturate_frag.glsl @@ -0,0 +1,14 @@ + +uniform float factor; +in vec2 texCoord_interp; +out vec4 fragColor; + +uniform vec4 color; +uniform sampler2D image; + +void main() +{ + vec4 tex = texture(image, texCoord_interp); + tex.rgb = ((0.3333333 * factor) * vec3(tex.r + tex.g + tex.b)) + (tex.rgb * (1.0 - factor)); + fragColor = tex * color; +} diff --git a/source/blender/gpu/shaders/gpu_shader_image_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_frag.glsl new file mode 100644 index 00000000000..6eeab8ca7e8 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_image_frag.glsl @@ -0,0 +1,10 @@ + +in vec2 texCoord_interp; +out vec4 fragColor; + +uniform sampler2D image; + +void main() +{ + fragColor = texture(image, texCoord_interp); +} diff --git a/source/blender/gpu/shaders/gpu_shader_image_interlace_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_interlace_frag.glsl new file mode 100644 index 00000000000..d95645f58e5 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_image_interlace_frag.glsl @@ -0,0 +1,34 @@ + +/* Keep these in sync with GPU_shader.h */ +#define INTERLACE_ROW 0 +#define INTERLACE_COLUMN 1 +#define INTERLACE_CHECKERBOARD 2 + +in vec2 texCoord_interp; +out vec4 fragColor; + +uniform int interlace_id; +uniform sampler2D image_a; +uniform sampler2D image_b; + +bool interlace() +{ + if (interlace_id == INTERLACE_CHECKERBOARD) { + return (int(gl_FragCoord.x + gl_FragCoord.y) & 1) != 0; + } + else if (interlace_id == INTERLACE_ROW) { + return (int(gl_FragCoord.y) & 1) != 0; + } + else if (interlace_id == INTERLACE_COLUMN) { + return (int(gl_FragCoord.x) & 1) != 0; + } +} + +void main() +{ + if (interlace()) { + fragColor = texture(image_a, texCoord_interp); + } else { + fragColor = texture(image_b, texCoord_interp); + } +} diff --git a/source/blender/gpu/shaders/gpu_shader_image_linear_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_linear_frag.glsl new file mode 100644 index 00000000000..97eb3afc177 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_image_linear_frag.glsl @@ -0,0 +1,30 @@ + +/* Display a linear image texture into sRGB space */ + +uniform sampler2D image; + +in vec2 texCoord_interp; + +out vec4 fragColor; + +float linearrgb_to_srgb(float c) +{ + if (c < 0.0031308) + return (c < 0.0) ? 0.0 : c * 12.92; + else + return 1.055 * pow(c, 1.0 / 2.4) - 0.055; +} + +void linearrgb_to_srgb(vec4 col_from, out vec4 col_to) +{ + col_to.r = linearrgb_to_srgb(col_from.r); + col_to.g = linearrgb_to_srgb(col_from.g); + col_to.b = linearrgb_to_srgb(col_from.b); + col_to.a = col_from.a; +} + +void main() { + fragColor = texture(image, texCoord_interp.st); + + linearrgb_to_srgb(fragColor, fragColor); +} diff --git a/source/blender/gpu/shaders/gpu_shader_image_mask_uniform_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_mask_uniform_color_frag.glsl new file mode 100644 index 00000000000..4a45d03175e --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_image_mask_uniform_color_frag.glsl @@ -0,0 +1,12 @@ + +in vec2 texCoord_interp; +out vec4 fragColor; + +uniform sampler2D image; +uniform vec4 color; + +void main() +{ + fragColor.a = texture(image, texCoord_interp).a * color.a; + fragColor.rgb = color.rgb; +} diff --git a/source/blender/gpu/shaders/gpu_shader_image_modulate_alpha_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_modulate_alpha_frag.glsl new file mode 100644 index 00000000000..51092d56e5e --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_image_modulate_alpha_frag.glsl @@ -0,0 +1,12 @@ + +in vec2 texCoord_interp; +out vec4 fragColor; + +uniform float alpha; +uniform sampler2D image; + +void main() +{ + fragColor = texture(image, texCoord_interp); + fragColor.a *= alpha; +} diff --git a/source/blender/gpu/shaders/gpu_shader_image_multisample_resolve_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_multisample_resolve_frag.glsl new file mode 100644 index 00000000000..57362c88320 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_image_multisample_resolve_frag.glsl @@ -0,0 +1,124 @@ + +uniform sampler2DMS depthMulti; +uniform sampler2DMS colorMulti; + +out vec4 fragColor; + +#if SAMPLES > 16 +#error "Too many samples" +#endif + +// #define USE_DEPTH_WEIGHTING + +void main() +{ + ivec2 texel = ivec2(gl_FragCoord.xy); + + bvec4 b1, b2, b3, b4; + vec4 w1, w2, w3, w4; + vec4 d1, d2, d3, d4; + vec4 c1, c2, c3, c4, c5, c6, c7, c8; + vec4 c9, c10, c11, c12, c13, c14, c15, c16; + d1 = d2 = d3 = d4 = vec4(1.0); + w1 = w2 = w3 = w4 = vec4(0.0); + c1 = c2 = c3 = c4 = c5 = c6 = c7 = c8 = vec4(0.0); + c9 = c10 = c11 = c12 = c13 = c14 = c15 = c16 = vec4(0.0); + + /* Depth */ + + d1.x = texelFetch(depthMulti, texel, 0).r; + d1.y = texelFetch(depthMulti, texel, 1).r; +#if SAMPLES > 2 + d1.z = texelFetch(depthMulti, texel, 2).r; + d1.w = texelFetch(depthMulti, texel, 3).r; +#endif +#if SAMPLES > 4 + d2.x = texelFetch(depthMulti, texel, 4).r; + d2.y = texelFetch(depthMulti, texel, 5).r; + d2.z = texelFetch(depthMulti, texel, 6).r; + d2.w = texelFetch(depthMulti, texel, 7).r; +#endif +#if SAMPLES > 8 + d3.x = texelFetch(depthMulti, texel, 8).r; + d3.y = texelFetch(depthMulti, texel, 9).r; + d3.z = texelFetch(depthMulti, texel, 10).r; + d3.w = texelFetch(depthMulti, texel, 11).r; + d4.x = texelFetch(depthMulti, texel, 12).r; + d4.y = texelFetch(depthMulti, texel, 13).r; + d4.z = texelFetch(depthMulti, texel, 14).r; + d4.w = texelFetch(depthMulti, texel, 15).r; +#endif + + /* COLOR */ + b1 = notEqual(d1, vec4(1.0)); + if (any(b1)) { + c1 = texelFetch(colorMulti, texel, 0); + c2 = texelFetch(colorMulti, texel, 1); +#if SAMPLES > 2 + c3 = texelFetch(colorMulti, texel, 2); + c4 = texelFetch(colorMulti, texel, 3); +#endif + w1 = vec4(b1); + } +#if SAMPLES > 4 + b2 = notEqual(d2, vec4(1.0)); + if (any(b2)) { + c5 = texelFetch(colorMulti, texel, 4); + c6 = texelFetch(colorMulti, texel, 5); + c7 = texelFetch(colorMulti, texel, 6); + c8 = texelFetch(colorMulti, texel, 7); + w2 = vec4(b2); + } +#endif +#if SAMPLES > 8 + b3 = notEqual(d3, vec4(1.0)); + if (any(b3)) { + c9 = texelFetch(colorMulti, texel, 8); + c10 = texelFetch(colorMulti, texel, 9); + c11 = texelFetch(colorMulti, texel, 10); + c12 = texelFetch(colorMulti, texel, 11); + w3 = vec4(b3); + } + b4 = notEqual(d4, vec4(1.0)); + if (any(b4)) { + c13 = texelFetch(colorMulti, texel, 12); + c14 = texelFetch(colorMulti, texel, 13); + c15 = texelFetch(colorMulti, texel, 14); + c16 = texelFetch(colorMulti, texel, 15); + w4 = vec4(b4); + } +#endif + +#if SAMPLES > 8 + d1 = min(d1, min(d3, d4)); +#endif +#if SAMPLES > 4 + d1 = min(d1, d2); +#endif +#if SAMPLES > 2 + d1.xy = min(d1.xy, d1.zw); +#endif + gl_FragDepth = min(d1.x, d1.y); + +#ifdef USE_DEPTH_WEIGHTING + c1 *= w1.x; c2 *= w1.y; c3 *= w1.z; c4 *= w1.w; + c5 *= w2.x; c6 *= w2.y; c7 *= w2.z; c8 *= w2.w; + c9 *= w3.x; c10 *= w3.y; c11 *= w3.z; c12 *= w3.w; + c13 *= w4.x; c14 *= w4.y; c15 *= w4.z; c16 *= w4.w; +#endif + + c1 = c1 + c2; +#if SAMPLES > 2 + c1 += c3 + c4; +#endif +#if SAMPLES > 4 + c1 += c5 + c6 + c7 + c8; +#endif +#if SAMPLES > 8 + c1 += c9 + c10 + c11 + c12 + c13 + c14 + c15 + c16; +#endif + + const float inv_samples = 1.0 / float(SAMPLES); + + fragColor = c1 * inv_samples; +} diff --git a/source/blender/gpu/shaders/gpu_shader_image_shuffle_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_shuffle_color_frag.glsl new file mode 100644 index 00000000000..64662247d69 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_image_shuffle_color_frag.glsl @@ -0,0 +1,16 @@ + +in vec2 texCoord_interp; +out vec4 fragColor; + +uniform sampler2D image; +uniform vec4 color; +uniform vec4 shuffle; + +void main() +{ + vec4 sample = texture(image, texCoord_interp); + fragColor = vec4(sample.r * shuffle.r + + sample.g * shuffle.g + + sample.b * shuffle.b + + sample.a * shuffle.a) * color; +} 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_camera_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_camera_vert.glsl new file mode 100644 index 00000000000..aec8fd9b0a1 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_instance_camera_vert.glsl @@ -0,0 +1,50 @@ + +uniform mat4 ViewProjectionMatrix; + +/* ---- Instanciated Attribs ---- */ +in float pos; + +/* ---- Per instance Attribs ---- */ +in vec3 color; +in vec4 corners[2]; /* trouble fetching vec2 */ +in float depth; +in vec4 tria; +in mat4 InstanceModelMatrix; + +flat out vec4 finalColor; + +void main() +{ + vec3 pPos; + + if (pos == 1.0) { + pPos = vec3(corners[0].xy, depth); + } + else if (pos == 2.0) { + pPos = vec3(corners[0].zw, depth); + } + else if (pos == 3.0) { + pPos = vec3(corners[1].xy, depth); + } + else if (pos == 4.0) { + pPos = vec3(corners[1].zw, depth); + } + else if (pos == 5.0) { + pPos = vec3(tria.xy, depth); + } + else if (pos == 6.0) { + vec2 ofs = tria.xy - corners[0].xy; + ofs.x = -ofs.x; + pPos = vec3(corners[1].zw + ofs, depth); + } + else if (pos == 7.0) { + pPos = vec3(tria.zw, depth); + } + else { + pPos = vec3(0.0); + } + + gl_Position = ViewProjectionMatrix * InstanceModelMatrix * vec4(pPos, 1.0); + + finalColor = vec4(color, 1.0); +} diff --git a/source/blender/gpu/shaders/gpu_shader_instance_distance_line_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_distance_line_vert.glsl new file mode 100644 index 00000000000..ced5bb7f684 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_instance_distance_line_vert.glsl @@ -0,0 +1,25 @@ + +uniform mat4 ViewProjectionMatrix; + +/* ---- Instanciated Attribs ---- */ +in vec3 pos; + +/* ---- Per instance Attribs ---- */ +in vec3 color; +in float start; +in float end; +in mat4 InstanceModelMatrix; + +uniform float size; + +flat out vec4 finalColor; + +void main() +{ + float len = end - start; + vec3 sta = vec3(0.0, 0.0, -start); + + gl_Position = ViewProjectionMatrix * InstanceModelMatrix * vec4(pos * -len + sta, 1.0); + gl_PointSize = size; + finalColor = vec4(color, 1.0); +} diff --git a/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_geom.glsl b/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_geom.glsl new file mode 100644 index 00000000000..e26f419b8cd --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_geom.glsl @@ -0,0 +1,57 @@ + +// Draw "fancy" wireframe, displaying front-facing, back-facing and +// silhouette lines differently. +// Mike Erwin, April 2015 + +// After working with this shader a while, convinced we should make +// separate shaders for perpective & ortho. (Oct 2016) + +// Due to perspective, the line segment's endpoints might disagree on +// whether the adjacent faces are front facing. This geometry shader +// decides which edge type to use if endpoints disagree. + +uniform mat4 ProjectionMatrix; + +uniform bool drawFront = true; +uniform bool drawBack = true; +uniform bool drawSilhouette = true; + +layout(lines) in; +layout(line_strip, max_vertices = 2) out; + +in vec4 MV_pos[]; +in float edgeClass[]; +in vec3 fCol[]; + +flat out vec4 finalColor; + +void emitLine(vec4 color) +{ + gl_Position = ProjectionMatrix * MV_pos[0]; + EmitVertex(); + gl_Position = ProjectionMatrix * MV_pos[1]; + finalColor = color; + EmitVertex(); + EndPrimitive(); +} + +void main() +{ + float finalEdgeClass = max(edgeClass[0], edgeClass[1]); + + if (finalEdgeClass > 0.0f) { + // front-facing edge + if (drawFront) + emitLine(vec4(fCol[0], 0.75)); + } + else if (finalEdgeClass < 0.0f) { + // back-facing edge + if (drawBack) + emitLine(vec4(fCol[0], 0.5)); + } + else { + // exactly one face is front-facing, silhouette edge + if (drawSilhouette) + emitLine(vec4(fCol[0], 1.0)); + } +} diff --git a/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_vert.glsl new file mode 100644 index 00000000000..fa30c9fb1ed --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_instance_edges_variying_color_vert.glsl @@ -0,0 +1,63 @@ + +// Draw "fancy" wireframe, displaying front-facing, back-facing and +// silhouette lines differently. +// Mike Erwin, April 2015 + +// After working with this shader a while, convinced we should make +// separate shaders for perpective & ortho. (Oct 2016) + +// Due to perspective, the line segment's endpoints might disagree on +// whether the adjacent faces are front facing. We use a geometry +// shader to resolve this properly. + +uniform mat4 ViewMatrix; +uniform mat4 ProjectionMatrix; + +in vec3 pos; +in vec3 N1, N2; // normals of faces this edge joins (object coords) + +/* instance attrib */ +in vec3 color; +in mat4 InstanceModelMatrix; + +out vec4 MV_pos; +out float edgeClass; +out vec3 fCol; + +// TODO: in float angle; // [-pi .. +pi], + peak, 0 flat, - valley + +bool front(mat3 NormalMatrix, vec3 N, vec3 eye) +{ + return dot(NormalMatrix * N, eye) > 0.0; +} + +void main() +{ + vec3 eye; + + mat4 ModelViewMatrix = ViewMatrix * InstanceModelMatrix; + + MV_pos = ModelViewMatrix * vec4(pos, 1.0); + + mat3 NormalMatrix = transpose(inverse(mat3(ModelViewMatrix))); + + /* if persp */ + if (ProjectionMatrix[3][3] == 0.0) { + eye = normalize(-MV_pos.xyz); + } + else { + eye = vec3(0.0, 0.0, 1.0); + } + + bool face_1_front = front(NormalMatrix, N1, eye); + bool face_2_front = front(NormalMatrix, N2, eye); + + if (face_1_front && face_2_front) + edgeClass = 1.0; // front-facing edge + else if (face_1_front || face_2_front) + edgeClass = 0.0; // exactly one face is front-facing, silhouette edge + else + edgeClass = -1.0; // back-facing edge + + fCol = color; +} diff --git a/source/blender/gpu/shaders/gpu_shader_instance_objectspace_variying_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_objectspace_variying_color_vert.glsl new file mode 100644 index 00000000000..9876717b297 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_instance_objectspace_variying_color_vert.glsl @@ -0,0 +1,27 @@ + +uniform mat4 ViewMatrix; +uniform mat4 ViewProjectionMatrix; + +/* ---- Instanciated Attribs ---- */ +in vec3 pos; +in vec3 nor; + +/* ---- Per instance Attribs ---- */ +in mat4 InstanceModelMatrix; +in vec4 color; + +out vec3 normal; +flat out vec4 finalColor; + +void main() +{ + mat4 ModelViewProjectionMatrix = ViewProjectionMatrix * InstanceModelMatrix; + /* This is slow and run per vertex, but it's still faster than + * doing it per instance on CPU and sending it on via instance attrib */ + mat3 NormalMatrix = transpose(inverse(mat3(ViewMatrix * InstanceModelMatrix))); + + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); + normal = NormalMatrix * nor; + + finalColor = color; +} diff --git a/source/blender/gpu/shaders/gpu_shader_instance_screen_aligned_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_screen_aligned_vert.glsl new file mode 100644 index 00000000000..2ee74b3eae0 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_instance_screen_aligned_vert.glsl @@ -0,0 +1,32 @@ + +uniform mat4 ViewProjectionMatrix; +uniform vec3 screen_vecs[2]; + +/* ---- Instanciated Attribs ---- */ +in vec3 pos; /* using Z as axis id */ + +/* ---- Per instance Attribs ---- */ +in mat4 InstanceModelMatrix; +in vec3 color; +in float size; + +flat out vec4 finalColor; + +void main() +{ + vec3 offset = vec3(0.0); + +#ifdef AXIS_NAME + if (pos.z == 0.0) + offset = vec3(1.125, 0.0, 0.0); + else if (pos.z == 1.0) + offset = vec3(0.0, 1.125, 0.0); + else + offset = vec3(0.0, 0.0, 1.125); + offset *= size; +#endif + + vec3 screen_pos = screen_vecs[0].xyz * pos.x + screen_vecs[1].xyz * pos.y; + gl_Position = ViewProjectionMatrix * (InstanceModelMatrix * vec4(offset, 1.0) + vec4(screen_pos * size, 0.0)); + finalColor = vec4(color, 1.0); +} diff --git a/source/blender/gpu/shaders/gpu_shader_instance_screenspace_variying_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_screenspace_variying_color_vert.glsl new file mode 100644 index 00000000000..ba0ac29fb79 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_instance_screenspace_variying_color_vert.glsl @@ -0,0 +1,29 @@ + +uniform mat4 ViewProjectionMatrix; +uniform vec3 screen_vecs[2]; +uniform float size; +uniform float pixel_size; + +/* ---- Instanciated Attribs ---- */ +in vec2 pos; + +/* ---- Per instance Attribs ---- */ +in vec3 world_pos; +in vec3 color; + +flat out vec4 finalColor; + +float mul_project_m4_v3_zfac(in vec3 co) +{ + return (ViewProjectionMatrix[0][3] * co.x) + + (ViewProjectionMatrix[1][3] * co.y) + + (ViewProjectionMatrix[2][3] * co.z) + ViewProjectionMatrix[3][3]; +} + +void main() +{ + float pix_size = mul_project_m4_v3_zfac(world_pos) * pixel_size; + vec3 screen_pos = screen_vecs[0].xyz * pos.x + screen_vecs[1].xyz * pos.y; + gl_Position = ViewProjectionMatrix * vec4(world_pos + screen_pos * size * pix_size, 1.0); + finalColor = vec4(color, 1.0); +} diff --git a/source/blender/gpu/shaders/gpu_shader_instance_variying_size_variying_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_variying_size_variying_color_vert.glsl new file mode 100644 index 00000000000..10a2ba61a2c --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_instance_variying_size_variying_color_vert.glsl @@ -0,0 +1,22 @@ + +uniform mat4 ViewProjectionMatrix; + +/* ---- Instanciated Attribs ---- */ +in vec3 pos; + +/* ---- Per instance Attribs ---- */ +in mat4 InstanceModelMatrix; +in vec3 color; +#ifdef UNIFORM_SCALE +in float size; +#else +in vec3 size; +#endif + +flat out vec4 finalColor; + +void main() +{ + gl_Position = ViewProjectionMatrix * InstanceModelMatrix * vec4(pos * size, 1.0); + finalColor = vec4(color, 1.0); +} diff --git a/source/blender/gpu/shaders/gpu_shader_instance_variying_size_variying_id_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_variying_size_variying_id_vert.glsl new file mode 100644 index 00000000000..49750dddb3c --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_instance_variying_size_variying_id_vert.glsl @@ -0,0 +1,23 @@ + +uniform mat4 ViewProjectionMatrix; +uniform int baseId; + +/* ---- Instanciated Attribs ---- */ +in vec3 pos; + +/* ---- Per instance Attribs ---- */ +in mat4 InstanceModelMatrix; +#ifdef UNIFORM_SCALE +in float size; +#else +in vec3 size; +#endif +in int callId; + +flat out uint finalId; + +void main() +{ + gl_Position = ViewProjectionMatrix * InstanceModelMatrix * vec4(pos * size, 1.0); + finalId = uint(baseId + callId); +} diff --git a/source/blender/gpu/shaders/gpu_shader_instance_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_vert.glsl new file mode 100644 index 00000000000..eac167e8045 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_instance_vert.glsl @@ -0,0 +1,13 @@ + +uniform mat4 ViewProjectionMatrix; + +/* ---- Instanciated Attribs ---- */ +in vec3 pos; + +/* ---- Per instance Attribs ---- */ +in mat4 InstanceModelMatrix; + +void main() +{ + gl_Position = ViewProjectionMatrix * InstanceModelMatrix * vec4(pos, 1.0); +} diff --git a/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_frag.glsl b/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_frag.glsl new file mode 100644 index 00000000000..7f445369833 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_frag.glsl @@ -0,0 +1,31 @@ + +in vec4 radii; +in vec4 finalColor; +in vec4 finalOutlineColor; +out vec4 fragColor; + +void main() { + vec2 quad = abs(gl_PointCoord - vec2(0.5)); + float dist = quad.x + quad.y; + +// transparent outside of point +// --- 0 --- +// smooth transition +// --- 1 --- +// pure outline color +// --- 2 --- +// smooth transition +// --- 3 --- +// pure point color +// ... +// dist = 0 at center of point + + float mid_stroke = 0.5 * (radii[1] + radii[2]); + + vec4 backgroundColor = vec4(finalOutlineColor.rgb, 0.0); + + if (dist > mid_stroke) + fragColor = mix(finalOutlineColor, backgroundColor, smoothstep(radii[1], radii[0], dist)); + else + fragColor = mix(finalColor, finalOutlineColor, smoothstep(radii[3], radii[2], dist)); +} diff --git a/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_vert.glsl b/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_vert.glsl new file mode 100644 index 00000000000..c49832bf9b4 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_keyframe_diamond_vert.glsl @@ -0,0 +1,34 @@ + +uniform mat4 ModelViewProjectionMatrix; + +const float pixel_fudge = sqrt(2.0); +const float outline_width = 1.15 * pixel_fudge; + +in vec2 pos; +in float size; +in vec4 color; +in vec4 outlineColor; +out vec4 finalColor; +out vec4 finalOutlineColor; +out vec4 radii; + +void main() { + gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0); + + // pass through unchanged + gl_PointSize = size + pixel_fudge; // 0.5 pixel_fudge on either side + finalColor = color; + finalOutlineColor = outlineColor; + + // calculate concentric radii in pixels + float radius = 0.5 * gl_PointSize; + + // start at the outside and progress toward the center + radii[0] = radius; + radii[1] = radius - pixel_fudge; + radii[2] = radius - outline_width; + radii[3] = radius - outline_width - pixel_fudge; + + // convert to PointCoord units + radii /= size; +} diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index ab044fff100..464851bae21 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -1,12 +1,18 @@ + +uniform mat4 ModelMatrix; +uniform mat4 ModelViewMatrix; +uniform mat4 ModelViewMatrixInverse; +uniform mat3 NormalMatrix; + +#ifndef ATTRIB +uniform mat4 ModelMatrixInverse; +#endif + /* Converters */ float convert_rgba_to_float(vec4 color) { -#ifdef USE_NEW_SHADING - return color.r * 0.2126 + color.g * 0.7152 + color.b * 0.0722; -#else - return (color.r + color.g + color.b) / 3.0; -#endif + return dot(color.rgb, vec3(0.2126, 0.7152, 0.0722)); } float exp_blender(float f) @@ -53,7 +59,7 @@ void rgb_to_hsv(vec4 rgb, out vec4 outcol) h = 0.0; } else { - c = (vec3(cmax, cmax, cmax) - rgb.xyz) / cdelta; + c = (vec3(cmax) - rgb.xyz) / cdelta; if (rgb.x == cmax) h = c[2] - c[1]; else if (rgb.y == cmax) h = 2.0 + c[0] - c[2]; @@ -155,39 +161,15 @@ void color_to_blender_normal_new_shading(vec3 color, out vec3 normal) normal.y = -2.0 * ((color.g) - 0.5); normal.z = -2.0 * ((color.b) - 0.5); } - +#ifndef M_PI #define M_PI 3.14159265358979323846 -#define M_1_PI 0.31830988618379069 +#endif +#ifndef M_1_PI +#define M_1_PI 0.318309886183790671538 +#endif /*********** SHADER NODES ***************/ -void vcol_attribute(vec4 attvcol, out vec4 vcol) -{ - vcol = vec4(attvcol.x, attvcol.y, attvcol.z, 1.0); -} - -void uv_attribute(vec2 attuv, out vec3 uv) -{ - uv = vec3(attuv * 2.0 - vec2(1.0, 1.0), 0.0); -} - -void geom( - vec3 co, vec3 nor, mat4 viewinvmat, vec3 attorco, vec2 attuv, vec4 attvcol, - out vec3 global, out vec3 local, out vec3 view, out vec3 orco, out vec3 uv, - out vec3 normal, out vec4 vcol, out float vcol_alpha, out float frontback) -{ - local = co; - view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(local) : vec3(0.0, 0.0, -1.0); - global = (viewinvmat * vec4(local, 1.0)).xyz; - orco = attorco; - uv_attribute(attuv, uv); - normal = -normalize(nor); /* blender render normal is negated */ - vcol_attribute(attvcol, vcol); - srgb_to_linearrgb(vcol, vcol); - vcol_alpha = attvcol.a; - frontback = (gl_FrontFacing) ? 1.0 : 0.0; -} - void particle_info( vec4 sprops, vec4 loc, vec3 vel, vec3 avel, out float index, out float random, out float age, @@ -272,17 +254,6 @@ void camera(vec3 co, out vec3 outview, out float outdepth, out float outdist) outview = normalize(co); } -void lamp( - vec4 col, float energy, vec3 lv, float dist, vec3 shadow, float visifac, - out vec4 outcol, out vec3 outlv, out float outdist, out vec4 outshadow, out float outvisifac) -{ - outcol = col * energy; - outlv = lv; - outdist = dist; - outshadow = vec4(shadow, 1.0); - outvisifac = visifac; -} - void math_add(float val1, float val2, out float outval) { outval = val1 + val2; @@ -449,13 +420,13 @@ void squeeze(float val, float width, float center, out float outval) void vec_math_add(vec3 v1, vec3 v2, out vec3 outvec, out float outval) { outvec = v1 + v2; - outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2])) / 3.0; + outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2])) * 0.333333; } void vec_math_sub(vec3 v1, vec3 v2, out vec3 outvec, out float outval) { outvec = v1 - v2; - outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2])) / 3.0; + outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2])) * 0.333333; } void vec_math_average(vec3 v1, vec3 v2, out vec3 outvec, out float outval) @@ -471,7 +442,7 @@ void vec_math_mix(float strength, vec3 v1, vec3 v2, out vec3 outvec) void vec_math_dot(vec3 v1, vec3 v2, out vec3 outvec, out float outval) { - outvec = vec3(0, 0, 0); + outvec = vec3(0); outval = dot(v1, v2); } @@ -513,9 +484,9 @@ void normal_new_shading(vec3 dir, vec3 nor, out vec3 outnor, out float outdot) void curves_vec(float fac, vec3 vec, sampler2D curvemap, out vec3 outvec) { - outvec.x = texture2D(curvemap, vec2((vec.x + 1.0) * 0.5, 0.0)).x; - outvec.y = texture2D(curvemap, vec2((vec.y + 1.0) * 0.5, 0.0)).y; - outvec.z = texture2D(curvemap, vec2((vec.z + 1.0) * 0.5, 0.0)).z; + outvec.x = texture(curvemap, vec2((vec.x + 1.0) * 0.5, 0.0)).x; + outvec.y = texture(curvemap, vec2((vec.y + 1.0) * 0.5, 0.0)).y; + outvec.z = texture(curvemap, vec2((vec.z + 1.0) * 0.5, 0.0)).z; if (fac != 1.0) outvec = (outvec * fac) + (vec * (1.0 - fac)); @@ -524,9 +495,9 @@ void curves_vec(float fac, vec3 vec, sampler2D curvemap, out vec3 outvec) void curves_rgb(float fac, vec4 col, sampler2D curvemap, out vec4 outcol) { - outcol.r = texture2D(curvemap, vec2(texture2D(curvemap, vec2(col.r, 0.0)).a, 0.0)).r; - outcol.g = texture2D(curvemap, vec2(texture2D(curvemap, vec2(col.g, 0.0)).a, 0.0)).g; - outcol.b = texture2D(curvemap, vec2(texture2D(curvemap, vec2(col.b, 0.0)).a, 0.0)).b; + outcol.r = texture(curvemap, vec2(texture(curvemap, vec2(col.r, 0.0)).a, 0.0)).r; + outcol.g = texture(curvemap, vec2(texture(curvemap, vec2(col.g, 0.0)).a, 0.0)).g; + outcol.b = texture(curvemap, vec2(texture(curvemap, vec2(col.b, 0.0)).a, 0.0)).b; if (fac != 1.0) outcol = (outcol * fac) + (col * (1.0 - fac)); @@ -846,22 +817,19 @@ void mix_linear(float fac, vec4 col1, vec4 col2, out vec4 outcol) void valtorgb(float fac, sampler2D colormap, out vec4 outcol, out float outalpha) { - outcol = texture2D(colormap, vec2(fac, 0.0)); + outcol = texture(colormap, vec2(fac, 0.0)); outalpha = outcol.a; } void rgbtobw(vec4 color, out float outval) { -#ifdef USE_NEW_SHADING - outval = color.r * 0.2126 + color.g * 0.7152 + color.b * 0.0722; -#else - outval = color.r * 0.35 + color.g * 0.45 + color.b * 0.2; /* keep these factors in sync with texture.h:RGBTOBW */ -#endif + vec3 factors = vec3(0.2126, 0.7152, 0.0722); + outval = dot(color.rgb, factors); } void invert(float fac, vec4 col, out vec4 outcol) { - outcol.xyz = mix(col.xyz, vec3(1.0, 1.0, 1.0) - col.xyz, fac); + outcol.xyz = mix(col.xyz, vec3(1.0) - col.xyz, fac); outcol.w = col.w; } @@ -939,56 +907,6 @@ void output_node(vec4 rgb, float alpha, out vec4 outrgb) /*********** TEXTURES ***************/ -void texture_flip_blend(vec3 vec, out vec3 outvec) -{ - outvec = vec.yxz; -} - -void texture_blend_lin(vec3 vec, out float outval) -{ - outval = (1.0 + vec.x) / 2.0; -} - -void texture_blend_quad(vec3 vec, out float outval) -{ - outval = max((1.0 + vec.x) / 2.0, 0.0); - outval *= outval; -} - -void texture_wood_sin(vec3 vec, out float value, out vec4 color, out vec3 normal) -{ - float a = sqrt(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z) * 20.0; - float wi = 0.5 + 0.5 * sin(a); - - value = wi; - color = vec4(wi, wi, wi, 1.0); - normal = vec3(0.0, 0.0, 0.0); -} - -void texture_image(vec3 vec, sampler2D ima, out float value, out vec4 color, out vec3 normal) -{ - color = texture2D(ima, (vec.xy + vec2(1.0, 1.0)) * 0.5); - value = color.a; - - normal.x = 2.0 * (color.r - 0.5); - normal.y = 2.0 * (0.5 - color.g); - normal.z = 2.0 * (color.b - 0.5); -} - -/************* MTEX *****************/ - -void texco_orco(vec3 attorco, out vec3 orco) -{ - orco = attorco; -} - -void texco_uv(vec2 attuv, out vec3 uv) -{ - /* disabled for now, works together with leaving out mtex_2d_mapping */ - // uv = vec3(attuv*2.0 - vec2(1.0, 1.0), 0.0); */ - uv = vec3(attuv, 0.0); -} - void texco_norm(vec3 normal, out vec3 outnormal) { /* corresponds to shi->orn, which is negated so cancels @@ -996,436 +914,11 @@ void texco_norm(vec3 normal, out vec3 outnormal) outnormal = normalize(normal); } -void texco_tangent(vec4 tangent, out vec3 outtangent) -{ - outtangent = normalize(tangent.xyz); -} - -void texco_global(mat4 viewinvmat, vec3 co, out vec3 global) -{ - global = (viewinvmat * vec4(co, 1.0)).xyz; -} - -void texco_object(mat4 viewinvmat, mat4 obinvmat, vec3 co, out vec3 object) -{ - object = (obinvmat * (viewinvmat * vec4(co, 1.0))).xyz; -} - -void texco_refl(vec3 vn, vec3 view, out vec3 ref) -{ - ref = view - 2.0 * dot(vn, view) * vn; -} - -void shade_norm(vec3 normal, out vec3 outnormal) -{ - /* blender render normal is negated */ - outnormal = -normalize(normal); -} - -void mtex_mirror(vec3 tcol, vec4 refcol, float tin, float colmirfac, out vec4 outrefcol) -{ - outrefcol = mix(refcol, vec4(1.0, tcol), tin * colmirfac); -} - -void mtex_rgb_blend(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol) -{ - float facm; - - fact *= facg; - facm = 1.0 - fact; - - incol = fact * texcol + facm * outcol; -} - -void mtex_rgb_mul(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol) -{ - float facm; - - fact *= facg; - facm = 1.0 - fact; - - incol = (facm + fact * texcol) * outcol; -} - -void mtex_rgb_screen(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol) -{ - float facm; - - fact *= facg; - facm = 1.0 - fact; - - incol = vec3(1.0) - (vec3(facm) + fact * (vec3(1.0) - texcol)) * (vec3(1.0) - outcol); -} - -void mtex_rgb_overlay(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol) -{ - float facm; - - fact *= facg; - facm = 1.0 - fact; - - if (outcol.r < 0.5) - incol.r = outcol.r * (facm + 2.0 * fact * texcol.r); - else - incol.r = 1.0 - (facm + 2.0 * fact * (1.0 - texcol.r)) * (1.0 - outcol.r); - - if (outcol.g < 0.5) - incol.g = outcol.g * (facm + 2.0 * fact * texcol.g); - else - incol.g = 1.0 - (facm + 2.0 * fact * (1.0 - texcol.g)) * (1.0 - outcol.g); - - if (outcol.b < 0.5) - incol.b = outcol.b * (facm + 2.0 * fact * texcol.b); - else - incol.b = 1.0 - (facm + 2.0 * fact * (1.0 - texcol.b)) * (1.0 - outcol.b); -} - -void mtex_rgb_sub(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol) -{ - incol = -fact * facg * texcol + outcol; -} - -void mtex_rgb_add(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol) -{ - incol = fact * facg * texcol + outcol; -} - -void mtex_rgb_div(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol) -{ - float facm; - - fact *= facg; - facm = 1.0 - fact; - - if (texcol.r != 0.0) incol.r = facm * outcol.r + fact * outcol.r / texcol.r; - if (texcol.g != 0.0) incol.g = facm * outcol.g + fact * outcol.g / texcol.g; - if (texcol.b != 0.0) incol.b = facm * outcol.b + fact * outcol.b / texcol.b; -} - -void mtex_rgb_diff(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol) -{ - float facm; - - fact *= facg; - facm = 1.0 - fact; - - incol = facm * outcol + fact * abs(texcol - outcol); -} - -void mtex_rgb_dark(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol) -{ - float facm, col; - - fact *= facg; - facm = 1.0 - fact; - - incol.r = min(outcol.r, texcol.r) * fact + outcol.r * facm; - incol.g = min(outcol.g, texcol.g) * fact + outcol.g * facm; - incol.b = min(outcol.b, texcol.b) * fact + outcol.b * facm; -} - -void mtex_rgb_light(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol) -{ - float facm, col; - - fact *= facg; - - col = fact * texcol.r; - if (col > outcol.r) incol.r = col; else incol.r = outcol.r; - col = fact * texcol.g; - if (col > outcol.g) incol.g = col; else incol.g = outcol.g; - col = fact * texcol.b; - if (col > outcol.b) incol.b = col; else incol.b = outcol.b; -} - -void mtex_rgb_hue(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol) -{ - vec4 col; - - mix_hue(fact * facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col); - incol.rgb = col.rgb; -} - -void mtex_rgb_sat(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol) -{ - vec4 col; - - mix_sat(fact * facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col); - incol.rgb = col.rgb; -} - -void mtex_rgb_val(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol) -{ - vec4 col; - - mix_val(fact * facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col); - incol.rgb = col.rgb; -} - -void mtex_rgb_color(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol) -{ - vec4 col; - - mix_color(fact * facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col); - incol.rgb = col.rgb; -} - -void mtex_rgb_soft(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol) -{ - vec4 col; - - mix_soft(fact * facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col); - incol.rgb = col.rgb; -} - -void mtex_rgb_linear(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol) -{ - fact *= facg; - - if (texcol.r > 0.5) - incol.r = outcol.r + fact * (2.0 * (texcol.r - 0.5)); - else - incol.r = outcol.r + fact * (2.0 * (texcol.r) - 1.0); - - if (texcol.g > 0.5) - incol.g = outcol.g + fact * (2.0 * (texcol.g - 0.5)); - else - incol.g = outcol.g + fact * (2.0 * (texcol.g) - 1.0); - - if (texcol.b > 0.5) - incol.b = outcol.b + fact * (2.0 * (texcol.b - 0.5)); - else - incol.b = outcol.b + fact * (2.0 * (texcol.b) - 1.0); -} - -void mtex_value_vars(inout float fact, float facg, out float facm) -{ - fact *= abs(facg); - facm = 1.0 - fact; - - if (facg < 0.0) { - float tmp = fact; - fact = facm; - facm = tmp; - } -} - -void mtex_value_blend(float outcol, float texcol, float fact, float facg, out float incol) -{ - float facm; - mtex_value_vars(fact, facg, facm); - - incol = fact * texcol + facm * outcol; -} - -void mtex_value_mul(float outcol, float texcol, float fact, float facg, out float incol) -{ - float facm; - mtex_value_vars(fact, facg, facm); - - facm = 1.0 - facg; - incol = (facm + fact * texcol) * outcol; -} - -void mtex_value_screen(float outcol, float texcol, float fact, float facg, out float incol) -{ - float facm; - mtex_value_vars(fact, facg, facm); - - facm = 1.0 - facg; - incol = 1.0 - (facm + fact * (1.0 - texcol)) * (1.0 - outcol); -} - -void mtex_value_sub(float outcol, float texcol, float fact, float facg, out float incol) -{ - float facm; - mtex_value_vars(fact, facg, facm); - - fact = -fact; - incol = fact * texcol + outcol; -} - -void mtex_value_add(float outcol, float texcol, float fact, float facg, out float incol) -{ - float facm; - mtex_value_vars(fact, facg, facm); - - fact = fact; - incol = fact * texcol + outcol; -} - -void mtex_value_div(float outcol, float texcol, float fact, float facg, out float incol) -{ - float facm; - mtex_value_vars(fact, facg, facm); - - if (texcol != 0.0) - incol = facm * outcol + fact * outcol / texcol; - else - incol = 0.0; -} - -void mtex_value_diff(float outcol, float texcol, float fact, float facg, out float incol) -{ - float facm; - mtex_value_vars(fact, facg, facm); - - incol = facm * outcol + fact * abs(texcol - outcol); -} - -void mtex_value_dark(float outcol, float texcol, float fact, float facg, out float incol) -{ - float facm; - mtex_value_vars(fact, facg, facm); - - incol = facm * outcol + fact * min(outcol, texcol); -} - -void mtex_value_light(float outcol, float texcol, float fact, float facg, out float incol) -{ - float facm; - mtex_value_vars(fact, facg, facm); - - float col = fact * texcol; - if (col > outcol) incol = col; else incol = outcol; -} - -void mtex_value_clamp_positive(float fac, out float outfac) -{ - outfac = max(fac, 0.0); -} - -void mtex_value_clamp(float fac, out float outfac) -{ - outfac = clamp(fac, 0.0, 1.0); -} - -void mtex_har_divide(float har, out float outhar) -{ - outhar = har / 128.0; -} - -void mtex_har_multiply_clamp(float har, out float outhar) -{ - har *= 128.0; - - if (har < 1.0) outhar = 1.0; - else if (har > 511.0) outhar = 511.0; - else outhar = har; -} - -void mtex_alpha_from_col(vec4 col, out float alpha) -{ - alpha = col.a; -} - -void mtex_alpha_to_col(vec4 col, float alpha, out vec4 outcol) -{ - outcol = vec4(col.rgb, alpha); -} - -void mtex_alpha_multiply_value(vec4 col, float value, out vec4 outcol) -{ - outcol = vec4(col.rgb, col.a * value); -} - -void mtex_rgbtoint(vec4 rgb, out float intensity) -{ - intensity = dot(vec3(0.35, 0.45, 0.2), rgb.rgb); -} - -void mtex_value_invert(float invalue, out float outvalue) -{ - outvalue = 1.0 - invalue; -} - -void mtex_rgb_invert(vec4 inrgb, out vec4 outrgb) -{ - outrgb = vec4(vec3(1.0) - inrgb.rgb, inrgb.a); -} - -void mtex_value_stencil(float stencil, float intensity, out float outstencil, out float outintensity) -{ - float fact = intensity; - outintensity = intensity * stencil; - outstencil = stencil * fact; -} - -void mtex_rgb_stencil(float stencil, vec4 rgb, out float outstencil, out vec4 outrgb) -{ - float fact = rgb.a; - outrgb = vec4(rgb.rgb, rgb.a * stencil); - outstencil = stencil * fact; -} - -void mtex_mapping_ofs(vec3 texco, vec3 ofs, out vec3 outtexco) -{ - outtexco = texco + ofs; -} - -void mtex_mapping_size(vec3 texco, vec3 size, out vec3 outtexco) -{ - outtexco = size * texco; -} - -void mtex_2d_mapping(vec3 vec, out vec3 outvec) -{ - outvec = vec3(vec.xy * 0.5 + vec2(0.5), vec.z); -} - vec3 mtex_2d_mapping(vec3 vec) { return vec3(vec.xy * 0.5 + vec2(0.5), vec.z); } -void mtex_cube_map(vec3 co, samplerCube ima, out float value, out vec4 color) -{ - color = textureCube(ima, co); - value = 1.0; -} - -void mtex_cube_map_refl_from_refldir( - samplerCube ima, vec3 reflecteddirection, out float value, out vec4 color) -{ - color = textureCube(ima, reflecteddirection); - value = color.a; -} - -void mtex_cube_map_refl( - samplerCube ima, vec3 vp, vec3 vn, mat4 viewmatrixinverse, mat4 viewmatrix, - out float value, out vec4 color) -{ - vec3 viewdirection = vec3(viewmatrixinverse * vec4(vp, 0.0)); - vec3 normaldirection = normalize(vec3(vec4(vn, 0.0) * viewmatrix)); - vec3 reflecteddirection = reflect(viewdirection, normaldirection); - color = textureCube(ima, reflecteddirection); - value = 1.0; -} - -void mtex_image(vec3 texco, sampler2D ima, out float value, out vec4 color) -{ - color = texture2D(ima, texco.xy); - value = 1.0; -} - -void mtex_normal(vec3 texco, sampler2D ima, out vec3 normal) -{ - // The invert of the red channel is to make - // the normal map compliant with the outside world. - // It needs to be done because in Blender - // the normal used points inward. - // Should this ever change this negate must be removed. - vec4 color = texture2D(ima, texco.xy); - normal = 2.0 * (vec3(-color.r, color.g, color.b) - vec3(-0.5, 0.5, 0.5)); -} - -void mtex_bump_normals_init(vec3 vN, out vec3 vNorg, out vec3 vNacc, out float fPrevMagnitude) -{ - vNorg = vN; - vNacc = vN; - fPrevMagnitude = 1.0; -} - /** helper method to extract the upper left 3x3 matrix from a 4x4 matrix */ mat3 to_mat3(mat4 m4) { @@ -1436,976 +929,6 @@ mat3 to_mat3(mat4 m4) return m3; } -void mtex_bump_init_objspace( - vec3 surf_pos, vec3 surf_norm, - mat4 mView, mat4 mViewInv, mat4 mObj, mat4 mObjInv, - float fPrevMagnitude_in, vec3 vNacc_in, - out float fPrevMagnitude_out, out vec3 vNacc_out, - out vec3 vR1, out vec3 vR2, out float fDet) -{ - mat3 obj2view = to_mat3(gl_ModelViewMatrix); - mat3 view2obj = to_mat3(gl_ModelViewMatrixInverse); - - vec3 vSigmaS = view2obj * dFdx(surf_pos); - vec3 vSigmaT = view2obj * dFdy(surf_pos); - vec3 vN = normalize(surf_norm * obj2view); - - vR1 = cross(vSigmaT, vN); - vR2 = cross(vN, vSigmaS); - fDet = dot(vSigmaS, vR1); - - /* pretransform vNacc (in mtex_bump_apply) using the inverse transposed */ - vR1 = vR1 * view2obj; - vR2 = vR2 * view2obj; - vN = vN * view2obj; - - float fMagnitude = abs(fDet) * length(vN); - vNacc_out = vNacc_in * (fMagnitude / fPrevMagnitude_in); - fPrevMagnitude_out = fMagnitude; -} - -void mtex_bump_init_texturespace( - vec3 surf_pos, vec3 surf_norm, - float fPrevMagnitude_in, vec3 vNacc_in, - out float fPrevMagnitude_out, out vec3 vNacc_out, - out vec3 vR1, out vec3 vR2, out float fDet) -{ - vec3 vSigmaS = dFdx(surf_pos); - vec3 vSigmaT = dFdy(surf_pos); - vec3 vN = surf_norm; /* normalized interpolated vertex normal */ - - vR1 = normalize(cross(vSigmaT, vN)); - vR2 = normalize(cross(vN, vSigmaS)); - fDet = sign(dot(vSigmaS, vR1)); - - float fMagnitude = abs(fDet); - vNacc_out = vNacc_in * (fMagnitude / fPrevMagnitude_in); - fPrevMagnitude_out = fMagnitude; -} - -void mtex_bump_init_viewspace( - vec3 surf_pos, vec3 surf_norm, - float fPrevMagnitude_in, vec3 vNacc_in, - out float fPrevMagnitude_out, out vec3 vNacc_out, - out vec3 vR1, out vec3 vR2, out float fDet) -{ - vec3 vSigmaS = dFdx(surf_pos); - vec3 vSigmaT = dFdy(surf_pos); - vec3 vN = surf_norm; /* normalized interpolated vertex normal */ - - vR1 = cross(vSigmaT, vN); - vR2 = cross(vN, vSigmaS); - fDet = dot(vSigmaS, vR1); - - float fMagnitude = abs(fDet); - vNacc_out = vNacc_in * (fMagnitude / fPrevMagnitude_in); - fPrevMagnitude_out = fMagnitude; -} - -void mtex_bump_tap3( - vec3 texco, sampler2D ima, float hScale, - out float dBs, out float dBt) -{ - vec2 STll = texco.xy; - vec2 STlr = texco.xy + dFdx(texco.xy); - vec2 STul = texco.xy + dFdy(texco.xy); - - float Hll, Hlr, Hul; - rgbtobw(texture2D(ima, STll), Hll); - rgbtobw(texture2D(ima, STlr), Hlr); - rgbtobw(texture2D(ima, STul), Hul); - - dBs = hScale * (Hlr - Hll); - dBt = hScale * (Hul - Hll); -} - -#ifdef BUMP_BICUBIC - -void mtex_bump_bicubic( - vec3 texco, sampler2D ima, float hScale, - out float dBs, out float dBt ) -{ - float Hl; - float Hr; - float Hd; - float Hu; - - vec2 TexDx = dFdx(texco.xy); - vec2 TexDy = dFdy(texco.xy); - - vec2 STl = texco.xy - 0.5 * TexDx; - vec2 STr = texco.xy + 0.5 * TexDx; - vec2 STd = texco.xy - 0.5 * TexDy; - vec2 STu = texco.xy + 0.5 * TexDy; - - rgbtobw(texture2D(ima, STl), Hl); - rgbtobw(texture2D(ima, STr), Hr); - rgbtobw(texture2D(ima, STd), Hd); - rgbtobw(texture2D(ima, STu), Hu); - - vec2 dHdxy = vec2(Hr - Hl, Hu - Hd); - float fBlend = clamp(1.0 - textureQueryLOD(ima, texco.xy).x, 0.0, 1.0); - if (fBlend != 0.0) { - // the derivative of the bicubic sampling of level 0 - ivec2 vDim; - vDim = textureSize(ima, 0); - - // taking the fract part of the texture coordinate is a hardcoded wrap mode. - // this is acceptable as textures use wrap mode exclusively in 3D view elsewhere in blender. - // this is done so that we can still get a valid texel with uvs outside the 0,1 range - // by texelFetch below, as coordinates are clamped when using this function. - vec2 fTexLoc = vDim * fract(texco.xy) - vec2(0.5, 0.5); - ivec2 iTexLoc = ivec2(floor(fTexLoc)); - vec2 t = clamp(fTexLoc - iTexLoc, 0.0, 1.0); // sat just to be pedantic - -/******************************************************************************************* - * This block will replace the one below when one channel textures are properly supported. * - ******************************************************************************************* - vec4 vSamplesUL = textureGather(ima, (iTexLoc+ivec2(-1,-1) + vec2(0.5,0.5))/vDim); - vec4 vSamplesUR = textureGather(ima, (iTexLoc+ivec2(1,-1) + vec2(0.5,0.5))/vDim); - vec4 vSamplesLL = textureGather(ima, (iTexLoc+ivec2(-1,1) + vec2(0.5,0.5))/vDim); - vec4 vSamplesLR = textureGather(ima, (iTexLoc+ivec2(1,1) + vec2(0.5,0.5))/vDim); - - mat4 H = mat4(vSamplesUL.w, vSamplesUL.x, vSamplesLL.w, vSamplesLL.x, - vSamplesUL.z, vSamplesUL.y, vSamplesLL.z, vSamplesLL.y, - vSamplesUR.w, vSamplesUR.x, vSamplesLR.w, vSamplesLR.x, - vSamplesUR.z, vSamplesUR.y, vSamplesLR.z, vSamplesLR.y); - */ - ivec2 iTexLocMod = iTexLoc + ivec2(-1, -1); - - mat4 H; - - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - ivec2 iTexTmp = iTexLocMod + ivec2(i, j); - - // wrap texture coordinates manually for texelFetch to work on uvs oitside the 0,1 range. - // this is guaranteed to work since we take the fractional part of the uv above. - iTexTmp.x = (iTexTmp.x < 0) ? iTexTmp.x + vDim.x : ((iTexTmp.x >= vDim.x) ? iTexTmp.x - vDim.x : iTexTmp.x); - iTexTmp.y = (iTexTmp.y < 0) ? iTexTmp.y + vDim.y : ((iTexTmp.y >= vDim.y) ? iTexTmp.y - vDim.y : iTexTmp.y); - - rgbtobw(texelFetch(ima, iTexTmp, 0), H[i][j]); - } - } - - float x = t.x, y = t.y; - float x2 = x * x, x3 = x2 * x, y2 = y * y, y3 = y2 * y; - - vec4 X = vec4(-0.5 * (x3 + x) + x2, 1.5 * x3 - 2.5 * x2 + 1, -1.5 * x3 + 2 * x2 + 0.5 * x, 0.5 * (x3 - x2)); - vec4 Y = vec4(-0.5 * (y3 + y) + y2, 1.5 * y3 - 2.5 * y2 + 1, -1.5 * y3 + 2 * y2 + 0.5 * y, 0.5 * (y3 - y2)); - vec4 dX = vec4(-1.5 * x2 + 2 * x - 0.5, 4.5 * x2 - 5 * x, -4.5 * x2 + 4 * x + 0.5, 1.5 * x2 - x); - vec4 dY = vec4(-1.5 * y2 + 2 * y - 0.5, 4.5 * y2 - 5 * y, -4.5 * y2 + 4 * y + 0.5, 1.5 * y2 - y); - - // complete derivative in normalized coordinates (mul by vDim) - vec2 dHdST = vDim * vec2(dot(Y, H * dX), dot(dY, H * X)); - - // transform derivative to screen-space - vec2 dHdxy_bicubic = vec2(dHdST.x * TexDx.x + dHdST.y * TexDx.y, - dHdST.x * TexDy.x + dHdST.y * TexDy.y); - - // blend between the two - dHdxy = dHdxy * (1 - fBlend) + dHdxy_bicubic * fBlend; - } - - dBs = hScale * dHdxy.x; - dBt = hScale * dHdxy.y; -} - -#endif - -void mtex_bump_tap5( - vec3 texco, sampler2D ima, float hScale, - out float dBs, out float dBt) -{ - vec2 TexDx = dFdx(texco.xy); - vec2 TexDy = dFdy(texco.xy); - - vec2 STc = texco.xy; - vec2 STl = texco.xy - 0.5 * TexDx; - vec2 STr = texco.xy + 0.5 * TexDx; - vec2 STd = texco.xy - 0.5 * TexDy; - vec2 STu = texco.xy + 0.5 * TexDy; - - float Hc, Hl, Hr, Hd, Hu; - rgbtobw(texture2D(ima, STc), Hc); - rgbtobw(texture2D(ima, STl), Hl); - rgbtobw(texture2D(ima, STr), Hr); - rgbtobw(texture2D(ima, STd), Hd); - rgbtobw(texture2D(ima, STu), Hu); - - dBs = hScale * (Hr - Hl); - dBt = hScale * (Hu - Hd); -} - -void mtex_bump_deriv( - vec3 texco, sampler2D ima, float ima_x, float ima_y, float hScale, - out float dBs, out float dBt) -{ - float s = 1.0; // negate this if flipped texture coordinate - vec2 TexDx = dFdx(texco.xy); - vec2 TexDy = dFdy(texco.xy); - - // this variant using a derivative map is described here - // http://mmikkelsen3d.blogspot.com/2011/07/derivative-maps.html - vec2 dim = vec2(ima_x, ima_y); - vec2 dBduv = hScale * dim * (2.0 * texture2D(ima, texco.xy).xy - 1.0); - - dBs = dBduv.x * TexDx.x + s * dBduv.y * TexDx.y; - dBt = dBduv.x * TexDy.x + s * dBduv.y * TexDy.y; -} - -void mtex_bump_apply( - float fDet, float dBs, float dBt, vec3 vR1, vec3 vR2, vec3 vNacc_in, - out vec3 vNacc_out, out vec3 perturbed_norm) -{ - vec3 vSurfGrad = sign(fDet) * (dBs * vR1 + dBt * vR2); - - vNacc_out = vNacc_in - vSurfGrad; - perturbed_norm = normalize(vNacc_out); -} - -void mtex_bump_apply_texspace( - float fDet, float dBs, float dBt, vec3 vR1, vec3 vR2, - sampler2D ima, vec3 texco, float ima_x, float ima_y, vec3 vNacc_in, - out vec3 vNacc_out, out vec3 perturbed_norm) -{ - vec2 TexDx = dFdx(texco.xy); - vec2 TexDy = dFdy(texco.xy); - - vec3 vSurfGrad = sign(fDet) * ( - dBs / length(vec2(ima_x * TexDx.x, ima_y * TexDx.y)) * vR1 + - dBt / length(vec2(ima_x * TexDy.x, ima_y * TexDy.y)) * vR2); - - vNacc_out = vNacc_in - vSurfGrad; - perturbed_norm = normalize(vNacc_out); -} - -void mtex_negate_texnormal(vec3 normal, out vec3 outnormal) -{ - outnormal = vec3(-normal.x, -normal.y, normal.z); -} - -void mtex_nspace_tangent(vec4 tangent, vec3 normal, vec3 texnormal, out vec3 outnormal) -{ - vec3 B = tangent.w * cross(normal, tangent.xyz); - - outnormal = texnormal.x * tangent.xyz + texnormal.y * B + texnormal.z * normal; - outnormal = normalize(outnormal); -} - -void mtex_nspace_world(mat4 viewmat, vec3 texnormal, out vec3 outnormal) -{ - outnormal = normalize((viewmat * vec4(texnormal, 0.0)).xyz); -} - -void mtex_nspace_object(vec3 texnormal, out vec3 outnormal) -{ - outnormal = normalize(gl_NormalMatrix * texnormal); -} - -void mtex_blend_normal(float norfac, vec3 normal, vec3 newnormal, out vec3 outnormal) -{ - outnormal = (1.0 - norfac) * normal + norfac * newnormal; - outnormal = normalize(outnormal); -} - -/******* MATERIAL *********/ - -void lamp_visibility_sun_hemi(vec3 lampvec, out vec3 lv, out float dist, out float visifac) -{ - lv = lampvec; - dist = 1.0; - visifac = 1.0; -} - -void lamp_visibility_other(vec3 co, vec3 lampco, out vec3 lv, out float dist, out float visifac) -{ - lv = co - lampco; - dist = length(lv); - lv = normalize(lv); - visifac = 1.0; -} - -void lamp_falloff_invlinear(float lampdist, float dist, out float visifac) -{ - visifac = lampdist / (lampdist + dist); -} - -void lamp_falloff_invsquare(float lampdist, float dist, out float visifac) -{ - visifac = lampdist / (lampdist + dist * dist); -} - -void lamp_falloff_sliders(float lampdist, float ld1, float ld2, float dist, out float visifac) -{ - float lampdistkw = lampdist * lampdist; - - visifac = lampdist / (lampdist + ld1 * dist); - visifac *= lampdistkw / (lampdistkw + ld2 * dist * dist); -} - -void lamp_falloff_invcoefficients(float coeff_const, float coeff_lin, float coeff_quad, float dist, out float visifac) -{ - vec3 coeff = vec3(coeff_const, coeff_lin, coeff_quad); - vec3 d_coeff = vec3(1.0, dist, dist * dist); - float visifac_r = dot(coeff, d_coeff); - if (visifac_r > 0.0) - visifac = 1.0 / visifac_r; - else - visifac = 0.0; -} - -void lamp_falloff_curve(float lampdist, sampler2D curvemap, float dist, out float visifac) -{ - visifac = texture2D(curvemap, vec2(dist / lampdist, 0.0)).x; -} - -void lamp_visibility_sphere(float lampdist, float dist, float visifac, out float outvisifac) -{ - float t = lampdist - dist; - - outvisifac = visifac * max(t, 0.0) / lampdist; -} - -void lamp_visibility_spot_square(vec3 lampvec, mat4 lampimat, vec2 scale, vec3 lv, out float inpr) -{ - if (dot(lv, lampvec) > 0.0) { - vec3 lvrot = (lampimat * vec4(lv, 0.0)).xyz; - /* without clever non-uniform scale, we could do: */ - // float x = max(abs(lvrot.x / lvrot.z), abs(lvrot.y / lvrot.z)); - float x = max(abs((lvrot.x / scale.x) / lvrot.z), abs((lvrot.y / scale.y) / lvrot.z)); - - inpr = 1.0 / sqrt(1.0 + x * x); - } - else - inpr = 0.0; -} - -void lamp_visibility_spot_circle(vec3 lampvec, mat4 lampimat, vec2 scale, vec3 lv, out float inpr) -{ - /* without clever non-uniform scale, we could do: */ - // inpr = dot(lv, lampvec); - if (dot(lv, lampvec) > 0.0) { - vec3 lvrot = (lampimat * vec4(lv, 0.0)).xyz; - float x = abs(lvrot.x / lvrot.z); - float y = abs(lvrot.y / lvrot.z); - - float ellipse = abs((x * x) / (scale.x * scale.x) + (y * y) / (scale.y * scale.y)); - - inpr = 1.0 / sqrt(1.0 + ellipse); - } - else - inpr = 0.0; -} - -void lamp_visibility_spot(float spotsi, float spotbl, float inpr, float visifac, out float outvisifac) -{ - float t = spotsi; - - if (inpr <= t) { - outvisifac = 0.0; - } - else { - t = inpr - t; - - /* soft area */ - if (spotbl != 0.0) - inpr *= smoothstep(0.0, 1.0, t / spotbl); - - outvisifac = visifac * inpr; - } -} - -void lamp_visibility_clamp(float visifac, out float outvisifac) -{ - outvisifac = (visifac < 0.001) ? 0.0 : visifac; -} - -void world_paper_view(vec3 vec, out vec3 outvec) -{ - vec3 nvec = normalize(vec); - outvec = (gl_ProjectionMatrix[3][3] == 0.0) ? vec3(nvec.x, 0.0, nvec.y) : vec3(0.0, 0.0, -1.0); -} - -void world_zen_mapping(vec3 view, float zenup, float zendown, out float zenfac) -{ - if (view.z >= 0.0) - zenfac = zenup; - else - zenfac = zendown; -} - -void world_blend_paper_real(vec3 vec, out float blend) -{ - blend = abs(vec.y); -} - -void world_blend_paper(vec3 vec, out float blend) -{ - blend = (vec.y + 1.0) * 0.5; -} - -void world_blend_real(vec3 vec, out float blend) -{ - blend = abs(normalize(vec).z); -} - -void world_blend(vec3 vec, out float blend) -{ - blend = (normalize(vec).z + 1) * 0.5; -} - -void shade_view(vec3 co, out vec3 view) -{ - /* handle perspective/orthographic */ - view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(co) : vec3(0.0, 0.0, -1.0); -} - -void shade_tangent_v(vec3 lv, vec3 tang, out vec3 vn) -{ - vec3 c = cross(lv, tang); - vec3 vnor = cross(c, tang); - - vn = -normalize(vnor); -} - -void shade_inp(vec3 vn, vec3 lv, out float inp) -{ - inp = dot(vn, lv); -} - -void shade_is_no_diffuse(out float is) -{ - is = 0.0; -} - -void shade_is_hemi(float inp, out float is) -{ - is = 0.5 * inp + 0.5; -} - -float area_lamp_energy(mat4 area, vec3 co, vec3 vn) -{ - vec3 vec[4], c[4]; - float rad[4], fac; - - vec[0] = normalize(co - area[0].xyz); - vec[1] = normalize(co - area[1].xyz); - vec[2] = normalize(co - area[2].xyz); - vec[3] = normalize(co - area[3].xyz); - - c[0] = normalize(cross(vec[0], vec[1])); - c[1] = normalize(cross(vec[1], vec[2])); - c[2] = normalize(cross(vec[2], vec[3])); - c[3] = normalize(cross(vec[3], vec[0])); - - rad[0] = acos(dot(vec[0], vec[1])); - rad[1] = acos(dot(vec[1], vec[2])); - rad[2] = acos(dot(vec[2], vec[3])); - rad[3] = acos(dot(vec[3], vec[0])); - - fac = rad[0] * dot(vn, c[0]); - fac += rad[1] * dot(vn, c[1]); - fac += rad[2] * dot(vn, c[2]); - fac += rad[3] * dot(vn, c[3]); - - return max(fac, 0.0); -} - -void shade_inp_area( - vec3 position, vec3 lampco, vec3 lampvec, vec3 vn, mat4 area, float areasize, float k, - out float inp) -{ - vec3 co = position; - vec3 vec = co - lampco; - - if (dot(vec, lampvec) < 0.0) { - inp = 0.0; - } - else { - float intens = area_lamp_energy(area, co, vn); - - inp = pow(intens * areasize, k); - } -} - -void shade_diffuse_oren_nayer(float nl, vec3 n, vec3 l, vec3 v, float rough, out float is) -{ - vec3 h = normalize(v + l); - float nh = max(dot(n, h), 0.0); - float nv = max(dot(n, v), 0.0); - float realnl = dot(n, l); - - if (realnl < 0.0) { - is = 0.0; - } - else if (nl < 0.0) { - is = 0.0; - } - else { - float vh = max(dot(v, h), 0.0); - float Lit_A = acos(realnl); - float View_A = acos(nv); - - vec3 Lit_B = normalize(l - realnl * n); - vec3 View_B = normalize(v - nv * n); - - float t = max(dot(Lit_B, View_B), 0.0); - - float a, b; - - if (Lit_A > View_A) { - a = Lit_A; - b = View_A; - } - else { - a = View_A; - b = Lit_A; - } - - float A = 1.0 - (0.5 * ((rough * rough) / ((rough * rough) + 0.33))); - float B = 0.45 * ((rough * rough) / ((rough * rough) + 0.09)); - - b *= 0.95; - is = nl * (A + (B * t * sin(a) * tan(b))); - } -} - -void shade_diffuse_toon(vec3 n, vec3 l, vec3 v, float size, float tsmooth, out float is) -{ - float rslt = dot(n, l); - float ang = acos(rslt); - - if (ang < size) is = 1.0; - else if (ang > (size + tsmooth) || tsmooth == 0.0) is = 0.0; - else is = 1.0 - ((ang - size) / tsmooth); -} - -void shade_diffuse_minnaert(float nl, vec3 n, vec3 v, float darkness, out float is) -{ - if (nl <= 0.0) { - is = 0.0; - } - else { - float nv = max(dot(n, v), 0.0); - - if (darkness <= 1.0) - is = nl * pow(max(nv * nl, 0.1), darkness - 1.0); - else - is = nl * pow(1.0001 - nv, darkness - 1.0); - } -} - -float fresnel_fac(vec3 view, vec3 vn, float grad, float fac) -{ - float t1, t2; - float ffac; - - if (fac == 0.0) { - ffac = 1.0; - } - else { - t1 = dot(view, vn); - if (t1 > 0.0) t2 = 1.0 + t1; - else t2 = 1.0 - t1; - - t2 = grad + (1.0 - grad) * pow(t2, fac); - - if (t2 < 0.0) ffac = 0.0; - else if (t2 > 1.0) ffac = 1.0; - else ffac = t2; - } - - return ffac; -} - -void shade_diffuse_fresnel(vec3 vn, vec3 lv, vec3 view, float fac_i, float fac, out float is) -{ - is = fresnel_fac(lv, vn, fac_i, fac); -} - -void shade_cubic(float is, out float outis) -{ - if (is > 0.0 && is < 1.0) - outis = smoothstep(0.0, 1.0, is); - else - outis = is; -} - -void shade_visifac(float i, float visifac, float refl, out float outi) -{ - /*if (i > 0.0)*/ - outi = max(i * visifac * refl, 0.0); - /*else - outi = i;*/ -} - -void shade_tangent_v_spec(vec3 tang, out vec3 vn) -{ - vn = tang; -} - -void shade_add_to_diffuse(float i, vec3 lampcol, vec3 col, out vec3 outcol) -{ - if (i > 0.0) - outcol = i * lampcol * col; - else - outcol = vec3(0.0, 0.0, 0.0); -} - -void shade_hemi_spec(vec3 vn, vec3 lv, vec3 view, float spec, float hard, float visifac, out float t) -{ - lv += view; - lv = normalize(lv); - - t = dot(vn, lv); - t = 0.5 * t + 0.5; - - t = visifac * spec * pow(t, hard); -} - -void shade_phong_spec(vec3 n, vec3 l, vec3 v, float hard, out float specfac) -{ - vec3 h = normalize(l + v); - float rslt = max(dot(h, n), 0.0); - - specfac = pow(rslt, hard); -} - -void shade_cooktorr_spec(vec3 n, vec3 l, vec3 v, float hard, out float specfac) -{ - vec3 h = normalize(v + l); - float nh = dot(n, h); - - if (nh < 0.0) { - specfac = 0.0; - } - else { - float nv = max(dot(n, v), 0.0); - float i = pow(nh, hard); - - i = i / (0.1 + nv); - specfac = i; - } -} - -void shade_blinn_spec(vec3 n, vec3 l, vec3 v, float refrac, float spec_power, out float specfac) -{ - if (refrac < 1.0) { - specfac = 0.0; - } - else if (spec_power == 0.0) { - specfac = 0.0; - } - else { - if (spec_power < 100.0) - spec_power = sqrt(1.0 / spec_power); - else - spec_power = 10.0 / spec_power; - - vec3 h = normalize(v + l); - float nh = dot(n, h); - if (nh < 0.0) { - specfac = 0.0; - } - else { - float nv = max(dot(n, v), 0.01); - float nl = dot(n, l); - if (nl <= 0.01) { - specfac = 0.0; - } - else { - float vh = max(dot(v, h), 0.01); - - float a = 1.0; - float b = (2.0 * nh * nv) / vh; - float c = (2.0 * nh * nl) / vh; - - float g = 0.0; - - if (a < b && a < c) g = a; - else if (b < a && b < c) g = b; - else if (c < a && c < b) g = c; - - float p = sqrt(((refrac * refrac) + (vh * vh) - 1.0)); - float f = ((((p - vh) * (p - vh)) / ((p + vh) * (p + vh))) * - (1.0 + ((((vh * (p + vh)) - 1.0) * ((vh * (p + vh)) - 1.0)) / - (((vh * (p - vh)) + 1.0) * ((vh * (p - vh)) + 1.0))))); - float ang = acos(nh); - - specfac = max(f * g * exp_blender((-(ang * ang) / (2.0 * spec_power * spec_power))), 0.0); - } - } - } -} - -void shade_wardiso_spec(vec3 n, vec3 l, vec3 v, float rms, out float specfac) -{ - vec3 h = normalize(l + v); - float nh = max(dot(n, h), 0.001); - float nv = max(dot(n, v), 0.001); - float nl = max(dot(n, l), 0.001); - float angle = tan(acos(nh)); - float alpha = max(rms, 0.001); - - specfac = nl * (1.0 / (4.0 * M_PI * alpha * alpha)) * (exp_blender(-(angle * angle) / (alpha * alpha)) / (sqrt(nv * nl))); -} - -void shade_toon_spec(vec3 n, vec3 l, vec3 v, float size, float tsmooth, out float specfac) -{ - vec3 h = normalize(l + v); - float rslt = dot(h, n); - float ang = acos(rslt); - - if (ang < size) rslt = 1.0; - else if (ang >= (size + tsmooth) || tsmooth == 0.0) rslt = 0.0; - else rslt = 1.0 - ((ang - size) / tsmooth); - - specfac = rslt; -} - -void shade_spec_area_inp(float specfac, float inp, out float outspecfac) -{ - outspecfac = specfac * inp; -} - -void shade_spec_t(float shadfac, float spec, float visifac, float specfac, out float t) -{ - t = shadfac * spec * visifac * specfac; -} - -void shade_add_spec(float t, vec3 lampcol, vec3 speccol, out vec3 outcol) -{ - outcol = t * lampcol * speccol; -} - -void shade_add_mirror(vec3 mir, vec4 refcol, vec3 combined, out vec3 result) -{ - result = mir * refcol.gba + (vec3(1.0) - mir * refcol.rrr) * combined; -} - -void alpha_spec_correction(vec3 spec, float spectra, float alpha, out float outalpha) -{ - if (spectra > 0.0) { - float t = clamp(max(max(spec.r, spec.g), spec.b) * spectra, 0.0, 1.0); - outalpha = (1.0 - t) * alpha + t; - } - else { - outalpha = alpha; - } -} - -void shade_add(vec4 col1, vec4 col2, out vec4 outcol) -{ - outcol = col1 + col2; -} - -void shade_madd(vec4 col, vec4 col1, vec4 col2, out vec4 outcol) -{ - outcol = col + col1 * col2; -} - -void shade_add_clamped(vec4 col1, vec4 col2, out vec4 outcol) -{ - outcol = col1 + max(col2, vec4(0.0, 0.0, 0.0, 0.0)); -} - -void shade_madd_clamped(vec4 col, vec4 col1, vec4 col2, out vec4 outcol) -{ - outcol = col + max(col1 * col2, vec4(0.0, 0.0, 0.0, 0.0)); -} - -void env_apply(vec4 col, vec3 hor, vec3 zen, vec4 f, mat4 vm, vec3 vn, out vec4 outcol) -{ - vec3 vv = normalize(vm[2].xyz); - float skyfac = 0.5 * (1.0 + dot(vn, -vv)); - outcol = col + f * vec4(mix(hor, zen, skyfac), 0); -} - -void shade_maddf(vec4 col, float f, vec4 col1, out vec4 outcol) -{ - outcol = col + f * col1; -} - -void shade_mul(vec4 col1, vec4 col2, out vec4 outcol) -{ - outcol = col1 * col2; -} - -void shade_mul_value(float fac, vec4 col, out vec4 outcol) -{ - outcol = col * fac; -} - -void shade_mul_value_v3(float fac, vec3 col, out vec3 outcol) -{ - outcol = col * fac; -} - -void shade_obcolor(vec4 col, vec4 obcol, out vec4 outcol) -{ - outcol = vec4(col.rgb * obcol.rgb, col.a); -} - -void ramp_rgbtobw(vec3 color, out float outval) -{ - outval = color.r * 0.3 + color.g * 0.58 + color.b * 0.12; -} - -void shade_only_shadow(float i, float shadfac, float energy, vec3 shadcol, out vec3 outshadrgb) -{ - outshadrgb = i * energy * (1.0 - shadfac) * (vec3(1.0) - shadcol); -} - -void shade_only_shadow_diffuse(vec3 shadrgb, vec3 rgb, vec4 diff, out vec4 outdiff) -{ - outdiff = diff - vec4(rgb * shadrgb, 0.0); -} - -void shade_only_shadow_specular(vec3 shadrgb, vec3 specrgb, vec4 spec, out vec4 outspec) -{ - outspec = spec - vec4(specrgb * shadrgb, 0.0); -} - -void shade_clamp_positive(vec4 col, out vec4 outcol) -{ - outcol = max(col, vec4(0.0)); -} - -void test_shadowbuf( - vec3 rco, sampler2DShadow shadowmap, mat4 shadowpersmat, float shadowbias, float inp, - out float result) -{ - if (inp <= 0.0) { - result = 0.0; - } - else { - vec4 co = shadowpersmat * vec4(rco, 1.0); - - //float bias = (1.5 - inp*inp)*shadowbias; - co.z -= shadowbias * co.w; - - if (co.w > 0.0 && co.x > 0.0 && co.x / co.w < 1.0 && co.y > 0.0 && co.y / co.w < 1.0) - result = shadow2DProj(shadowmap, co).x; - else - result = 1.0; - } -} - -void test_shadowbuf_vsm( - vec3 rco, sampler2D shadowmap, mat4 shadowpersmat, float shadowbias, float bleedbias, float inp, - out float result) -{ - if (inp <= 0.0) { - result = 0.0; - } - else { - vec4 co = shadowpersmat * vec4(rco, 1.0); - if (co.w > 0.0 && co.x > 0.0 && co.x / co.w < 1.0 && co.y > 0.0 && co.y / co.w < 1.0) { - vec2 moments = texture2DProj(shadowmap, co).rg; - float dist = co.z / co.w; - float p = 0.0; - - if (dist <= moments.x) - p = 1.0; - - float variance = moments.y - (moments.x * moments.x); - variance = max(variance, shadowbias / 10.0); - - float d = moments.x - dist; - float p_max = variance / (variance + d * d); - - // Now reduce light-bleeding by removing the [0, x] tail and linearly rescaling (x, 1] - p_max = clamp((p_max - bleedbias) / (1.0 - bleedbias), 0.0, 1.0); - - result = max(p, p_max); - } - else { - result = 1.0; - } - } -} - -void shadows_only( - vec3 rco, sampler2DShadow shadowmap, mat4 shadowpersmat, - float shadowbias, vec3 shadowcolor, float inp, - out vec3 result) -{ - result = vec3(1.0); - - if (inp > 0.0) { - float shadfac; - - test_shadowbuf(rco, shadowmap, shadowpersmat, shadowbias, inp, shadfac); - result -= (1.0 - shadfac) * (vec3(1.0) - shadowcolor); - } -} - -void shadows_only_vsm( - vec3 rco, sampler2D shadowmap, mat4 shadowpersmat, - float shadowbias, float bleedbias, vec3 shadowcolor, float inp, - out vec3 result) -{ - result = vec3(1.0); - - if (inp > 0.0) { - float shadfac; - - test_shadowbuf_vsm(rco, shadowmap, shadowpersmat, shadowbias, bleedbias, inp, shadfac); - result -= (1.0 - shadfac) * (vec3(1.0) - shadowcolor); - } -} - -void shade_light_texture(vec3 rco, sampler2D cookie, mat4 shadowpersmat, out vec4 result) -{ - - vec4 co = shadowpersmat * vec4(rco, 1.0); - - result = texture2DProj(cookie, co); -} - -void shade_exposure_correct(vec3 col, float linfac, float logfac, out vec3 outcol) -{ - outcol = linfac * (1.0 - exp(col * logfac)); -} - -void shade_mist_factor( - vec3 co, float enable, float miststa, float mistdist, float misttype, float misi, - out float outfac) -{ - if (enable == 1.0) { - float fac, zcor; - - zcor = (gl_ProjectionMatrix[3][3] == 0.0) ? length(co) : -co[2]; - - fac = clamp((zcor - miststa) / mistdist, 0.0, 1.0); - if (misttype == 0.0) fac *= fac; - else if (misttype == 1.0) ; - else fac = sqrt(fac); - - outfac = 1.0 - (1.0 - fac) * (1.0 - misi); - } - else { - outfac = 0.0; - } -} - -void shade_world_mix(vec3 hor, vec4 col, out vec4 outcol) -{ - float fac = clamp(col.a, 0.0, 1.0); - outcol = vec4(mix(hor, col.rgb, fac), col.a); -} - -void shade_alpha_opaque(vec4 col, out vec4 outcol) -{ - outcol = vec4(col.rgb, 1.0); -} - -void shade_alpha_obcolor(vec4 col, vec4 obcol, out vec4 outcol) -{ - outcol = vec4(col.rgb, col.a * obcol.a); -} - /*********** NEW SHADER UTILITIES **************/ float fresnel_dielectric_0(float eta) @@ -2451,7 +974,15 @@ float hypot(float x, float y) void generated_from_orco(vec3 orco, out vec3 generated) { - generated = orco * 0.5 + vec3(0.5); +#ifdef VOLUMETRICS +#ifdef MESH_SHADER + generated = volumeObjectLocalCoord; +#else + generated = worldPosition; +#endif +#else + generated = orco; +#endif } int floor_to_int(float x) @@ -2464,7 +995,6 @@ int quick_floor(float x) return int(x) - ((x < 0) ? 1 : 0); } -#ifdef BIT_OPERATIONS float integer_noise(int n) { int nn; @@ -2528,7 +1058,6 @@ vec3 cellnoise_color(vec3 p) return vec3(r, g, b); } -#endif // BIT_OPERATIONS float floorfrac(float x, out int i) { @@ -2536,317 +1065,349 @@ float floorfrac(float x, out int i) return x - i; } +/* bsdfs */ -/* Principled BSDF operations */ - -float sqr(float a) +void convert_metallic_to_specular_tinted( + vec3 basecol, float metallic, float specular_fac, float specular_tint, + out vec3 diffuse, out vec3 f0) { - return a*a; + vec3 dielectric = vec3(0.034) * specular_fac * 2.0; + float lum = dot(basecol, vec3(0.3, 0.6, 0.1)); /* luminance approx. */ + vec3 tint = lum > 0 ? basecol / lum : vec3(1.0); /* normalize lum. to isolate hue+sat */ + f0 = mix(dielectric * mix(vec3(1.0), tint, specular_tint), basecol, metallic); + diffuse = mix(basecol, vec3(0.0), metallic); } -float schlick_fresnel(float u) +#ifndef VOLUMETRICS +void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out Closure result) { - float m = clamp(1.0 - u, 0.0, 1.0); - float m2 = m * m; - return m2 * m2 * m; // pow(m,5) + vec3 vN = normalize(mat3(ViewMatrix) * N); + result = CLOSURE_DEFAULT; + result.ssr_normal = normal_encode(vN, viewCameraVec); + eevee_closure_diffuse(N, color.rgb, 1.0, result.radiance); + result.radiance *= color.rgb; } -float GTR1(float NdotH, float a) +void node_bsdf_glossy(vec4 color, float roughness, vec3 N, float ssr_id, out Closure result) { - if (a >= 1.0) { - return M_1_PI; - } - - a = max(a, 0.001); - float a2 = a*a; - float t = 1.0 + (a2 - 1.0) * NdotH*NdotH; - return (a2 - 1.0) / (M_PI * log(a2) * t); + vec3 out_spec, ssr_spec; + 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; + result.radiance = out_spec * color.rgb; + result.ssr_data = vec4(ssr_spec * color.rgb, roughness); + result.ssr_normal = normal_encode(vN, viewCameraVec); + result.ssr_id = int(ssr_id); } -float GTR2(float NdotH, float a) +void node_bsdf_anisotropic( + vec4 color, float roughness, float anisotropy, float rotation, vec3 N, vec3 T, + out Closure result) { - float a2 = a*a; - float t = 1.0 + (a2 - 1.0) * NdotH*NdotH; - return a2 / (M_PI * t*t); + node_bsdf_diffuse(color, 0.0, N, result); } -float GTR2_aniso(float NdotH, float HdotX, float HdotY, float ax, float ay) +void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, float ssr_id, out Closure result) { - return 1.0 / (M_PI * ax*ay * sqr(sqr(HdotX / ax) + sqr(HdotY / ay) + NdotH*NdotH)); + vec3 out_spec, out_refr, ssr_spec; + 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; + out_spec *= color.rgb; + float fresnel = F_eta(ior, dot(N, cameraVec)); + vec3 vN = normalize(mat3(ViewMatrix) * N); + result = CLOSURE_DEFAULT; + result.radiance = mix(out_refr, out_spec, fresnel); + result.ssr_data = vec4(ssr_spec * color.rgb * fresnel, roughness); + result.ssr_normal = normal_encode(vN, viewCameraVec); + result.ssr_id = int(ssr_id); } -float smithG_GGX(float NdotV, float alphaG) +void node_bsdf_toon(vec4 color, float size, float tsmooth, vec3 N, out Closure result) { - float a = alphaG*alphaG; - float b = NdotV*NdotV; - return 1.0 / (NdotV + sqrt(a + b - a * b)); -} - -vec3 rotate_vector(vec3 p, vec3 n, float theta) { - return ( - p * cos(theta) + cross(n, p) * - sin(theta) + n * dot(p, n) * - (1.0 - cos(theta)) - ); + node_bsdf_diffuse(color, 0.0, N, result); } +void node_bsdf_principled_clearcoat(vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular, + float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat, + float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, float ssr_id, + float sss_id, vec3 sss_scale, out Closure result) +{ + metallic = saturate(metallic); + transmission = saturate(transmission); -/*********** NEW SHADER NODES ***************/ - -#define NUM_LIGHTS 3 + vec3 diffuse, f0, out_diff, out_spec, out_trans, out_refr, ssr_spec; + convert_metallic_to_specular_tinted(base_color.rgb, metallic, specular, specular_tint, diffuse, f0); -/* bsdfs */ + transmission *= 1.0 - metallic; + subsurface *= 1.0 - metallic; -void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out vec4 result) -{ - /* ambient light */ - vec3 L = vec3(0.2); + clearcoat *= 0.25; + clearcoat *= 1.0 - transmission; - /* directional lights */ - for (int i = 0; i < NUM_LIGHTS; i++) { - vec3 light_position = gl_LightSource[i].position.xyz; - vec3 light_diffuse = gl_LightSource[i].diffuse.rgb; + vec3 mixed_ss_base_color = mix(diffuse, subsurface_color.rgb, subsurface); - float bsdf = max(dot(N, light_position), 0.0); - L += light_diffuse * bsdf; - } +#ifdef USE_SSS + diffuse = vec3(0.0); +#else + diffuse = mixed_ss_base_color; +#endif - result = vec4(L * color.rgb, 1.0); + f0 = mix(f0, vec3(1.0), transmission); + + float sss_scalef = dot(sss_scale, vec3(1.0 / 3.0)) * subsurface; + eevee_closure_principled(N, mixed_ss_base_color, f0, int(ssr_id), roughness, + CN, clearcoat, clearcoat_roughness, 1.0, sss_scalef, ior, + out_diff, out_trans, out_spec, out_refr, ssr_spec); + + vec3 refr_color = base_color.rgb; + refr_color *= (refractionDepth > 0.0) ? refr_color : vec3(1.0); /* Simulate 2 transmission event */ + + float fresnel = F_eta(ior, dot(N, cameraVec)); + vec3 refr_spec_color = base_color.rgb * fresnel; + /* This bit maybe innacurate. */ + out_refr = out_refr * refr_color * (1.0 - fresnel) + out_spec * refr_spec_color; + + ssr_spec = mix(ssr_spec, refr_spec_color, transmission); + + vec3 vN = normalize(mat3(ViewMatrix) * N); + result = CLOSURE_DEFAULT; + result.radiance = out_spec + out_diff * diffuse; + result.radiance = mix(result.radiance, out_refr, transmission); + result.ssr_data = vec4(ssr_spec, roughness); + result.ssr_normal = normal_encode(vN, viewCameraVec); + result.ssr_id = int(ssr_id); +#ifdef USE_SSS + result.sss_data.a = sss_scalef; + result.sss_data.rgb = out_diff + out_trans; +# ifdef USE_SSS_ALBEDO + result.sss_albedo.rgb = mixed_ss_base_color; +# else + result.sss_data.rgb *= mixed_ss_base_color; +# endif + result.sss_data.rgb *= (1.0 - transmission); +#endif } -void node_bsdf_glossy(vec4 color, float roughness, vec3 N, out vec4 result) +void node_bsdf_translucent(vec4 color, vec3 N, out Closure result) { - /* ambient light */ - vec3 L = vec3(0.2); - - /* directional lights */ - for (int i = 0; i < NUM_LIGHTS; i++) { - vec3 light_position = gl_LightSource[i].position.xyz; - vec3 H = gl_LightSource[i].halfVector.xyz; - vec3 light_diffuse = gl_LightSource[i].diffuse.rgb; - vec3 light_specular = gl_LightSource[i].specular.rgb; - - /* we mix in some diffuse so low roughness still shows up */ - 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; - } - - result = vec4(L * color.rgb, 1.0); + node_bsdf_diffuse(color, 0.0, -N, result); } -void node_bsdf_anisotropic( - vec4 color, float roughness, float anisotropy, float rotation, vec3 N, vec3 T, - out vec4 result) +void node_bsdf_transparent(vec4 color, out Closure result) { - node_bsdf_diffuse(color, 0.0, N, result); + /* this isn't right */ + result = CLOSURE_DEFAULT; + result.radiance = vec3(0.0); + result.opacity = 0.0; + result.ssr_id = TRANSPARENT_CLOSURE_FLAG; } -void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, out vec4 result) +void node_bsdf_velvet(vec4 color, float sigma, vec3 N, out Closure result) { node_bsdf_diffuse(color, 0.0, N, result); } -void node_bsdf_toon(vec4 color, float size, float tsmooth, vec3 N, out vec4 result) -{ +void node_subsurface_scattering( + vec4 color, float scale, vec3 radius, float sharpen, float texture_blur, vec3 N, float sss_id, + out Closure result) +{ +#if defined(USE_SSS) + vec3 out_diff, out_trans; + vec3 vN = normalize(mat3(ViewMatrix) * N); + result = CLOSURE_DEFAULT; + result.ssr_data = vec4(0.0); + result.ssr_normal = normal_encode(vN, viewCameraVec); + result.ssr_id = -1; + result.sss_data.a = scale; + eevee_closure_subsurface(N, color.rgb, 1.0, scale, out_diff, out_trans); + result.sss_data.rgb = out_diff + out_trans; +#ifdef USE_SSS_ALBEDO + /* Not perfect for texture_blur not exaclty equal to 0.0 or 1.0. */ + result.sss_albedo.rgb = mix(color.rgb, vec3(1.0), texture_blur); + result.sss_data.rgb *= mix(vec3(1.0), color.rgb, texture_blur); +#else + result.sss_data.rgb *= color.rgb; +#endif +#else node_bsdf_diffuse(color, 0.0, N, result); +#endif } -void node_bsdf_principled(vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular, - float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat, - float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, out vec4 result) +void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out Closure result) { - /* ambient light */ - // TODO: set ambient light to an appropriate value - vec3 L = mix(0.1, 0.03, metallic) * mix(base_color.rgb, subsurface_color.rgb, subsurface * (1.0 - metallic)); - - float eta = (2.0 / (1.0 - sqrt(0.08 * specular))) - 1.0; - - /* set the viewing vector */ - vec3 V = (gl_ProjectionMatrix[3][3] == 0.0) ? -normalize(I) : vec3(0.0, 0.0, 1.0); - - /* get the tangent */ - vec3 Tangent = T; - if (T == vec3(0.0)) { - // if no tangent is set, use a default tangent - if(N.x != N.y || N.x != N.z) { - Tangent = vec3(N.z-N.y, N.x-N.z, N.y-N.x); // (1,1,1) x N - } - else { - Tangent = vec3(N.z-N.y, N.x+N.z, -N.y-N.x); // (-1,1,1) x N - } - } - - /* rotate tangent */ - if (anisotropic_rotation != 0.0) { - Tangent = rotate_vector(Tangent, N, anisotropic_rotation * 2.0 * M_PI); - } - - /* calculate the tangent and bitangent */ - vec3 Y = normalize(cross(N, Tangent)); - vec3 X = cross(Y, N); - - /* fresnel normalization parameters */ - float F0 = fresnel_dielectric_0(eta); - float F0_norm = 1.0 / (1.0 - F0); - - /* directional lights */ - for (int i = 0; i < NUM_LIGHTS; i++) { - vec3 light_position_world = gl_LightSource[i].position.xyz; - vec3 light_position = normalize(light_position_world); - - vec3 H = normalize(light_position + V); - - vec3 light_diffuse = gl_LightSource[i].diffuse.rgb; - vec3 light_specular = gl_LightSource[i].specular.rgb; - - float NdotL = dot(N, light_position); - float NdotV = dot(N, V); - float LdotH = dot(light_position, H); - - vec3 diffuse_and_specular_bsdf = vec3(0.0); - if (NdotL >= 0.0 && NdotV >= 0.0) { - float NdotH = dot(N, H); - - float Cdlum = 0.3 * base_color.r + 0.6 * base_color.g + 0.1 * base_color.b; // luminance approx. - - vec3 Ctint = Cdlum > 0 ? base_color.rgb / Cdlum : vec3(1.0); // normalize lum. to isolate hue+sat - vec3 Cspec0 = mix(specular * 0.08 * mix(vec3(1.0), Ctint, specular_tint), base_color.rgb, metallic); - vec3 Csheen = mix(vec3(1.0), Ctint, sheen_tint); - - // Diffuse fresnel - go from 1 at normal incidence to .5 at grazing - // and mix in diffuse retro-reflection based on roughness - - float FL = schlick_fresnel(NdotL), FV = schlick_fresnel(NdotV); - float Fd90 = 0.5 + 2.0 * LdotH*LdotH * roughness; - float Fd = mix(1.0, Fd90, FL) * mix(1.0, Fd90, FV); - - // Based on Hanrahan-Krueger brdf approximation of isotropic bssrdf - // 1.25 scale is used to (roughly) preserve albedo - // Fss90 used to "flatten" retroreflection based on roughness - float Fss90 = LdotH*LdotH * roughness; - float Fss = mix(1.0, Fss90, FL) * mix(1.0, Fss90, FV); - float ss = 1.25 * (Fss * (1.0 / (NdotL + NdotV) - 0.5) + 0.5); - - // specular - float aspect = sqrt(1.0 - anisotropic * 0.9); - float a = sqr(roughness); - float ax = max(0.001, a / aspect); - float ay = max(0.001, a * aspect); - float Ds = GTR2_aniso(NdotH, dot(H, X), dot(H, Y), ax, ay); //GTR2(NdotH, a); - float FH = (fresnel_dielectric_cos(LdotH, eta) - F0) * F0_norm; - vec3 Fs = mix(Cspec0, vec3(1.0), FH); - float roughg = sqr(roughness * 0.5 + 0.5); - float Gs = smithG_GGX(NdotL, roughg) * smithG_GGX(NdotV, roughg); - - // sheen - vec3 Fsheen = schlick_fresnel(LdotH) * sheen * Csheen; + vec3 out_refr; + color.rgb *= (refractionDepth > 0.0) ? color.rgb : vec3(1.0); /* Simulate 2 absorption event. */ + 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; +} - vec3 diffuse_bsdf = (mix(Fd * base_color.rgb, ss * subsurface_color.rgb, subsurface) + Fsheen) * light_diffuse; - vec3 specular_bsdf = Gs * Fs * Ds * light_specular; - diffuse_and_specular_bsdf = diffuse_bsdf * (1.0 - metallic) + specular_bsdf; - } - diffuse_and_specular_bsdf *= max(NdotL, 0.0); +void node_ambient_occlusion(vec4 color, float distance, vec3 normal, out vec4 result_color, out float result_ao) +{ + vec3 bent_normal; + vec4 rand = texelFetch(utilTex, ivec3(ivec2(gl_FragCoord.xy) % LUT_SIZE, 2.0), 0); + result_ao = occlusion_compute(normalize(normal), viewPosition, 1.0, rand, bent_normal); + result_color = result_ao * color; +} - float CNdotL = dot(CN, light_position); - float CNdotV = dot(CN, V); +#endif /* VOLUMETRICS */ - vec3 clearcoat_bsdf = vec3(0.0); - if (CNdotL >= 0.0 && CNdotV >= 0.0 && clearcoat > 0.0) { - float CNdotH = dot(CN, H); - //float FH = schlick_fresnel(LdotH); +/* emission */ - // clearcoat (ior = 1.5 -> F0 = 0.04) - float Dr = GTR1(CNdotH, sqr(clearcoat_roughness)); - float Fr = fresnel_dielectric_cos(LdotH, 1.5); //mix(0.04, 1.0, FH); - float Gr = smithG_GGX(CNdotL, 0.25) * smithG_GGX(CNdotV, 0.25); +void node_emission(vec4 color, float strength, vec3 vN, out Closure result) +{ +#ifndef VOLUMETRICS + color *= strength; + result = CLOSURE_DEFAULT; + result.radiance = color.rgb; + result.opacity = color.a; + result.ssr_normal = normal_encode(vN, viewCameraVec); +#else + result = Closure(vec3(0.0), vec3(0.0), color.rgb * strength, 0.0); +#endif +} - clearcoat_bsdf = clearcoat * Gr * Fr * Dr * vec3(0.25) * light_specular; - } - clearcoat_bsdf *= max(CNdotL, 0.0); +/* background */ - L += diffuse_and_specular_bsdf + clearcoat_bsdf; - } +void background_transform_to_world(vec3 viewvec, out vec3 worldvec) +{ + vec4 v = (ProjectionMatrix[3][3] == 0.0) ? vec4(viewvec, 1.0) : vec4(0.0, 0.0, 1.0, 1.0); + vec4 co_homogenous = (ProjectionMatrixInverse * v); - result = vec4(L, 1.0); + vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0); +#if defined(WORLD_BACKGROUND) || defined(PROBE_CAPTURE) + worldvec = (ViewMatrixInverse * co).xyz; +#else + worldvec = (ModelViewMatrixInverse * co).xyz; +#endif } -void node_bsdf_translucent(vec4 color, vec3 N, out vec4 result) +void node_background(vec4 color, float strength, out Closure result) { - node_bsdf_diffuse(color, 0.0, N, result); +#ifndef VOLUMETRICS + color *= strength; + result = CLOSURE_DEFAULT; + result.radiance = color.rgb; + result.opacity = color.a; +#else + result = CLOSURE_DEFAULT; +#endif } -void node_bsdf_transparent(vec4 color, out vec4 result) -{ - /* this isn't right */ - result.r = color.r; - result.g = color.g; - result.b = color.b; - result.a = 0.0; -} +/* volumes */ -void node_bsdf_velvet(vec4 color, float sigma, vec3 N, out vec4 result) +void node_volume_scatter(vec4 color, float density, float anisotropy, out Closure result) { - node_bsdf_diffuse(color, 0.0, N, result); +#ifdef VOLUMETRICS + result = Closure(vec3(0.0), color.rgb * density, vec3(0.0), anisotropy); +#else + result = CLOSURE_DEFAULT; +#endif } -void node_subsurface_scattering( - vec4 color, float scale, vec3 radius, float sharpen, float texture_blur, vec3 N, - out vec4 result) +void node_volume_absorption(vec4 color, float density, out Closure result) { - node_bsdf_diffuse(color, 0.0, N, result); +#ifdef VOLUMETRICS + result = Closure((1.0 - color.rgb) * density, vec3(0.0), vec3(0.0), 0.0); +#else + result = CLOSURE_DEFAULT; +#endif } -void node_bsdf_hair(vec4 color, float offset, float roughnessu, float roughnessv, vec3 tangent, out vec4 result) +void node_blackbody(float temperature, sampler2D spectrummap, out vec4 color) { - result = 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_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out vec4 result) +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) { - node_bsdf_diffuse(color, 0.0, N, result); -} +#ifdef VOLUMETRICS + vec3 absorption_coeff = vec3(0.0); + vec3 scatter_coeff = vec3(0.0); + vec3 emission_coeff = vec3(0.0); -void node_ambient_occlusion(vec4 color, float distance, vec3 normal, out vec4 result_color, out float result_ao) -{ - result_color = color; - result_ao = 1.0; -} + /* Compute density. */ + density = max(density, 0.0); -/* emission */ + if(density > 1e-5) { + density = max(density * density_attribute, 0.0); + } -void node_emission(vec4 color, float strength, vec3 N, out vec4 result) -{ - result = color * strength; -} + if(density > 1e-5) { + /* Compute scattering and absorption coefficients. */ + vec3 scatter_color = color.rgb * color_attribute.rgb; -/* background */ + 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; + } -void background_transform_to_world(vec3 viewvec, out vec3 worldvec) -{ - vec4 v = (gl_ProjectionMatrix[3][3] == 0.0) ? vec4(viewvec, 1.0) : vec4(0.0, 0.0, 1.0, 1.0); - vec4 co_homogenous = (gl_ProjectionMatrixInverse * v); + /* Compute emission. */ + emission_strength = max(emission_strength, 0.0); - vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0); - worldvec = (gl_ModelViewMatrixInverse * co).xyz; -} + if(emission_strength > 1e-5) { + emission_coeff += emission_strength * emission_color.rgb; + } -void node_background(vec4 color, float strength, vec3 N, out vec4 result) -{ - result = color * strength; + 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, vec4 shader1, vec4 shader2, out vec4 shader) +void node_mix_shader(float fac, Closure shader1, Closure shader2, out Closure shader) { - shader = mix(shader1, shader2, fac); + shader = closure_mix(shader1, shader2, fac); } -void node_add_shader(vec4 shader1, vec4 shader2, out vec4 shader) +void node_add_shader(Closure shader1, Closure shader2, out Closure shader) { - shader = shader1 + shader2; + shader = closure_add(shader1, shader2); } /* fresnel */ @@ -2854,7 +1415,7 @@ void node_add_shader(vec4 shader1, vec4 shader2, out vec4 shader) void node_fresnel(float ior, vec3 N, vec3 I, out float result) { /* handle perspective/orthographic */ - vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0); + vec3 I_view = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0); float eta = max(ior, 0.00001); result = fresnel_dielectric(I_view, N, (gl_FrontFacing) ? eta : 1.0 / eta); @@ -2866,7 +1427,7 @@ void node_layer_weight(float blend, vec3 N, vec3 I, out float fresnel, out float { /* fresnel */ float eta = max(1.0 - blend, 0.00001); - vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0); + vec3 I_view = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0); fresnel = fresnel_dielectric(I_view, N, (gl_FrontFacing) ? 1.0 / eta : eta); @@ -2896,11 +1457,67 @@ void node_gamma(vec4 col, float gamma, out vec4 outcol) /* geometry */ +void node_attribute_volume_density(sampler3D tex, out vec4 outcol, out vec3 outvec, out float outf) +{ +#if defined(MESH_SHADER) && defined(VOLUMETRICS) + vec3 cos = volumeObjectLocalCoord; +#else + vec3 cos = vec3(0.0); +#endif + outvec = texture(tex, cos).aaa; + outcol = vec4(outvec, 1.0); + outf = dot(vec3(1.0 / 3.0), outvec); +} + +void node_attribute_volume_color(sampler3D tex, out vec4 outcol, out vec3 outvec, out float outf) +{ +#if defined(MESH_SHADER) && defined(VOLUMETRICS) + vec3 cos = volumeObjectLocalCoord; +#else + vec3 cos = vec3(0.0); +#endif + + 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); +} + +void node_attribute_volume_flame(sampler3D tex, out vec4 outcol, out vec3 outvec, out float outf) +{ +#if defined(MESH_SHADER) && defined(VOLUMETRICS) + vec3 cos = volumeObjectLocalCoord; +#else + vec3 cos = vec3(0.0); +#endif + 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(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) { outcol = vec4(attr, 1.0); outvec = attr; - outf = (attr.x + attr.y + attr.z) / 3.0; + outf = dot(vec3(1.0 / 3.0), attr); } void node_uvmap(vec3 attr_uv, out vec3 outvec) @@ -2908,19 +1525,47 @@ void node_uvmap(vec3 attr_uv, out vec3 outvec) outvec = attr_uv; } +void tangent_orco_x(vec3 orco_in, out vec3 orco_out) +{ + orco_out = vec3(0.0, (orco_in.z - 0.5) * -0.5, (orco_in.y - 0.5) * 0.5); +} + +void tangent_orco_y(vec3 orco_in, out vec3 orco_out) +{ + orco_out = vec3((orco_in.z - 0.5) * -0.5, 0.0, (orco_in.x - 0.5) * 0.5); +} + +void tangent_orco_z(vec3 orco_in, out vec3 orco_out) +{ + orco_out = vec3((orco_in.y - 0.5) * -0.5, (orco_in.x - 0.5) * 0.5, 0.0); +} + +void node_tangentmap(vec4 attr_tangent, mat4 toworld, out vec3 tangent) +{ + tangent = (toworld * vec4(attr_tangent.xyz, 0.0)).xyz; +} + +void node_tangent(vec3 N, vec3 orco, mat4 objmat, mat4 toworld, out vec3 T) +{ + N = (toworld * vec4(N, 0.0)).xyz; + T = (objmat * vec4(orco, 0.0)).xyz; + T = cross(N, normalize(cross(T, N))); +} + void node_geometry( - vec3 I, vec3 N, mat4 toworld, + vec3 I, vec3 N, vec3 orco, mat4 objmat, mat4 toworld, out vec3 position, out vec3 normal, out vec3 tangent, out vec3 true_normal, out vec3 incoming, out vec3 parametric, out float backfacing, out float pointiness) { - position = (toworld * vec4(I, 1.0)).xyz; + position = worldPosition; normal = (toworld * vec4(N, 0.0)).xyz; - tangent = vec3(0.0); + tangent_orco_z(orco, orco); + node_tangent(N, orco, objmat, toworld, tangent); true_normal = normal; /* handle perspective/orthographic */ - vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0); + vec3 I_view = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0); incoming = -(toworld * vec4(I_view, 0.0)).xyz; parametric = vec3(0.0); @@ -2934,16 +1579,15 @@ void node_tex_coord( out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object, out vec3 camera, out vec3 window, out vec3 reflection) { - generated = attr_orco * 0.5 + vec3(0.5); + generated = attr_orco; normal = normalize((obinvmat * (viewinvmat * vec4(N, 0.0))).xyz); uv = attr_uv; object = (obinvmat * (viewinvmat * vec4(I, 1.0))).xyz; camera = vec3(I.xy, -I.z); - vec4 projvec = gl_ProjectionMatrix * vec4(I, 1.0); + vec4 projvec = ProjectionMatrix * vec4(I, 1.0); window = vec3(mtex_2d_mapping(projvec.xyz / projvec.w).xy * camerafac.xy + camerafac.zw, 0.0); - vec3 shade_I; - shade_view(I, shade_I); + vec3 shade_I = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0); vec3 view_reflection = reflect(shade_I, normalize(N)); reflection = (viewinvmat * vec4(view_reflection, 0.0)).xyz; } @@ -2954,13 +1598,18 @@ void node_tex_coord_background( out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object, out vec3 camera, out vec3 window, out vec3 reflection) { - vec4 v = (gl_ProjectionMatrix[3][3] == 0.0) ? vec4(I, 1.0) : vec4(0.0, 0.0, 1.0, 1.0); - vec4 co_homogenous = (gl_ProjectionMatrixInverse * v); + vec4 v = (ProjectionMatrix[3][3] == 0.0) ? vec4(I, 1.0) : vec4(0.0, 0.0, 1.0, 1.0); + vec4 co_homogenous = (ProjectionMatrixInverse * v); vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0); co = normalize(co); - vec3 coords = (gl_ModelViewMatrixInverse * co).xyz; + +#if defined(WORLD_BACKGROUND) || defined(PROBE_CAPTURE) + vec3 coords = (ViewMatrixInverse * co).xyz; +#else + vec3 coords = (ModelViewMatrixInverse * co).xyz; +#endif generated = coords; normal = -coords; @@ -2968,13 +1617,17 @@ void node_tex_coord_background( object = coords; camera = vec3(co.xy, -co.z); - window = (gl_ProjectionMatrix[3][3] == 0.0) ? + window = (ProjectionMatrix[3][3] == 0.0) ? vec3(mtex_2d_mapping(I).xy * camerafac.xy + camerafac.zw, 0.0) : vec3(vec2(0.5) * camerafac.xy + camerafac.zw, 0.0); reflection = -coords; } +#if defined(WORLD_BACKGROUND) || (defined(PROBE_CAPTURE) && !defined(MESH_SHADER)) +#define node_tex_coord node_tex_coord_background +#endif + /* textures */ float calc_gradient(vec3 p, int gradient_type) @@ -3044,7 +1697,6 @@ void node_tex_checker(vec3 co, vec4 color1, vec4 color2, float scale, out vec4 c fac = check ? 1.0 : 0.0; } -#ifdef BIT_OPERATIONS vec2 calc_brick_texture(vec3 p, float mortar_size, float mortar_smooth, float bias, float brick_width, float row_height, float offset_amount, int offset_frequency, @@ -3080,7 +1732,6 @@ vec2 calc_brick_texture(vec3 p, float mortar_size, float mortar_smooth, float bi return vec2(tint, smoothstep(0.0, mortar_smooth, min_dist)); } } -#endif void node_tex_brick(vec3 co, vec4 color1, vec4 color2, @@ -3091,7 +1742,6 @@ void node_tex_brick(vec3 co, float squash_amount, float squash_frequency, out vec4 color, out float fac) { -#ifdef BIT_OPERATIONS vec2 f2 = calc_brick_texture(co * scale, mortar_size, mortar_smooth, bias, brick_width, row_height, @@ -3105,10 +1755,6 @@ void node_tex_brick(vec3 co, } color = mix(color1, mortar, f); fac = f; -#else - color = vec4(1.0); - fac = 1.0; -#endif } void node_tex_clouds(vec3 co, float size, out vec4 color, out float fac) @@ -3123,7 +1769,15 @@ void node_tex_environment_equirectangular(vec3 co, sampler2D ima, out vec4 color float u = -atan(nco.y, nco.x) / (2.0 * M_PI) + 0.5; float v = atan(nco.z, hypot(nco.x, nco.y)) / M_PI + 0.5; - color = texture2D(ima, vec2(u, v)); + /* Fix pole bleeding */ + float half_width = 0.5 / float(textureSize(ima, 0).x); + v = clamp(v, half_width, 1.0 - half_width); + + /* Fix u = 0 seam */ + /* This is caused by texture filtering, since uv don't have smooth derivatives + * at u = 0 or 2PI, hardware filtering is using the smallest mipmap for certain + * texels. So we force the highest mipmap and don't do anisotropic filtering. */ + color = textureLod(ima, vec2(u, v), 0.0); } void node_tex_environment_mirror_ball(vec3 co, sampler2D ima, out vec4 color) @@ -3139,7 +1793,7 @@ void node_tex_environment_mirror_ball(vec3 co, sampler2D ima, out vec4 color) float u = 0.5 * (nco.x + 1.0); float v = 0.5 * (nco.z + 1.0); - color = texture2D(ima, vec2(u, v)); + color = texture(ima, vec2(u, v)); } void node_tex_environment_empty(vec3 co, out vec4 color) @@ -3147,24 +1801,192 @@ void node_tex_environment_empty(vec3 co, out vec4 color) color = vec4(1.0, 0.0, 1.0, 1.0); } -void node_tex_image(vec3 co, sampler2D ima, out vec4 color, out float alpha) +void node_tex_image_linear(vec3 co, sampler2D ima, out vec4 color, out float alpha) +{ + color = texture(ima, co.xy); + alpha = color.a; +} + +void node_tex_image_nearest(vec3 co, sampler2D ima, out vec4 color, out float alpha) { - color = texture2D(ima, co.xy); + ivec2 pix = ivec2(co.xy * textureSize(ima, 0).xy); + color = texelFetch(ima, pix, 0); alpha = color.a; } +void node_tex_image_cubic(vec3 co, sampler2D ima, out vec4 color, out float alpha) +{ + vec2 tex_size = vec2(textureSize(ima, 0).xy); + + co.xy *= tex_size; + /* texel center */ + vec2 tc = floor(co.xy - 0.5) + 0.5; + vec2 f = co.xy - tc; + vec2 f2 = f * f; + vec2 f3 = f2 * f; + /* Bspline coefs (optimized) */ + vec2 w3 = f3 / 6.0; + vec2 w0 = -w3 + f2 * 0.5 - f * 0.5 + 1.0 / 6.0; + vec2 w1 = f3 * 0.5 - f2 * 1.0 + 2.0 / 3.0; + vec2 w2 = 1.0 - w0 - w1 - w3; + +#if 1 /* Optimized version using 4 filtered tap. */ + vec2 s0 = w0 + w1; + vec2 s1 = w2 + w3; + + vec2 f0 = w1 / (w0 + w1); + vec2 f1 = w3 / (w2 + w3); + + vec4 final_co; + final_co.xy = tc - 1.0 + f0; + final_co.zw = tc + 1.0 + f1; + + final_co /= tex_size.xyxy; + + color = texture(ima, final_co.xy) * s0.x * s0.y; + color += texture(ima, final_co.zy) * s1.x * s0.y; + color += texture(ima, final_co.xw) * s0.x * s1.y; + color += texture(ima, final_co.zw) * s1.x * s1.y; + +#else /* Reference bruteforce 16 tap. */ + color = texelFetch(ima, ivec2(tc + vec2(-1.0, -1.0)), 0) * w0.x * w0.y; + color += texelFetch(ima, ivec2(tc + vec2( 0.0, -1.0)), 0) * w1.x * w0.y; + color += texelFetch(ima, ivec2(tc + vec2( 1.0, -1.0)), 0) * w2.x * w0.y; + color += texelFetch(ima, ivec2(tc + vec2( 2.0, -1.0)), 0) * w3.x * w0.y; + + color += texelFetch(ima, ivec2(tc + vec2(-1.0, 0.0)), 0) * w0.x * w1.y; + color += texelFetch(ima, ivec2(tc + vec2( 0.0, 0.0)), 0) * w1.x * w1.y; + color += texelFetch(ima, ivec2(tc + vec2( 1.0, 0.0)), 0) * w2.x * w1.y; + color += texelFetch(ima, ivec2(tc + vec2( 2.0, 0.0)), 0) * w3.x * w1.y; + + color += texelFetch(ima, ivec2(tc + vec2(-1.0, 1.0)), 0) * w0.x * w2.y; + color += texelFetch(ima, ivec2(tc + vec2( 0.0, 1.0)), 0) * w1.x * w2.y; + color += texelFetch(ima, ivec2(tc + vec2( 1.0, 1.0)), 0) * w2.x * w2.y; + color += texelFetch(ima, ivec2(tc + vec2( 2.0, 1.0)), 0) * w3.x * w2.y; + + color += texelFetch(ima, ivec2(tc + vec2(-1.0, 2.0)), 0) * w0.x * w3.y; + color += texelFetch(ima, ivec2(tc + vec2( 0.0, 2.0)), 0) * w1.x * w3.y; + color += texelFetch(ima, ivec2(tc + vec2( 1.0, 2.0)), 0) * w2.x * w3.y; + color += texelFetch(ima, ivec2(tc + vec2( 2.0, 2.0)), 0) * w3.x * w3.y; +#endif + + alpha = color.a; +} + +void node_tex_image_smart(vec3 co, sampler2D ima, out vec4 color, out float alpha) +{ + /* use cubic for now */ + node_tex_image_cubic(co, ima, color, alpha); +} + +void tex_box_sample_linear(vec3 texco, + vec3 N, + sampler2D ima, + out vec4 color1, + out vec4 color2, + out vec4 color3) +{ + /* X projection */ + vec2 uv = texco.yz; + if (N.x < 0.0) { + uv.x = 1.0 - uv.x; + } + color1 = texture(ima, uv); + /* Y projection */ + uv = texco.xz; + if (N.y > 0.0) { + uv.x = 1.0 - uv.x; + } + color2 = texture(ima, uv); + /* Z projection */ + uv = texco.yx; + if (N.z > 0.0) { + uv.x = 1.0 - uv.x; + } + color3 = texture(ima, uv); +} + +void tex_box_sample_nearest(vec3 texco, + vec3 N, + sampler2D ima, + out vec4 color1, + out vec4 color2, + out vec4 color3) +{ + /* X projection */ + vec2 uv = texco.yz; + if (N.x < 0.0) { + uv.x = 1.0 - uv.x; + } + ivec2 pix = ivec2(uv.xy * textureSize(ima, 0).xy); + color1 = texelFetch(ima, pix, 0); + /* Y projection */ + uv = texco.xz; + if (N.y > 0.0) { + uv.x = 1.0 - uv.x; + } + pix = ivec2(uv.xy * textureSize(ima, 0).xy); + color2 = texelFetch(ima, pix, 0); + /* Z projection */ + uv = texco.yx; + if (N.z > 0.0) { + uv.x = 1.0 - uv.x; + } + pix = ivec2(uv.xy * textureSize(ima, 0).xy); + color3 = texelFetch(ima, pix, 0); +} + +void tex_box_sample_cubic(vec3 texco, + vec3 N, + sampler2D ima, + out vec4 color1, + out vec4 color2, + out vec4 color3) +{ + float alpha; + /* X projection */ + vec2 uv = texco.yz; + if (N.x < 0.0) { + uv.x = 1.0 - uv.x; + } + node_tex_image_cubic(uv.xyy, ima, color1, alpha); + /* Y projection */ + uv = texco.xz; + if (N.y > 0.0) { + uv.x = 1.0 - uv.x; + } + node_tex_image_cubic(uv.xyy, ima, color2, alpha); + /* Z projection */ + uv = texco.yx; + if (N.z > 0.0) { + uv.x = 1.0 - uv.x; + } + node_tex_image_cubic(uv.xyy, ima, color3, alpha); +} + +void tex_box_sample_smart(vec3 texco, + vec3 N, + sampler2D ima, + out vec4 color1, + out vec4 color2, + out vec4 color3) +{ + tex_box_sample_cubic(texco, N, ima, color1, color2, color3); +} + void node_tex_image_box(vec3 texco, vec3 N, + vec4 color1, + vec4 color2, + vec4 color3, sampler2D ima, float blend, out vec4 color, out float alpha) { - vec3 signed_N = N; - /* project from direction vector to barycentric coordinates in triangles */ - N = vec3(abs(N.x), abs(N.y), abs(N.z)); - N /= (N.x + N.y + N.z); + N = abs(N); + N /= dot(N, vec3(1.0)); /* basic idea is to think of this as a triangle, each corner representing * one of the 3 faces of the cube. in the corners we have single textures, @@ -3174,72 +1996,36 @@ void node_tex_image_box(vec3 texco, * the Nxyz values are the barycentric coordinates in an equilateral * triangle, which in case of blending, in the middle has a smaller * equilateral triangle where 3 textures blend. this divides things into - * 7 zones, with an if () test for each zone */ + * 7 zones, with an if () test for each zone + * EDIT: Now there is only 4 if's. */ - vec3 weight = vec3(0.0, 0.0, 0.0); - float limit = 0.5 * (1.0 + blend); + float limit = 0.5 + 0.5 * blend; - /* first test for corners with single texture */ - if (N.x > limit * (N.x + N.y) && N.x > limit * (N.x + N.z)) { - weight.x = 1.0; - } - else if (N.y > limit * (N.x + N.y) && N.y > limit * (N.y + N.z)) { - weight.y = 1.0; + vec3 weight; + weight.x = N.x / (N.x + N.y); + weight.y = N.y / (N.y + N.z); + weight.z = N.z / (N.x + N.z); + weight = clamp((weight - 0.5 * (1.0 - blend)) / max(1e-8, blend), 0.0, 1.0); + + /* test for mixes between two textures */ + if (N.z < (1.0 - limit) * (N.y + N.x)) { + weight.z = 0.0; + weight.y = 1.0 - weight.x; } - else if (N.z > limit * (N.x + N.z) && N.z > limit * (N.y + N.z)) { - weight.z = 1.0; + else if (N.x < (1.0 - limit) * (N.y + N.z)) { + weight.x = 0.0; + weight.z = 1.0 - weight.y; } - else if (blend > 0.0) { - /* in case of blending, test for mixes between two textures */ - if (N.z < (1.0 - limit) * (N.y + N.x)) { - weight.x = N.x / (N.x + N.y); - weight.x = clamp((weight.x - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0); - weight.y = 1.0 - weight.x; - } - else if (N.x < (1.0 - limit) * (N.y + N.z)) { - weight.y = N.y / (N.y + N.z); - weight.y = clamp((weight.y - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0); - weight.z = 1.0 - weight.y; - } - else if (N.y < (1.0 - limit) * (N.x + N.z)) { - weight.x = N.x / (N.x + N.z); - weight.x = clamp((weight.x - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0); - weight.z = 1.0 - weight.x; - } - else { - /* last case, we have a mix between three */ - weight.x = ((2.0 - limit) * N.x + (limit - 1.0)) / (2.0 * limit - 1.0); - weight.y = ((2.0 - limit) * N.y + (limit - 1.0)) / (2.0 * limit - 1.0); - weight.z = ((2.0 - limit) * N.z + (limit - 1.0)) / (2.0 * limit - 1.0); - } + else if (N.y < (1.0 - limit) * (N.x + N.z)) { + weight.y = 0.0; + weight.x = 1.0 - weight.z; } else { - /* Desperate mode, no valid choice anyway, fallback to one side.*/ - weight.x = 1.0; - } - color = vec4(0); - if (weight.x > 0.0) { - vec2 uv = texco.yz; - if(signed_N.x < 0.0) { - uv.x = 1.0 - uv.x; - } - color += weight.x * texture2D(ima, uv); - } - if (weight.y > 0.0) { - vec2 uv = texco.xz; - if(signed_N.y > 0.0) { - uv.x = 1.0 - uv.x; - } - color += weight.y * texture2D(ima, uv); - } - if (weight.z > 0.0) { - vec2 uv = texco.yx; - if(signed_N.z > 0.0) { - uv.x = 1.0 - uv.x; - } - color += weight.z * texture2D(ima, uv); + /* last case, we have a mix between three */ + weight = ((2.0 - limit) * N + (limit - 1.0)) / max(1e-8, 2.0 * limit - 1.0); } + color = weight.x * color1 + weight.y * color2 + weight.z * color3; alpha = color.a; } @@ -3310,7 +2096,6 @@ void node_tex_magic(vec3 co, float scale, float distortion, float depth, out vec fac = (color.x + color.y + color.z) / 3.0; } -#ifdef BIT_OPERATIONS float noise_fade(float t) { return t * t * t * (t * (t * 6.0 - 15.0) + 10.0); @@ -3385,10 +2170,9 @@ float noise_turbulence(vec3 p, float octaves, int hard) float fscale = 1.0; float amp = 1.0; float sum = 0.0; - int i, n; octaves = clamp(octaves, 0.0, 16.0); - n = int(octaves); - for (i = 0; i <= n; i++) { + int n = int(octaves); + for (int i = 0; i <= n; i++) { float t = noise(fscale * p); if (hard != 0) { t = abs(2.0 * t - 1.0); @@ -3398,7 +2182,7 @@ float noise_turbulence(vec3 p, float octaves, int hard) fscale *= 2.0; } float rmd = octaves - floor(octaves); - if (rmd != 0.0) { + if (rmd != 0.0) { float t = noise(fscale * p); if (hard != 0) { t = abs(2.0 * t - 1.0); @@ -3413,11 +2197,9 @@ float noise_turbulence(vec3 p, float octaves, int hard) return sum; } } -#endif // BIT_OPERATIONS void node_tex_noise(vec3 co, float scale, float detail, float distortion, out vec4 color, out float fac) { -#ifdef BIT_OPERATIONS vec3 p = co * scale; int hard = 0; if (distortion != 0.0) { @@ -3433,15 +2215,8 @@ void node_tex_noise(vec3 co, float scale, float detail, float distortion, out ve noise_turbulence(vec3(p.y, p.x, p.z), detail, hard), noise_turbulence(vec3(p.y, p.z, p.x), detail, hard), 1); -#else // BIT_OPERATIONS - color = vec4(1.0); - fac = 1.0; -#endif // BIT_OPERATIONS } - -#ifdef BIT_OPERATIONS - /* Musgrave fBm * * H: fractal increment parameter @@ -3457,9 +2232,8 @@ float noise_musgrave_fBm(vec3 p, float H, float lacunarity, float octaves) float value = 0.0; float pwr = 1.0; float pwHL = pow(lacunarity, -H); - int i; - for (i = 0; i < int(octaves); i++) { + for (int i = 0; i < int(octaves); i++) { value += snoise(p) * pwr; pwr *= pwHL; p *= lacunarity; @@ -3485,9 +2259,8 @@ float noise_musgrave_multi_fractal(vec3 p, float H, float lacunarity, float octa float value = 1.0; float pwr = 1.0; float pwHL = pow(lacunarity, -H); - int i; - for (i = 0; i < int(octaves); i++) { + for (int i = 0; i < int(octaves); i++) { value *= (pwr * snoise(p) + 1.0); pwr *= pwHL; p *= lacunarity; @@ -3513,13 +2286,12 @@ float noise_musgrave_hetero_terrain(vec3 p, float H, float lacunarity, float oct float value, increment, rmd; float pwHL = pow(lacunarity, -H); float pwr = pwHL; - int i; /* first unscaled octave of function; later octaves are scaled */ value = offset + snoise(p); p *= lacunarity; - for (i = 1; i < int(octaves); i++) { + for (int i = 1; i < int(octaves); i++) { increment = (snoise(p) + offset) * pwr * value; value += increment; pwr *= pwHL; @@ -3548,13 +2320,12 @@ float noise_musgrave_hybrid_multi_fractal(vec3 p, float H, float lacunarity, flo float result, signal, weight, rmd; float pwHL = pow(lacunarity, -H); float pwr = pwHL; - int i; result = snoise(p) + offset; weight = gain * result; p *= lacunarity; - for (i = 1; (weight > 0.001f) && (i < int(octaves)); i++) { + for (int i = 1; (weight > 0.001f) && (i < int(octaves)); i++) { if (weight > 1.0) weight = 1.0; @@ -3585,14 +2356,13 @@ float noise_musgrave_ridged_multi_fractal(vec3 p, float H, float lacunarity, flo float result, signal, weight; float pwHL = pow(lacunarity, -H); float pwr = pwHL; - int i; signal = offset - abs(snoise(p)); signal *= signal; result = signal; weight = 1.0; - for (i = 1; i < int(octaves); i++) { + for (int i = 1; i < int(octaves); i++) { p *= lacunarity; weight = clamp(signal * gain, 0.0, 1.0); signal = offset - abs(snoise(p)); @@ -3614,19 +2384,18 @@ float svm_musgrave(int type, float gain, vec3 p) { - if (type == 0 /*NODE_MUSGRAVE_MULTIFRACTAL*/) + if (type == 0 /* NODE_MUSGRAVE_MULTIFRACTAL */) return intensity * noise_musgrave_multi_fractal(p, dimension, lacunarity, octaves); - else if (type == 1 /*NODE_MUSGRAVE_FBM*/) + else if (type == 1 /* NODE_MUSGRAVE_FBM */) return intensity * noise_musgrave_fBm(p, dimension, lacunarity, octaves); - else if (type == 2 /*NODE_MUSGRAVE_HYBRID_MULTIFRACTAL*/) + else if (type == 2 /* NODE_MUSGRAVE_HYBRID_MULTIFRACTAL */) return intensity * noise_musgrave_hybrid_multi_fractal(p, dimension, lacunarity, octaves, offset, gain); - else if (type == 3 /*NODE_MUSGRAVE_RIDGED_MULTIFRACTAL*/) + else if (type == 3 /* NODE_MUSGRAVE_RIDGED_MULTIFRACTAL */) return intensity * noise_musgrave_ridged_multi_fractal(p, dimension, lacunarity, octaves, offset, gain); - else if (type == 4 /*NODE_MUSGRAVE_HETERO_TERRAIN*/) + else if (type == 4 /* NODE_MUSGRAVE_HETERO_TERRAIN */) return intensity * noise_musgrave_hetero_terrain(p, dimension, lacunarity, octaves, offset); return 0.0; } -#endif // #ifdef BIT_OPERATIONS void node_tex_musgrave(vec3 co, float scale, @@ -3639,7 +2408,6 @@ void node_tex_musgrave(vec3 co, out vec4 color, out float fac) { -#ifdef BIT_OPERATIONS fac = svm_musgrave(int(type), dimension, lacunarity, @@ -3648,9 +2416,6 @@ void node_tex_musgrave(vec3 co, 1.0, gain, co * scale); -#else - fac = 1.0; -#endif color = vec4(fac, fac, fac, 1.0); } @@ -3662,7 +2427,6 @@ void node_tex_sky(vec3 co, out vec4 color) void node_tex_voronoi(vec3 co, float scale, float exponent, float coloring, out vec4 color, out float fac) { -#ifdef BIT_OPERATIONS vec3 p = co * scale; int xx, yy, zz, xi, yi, zi; float da[4]; @@ -3727,13 +2491,8 @@ void node_tex_voronoi(vec3 co, float scale, float exponent, float coloring, out color = vec4(cellnoise_color(pa[0]), 1); fac = (color.x + color.y + color.z) * (1.0 / 3.0); } -#else // BIT_OPERATIONS - color = vec4(1.0); - fac = 1.0; -#endif // BIT_OPERATIONS } -#ifdef BIT_OPERATIONS float calc_wave(vec3 p, float distortion, float detail, float detail_scale, int wave_type, int wave_profile) { float n; @@ -3755,22 +2514,16 @@ float calc_wave(vec3 p, float distortion, float detail, float detail_scale, int return (n < 0.0) ? n + 1.0 : n; } } -#endif // BIT_OPERATIONS void node_tex_wave( vec3 co, float scale, float distortion, float detail, float detail_scale, float wave_type, float wave_profile, out vec4 color, out float fac) { -#ifdef BIT_OPERATIONS float f; f = calc_wave(co * scale, distortion, detail, detail_scale, int(wave_type), int(wave_profile)); color = vec4(f, f, f, 1.0); fac = f; -#else // BIT_OPERATIONS - color = vec4(1.0); - fac = 1; -#endif // BIT_OPERATIONS } /* light path */ @@ -3790,13 +2543,21 @@ void node_light_path( out float transparent_depth, out float transmission_depth) { +#ifndef PROBE_CAPTURE is_camera_ray = 1.0; - is_shadow_ray = 0.0; - is_diffuse_ray = 0.0; is_glossy_ray = 0.0; - is_singular_ray = 0.0; + is_diffuse_ray = 0.0; is_reflection_ray = 0.0; is_transmission_ray = 0.0; +#else + is_camera_ray = 0.0; + is_glossy_ray = 1.0; + is_diffuse_ray = 1.0; + is_reflection_ray = 1.0; + is_transmission_ray = 1.0; +#endif + is_shadow_ray = 0.0; + is_singular_ray = 0.0; ray_length = 1.0; ray_depth = 1.0; diffuse_depth = 1.0; @@ -3859,6 +2620,23 @@ void node_bevel(float radius, vec3 N, out vec3 result) result = N; } +void node_hair_info(out float is_strand, out float intercept, out float thickness, out vec3 tangent, out float random) +{ +#ifdef HAIR_SHADER + is_strand = 1.0; + intercept = hairTime; + thickness = hairThickness; + tangent = normalize(hairTangent); + random = wang_hash_noise(uint(hairStrandID)); /* TODO: could be precomputed per strand instead. */ +#else + is_strand = 0.0; + intercept = 0.0; + thickness = 0.0; + tangent = vec3(1.0); + random = 0.0; +#endif +} + void node_displacement_object(float height, float midlevel, float scale, vec3 N, mat4 obmat, out vec3 result) { N = (vec4(N, 0.0) * obmat).xyz; @@ -3895,37 +2673,91 @@ void node_vector_displacement_world(vec4 vector, float midlevel, float scale, ou /* output */ -void node_output_material(vec4 surface, vec4 volume, vec3 displacement, out vec4 result) +void node_output_material(Closure surface, Closure volume, vec3 displacement, out Closure result) { +#ifdef VOLUMETRICS + result = volume; +#else result = surface; +#endif } -void node_output_world(vec4 surface, vec4 volume, out vec4 result) +uniform float backgroundAlpha; + +void node_output_world(Closure surface, Closure volume, out Closure result) { - result = surface; +#ifndef VOLUMETRICS + result.radiance = surface.radiance; + result.opacity = backgroundAlpha; +#else + result = volume; +#endif /* VOLUMETRICS */ } -/* ********************** matcap style render ******************** */ - -void material_preview_matcap(vec4 color, sampler2D ima, vec4 N, vec4 mask, out vec4 result) +#ifndef VOLUMETRICS +/* TODO : clean this ifdef mess */ +/* EEVEE output */ +void world_normals_get(out vec3 N) { - vec3 normal; - vec2 tex; - -#ifndef USE_OPENSUBDIV - /* remap to 0.0 - 1.0 range. This is done because OpenGL 2.0 clamps colors - * between shader stages and we want the full range of the normal */ - normal = vec3(2.0, 2.0, 2.0) * vec3(N.x, N.y, N.z) - vec3(1.0, 1.0, 1.0); - if (normal.z < 0.0) { - normal.z = 0.0; +#ifdef HAIR_SHADER + vec3 B = normalize(cross(worldNormal, hairTangent)); + float cos_theta; + if (hairThicknessRes == 1) { + vec4 rand = texelFetch(utilTex, ivec3(ivec2(gl_FragCoord.xy) % LUT_SIZE, 2.0), 0); + /* Random cosine normal distribution on the hair surface. */ + cos_theta = rand.x * 2.0 - 1.0; + } + else { + /* Shade as a cylinder. */ + cos_theta = hairThickTime / hairThickness; } - normal = normalize(normal); + float sin_theta = sqrt(max(0.0, 1.0f - cos_theta*cos_theta));; + N = normalize(worldNormal * sin_theta + B * cos_theta); #else - normal = inpt.v.normal; - mask = vec4(1.0, 1.0, 1.0, 1.0); + N = gl_FrontFacing ? worldNormal : -worldNormal; #endif +} + +void node_eevee_specular( + vec4 diffuse, vec4 specular, float roughness, vec4 emissive, float transp, vec3 normal, + float clearcoat, float clearcoat_roughness, vec3 clearcoat_normal, + float occlusion, float ssr_id, out Closure result) +{ + vec3 out_diff, out_spec, ssr_spec; + eevee_closure_default(normal, diffuse.rgb, specular.rgb, int(ssr_id), roughness, occlusion, + out_diff, out_spec, ssr_spec); - tex.x = 0.5 + 0.49 * normal.x; - tex.y = 0.5 + 0.49 * normal.y; - result = texture2D(ima, tex) * mask; + vec3 vN = normalize(mat3(ViewMatrix) * normal); + result = CLOSURE_DEFAULT; + result.radiance = out_diff * diffuse.rgb + out_spec + emissive.rgb; + result.opacity = 1.0 - transp; + result.ssr_data = vec4(ssr_spec, roughness); + result.ssr_normal = normal_encode(vN, viewCameraVec); + result.ssr_id = int(ssr_id); } + +void node_shader_to_rgba(Closure cl, out vec4 outcol, out float outalpha) +{ + vec4 spec_accum = vec4(0.0); + if (ssrToggle && cl.ssr_id == outputSsrId) { + vec3 V = cameraVec; + vec3 vN = normal_decode(cl.ssr_normal, viewCameraVec); + vec3 N = transform_direction(ViewMatrixInverse, vN); + float roughness = cl.ssr_data.a; + float roughnessSquared = max(1e-3, roughness * roughness); + fallback_cubemap(N, V, worldPosition, viewPosition, roughness, roughnessSquared, spec_accum); + } + + outalpha = cl.opacity; + outcol = vec4((spec_accum.rgb * cl.ssr_data.rgb) + cl.radiance, 1.0); + +# ifdef USE_SSS +# ifdef USE_SSS_ALBEDO + outcol.rgb += cl.sss_data.rgb * cl.sss_albedo; +# else + outcol.rgb += cl.sss_data.rgb; +# endif +# endif +} + +#endif /* VOLUMETRICS */ diff --git a/source/blender/gpu/shaders/gpu_shader_point_uniform_color_aa_frag.glsl b/source/blender/gpu/shaders/gpu_shader_point_uniform_color_aa_frag.glsl new file mode 100644 index 00000000000..fef81cf58fe --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_point_uniform_color_aa_frag.glsl @@ -0,0 +1,24 @@ + +uniform vec4 color; + +in vec2 radii; +out vec4 fragColor; + +void main() { + float dist = length(gl_PointCoord - vec2(0.5)); + +// transparent outside of point +// --- 0 --- +// smooth transition +// --- 1 --- +// pure point color +// ... +// dist = 0 at center of point + + fragColor.rgb = color.rgb; + fragColor.a = mix(color.a, 0.0, smoothstep(radii[1], radii[0], dist)); + + if (fragColor.a == 0.0) { + discard; + } +} diff --git a/source/blender/gpu/shaders/gpu_shader_point_uniform_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_point_uniform_color_frag.glsl new file mode 100644 index 00000000000..852c76fcb26 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_point_uniform_color_frag.glsl @@ -0,0 +1,17 @@ + +uniform vec4 color; + +out vec4 fragColor; + +void main() +{ + vec2 centered = gl_PointCoord - vec2(0.5); + float dist_squared = dot(centered, centered); + const float rad_squared = 0.25; + + // round point with jaggy edges + if (dist_squared > rad_squared) + discard; + + fragColor = color; +} diff --git a/source/blender/gpu/shaders/gpu_shader_point_uniform_color_outline_aa_frag.glsl b/source/blender/gpu/shaders/gpu_shader_point_uniform_color_outline_aa_frag.glsl new file mode 100644 index 00000000000..eae5ee633ae --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_point_uniform_color_outline_aa_frag.glsl @@ -0,0 +1,36 @@ + +uniform vec4 color; +uniform vec4 outlineColor; + +in vec4 radii; +out vec4 fragColor; + +void main() { + float dist = length(gl_PointCoord - vec2(0.5)); + +// transparent outside of point +// --- 0 --- +// smooth transition +// --- 1 --- +// pure outline color +// --- 2 --- +// smooth transition +// --- 3 --- +// pure point color +// ... +// dist = 0 at center of point + + float midStroke = 0.5 * (radii[1] + radii[2]); + + if (dist > midStroke) { + fragColor.rgb = outlineColor.rgb; + fragColor.a = mix(outlineColor.a, 0.0, smoothstep(radii[1], radii[0], dist)); + } + else { + fragColor = mix(color, outlineColor, smoothstep(radii[3], radii[2], dist)); + } + + if (fragColor.a == 0.0) { + discard; + } +} diff --git a/source/blender/gpu/shaders/gpu_shader_point_varying_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_point_varying_color_frag.glsl new file mode 100644 index 00000000000..2d2724bb686 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_point_varying_color_frag.glsl @@ -0,0 +1,16 @@ + +in vec4 finalColor; +out vec4 fragColor; + +void main() +{ + vec2 centered = gl_PointCoord - vec2(0.5); + float dist_squared = dot(centered, centered); + const float rad_squared = 0.25; + + // round point with jaggy edges + if (dist_squared > rad_squared) + discard; + + fragColor = finalColor; +} diff --git a/source/blender/gpu/shaders/gpu_shader_point_varying_color_outline_aa_frag.glsl b/source/blender/gpu/shaders/gpu_shader_point_varying_color_outline_aa_frag.glsl new file mode 100644 index 00000000000..9b7d4bfc6d6 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_point_varying_color_outline_aa_frag.glsl @@ -0,0 +1,31 @@ + +uniform vec4 outlineColor; + +in vec4 radii; +in vec4 fillColor; +out vec4 fragColor; + +void main() { + float dist = length(gl_PointCoord - vec2(0.5)); + +// transparent outside of point +// --- 0 --- +// smooth transition +// --- 1 --- +// pure outline color +// --- 2 --- +// smooth transition +// --- 3 --- +// pure fill color +// ... +// dist = 0 at center of point + + float midStroke = 0.5 * (radii[1] + radii[2]); + + if (dist > midStroke) { + fragColor.rgb = outlineColor.rgb; + fragColor.a = mix(outlineColor.a, 0.0, smoothstep(radii[1], radii[0], dist)); + } + else + fragColor = mix(fillColor, outlineColor, smoothstep(radii[3], radii[2], dist)); +} diff --git a/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl b/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl index b485d2cce86..78241a798a2 100644 --- a/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl @@ -1,16 +1,19 @@ uniform vec2 ScaleU; uniform sampler2D textureSource; +in vec2 texCoord_interp; +out vec4 fragColor; + void main() { vec4 color = vec4(0.0); - color += texture2D(textureSource, gl_TexCoord[0].st + vec2(-3.0 * ScaleU.x, -3.0 * ScaleU.y)) * 0.015625; - color += texture2D(textureSource, gl_TexCoord[0].st + vec2(-2.0 * ScaleU.x, -2.0 * ScaleU.y)) * 0.09375; - color += texture2D(textureSource, gl_TexCoord[0].st + vec2(-1.0 * ScaleU.x, -1.0 * ScaleU.y)) * 0.234375; - color += texture2D(textureSource, gl_TexCoord[0].st + vec2(0.0, 0.0)) * 0.3125; - color += texture2D(textureSource, gl_TexCoord[0].st + vec2(1.0 * ScaleU.x, 1.0 * ScaleU.y)) * 0.234375; - color += texture2D(textureSource, gl_TexCoord[0].st + vec2(2.0 * ScaleU.x, 2.0 * ScaleU.y)) * 0.09375; - color += texture2D(textureSource, gl_TexCoord[0].st + vec2(3.0 * ScaleU.x, 3.0 * ScaleU.y)) * 0.015625; + color += texture(textureSource, texCoord_interp.st + vec2(-3.0 * ScaleU.x, -3.0 * ScaleU.y)) * 0.015625; + color += texture(textureSource, texCoord_interp.st + vec2(-2.0 * ScaleU.x, -2.0 * ScaleU.y)) * 0.09375; + color += texture(textureSource, texCoord_interp.st + vec2(-1.0 * ScaleU.x, -1.0 * ScaleU.y)) * 0.234375; + color += texture(textureSource, texCoord_interp.st + vec2(0.0, 0.0)) * 0.3125; + color += texture(textureSource, texCoord_interp.st + vec2(1.0 * ScaleU.x, 1.0 * ScaleU.y)) * 0.234375; + color += texture(textureSource, texCoord_interp.st + vec2(2.0 * ScaleU.x, 2.0 * ScaleU.y)) * 0.09375; + color += texture(textureSource, texCoord_interp.st + vec2(3.0 * ScaleU.x, 3.0 * ScaleU.y)) * 0.015625; - gl_FragColor = color; + fragColor = color; } 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 5d00108b052..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,6 +1,14 @@ +out vec2 texCoord_interp; + void main() { - gl_Position = ftransform(); - gl_TexCoord[0] = gl_MultiTexCoord0; + 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_simple_lighting_frag.glsl b/source/blender/gpu/shaders/gpu_shader_simple_lighting_frag.glsl new file mode 100644 index 00000000000..d65768eff4d --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_simple_lighting_frag.glsl @@ -0,0 +1,18 @@ + +#ifndef USE_INSTANCE_COLOR +uniform vec4 color; +#endif +uniform vec3 light; + +in vec3 normal; +#ifdef USE_INSTANCE_COLOR +flat in vec4 finalColor; +# define color finalColor +#endif +out vec4 fragColor; + +void main() +{ + fragColor = color; + fragColor.xyz *= clamp(dot(normalize(normal), light), 0.0, 1.0); +} diff --git a/source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_alpha_frag.glsl b/source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_alpha_frag.glsl new file mode 100644 index 00000000000..6b13f408c84 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_alpha_frag.glsl @@ -0,0 +1,14 @@ + +uniform vec3 light; +uniform float alpha; +uniform float global; + +in vec3 normal; +in vec4 finalColor; +out vec4 fragColor; + +void main() +{ + fragColor = finalColor * (global + (1.0 - global) * max(0.0, dot(normalize(normal), light))); + fragColor.a = alpha; +} diff --git a/source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_frag.glsl new file mode 100644 index 00000000000..58c5f292647 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_frag.glsl @@ -0,0 +1,16 @@ + +uniform vec3 light; + +#ifdef USE_FLAT_NORMAL +flat in vec3 normal; +flat in vec4 finalColor; +#else +in vec3 normal; +in vec4 finalColor; +#endif +out vec4 fragColor; + +void main() +{ + fragColor = finalColor * max(0.0, dot(normalize(normal), light)); +} diff --git a/source/blender/gpu/shaders/gpu_shader_smoke_frag.glsl b/source/blender/gpu/shaders/gpu_shader_smoke_frag.glsl index 6ded453225e..b57bd5b6a37 100644 --- a/source/blender/gpu/shaders/gpu_shader_smoke_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_smoke_frag.glsl @@ -1,5 +1,6 @@ -varying vec3 coords; +in vec3 coords; +out vec4 fragColor; uniform vec3 active_color; uniform float step_size; @@ -16,7 +17,7 @@ uniform sampler3D color_band_texture; void main() { /* compute color and density from volume texture */ - vec4 soot = texture3D(soot_texture, coords); + vec4 soot = texture(soot_texture, coords); #ifndef USE_COBA vec3 soot_color; @@ -24,7 +25,7 @@ void main() soot_color = active_color * soot.rgb / soot.a; } else { - soot_color = vec3(0, 0, 0); + soot_color = vec3(0); } float soot_density = density_scale * soot.a; @@ -33,16 +34,14 @@ void main() float soot_alpha = 1.0 - soot_transmittance; /* shade */ - float shadow = texture3D(shadow_texture, coords).r; + float shadow = texture(shadow_texture, coords).r; soot_color *= soot_transmittance * shadow; /* premultiply alpha */ - vec4 color = vec4(soot_alpha * soot_color, soot_alpha); + fragColor = vec4(soot_alpha * soot_color, soot_alpha); #else - float color_band = texture3D(color_band_texture, coords).r; - vec4 transfer_function = texture1D(transfer_texture, color_band); - vec4 color = transfer_function * density_scale; + float color_band = texture(color_band_texture, coords).r; + vec4 transfer_function = texture(transfer_texture, color_band); + fragColor = transfer_function * density_scale; #endif - - gl_FragColor = color; } diff --git a/source/blender/gpu/shaders/gpu_shader_smoke_vert.glsl b/source/blender/gpu/shaders/gpu_shader_smoke_vert.glsl index 297486ae26a..8c30e9baf9e 100644 --- a/source/blender/gpu/shaders/gpu_shader_smoke_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_smoke_vert.glsl @@ -1,5 +1,7 @@ -varying vec3 coords; +uniform mat4 ModelViewProjectionMatrix; + +out vec3 coords; uniform vec3 min_location; uniform vec3 invsize; @@ -7,6 +9,7 @@ uniform vec3 ob_sizei; void main() { - gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_Vertex.xyz * ob_sizei, 1.0); + // TODO: swap gl_Vertex for vec3 pos, update smoke setup code + gl_Position = ModelViewProjectionMatrix * vec4(gl_Vertex.xyz * ob_sizei, 1.0); coords = (gl_Vertex.xyz - min_location) * invsize; } diff --git a/source/blender/gpu/shaders/gpu_shader_text_frag.glsl b/source/blender/gpu/shaders/gpu_shader_text_frag.glsl new file mode 100644 index 00000000000..fbfa4cfcc9d --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_text_frag.glsl @@ -0,0 +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 + 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 new file mode 100644 index 00000000000..338156f5b68 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_text_vert.glsl @@ -0,0 +1,17 @@ + +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() +{ + pos_rect = pos; + tex_rect = tex; + color = col; +} diff --git a/source/blender/gpu/shaders/gpu_shader_uniform_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_uniform_color_frag.glsl new file mode 100644 index 00000000000..118a661863d --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_uniform_color_frag.glsl @@ -0,0 +1,21 @@ + +#if defined(USE_COLOR_U32) +uniform uint color; +#else +uniform vec4 color; +#endif + +out vec4 fragColor; + +void main() +{ +#if defined(USE_COLOR_U32) + fragColor = vec4( + ((color ) & uint(0xFF)) * (1.0f / 255.0f), + ((color >> 8) & uint(0xFF)) * (1.0f / 255.0f), + ((color >> 16) & uint(0xFF)) * (1.0f / 255.0f), + ((color >> 24) ) * (1.0f / 255.0f)); +#else + fragColor = color; +#endif +} diff --git a/source/blender/gpu/shaders/gpu_shader_vertex.glsl b/source/blender/gpu/shaders/gpu_shader_vertex.glsl index 2c5bcd54b33..e297c242044 100644 --- a/source/blender/gpu/shaders/gpu_shader_vertex.glsl +++ b/source/blender/gpu/shaders/gpu_shader_vertex.glsl @@ -1,3 +1,8 @@ + +uniform mat4 ModelViewMatrix; +uniform mat4 ProjectionMatrix; +uniform mat3 NormalMatrix; + #ifdef USE_OPENSUBDIV in vec3 normal; in vec4 position; @@ -7,8 +12,8 @@ out block { } outpt; #endif -varying vec3 varposition; -varying vec3 varnormal; +out vec3 varposition; +out vec3 varnormal; #ifdef CLIP_WORKAROUND varying float gl_ClipDistance[6]; @@ -42,11 +47,7 @@ void srgb_to_linearrgb(vec4 col_from, out vec4 col_to) bool is_srgb(int info) { -#ifdef USE_NEW_SHADING return (info == 1)? true: false; -#else - return false; -#endif } void set_var_from_attr(float attr, int info, out float var) @@ -89,11 +90,11 @@ void main() vec3 normal = gl_Normal; #endif - vec4 co = gl_ModelViewMatrix * position; + vec4 co = ModelViewMatrix * position; varposition = co.xyz; - varnormal = normalize(gl_NormalMatrix * normal); - gl_Position = gl_ProjectionMatrix * co; + varnormal = normalize(NormalMatrix * normal); + gl_Position = ProjectionMatrix * co; #ifdef CLIP_WORKAROUND int i; diff --git a/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl b/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl index a81d2bcef69..6f97ef8abef 100644 --- a/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl +++ b/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl @@ -1,7 +1,6 @@ -varying vec3 varposition; -varying vec3 varnormal; - +out vec3 varposition; +out vec3 varnormal; /* Color, keep in sync with: gpu_shader_vertex.glsl */ @@ -30,11 +29,7 @@ void srgb_to_linearrgb(vec4 col_from, out vec4 col_to) bool is_srgb(int info) { -#ifdef USE_NEW_SHADING return (info == 1)? true: false; -#else - return false; -#endif } void set_var_from_attr(float attr, int info, out float var) diff --git a/source/blender/gpu/shaders/gpu_shader_vsm_store_frag.glsl b/source/blender/gpu/shaders/gpu_shader_vsm_store_frag.glsl index 3761bf350eb..6aad94bbf59 100644 --- a/source/blender/gpu/shaders/gpu_shader_vsm_store_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_vsm_store_frag.glsl @@ -2,7 +2,8 @@ * This fragment shader was initially found at http://fabiensanglard.net/shadowmappingVSM/index.php */ -varying vec4 v_position; +in vec4 v_position; +out vec4 fragColor; void main() { @@ -17,5 +18,6 @@ void main() float dy = dFdy(depth); moment2 += 0.25 * (dx * dx + dy * dy); - gl_FragColor = vec4(moment1, moment2, 0.0, 0.0); + fragColor = vec4(moment1, moment2, 0.0, 0.0); + // TODO: write to a 2-component target --^ } diff --git a/source/blender/gpu/shaders/gpu_shader_vsm_store_vert.glsl b/source/blender/gpu/shaders/gpu_shader_vsm_store_vert.glsl index 224c3e78adc..def835156f7 100644 --- a/source/blender/gpu/shaders/gpu_shader_vsm_store_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_vsm_store_vert.glsl @@ -1,7 +1,10 @@ -varying vec4 v_position; + +uniform mat4 ModelViewProjectionMatrix; + +out vec4 v_position; void main() { - gl_Position = ftransform(); + gl_Position = ModelViewProjectionMatrix * gl_Vertex; v_position = gl_Position; } |