diff options
Diffstat (limited to 'source/blender/gpu/shaders')
23 files changed, 249 insertions, 477 deletions
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 deleted file mode 100644 index 181b1bf3fad..00000000000 --- a/source/blender/gpu/shaders/gpu_shader_2D_smooth_color_dithered_frag.glsl +++ /dev/null @@ -1,18 +0,0 @@ - -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 index 4f275c5b220..1333c00682c 100644 --- a/source/blender/gpu/shaders/gpu_shader_2D_smooth_color_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_2D_smooth_color_frag.glsl @@ -5,4 +5,5 @@ out vec4 fragColor; void main() { fragColor = finalColor; + fragColor = blender_srgb_to_framebuffer_space(fragColor); } 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 index 18f58d52f32..bdc87baf924 100644 --- a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl @@ -35,4 +35,6 @@ void main() if (butCo > 0.0) { fragColor.a = 1.0; } + + fragColor = blender_srgb_to_framebuffer_space(fragColor); } 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 index 0b2bc08944e..d7cc851556b 100644 --- a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl @@ -12,42 +12,15 @@ /* 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)); +const vec2 cornervec[9] = vec2[9](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)); /* 4bits for jitter id */ #define JIT_OFS 6u @@ -189,26 +162,26 @@ 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; + vec2 v = cornervec[vofs]; /* Scale by corner radius */ v *= roundCorners[cflag] * ((is_inner) ? radsi : rads); - - /* Position to corner */ + /* Flip in the right direction and osition to corner */ vec4 rct = (is_inner) ? recti : rect; if (cflag == BOTTOM_LEFT) { v += rct.xz; } else if (cflag == BOTTOM_RIGHT) { + v = vec2(-v.y, v.x); v += rct.yz; } else if (cflag == TOP_RIGHT) { + v = -v; v += rct.yw; } else /* (cflag == TOP_LEFT) */ { + v = vec2(v.y, -v.x); v += rct.xw; } @@ -238,7 +211,7 @@ vec2 do_widget(void) } bool is_emboss = (vflag & EMBOSS_FLAG) != 0u; - v.y -= (is_emboss) ? 1.0f : 0.0; + v.y -= (is_emboss) ? (recti.z - rect.z) : 0.0; return v; } 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 deleted file mode 100644 index 7fa571343a2..00000000000 --- a/source/blender/gpu/shaders/gpu_shader_3D_normal_smooth_color_vert.glsl +++ /dev/null @@ -1,22 +0,0 @@ - -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_polyline_frag.glsl b/source/blender/gpu/shaders/gpu_shader_3D_polyline_frag.glsl new file mode 100644 index 00000000000..9c6b109d659 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_3D_polyline_frag.glsl @@ -0,0 +1,24 @@ + +uniform float lineWidth; + +in vec4 finalColor; +noperspective in float smoothline; +#ifdef CLIP +in float clip; +#endif + +out vec4 fragColor; + +#define SMOOTH_WIDTH 1.0 + +void main() +{ +#ifdef CLIP + if (clip < 0.0) { + discard; + } +#endif + fragColor = finalColor; + fragColor.a *= clamp((lineWidth + SMOOTH_WIDTH) * 0.5 - abs(smoothline), 0.0, 1.0); + fragColor = blender_srgb_to_framebuffer_space(fragColor); +} diff --git a/source/blender/gpu/shaders/gpu_shader_3D_polyline_geom.glsl b/source/blender/gpu/shaders/gpu_shader_3D_polyline_geom.glsl new file mode 100644 index 00000000000..b28205b349e --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_3D_polyline_geom.glsl @@ -0,0 +1,68 @@ + +layout(lines) in; +layout(triangle_strip, max_vertices = 4) out; + +uniform vec4 color; +uniform vec2 viewportSize; +uniform float lineWidth; + +#if !defined(UNIFORM) +in vec4 finalColor_g[]; +#endif + +#ifdef CLIP +in float clip_g[]; +out float clip; +#endif + +out vec4 finalColor; +noperspective out float smoothline; + +#define SMOOTH_WIDTH 1.0 + +void do_vertex(const int i, vec2 ofs) +{ +#if defined(UNIFORM) + finalColor = color; + +#elif defined(FLAT) + finalColor = finalColor_g[0]; + +#elif defined(SMOOTH) + finalColor = finalColor_g[i]; +#endif + +#ifdef CLIP + clip = clip_g[i]; +#endif + + smoothline = (lineWidth + SMOOTH_WIDTH) * 0.5; + gl_Position = gl_in[i].gl_Position; + gl_Position.xy += ofs * gl_Position.w; + EmitVertex(); + + smoothline = -(lineWidth + SMOOTH_WIDTH) * 0.5; + gl_Position = gl_in[i].gl_Position; + gl_Position.xy -= ofs * gl_Position.w; + EmitVertex(); +} + +void main(void) +{ + vec2 p0 = gl_in[0].gl_Position.xy / gl_in[0].gl_Position.w; + vec2 p1 = gl_in[1].gl_Position.xy / gl_in[1].gl_Position.w; + vec2 e = normalize((p1 - p0) * viewportSize.xy); +#if 0 /* Hard turn when line direction changes quadrant. */ + e = abs(e); + vec2 ofs = (e.x > e.y) ? vec2(0.0, 1.0 / e.x) : vec2(1.0 / e.y, 0.0); +#else /* Use perpendicular direction. */ + vec2 ofs = vec2(-e.y, e.x); +#endif + ofs /= viewportSize.xy; + ofs *= lineWidth + SMOOTH_WIDTH; + + do_vertex(0, ofs); + do_vertex(1, ofs); + + EndPrimitive(); +} diff --git a/source/blender/gpu/shaders/gpu_shader_3D_polyline_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_polyline_vert.glsl new file mode 100644 index 00000000000..28aa2a4ccc6 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_3D_polyline_vert.glsl @@ -0,0 +1,28 @@ + +uniform mat4 ModelViewProjectionMatrix; +uniform mat4 ModelMatrix; +uniform vec4 ClipPlane; + +in vec3 pos; + +#if !defined(UNIFORM) +in vec4 color; + +out vec4 finalColor_g; +#endif + +#ifdef CLIP +out float clip_g; +#endif + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); +#if !defined(UNIFORM) + finalColor_g = color; +#endif + +#ifdef CLIP + clip_g = dot(ModelMatrix * vec4(pos, 1.0), ClipPlane); +#endif +} 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 index 7bd44ba9b88..3a2d96c9929 100644 --- a/source/blender/gpu/shaders/gpu_shader_3D_smooth_color_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_3D_smooth_color_frag.glsl @@ -5,4 +5,5 @@ out vec4 fragColor; void main() { fragColor = finalColor; + fragColor = blender_srgb_to_framebuffer_space(fragColor); } diff --git a/source/blender/gpu/shaders/gpu_shader_colorspace_lib.glsl b/source/blender/gpu/shaders/gpu_shader_colorspace_lib.glsl new file mode 100644 index 00000000000..aae659516bb --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_colorspace_lib.glsl @@ -0,0 +1,16 @@ + +/* Undefine the macro that avoids compilation errors. */ +#undef blender_srgb_to_framebuffer_space + +uniform bool srgbTarget = false; + +vec4 blender_srgb_to_framebuffer_space(vec4 color) +{ + if (srgbTarget) { + vec3 c = max(color.rgb, vec3(0.0)); + vec3 c1 = c * (1.0 / 12.92); + vec3 c2 = pow((c + 0.055) * (1.0 / 1.055), vec3(2.4)); + color.rgb = mix(c1, c2, step(vec3(0.04045), c)); + } + return color; +} diff --git a/source/blender/gpu/shaders/gpu_shader_flat_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_flat_color_frag.glsl index 6c214534812..99d8b6ab685 100644 --- a/source/blender/gpu/shaders/gpu_shader_flat_color_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_flat_color_frag.glsl @@ -5,4 +5,5 @@ out vec4 fragColor; void main() { fragColor = finalColor; + fragColor = blender_srgb_to_framebuffer_space(fragColor); } 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 deleted file mode 100644 index 0f2749362b9..00000000000 --- a/source/blender/gpu/shaders/gpu_shader_image_depth_copy_frag.glsl +++ /dev/null @@ -1,12 +0,0 @@ - -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 deleted file mode 100644 index 017b21076c8..00000000000 --- a/source/blender/gpu/shaders/gpu_shader_image_depth_linear_frag.glsl +++ /dev/null @@ -1,16 +0,0 @@ - -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_multisample_resolve_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_multisample_resolve_frag.glsl deleted file mode 100644 index ca425374a1b..00000000000 --- a/source/blender/gpu/shaders/gpu_shader_image_multisample_resolve_frag.glsl +++ /dev/null @@ -1,119 +0,0 @@ - -uniform sampler2DMS depthMulti; -uniform sampler2DMS colorMulti; - -out vec4 fragColor; - -#if SAMPLES > 16 -# error "Too many samples" -#endif - -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(0.5); - 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); - -#ifdef USE_DEPTH - /* 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 -#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 - -#ifdef USE_DEPTH -# if SAMPLES > 8 - d1 = min(d1, min(d3, d4)); -# endif -# if SAMPLES > 4 - d1 = min(d1, d2); - d1 = min(d1, d2); -# endif -# if SAMPLES > 2 - d1.xy = min(d1.xy, d1.zw); -# endif - gl_FragDepth = min(d1.x, d1.y); -#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_simple_lighting_smooth_color_alpha_frag.glsl b/source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_alpha_frag.glsl deleted file mode 100644 index 2ed99be2bcf..00000000000 --- a/source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_alpha_frag.glsl +++ /dev/null @@ -1,14 +0,0 @@ - -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 deleted file mode 100644 index 738b0d84e51..00000000000 --- a/source/blender/gpu/shaders/gpu_shader_simple_lighting_smooth_color_frag.glsl +++ /dev/null @@ -1,16 +0,0 @@ - -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_uniform_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_uniform_color_frag.glsl index cfa82572e87..2033401db67 100644 --- a/source/blender/gpu/shaders/gpu_shader_uniform_color_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_uniform_color_frag.glsl @@ -17,8 +17,5 @@ void main() #else fragColor = color; #endif - -#if defined(USE_BACKGROUND) - gl_FragDepth = 1.0; -#endif + fragColor = blender_srgb_to_framebuffer_space(fragColor); } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_fractal_noise.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_fractal_noise.glsl index 701b07b4aae..f25691c1a83 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_fractal_noise.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_fractal_noise.glsl @@ -1,111 +1,115 @@ /* The fractal_noise functions are all exactly the same except for the input type. */ -float fractal_noise(float p, float octaves) +float fractal_noise(float p, float octaves, float roughness) { float fscale = 1.0; float amp = 1.0; + float maxamp = 0.0; float sum = 0.0; octaves = clamp(octaves, 0.0, 16.0); int n = int(octaves); for (int i = 0; i <= n; i++) { float t = noise(fscale * p); sum += t * amp; - amp *= 0.5; + maxamp += amp; + amp *= clamp(roughness, 0.0, 1.0); fscale *= 2.0; } float rmd = octaves - floor(octaves); if (rmd != 0.0) { float t = noise(fscale * p); float sum2 = sum + t * amp; - sum *= (float(1 << n) / float((1 << (n + 1)) - 1)); - sum2 *= (float(1 << (n + 1)) / float((1 << (n + 2)) - 1)); + sum /= maxamp; + sum2 /= maxamp + amp; return (1.0 - rmd) * sum + rmd * sum2; } else { - sum *= (float(1 << n) / float((1 << (n + 1)) - 1)); - return sum; + return sum / maxamp; } } /* The fractal_noise functions are all exactly the same except for the input type. */ -float fractal_noise(vec2 p, float octaves) +float fractal_noise(vec2 p, float octaves, float roughness) { float fscale = 1.0; float amp = 1.0; + float maxamp = 0.0; float sum = 0.0; octaves = clamp(octaves, 0.0, 16.0); int n = int(octaves); for (int i = 0; i <= n; i++) { float t = noise(fscale * p); sum += t * amp; - amp *= 0.5; + maxamp += amp; + amp *= clamp(roughness, 0.0, 1.0); fscale *= 2.0; } float rmd = octaves - floor(octaves); if (rmd != 0.0) { float t = noise(fscale * p); float sum2 = sum + t * amp; - sum *= (float(1 << n) / float((1 << (n + 1)) - 1)); - sum2 *= (float(1 << (n + 1)) / float((1 << (n + 2)) - 1)); + sum /= maxamp; + sum2 /= maxamp + amp; return (1.0 - rmd) * sum + rmd * sum2; } else { - sum *= (float(1 << n) / float((1 << (n + 1)) - 1)); - return sum; + return sum / maxamp; } } /* The fractal_noise functions are all exactly the same except for the input type. */ -float fractal_noise(vec3 p, float octaves) +float fractal_noise(vec3 p, float octaves, float roughness) { float fscale = 1.0; float amp = 1.0; + float maxamp = 0.0; float sum = 0.0; octaves = clamp(octaves, 0.0, 16.0); int n = int(octaves); for (int i = 0; i <= n; i++) { float t = noise(fscale * p); sum += t * amp; - amp *= 0.5; + maxamp += amp; + amp *= clamp(roughness, 0.0, 1.0); fscale *= 2.0; } float rmd = octaves - floor(octaves); if (rmd != 0.0) { float t = noise(fscale * p); float sum2 = sum + t * amp; - sum *= (float(1 << n) / float((1 << (n + 1)) - 1)); - sum2 *= (float(1 << (n + 1)) / float((1 << (n + 2)) - 1)); + sum /= maxamp; + sum2 /= maxamp + amp; return (1.0 - rmd) * sum + rmd * sum2; } else { - sum *= (float(1 << n) / float((1 << (n + 1)) - 1)); - return sum; + return sum / maxamp; } } /* The fractal_noise functions are all exactly the same except for the input type. */ -float fractal_noise(vec4 p, float octaves) +float fractal_noise(vec4 p, float octaves, float roughness) { float fscale = 1.0; float amp = 1.0; + float maxamp = 0.0; float sum = 0.0; octaves = clamp(octaves, 0.0, 16.0); int n = int(octaves); for (int i = 0; i <= n; i++) { float t = noise(fscale * p); sum += t * amp; - amp *= 0.5; + maxamp += amp; + amp *= clamp(roughness, 0.0, 1.0); fscale *= 2.0; } float rmd = octaves - floor(octaves); if (rmd != 0.0) { float t = noise(fscale * p); float sum2 = sum + t * amp; - sum *= (float(1 << n) / float((1 << (n + 1)) - 1)); - sum2 *= (float(1 << (n + 1)) / float((1 << (n + 2)) - 1)); + sum /= maxamp; + sum2 /= maxamp + amp; return (1.0 - rmd) * sum + rmd * sum2; } else { - sum *= (float(1 << n) / float((1 << (n + 1)) - 1)); - return sum; + return sum / maxamp; } } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_output_material.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_output_material.glsl index 62f76d46088..4cb00c15b78 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_output_material.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_output_material.glsl @@ -1,8 +1,16 @@ -void node_output_material(Closure surface, Closure volume, vec3 displacement, out Closure result) +void node_output_material( + Closure surface, Closure volume, vec3 displacement, float alpha_threshold, out Closure result) { #ifdef VOLUMETRICS result = volume; #else result = surface; +# if defined(USE_ALPHA_HASH) + /* Alpha clip emulation. */ + if (alpha_threshold >= 0.0) { + float alpha = saturate(1.0 - avg(result.transmittance)); + result.transmittance = vec3(step(alpha, alpha_threshold)); + } +# endif #endif } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_tex_environment.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_tex_environment.glsl index 9bd36f8a757..20a65f23c05 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_tex_environment.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_tex_environment.glsl @@ -15,16 +15,11 @@ void node_tex_environment_texco(vec3 viewvec, out vec3 worldvec) #endif } -void node_tex_environment_equirectangular(vec3 co, float clamp_size, sampler2D ima, out vec3 uv) +void node_tex_environment_equirectangular(vec3 co, out vec3 uv) { vec3 nco = normalize(co); uv.x = -atan(nco.y, nco.x) / (2.0 * M_PI) + 0.5; uv.y = atan(nco.z, hypot(nco.x, nco.y)) / M_PI + 0.5; - - /* Fix pole bleeding */ - float half_height = clamp_size / float(textureSize(ima, 0).y); - uv.y = clamp(uv.y, half_height, 1.0 - half_height); - uv.z = 0.0; } void node_tex_environment_mirror_ball(vec3 co, out vec3 uv) diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_tex_image.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_tex_image.glsl index c39bec8ac64..df949f7358b 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_tex_image.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_tex_image.glsl @@ -54,19 +54,6 @@ void node_tex_image_linear(vec3 co, sampler2D ima, out vec4 color, out float alp alpha = color.a; } -void node_tex_image_linear_no_mip(vec3 co, sampler2D ima, out vec4 color, out float alpha) -{ - color = safe_color(textureLod(ima, co.xy, 0.0)); - alpha = color.a; -} - -void node_tex_image_nearest(vec3 co, sampler2D ima, out vec4 color, out float alpha) -{ - ivec2 pix = ivec2(fract(co.xy) * textureSize(ima, 0).xy); - color = safe_color(texelFetch(ima, pix, 0)); - alpha = color.a; -} - /** \param f: Signed distance to texel center. */ void cubic_bspline_coefs(vec2 f, out vec2 w0, out vec2 w1, out vec2 w2, out vec2 w3) { @@ -79,8 +66,7 @@ void cubic_bspline_coefs(vec2 f, out vec2 w0, out vec2 w1, out vec2 w2, out vec2 w2 = 1.0 - w0 - w1 - w3; } -void node_tex_image_cubic_ex( - vec3 co, sampler2D ima, float do_extend, out vec4 color, out float alpha) +void node_tex_image_cubic(vec3 co, sampler2D ima, out vec4 color, out float alpha) { vec2 tex_size = vec2(textureSize(ima, 0).xy); @@ -101,9 +87,6 @@ void node_tex_image_cubic_ex( final_co.xy = tc - 1.0 + f0; final_co.zw = tc + 1.0 + f1; - if (do_extend == 1.0) { - final_co = clamp(final_co, vec4(0.5), tex_size.xyxy - 0.5); - } final_co /= tex_size.xyxy; color = safe_color(textureLod(ima, final_co.xy, 0.0)) * s0.x * s0.y; @@ -136,22 +119,6 @@ void node_tex_image_cubic_ex( alpha = color.a; } -void node_tex_image_cubic(vec3 co, sampler2D ima, out vec4 color, out float alpha) -{ - node_tex_image_cubic_ex(co, ima, 0.0, color, alpha); -} - -void node_tex_image_cubic_extend(vec3 co, sampler2D ima, out vec4 color, out float alpha) -{ - node_tex_image_cubic_ex(co, ima, 1.0, color, alpha); -} - -void node_tex_image_smart(vec3 co, sampler2D ima, out vec4 color, out float alpha) -{ - /* use cubic for now */ - node_tex_image_cubic_ex(co, ima, 0.0, color, alpha); -} - void tex_box_sample_linear( vec3 texco, vec3 N, sampler2D ima, out vec4 color1, out vec4 color2, out vec4 color3) { @@ -175,32 +142,6 @@ void tex_box_sample_linear( 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(fract(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(fract(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(fract(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) { @@ -210,36 +151,23 @@ void tex_box_sample_cubic( if (N.x < 0.0) { uv.x = 1.0 - uv.x; } - node_tex_image_cubic_ex(uv.xyy, ima, 0.0, color1, alpha); + 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_ex(uv.xyy, ima, 0.0, color2, alpha); + 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_ex(uv.xyy, ima, 0.0, color3, alpha); + 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) +void tex_box_blend( + vec3 N, vec4 color1, vec4 color2, vec4 color3, float blend, out vec4 color, out float alpha) { /* project from direction vector to barycentric coordinates in triangles */ N = abs(N); @@ -284,70 +212,6 @@ void node_tex_image_box(vec3 texco, alpha = color.a; } -void tex_clip_linear(vec3 co, sampler2D ima, vec4 icolor, out vec4 color, out float alpha) -{ - vec2 tex_size = vec2(textureSize(ima, 0).xy); - vec2 minco = min(co.xy, 1.0 - co.xy); - minco = clamp(minco * tex_size + 0.5, 0.0, 1.0); - float fac = minco.x * minco.y; - - color = mix(vec4(0.0), icolor, fac); - alpha = color.a; -} - -void tex_clip_nearest(vec3 co, sampler2D ima, vec4 icolor, out vec4 color, out float alpha) -{ - vec4 minco = vec4(co.xy, 1.0 - co.xy); - color = (any(lessThan(minco, vec4(0.0)))) ? vec4(0.0) : icolor; - alpha = color.a; -} - -void tex_clip_cubic(vec3 co, sampler2D ima, vec4 icolor, 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 w0, w1, w2, w3; - cubic_bspline_coefs(co.xy - tc, w0, w1, w2, w3); - - /* TODO Optimize this part. I'm sure there is a smarter way to do that. - * Could do that when sampling? */ -#define CLIP_CUBIC_SAMPLE(samp, size) \ - (float(all(greaterThan(samp, vec2(-0.5)))) * float(all(lessThan(ivec2(samp), itex_size)))) - ivec2 itex_size = textureSize(ima, 0).xy; - float fac; - fac = CLIP_CUBIC_SAMPLE(tc + vec2(-1.0, -1.0), itex_size) * w0.x * w0.y; - fac += CLIP_CUBIC_SAMPLE(tc + vec2(0.0, -1.0), itex_size) * w1.x * w0.y; - fac += CLIP_CUBIC_SAMPLE(tc + vec2(1.0, -1.0), itex_size) * w2.x * w0.y; - fac += CLIP_CUBIC_SAMPLE(tc + vec2(2.0, -1.0), itex_size) * w3.x * w0.y; - - fac += CLIP_CUBIC_SAMPLE(tc + vec2(-1.0, 0.0), itex_size) * w0.x * w1.y; - fac += CLIP_CUBIC_SAMPLE(tc + vec2(0.0, 0.0), itex_size) * w1.x * w1.y; - fac += CLIP_CUBIC_SAMPLE(tc + vec2(1.0, 0.0), itex_size) * w2.x * w1.y; - fac += CLIP_CUBIC_SAMPLE(tc + vec2(2.0, 0.0), itex_size) * w3.x * w1.y; - - fac += CLIP_CUBIC_SAMPLE(tc + vec2(-1.0, 1.0), itex_size) * w0.x * w2.y; - fac += CLIP_CUBIC_SAMPLE(tc + vec2(0.0, 1.0), itex_size) * w1.x * w2.y; - fac += CLIP_CUBIC_SAMPLE(tc + vec2(1.0, 1.0), itex_size) * w2.x * w2.y; - fac += CLIP_CUBIC_SAMPLE(tc + vec2(2.0, 1.0), itex_size) * w3.x * w2.y; - - fac += CLIP_CUBIC_SAMPLE(tc + vec2(-1.0, 2.0), itex_size) * w0.x * w3.y; - fac += CLIP_CUBIC_SAMPLE(tc + vec2(0.0, 2.0), itex_size) * w1.x * w3.y; - fac += CLIP_CUBIC_SAMPLE(tc + vec2(1.0, 2.0), itex_size) * w2.x * w3.y; - fac += CLIP_CUBIC_SAMPLE(tc + vec2(2.0, 2.0), itex_size) * w3.x * w3.y; -#undef CLIP_CUBIC_SAMPLE - - color = mix(vec4(0.0), icolor, fac); - alpha = color.a; -} - -void tex_clip_smart(vec3 co, sampler2D ima, vec4 icolor, out vec4 color, out float alpha) -{ - tex_clip_cubic(co, ima, icolor, color, alpha); -} - void node_tex_image_empty(vec3 co, out vec4 color, out float alpha) { color = vec4(0.0); @@ -389,20 +253,6 @@ void node_tex_tile_linear( alpha = color.a; } -void node_tex_tile_nearest( - vec3 co, sampler2DArray ima, sampler1DArray map, out vec4 color, out float alpha) -{ - if (node_tex_tile_lookup(co, ima, map)) { - ivec3 pix = ivec3(fract(co.xy) * textureSize(ima, 0).xy, co.z); - color = safe_color(texelFetch(ima, pix, 0)); - } - else { - color = vec4(1.0, 0.0, 1.0, 1.0); - } - - alpha = color.a; -} - void node_tex_tile_cubic( vec3 co, sampler2DArray ima, sampler1DArray map, out vec4 color, out float alpha) { @@ -437,9 +287,3 @@ void node_tex_tile_cubic( alpha = color.a; } - -void node_tex_tile_smart( - vec3 co, sampler2DArray ima, sampler1DArray map, out vec4 color, out float alpha) -{ - node_tex_tile_cubic(co, ima, map, color, alpha); -} diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_tex_noise.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_tex_noise.glsl index 6aeb23b1f99..d8d9ecdf287 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_tex_noise.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_tex_noise.glsl @@ -32,23 +32,35 @@ vec4 random_vec4_offset(float seed) 100.0 + hash_vec2_to_float(vec2(seed, 3.0)) * 100.0); } -void node_noise_texture_1d( - vec3 co, float w, float scale, float detail, float distortion, out float value, out vec4 color) +void node_noise_texture_1d(vec3 co, + float w, + float scale, + float detail, + float roughness, + float distortion, + out float value, + out vec4 color) { float p = w * scale; if (distortion != 0.0) { p += snoise(p + random_float_offset(0.0)) * distortion; } - value = fractal_noise(p, detail); + value = fractal_noise(p, detail, roughness); color = vec4(value, - fractal_noise(p + random_float_offset(1.0), detail), - fractal_noise(p + random_float_offset(2.0), detail), + fractal_noise(p + random_float_offset(1.0), detail, roughness), + fractal_noise(p + random_float_offset(2.0), detail, roughness), 1.0); } -void node_noise_texture_2d( - vec3 co, float w, float scale, float detail, float distortion, out float value, out vec4 color) +void node_noise_texture_2d(vec3 co, + float w, + float scale, + float detail, + float roughness, + float distortion, + out float value, + out vec4 color) { vec2 p = co.xy * scale; if (distortion != 0.0) { @@ -56,15 +68,21 @@ void node_noise_texture_2d( snoise(p + random_vec2_offset(1.0)) * distortion); } - value = fractal_noise(p, detail); + value = fractal_noise(p, detail, roughness); color = vec4(value, - fractal_noise(p + random_vec2_offset(2.0), detail), - fractal_noise(p + random_vec2_offset(3.0), detail), + fractal_noise(p + random_vec2_offset(2.0), detail, roughness), + fractal_noise(p + random_vec2_offset(3.0), detail, roughness), 1.0); } -void node_noise_texture_3d( - vec3 co, float w, float scale, float detail, float distortion, out float value, out vec4 color) +void node_noise_texture_3d(vec3 co, + float w, + float scale, + float detail, + float roughness, + float distortion, + out float value, + out vec4 color) { vec3 p = co * scale; if (distortion != 0.0) { @@ -73,15 +91,21 @@ void node_noise_texture_3d( snoise(p + random_vec3_offset(2.0)) * distortion); } - value = fractal_noise(p, detail); + value = fractal_noise(p, detail, roughness); color = vec4(value, - fractal_noise(p + random_vec3_offset(3.0), detail), - fractal_noise(p + random_vec3_offset(4.0), detail), + fractal_noise(p + random_vec3_offset(3.0), detail, roughness), + fractal_noise(p + random_vec3_offset(4.0), detail, roughness), 1.0); } -void node_noise_texture_4d( - vec3 co, float w, float scale, float detail, float distortion, out float value, out vec4 color) +void node_noise_texture_4d(vec3 co, + float w, + float scale, + float detail, + float roughness, + float distortion, + out float value, + out vec4 color) { vec4 p = vec4(co, w) * scale; if (distortion != 0.0) { @@ -91,9 +115,9 @@ void node_noise_texture_4d( snoise(p + random_vec4_offset(3.0)) * distortion); } - value = fractal_noise(p, detail); + value = fractal_noise(p, detail, roughness); color = vec4(value, - fractal_noise(p + random_vec4_offset(4.0), detail), - fractal_noise(p + random_vec4_offset(5.0), detail), + fractal_noise(p + random_vec4_offset(4.0), detail, roughness), + fractal_noise(p + random_vec4_offset(5.0), detail, roughness), 1.0); } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_tex_wave.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_tex_wave.glsl index c72f9717af3..070f42a5e30 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_tex_wave.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_tex_wave.glsl @@ -2,6 +2,7 @@ float calc_wave(vec3 p, float distortion, float detail, float detail_scale, + float detail_roughness, float phase, int wave_type, int bands_dir, @@ -46,7 +47,7 @@ float calc_wave(vec3 p, n += phase; if (distortion != 0.0) { - n += distortion * (fractal_noise(p * detail_scale, detail) * 2.0 - 1.0); + n += distortion * (fractal_noise(p * detail_scale, detail, detail_roughness) * 2.0 - 1.0); } if (wave_profile == 0) { /* profile sin */ @@ -67,6 +68,7 @@ void node_tex_wave(vec3 co, float distortion, float detail, float detail_scale, + float detail_roughness, float phase, float wave_type, float bands_dir, @@ -80,6 +82,7 @@ void node_tex_wave(vec3 co, distortion, detail, detail_scale, + detail_roughness, phase, int(wave_type), int(bands_dir), |