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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/gpu/shaders')
-rw-r--r--source/blender/gpu/shaders/gpu_program_smoke_color_frag.glsl32
-rw-r--r--source/blender/gpu/shaders/gpu_program_smoke_frag.glsl27
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl14
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl208
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_dof_hq_frag.glsl166
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_dof_hq_geo.glsl50
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_dof_hq_vert.glsl58
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_dof_vert.glsl68
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_lib.glsl39
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl94
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_vert.glsl9
-rw-r--r--source/blender/gpu/shaders/gpu_shader_geometry.glsl100
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl202
-rw-r--r--source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl2
-rw-r--r--source/blender/gpu/shaders/gpu_shader_vertex.glsl21
-rw-r--r--source/blender/gpu/shaders/gpu_shader_vertex_world.glsl13
16 files changed, 1060 insertions, 43 deletions
diff --git a/source/blender/gpu/shaders/gpu_program_smoke_color_frag.glsl b/source/blender/gpu/shaders/gpu_program_smoke_color_frag.glsl
new file mode 100644
index 00000000000..a94c823f408
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_program_smoke_color_frag.glsl
@@ -0,0 +1,32 @@
+!!ARBfp1.0
+PARAM dx = program.local[0];
+PARAM darkness = program.local[1];
+PARAM render = program.local[2];
+PARAM f = {1.442695041, 1.442695041, 1.442695041, 1.442695041};
+TEMP temp, shadow, flame, spec, value;
+TEX temp, fragment.texcoord[0], texture[0], 3D;
+TEX shadow, fragment.texcoord[0], texture[1], 3D;
+TEX flame, fragment.texcoord[0], texture[2], 3D;
+TEX spec, flame.r, texture[3], 1D;
+# unpremultiply volume texture
+RCP value.r, temp.a;
+MUL temp.r, temp.r, value.r;
+MUL temp.g, temp.g, value.r;
+MUL temp.b, temp.b, value.r;
+# calculate shading factor from density
+MUL value.r, temp.a, darkness.a;
+MUL value.r, value.r, dx.r;
+MUL value.r, value.r, f.r;
+EX2 value.r, -value.r;
+# alpha
+SUB temp.a, 1.0, value.r;
+# shade colors
+MUL temp.r, temp.r, shadow.r;
+MUL temp.g, temp.g, shadow.r;
+MUL temp.b, temp.b, shadow.r;
+MUL temp.r, temp.r, value.r;
+MUL temp.g, temp.g, value.r;
+MUL temp.b, temp.b, value.r;
+# for now this just replace smoke shading if rendering fire
+CMP result.color, render.r, temp, spec;
+END
diff --git a/source/blender/gpu/shaders/gpu_program_smoke_frag.glsl b/source/blender/gpu/shaders/gpu_program_smoke_frag.glsl
new file mode 100644
index 00000000000..04b171d24bd
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_program_smoke_frag.glsl
@@ -0,0 +1,27 @@
+!!ARBfp1.0
+PARAM dx = program.local[0];
+PARAM darkness = program.local[1];
+PARAM render = program.local[2];
+PARAM f = {1.442695041, 1.442695041, 1.442695041, 0.01};
+TEMP temp, shadow, flame, spec, value;
+TEX temp, fragment.texcoord[0], texture[0], 3D;
+TEX shadow, fragment.texcoord[0], texture[1], 3D;
+TEX flame, fragment.texcoord[0], texture[2], 3D;
+TEX spec, flame.r, texture[3], 1D;
+# calculate shading factor from density
+MUL value.r, temp.a, darkness.a;
+MUL value.r, value.r, dx.r;
+MUL value.r, value.r, f.r;
+EX2 temp, -value.r;
+# alpha
+SUB temp.a, 1.0, temp.r;
+# shade colors
+MUL temp.r, temp.r, shadow.r;
+MUL temp.g, temp.g, shadow.r;
+MUL temp.b, temp.b, shadow.r;
+MUL temp.r, temp.r, darkness.r;
+MUL temp.g, temp.g, darkness.g;
+MUL temp.b, temp.b, darkness.b;
+# for now this just replace smoke shading if rendering fire
+CMP result.color, render.r, temp, spec;
+END
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl b/source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl
new file mode 100644
index 00000000000..e04cd7d3306
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl
@@ -0,0 +1,14 @@
+uniform sampler2D depthbuffer;
+varying vec4 uvcoordsvar;
+
+void main(void)
+{
+ float depth = texture2D(depthbuffer, uvcoordsvar.xy).r;
+
+ /* XRay background, discard */
+ if (depth >= 1.0) {
+ discard;
+ }
+
+ gl_FragDepth = depth;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl b/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl
new file mode 100644
index 00000000000..e9dab04de5d
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl
@@ -0,0 +1,208 @@
+/* amount of offset to move one pixel left-right.
+ * In second pass some dimensions are zero to control verical/horizontal convolution */
+uniform vec2 invrendertargetdim;
+// color buffer
+uniform sampler2D colorbuffer;
+//blurred color buffer for DOF effect
+uniform sampler2D blurredcolorbuffer;
+// slightly blurred buffer
+uniform sampler2D mblurredcolorbuffer;
+// depth buffer
+uniform sampler2D depthbuffer;
+
+// this includes focal distance in x and aperture size in y
+uniform vec4 dof_params;
+
+// viewvectors for reconstruction of world space
+uniform vec4 viewvecs[3];
+
+// coordinates on framebuffer in normalized (0.0-1.0) uv space
+varying vec4 uvcoordsvar;
+
+/* color texture coordinates, offset by a small amount */
+varying vec2 color_uv1;
+varying vec2 color_uv2;
+
+varying vec2 depth_uv1;
+varying vec2 depth_uv2;
+varying vec2 depth_uv3;
+varying vec2 depth_uv4;
+
+
+float calculate_far_coc(in float zdepth)
+{
+ float coc = dof_params.x * max(1.0 - dof_params.y / zdepth, 0.0);
+
+ /* multiply by 1.0 / sensor size to get the normalized size */
+ return coc * dof_params.z;
+}
+
+/* near coc only! when distance is nearer than focus plane first term is bigger than one */
+vec4 calculate_near_coc(in vec4 zdepth)
+{
+ vec4 coc = dof_params.x * max(vec4(dof_params.y) / zdepth - vec4(1.0), vec4(0.0));
+
+ /* multiply by 1.0 / sensor size to get the normalized size */
+ return coc * dof_params.z;
+}
+
+/* first pass blurs the color buffer heavily and gets the near coc only.
+ * There are many texture accesses here but they are done on a
+ * lower resolution image so overall bandwidth is not a concern */
+void first_pass()
+{
+ vec4 depth;
+ vec4 zdepth;
+ vec4 coc;
+ float final_coc;
+
+ /* amount to add to uvs so that they move one row further */
+ vec2 offset_row[3];
+ offset_row[0] = vec2(0.0, invrendertargetdim.y);
+ offset_row[1] = 2.0 * offset_row[0];
+ 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]);
+ 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;
+
+ 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;
+
+ 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;
+
+ 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;
+
+ 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);
+}
+
+/* second pass, gaussian blur the downsampled image */
+void second_pass()
+{
+ vec4 depth = vec4(texture2D(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;
+}
+
+
+/* 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);
+ float coc = 2.0 * max(color_blurred.a, color.a); - color.a;
+ gl_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);
+
+ gl_FragColor = color / 4.0;
+}
+
+vec4 small_sample_blur(in sampler2D colorbuffer, in vec2 uv, in vec4 color)
+{
+ float weight = 1.0/ 17.0;
+ 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);
+
+ return result;
+}
+
+
+/* fourth pass, just visualize the third pass contents */
+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 smallblurred = small_sample_blur(colorbuffer, uvcoordsvar.xy, color_orig);
+ float depth = texture2D(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);
+
+ /* calculate final coc here */
+ float coc = max(max(coc_far, mediumblurred.a), 0.0);
+
+ float width = 2.5;
+ float radius = 0.2;
+
+ factors.x = 1.0 - clamp(width * coc, 0.0, 1.0);
+ factors.y = 1.0 - clamp(abs(width * (coc - 2.0 * radius)), 0.0, 1.0);
+ factors.z = 1.0 - clamp(abs(width * (coc - 3.0 * radius)), 0.0, 1.0);
+ factors.w = 1.0 - clamp(abs(width * (coc - 4.0 * radius)), 0.0, 1.0);
+ /* blend! */
+ vec4 color = factors.x * color_orig + factors.y * smallblurred + factors.z * mediumblurred + factors.w * highblurred;
+
+ 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);
+}
+
+
+void main()
+{
+#ifdef FIRST_PASS
+ first_pass();
+#elif defined(SECOND_PASS)
+ second_pass();
+#elif defined(THIRD_PASS)
+ third_pass();
+#elif defined(FOURTH_PASS)
+ fourth_pass();
+#elif defined(FIFTH_PASS)
+ fifth_pass();
+#endif
+}
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
new file mode 100644
index 00000000000..e315d2fb97a
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_frag.glsl
@@ -0,0 +1,166 @@
+/* amount of offset to move one pixel left-right.
+ * In second pass some dimensions are zero to control verical/horizontal convolution */
+uniform vec2 invrendertargetdim;
+
+uniform ivec2 rendertargetdim;
+
+/* color buffer */
+uniform sampler2D colorbuffer;
+uniform sampler2D farbuffer;
+uniform sampler2D nearbuffer;
+
+/* depth buffer */
+uniform sampler2D depthbuffer;
+
+uniform sampler2D cocbuffer;
+
+/* this includes focal distance in x and aperture size in y */
+uniform vec4 dof_params;
+
+/* viewvectors for reconstruction of world space */
+uniform vec4 viewvecs[3];
+
+/* initial uv coordinate */
+varying vec2 uvcoord;
+
+/* coordinate used for calculating radius et al set in geometry shader */
+varying vec2 particlecoord;
+varying vec4 color;
+
+/* downsampling coordinates */
+varying vec2 downsample1;
+varying vec2 downsample2;
+varying vec2 downsample3;
+varying vec2 downsample4;
+
+#define M_PI 3.1415926535897932384626433832795
+
+/* calculate 4 samples at once */
+vec4 calculate_coc(in vec4 zdepth)
+{
+ vec4 coc = dof_params.x * (vec4(dof_params.y) / zdepth - vec4(1.0));
+
+ /* multiply by 1.0 / sensor size to get the normalized size */
+ return coc * dof_params.z;
+}
+
+#define THRESHOLD 0.0
+
+/* downsample the color buffer to half resolution */
+void downsample_pass()
+{
+ vec4 depth;
+ vec4 zdepth;
+ vec4 coc;
+ 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);
+
+ depth.r = texture2D(depthbuffer, downsample1).r;
+ depth.g = texture2D(depthbuffer, downsample2).r;
+ depth.b = texture2D(depthbuffer, downsample3).r;
+ depth.a = texture2D(depthbuffer, downsample4).r;
+
+ zdepth = get_view_space_z_from_depth(vec4(viewvecs[0].z), vec4(viewvecs[1].z), depth);
+ coc = calculate_coc(zdepth);
+ vec4 coc_far = -coc;
+
+ /* now we need to write the near-far fields premultiplied by the coc */
+ vec4 near_weights = vec4((coc.x >= THRESHOLD) ? 1.0 : 0.0, (coc.y >= THRESHOLD) ? 1.0 : 0.0,
+ (coc.z >= THRESHOLD) ? 1.0 : 0.0, (coc.w >= THRESHOLD) ? 1.0 : 0.0);
+ vec4 far_weights = vec4((coc_far.x >= THRESHOLD) ? 1.0 : 0.0, (coc_far.y >= THRESHOLD) ? 1.0 : 0.0,
+ (coc_far.z >= THRESHOLD) ? 1.0 : 0.0, (coc_far.w >= THRESHOLD) ? 1.0 : 0.0);
+
+ near_coc = max(max(max(coc.x, coc.y), max(coc.z, coc.w)), 0.0);
+ far_coc = max(max(max(coc_far.x, coc_far.y), max(coc_far.z, coc_far.w)), 0.0);
+
+ float norm_near = dot(near_weights, vec4(1.0));
+ 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 +
+ color4 * near_weights.w;
+ gl_FragData[1] = 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;
+ if (norm_far > 0.0)
+ gl_FragData[1] /= norm_far;
+ gl_FragData[2] = vec4(near_coc, far_coc, 0.0, 1.0);
+}
+
+/* accumulate color in the near/far blur buffers */
+void accumulate_pass(void) {
+ float theta = atan(particlecoord.y, particlecoord.x);
+ float r;
+
+ 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))));
+
+ if (dot(particlecoord, particlecoord) > r * r)
+ discard;
+
+ gl_FragData[0] = color;
+}
+#define MERGE_THRESHOLD 4.0
+
+/* combine the passes, */
+void final_pass(void) {
+ vec4 finalcolor;
+ float totalweight;
+ float depth = texture2D(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);
+ float farweight = farcolor.a;
+ if (farweight > 0.0)
+ farcolor /= farweight;
+ vec4 nearcolor = texture2D(nearbuffer, uvcoord);
+
+ vec4 srccolor = texture2D(colorbuffer, uvcoord);
+
+ vec4 coc = texture2D(cocbuffer, uvcoord);
+
+ float mixfac = smoothstep(1.0, MERGE_THRESHOLD, coc_far);
+ finalcolor = mix(srccolor, farcolor, mixfac);
+
+ farweight = mix(1.0, farweight, mixfac);
+
+ float nearweight = nearcolor.a;
+ if (nearweight > 0.0) {
+ nearcolor /= nearweight;
+ }
+
+ if (coc_near > 1.0) {
+ nearweight = 1.0;
+ finalcolor = nearcolor;
+ }
+ else {
+ totalweight = nearweight + farweight;
+ finalcolor = mix(finalcolor, nearcolor, nearweight / totalweight);
+ }
+
+ gl_FragData[0] = finalcolor;
+}
+
+void main()
+{
+#ifdef FIRST_PASS
+ downsample_pass();
+#elif defined(SECOND_PASS)
+ accumulate_pass();
+#elif defined(THIRD_PASS)
+ final_pass();
+#endif
+}
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
new file mode 100644
index 00000000000..7918122a681
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_geo.glsl
@@ -0,0 +1,50 @@
+uniform ivec2 rendertargetdim;
+uniform sampler2D colorbuffer;
+
+uniform vec2 layerselection;
+
+uniform sampler2D cocbuffer;
+
+/* initial uv coordinate */
+varying in vec2 uvcoord[1];
+varying out vec2 particlecoord;
+varying out vec4 color;
+
+
+#define M_PI 3.1415926535897932384626433832795
+
+void main(void)
+{
+ vec4 coc = texture2DLod(cocbuffer, uvcoord[0], 0.0);
+
+ float offset_val = dot(coc.rg, layerselection);
+ if (offset_val < 1.0)
+ return;
+
+ vec4 colortex = texture2DLod(colorbuffer, uvcoord[0], 0.0);
+
+ /* find the area the pixel will cover and divide the color by it */
+ float alpha = 1.0 / (offset_val * offset_val * M_PI);
+ colortex *= alpha;
+ colortex.a = alpha;
+
+ vec2 offset_far = vec2(offset_val * 0.5) / vec2(rendertargetdim.x, rendertargetdim.y);
+
+ gl_Position = gl_PositionIn[0] + vec4(-offset_far.x, -offset_far.y, 0.0, 0.0);
+ color = colortex;
+ particlecoord = vec2(-1.0, -1.0);
+ EmitVertex();
+ gl_Position = gl_PositionIn[0] + vec4(-offset_far.x, offset_far.y, 0.0, 0.0);
+ particlecoord = vec2(-1.0, 1.0);
+ color = colortex;
+ EmitVertex();
+ gl_Position = gl_PositionIn[0] + vec4(offset_far.x, -offset_far.y, 0.0, 0.0);
+ particlecoord = vec2(1.0, -1.0);
+ color = colortex;
+ EmitVertex();
+ gl_Position = gl_PositionIn[0] + 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
new file mode 100644
index 00000000000..09a0c75facc
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_vert.glsl
@@ -0,0 +1,58 @@
+uniform vec2 invrendertargetdim;
+uniform ivec2 rendertargetdim;
+/* initial uv coordinate */
+varying vec2 uvcoord;
+
+/* coordinate used for calculating radius et al set in geometry shader */
+varying vec2 particlecoord;
+
+/* downsampling coordinates */
+varying vec2 downsample1;
+varying vec2 downsample2;
+varying vec2 downsample3;
+varying vec2 downsample4;
+
+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;
+
+ gl_Position = gl_Vertex;
+}
+
+/* geometry shading pass, calculate a texture coordinate based on the indexed id */
+void vert_dof_coc_scatter_pass()
+{
+ vec2 pixel = vec2(rendertargetdim.x, rendertargetdim.y);
+ /* some math to get the target pixel */
+ int row = gl_InstanceID / rendertargetdim.x;
+ int column = gl_InstanceID % rendertargetdim.x;
+ uvcoord = (vec2(column, row) + vec2(0.5)) / pixel;
+
+ vec2 pos = uvcoord * 2.0 - vec2(1.0);
+ gl_Position = vec4(pos.x, pos.y, 0.0, 1.0);
+
+// uvcoord = vec2(0.5, 0.5);
+// gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
+}
+
+void vert_dof_final()
+{
+ uvcoord = gl_MultiTexCoord0.xy;
+ gl_Position = gl_Vertex;
+}
+
+void main()
+{
+#if defined(FIRST_PASS)
+ vert_dof_downsample();
+#elif defined(SECOND_PASS)
+ vert_dof_coc_scatter_pass();
+#else
+ vert_dof_final();
+#endif
+} \ No newline at end of file
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_dof_vert.glsl b/source/blender/gpu/shaders/gpu_shader_fx_dof_vert.glsl
new file mode 100644
index 00000000000..a2ef990c4e8
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_vert.glsl
@@ -0,0 +1,68 @@
+uniform vec2 invrendertargetdim;
+
+//texture coordinates for framebuffer read
+varying vec4 uvcoordsvar;
+
+/* color texture coordinates, offset by a small amount */
+varying vec2 color_uv1;
+varying vec2 color_uv2;
+
+varying vec2 depth_uv1;
+varying vec2 depth_uv2;
+varying vec2 depth_uv3;
+varying vec2 depth_uv4;
+
+//very simple shader for gull screen FX, just pass values on
+
+void vert_generic()
+{
+ uvcoordsvar = gl_MultiTexCoord0;
+ gl_Position = gl_Vertex;
+}
+
+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;
+
+ 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;
+
+ gl_Position = gl_Vertex;
+}
+
+void vert_dof_fourth_pass()
+{
+ vec4 halfpixel = vec4(-0.5, 0.5, -0.5, 0.5);
+ uvcoordsvar = gl_MultiTexCoord0.xxyy + halfpixel * vec4(invrendertargetdim.x,
+ invrendertargetdim.x, invrendertargetdim.y, invrendertargetdim.y);
+
+ gl_Position = gl_Vertex;
+}
+
+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;
+}
+
+void main()
+{
+#ifdef FIRST_PASS
+ vert_dof_first_pass();
+#elif defined(FOURTH_PASS)
+ vert_dof_fourth_pass();
+#elif defined(FIFTH_PASS)
+ vert_dof_fifth_pass();
+#else
+ vert_generic();
+#endif
+}
+
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl b/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl
new file mode 100644
index 00000000000..1dc49b52be1
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl
@@ -0,0 +1,39 @@
+/* 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]);
+
+ return zview * (viewvec_origin + vec3(uvcoords, 0.0) * viewvec_diff);
+}
+
+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]));
+}
+
+#else
+/* orthographic camera code */
+
+vec3 get_view_space_from_depth(in vec2 uvcoords, in vec3 viewvec_origin, in vec3 viewvec_diff, in float depth)
+{
+ vec3 offset = vec3(uvcoords, depth);
+
+ return vec3(viewvec_origin + offset * viewvec_diff);
+}
+
+vec4 get_view_space_z_from_depth(in vec4 near, in vec4 range, in vec4 depth)
+{
+ return -(near + depth * range);
+}
+
+#endif
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl b/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl
new file mode 100644
index 00000000000..494a74dcdf8
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl
@@ -0,0 +1,94 @@
+// color buffer
+uniform sampler2D colorbuffer;
+
+// jitter texture for ssao
+uniform sampler2D jitter_tex;
+
+// concentric sample texture for ssao
+uniform sampler1D ssao_concentric_tex;
+
+// depth buffer
+uniform sampler2D depthbuffer;
+// coordinates on framebuffer in normalized (0.0-1.0) uv space
+varying vec4 uvcoordsvar;
+
+/* ssao_params.x : pixel scale for the ssao radious */
+/* ssao_params.y : factor for the ssao darkening */
+uniform vec4 ssao_params;
+uniform vec3 ssao_sample_params;
+uniform vec4 ssao_color;
+
+/* store the view space vectors for the corners of the view frustum here.
+ * It helps to quickly reconstruct view space vectors by using uv coordinates,
+ * see http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
+uniform vec4 viewvecs[3];
+
+vec3 calculate_view_space_normal(in vec3 viewposition)
+{
+ vec3 normal = cross(normalize(dFdx(viewposition)),
+ ssao_params.w * normalize(dFdy(viewposition)));
+ normalize(normal);
+ return normal;
+}
+
+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 rotY = vec2(-rotX.y, rotX.x);
+
+ /* occlusion is zero in full depth */
+ if (depth == 1.0)
+ return 0.0;
+
+ vec3 position = get_view_space_from_depth(uvcoordsvar.xy, viewvecs[0].xyz, viewvecs[1].xyz, depth);
+ vec3 normal = calculate_view_space_normal(position);
+
+ // 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;
+ /* convert from -1.0...1.0 range to 0.0..1.0 for easy use with texture coordinates */
+ offset *= 0.5;
+
+ float factor = 0.0;
+ int x;
+ 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;
+
+ /* rotate with random direction to get jittered result */
+ vec2 dir_jittered = vec2(dot(dir_sample, rotX), dot(dir_sample, rotY));
+
+ vec2 uvcoords = uvcoordsvar.xy + dir_jittered * offset;
+
+ 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;
+ 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;
+ float len = length(dir);
+ float f = dot(dir, normal);
+
+ /* use minor bias here to avoid self shadowing */
+ if (f > 0.05 * len + 0.0001)
+ factor += f * 1.0/(len * (1.0 + len * len * ssao_params.z));
+ }
+ }
+
+ factor /= ssao_sample_params.x;
+
+ return clamp(factor * ssao_params.y, 0.0, 1.0);
+}
+
+void main()
+{
+ float depth = texture2D(depthbuffer, uvcoordsvar.xy).r;
+ vec4 scene_col = texture2D(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);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_vert.glsl b/source/blender/gpu/shaders/gpu_shader_fx_vert.glsl
new file mode 100644
index 00000000000..5194e414520
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_fx_vert.glsl
@@ -0,0 +1,9 @@
+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
new file mode 100644
index 00000000000..a0ae96a1f72
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_geometry.glsl
@@ -0,0 +1,100 @@
+uniform int PrimitiveIdBase;
+uniform int osd_active_uv_offset;
+
+varying vec3 varnormal;
+varying vec3 varposition;
+
+in block {
+ VertexData v;
+} inpt[4];
+
+uniform bool osd_flat_shading;
+uniform int osd_fvar_count;
+
+#define INTERP_FACE_VARYING_2(result, fvarOffset, tessCoord) \
+ { \
+ vec2 v[4]; \
+ int primOffset = (gl_PrimitiveID + PrimitiveIdBase) * 4; \
+ for (int i = 0; i < 4; ++i) { \
+ int index = (primOffset + i) * osd_fvar_count + fvarOffset; \
+ v[i] = vec2(texelFetch(FVarDataBuffer, index).s, \
+ texelFetch(FVarDataBuffer, index + 1).s); \
+ } \
+ result = mix(mix(v[0], v[1], tessCoord.s), \
+ mix(v[3], v[2], tessCoord.s), \
+ tessCoord.t); \
+ }
+
+uniform samplerBuffer FVarDataBuffer;
+
+out block {
+ VertexData v;
+} outpt;
+
+void set_mtface_vertex_attrs(vec2 st);
+
+void emit_flat(int index, vec3 normal)
+{
+ outpt.v.position = inpt[index].v.position;
+ outpt.v.normal = normal;
+
+ /* Compatibility */
+ varnormal = outpt.v.normal;
+ varposition = outpt.v.position.xyz;
+
+ /* TODO(sergey): Only uniform subdivisions atm. */
+ vec2 quadst[4] = vec2[](vec2(0,0), vec2(1,0), vec2(1,1), vec2(0,1));
+ vec2 st = quadst[index];
+
+ INTERP_FACE_VARYING_2(outpt.v.uv, osd_active_uv_offset, st);
+
+ set_mtface_vertex_attrs(st);
+
+ gl_Position = gl_ProjectionMatrix * inpt[index].v.position;
+ EmitVertex();
+}
+
+void emit_smooth(int index)
+{
+ outpt.v.position = inpt[index].v.position;
+ outpt.v.normal = inpt[index].v.normal;
+
+ /* Compatibility */
+ varnormal = outpt.v.normal;
+ varposition = outpt.v.position.xyz;
+
+ /* TODO(sergey): Only uniform subdivisions atm. */
+ vec2 quadst[4] = vec2[](vec2(0,0), vec2(1,0), vec2(1,1), vec2(0,1));
+ vec2 st = quadst[index];
+
+ INTERP_FACE_VARYING_2(outpt.v.uv, osd_active_uv_offset, st);
+
+ set_mtface_vertex_attrs(st);
+
+ gl_Position = gl_ProjectionMatrix * inpt[index].v.position;
+ EmitVertex();
+}
+
+void main()
+{
+ gl_PrimitiveID = gl_PrimitiveIDIn;
+
+ if (osd_flat_shading) {
+ vec3 A = (inpt[0].v.position - inpt[1].v.position).xyz;
+ vec3 B = (inpt[3].v.position - inpt[1].v.position).xyz;
+ vec3 flat_normal = normalize(cross(B, A));
+ emit_flat(0, flat_normal);
+ emit_flat(1, flat_normal);
+ emit_flat(3, flat_normal);
+ emit_flat(2, flat_normal);
+ }
+ else {
+ emit_smooth(0);
+ emit_smooth(1);
+ emit_smooth(3);
+ emit_smooth(2);
+ }
+ EndPrimitive();
+}
+
+void set_mtface_vertex_attrs(vec2 st) {
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 3ba36c11311..311fcb8ead2 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -149,10 +149,23 @@ void geom(vec3 co, vec3 nor, mat4 viewinvmat, vec3 attorco, vec2 attuv, vec4 att
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, vec3 loc, vec3 vel, vec3 avel, out float index, out float age, out float life_time, out vec3 location, out float size, out vec3 velocity, out vec3 angular_velocity)
+{
+ index = sprops.x;
+ age = sprops.y;
+ life_time = sprops.z;
+ size = sprops.w;
+
+ location = loc;
+ velocity = vel;
+ angular_velocity = avel;
+}
+
void mapping(vec3 vec, mat4 mat, vec3 minvec, vec3 maxvec, float domin, float domax, out vec3 outvec)
{
outvec = (mat * vec4(vec, 1.0)).xyz;
@@ -169,9 +182,9 @@ void camera(vec3 co, out vec3 outview, out float outdepth, out float outdist)
outview = normalize(co);
}
-void lamp(vec4 col, vec3 lv, float dist, vec3 shadow, float visifac, out vec4 outcol, out vec3 outlv, out float outdist, out vec4 outshadow, out float outvisifac)
+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;
+ outcol = col * energy;
outlv = lv;
outdist = dist;
outshadow = vec4(shadow, 1.0);
@@ -297,6 +310,10 @@ void math_modulo(float val1, float val2, out float outval)
outval = 0.0;
else
outval = mod(val1, val2);
+
+ /* change sign to match C convention, mod in GLSL will take absolute for negative numbers,
+ * see https://www.opengl.org/sdk/docs/man/html/mod.xhtml */
+ outval = (val1 > 0.0) ? outval : -outval;
}
void math_abs(float val1, out float outval)
@@ -338,6 +355,7 @@ void vec_math_cross(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
{
outvec = cross(v1, v2);
outval = length(outvec);
+ outvec /= outval;
}
void vec_math_normalize(vec3 v, out vec3 outvec, out float outval)
@@ -357,6 +375,12 @@ void normal(vec3 dir, vec3 nor, out vec3 outnor, out float outdot)
outdot = -dot(dir, nor);
}
+void normal_new_shading(vec3 dir, vec3 nor, out vec3 outnor, out float outdot)
+{
+ outnor = normalize(nor);
+ outdot = dot(normalize(dir), nor);
+}
+
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;
@@ -687,22 +711,7 @@ void mix_linear(float fac, vec4 col1, vec4 col2, out vec4 outcol)
{
fac = clamp(fac, 0.0, 1.0);
- outcol = col1;
-
- if(col2.r > 0.5)
- outcol.r= col1.r + fac*(2.0*(col2.r - 0.5));
- else
- outcol.r= col1.r + fac*(2.0*(col2.r) - 1.0);
-
- if(col2.g > 0.5)
- outcol.g= col1.g + fac*(2.0*(col2.g - 0.5));
- else
- outcol.g= col1.g + fac*(2.0*(col2.g) - 1.0);
-
- if(col2.b > 0.5)
- outcol.b= col1.b + fac*(2.0*(col2.b - 0.5));
- else
- outcol.b= col1.b + fac*(2.0*(col2.b) - 1.0);
+ outcol = col1 + fac*(2.0*(col2 - vec4(0.5)));
}
void valtorgb(float fac, sampler2D colormap, out vec4 outcol, out float outalpha)
@@ -722,6 +731,16 @@ void invert(float fac, vec4 col, out vec4 outcol)
outcol.w = col.w;
}
+void clamp_vec3(vec3 vec, vec3 min, vec3 max, out vec3 out_vec)
+{
+ out_vec = clamp(vec, min, max);
+}
+
+void clamp_val(float value, float min, float max, out float out_value)
+{
+ out_value = clamp(value, min, max);
+}
+
void hue_sat(float hue, float sat, float value, float fac, vec4 col, out vec4 outcol)
{
vec4 hsv;
@@ -1507,9 +1526,9 @@ void mtex_nspace_world(mat4 viewmat, vec3 texnormal, out vec3 outnormal)
outnormal = normalize((viewmat*vec4(texnormal, 0.0)).xyz);
}
-void mtex_nspace_object(mat4 viewmat, mat4 obmat, vec3 texnormal, out vec3 outnormal)
+void mtex_nspace_object(vec3 texnormal, out vec3 outnormal)
{
- outnormal = normalize((viewmat*(obmat*vec4(texnormal, 0.0))).xyz);
+ outnormal = normalize(gl_NormalMatrix * texnormal);
}
void mtex_blend_normal(float norfac, vec3 normal, vec3 newnormal, out vec3 outnormal)
@@ -1925,6 +1944,17 @@ void shade_add_spec(float t, vec3 lampcol, vec3 speccol, out vec3 outcol)
outcol = t*lampcol*speccol;
}
+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;
@@ -1960,6 +1990,11 @@ 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);
@@ -2077,18 +2112,23 @@ void shade_exposure_correct(vec3 col, float linfac, float logfac, out vec3 outco
outcol = linfac*(1.0 - exp(col*logfac));
}
-void shade_mist_factor(vec3 co, float miststa, float mistdist, float misttype, float misi, out float outfac)
+void shade_mist_factor(vec3 co, float enable, float miststa, float mistdist, float misttype, float misi, out float outfac)
{
- float fac, zcor;
+ 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);
+ 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);
+ outfac = 1.0 - (1.0 - fac) * (1.0 - misi);
+ }
+ else {
+ outfac = 0.0;
+ }
}
void shade_world_mix(vec3 hor, vec4 col, out vec4 outcol)
@@ -2223,6 +2263,16 @@ void node_bsdf_hair(vec4 color, float offset, float roughnessu, float roughnessv
result = color;
}
+void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out vec4 result)
+{
+ node_bsdf_diffuse(color, 0.0, N, result);
+}
+
+void node_ambient_occlusion(vec4 color, out vec4 result)
+{
+ result = color;
+}
+
/* emission */
void node_emission(vec4 color, float strength, vec3 N, out vec4 result)
@@ -2230,6 +2280,22 @@ void node_emission(vec4 color, float strength, vec3 N, out vec4 result)
result = color*strength;
}
+/* background */
+
+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);
+
+ vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
+ worldvec = (gl_ModelViewMatrixInverse * co).xyz;
+}
+
+void node_background(vec4 color, float strength, vec3 N, out vec4 result)
+{
+ result = color*strength;
+}
+
/* closures */
void node_mix_shader(float fac, vec4 shader1, vec4 shader2, out vec4 shader)
@@ -2259,10 +2325,12 @@ void node_layer_weight(float blend, vec3 N, vec3 I, out float fresnel, out float
{
/* fresnel */
float eta = max(1.0 - blend, 0.00001);
- fresnel = fresnel_dielectric(normalize(I), N, (gl_FrontFacing)? 1.0/eta : eta );
+ vec3 I_view = (gl_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 );
/* facing */
- facing = abs(dot(normalize(I), N));
+ facing = abs(dot(I_view, N));
if(blend != 0.5) {
blend = clamp(blend, 0.0, 0.99999);
blend = (blend < 0.5)? 2.0*blend: 0.5/(1.0 - blend);
@@ -2302,7 +2370,7 @@ void node_uvmap(vec3 attr_uv, out vec3 outvec)
void node_geometry(vec3 I, vec3 N, 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 backfacing, out float pointiness)
{
position = (toworld*vec4(I, 1.0)).xyz;
normal = (toworld*vec4(N, 0.0)).xyz;
@@ -2315,20 +2383,21 @@ void node_geometry(vec3 I, vec3 N, mat4 toworld,
parametric = vec3(0.0);
backfacing = (gl_FrontFacing)? 0.0: 1.0;
+ pointiness = 0.0;
}
-void node_tex_coord(vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat,
+void node_tex_coord(vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat, vec4 camerafac,
vec3 attr_orco, vec3 attr_uv,
out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object,
out vec3 camera, out vec3 window, out vec3 reflection)
{
- generated = mtex_2d_mapping(attr_orco);
+ generated = attr_orco * 0.5 + vec3(0.5);
normal = normalize((obinvmat*(viewinvmat*vec4(N, 0.0))).xyz);
uv = attr_uv;
object = (obinvmat*(viewinvmat*vec4(I, 1.0))).xyz;
- camera = I;
+ camera = vec3(I.xy, -I.z);
vec4 projvec = gl_ProjectionMatrix * vec4(I, 1.0);
- window = mtex_2d_mapping(projvec.xyz/projvec.w);
+ window = vec3(mtex_2d_mapping(projvec.xyz/projvec.w).xy * camerafac.xy + camerafac.zw, 0.0);
vec3 shade_I;
shade_view(I, shade_I);
@@ -2336,6 +2405,32 @@ void node_tex_coord(vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat,
reflection = (viewinvmat*vec4(view_reflection, 0.0)).xyz;
}
+void node_tex_coord_background(vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat, vec4 camerafac,
+ vec3 attr_orco, vec3 attr_uv,
+ 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 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
+
+ co = normalize(co);
+ vec3 coords = (gl_ModelViewMatrixInverse * co).xyz;
+
+ generated = coords;
+ normal = -coords;
+ uv = vec3(attr_uv.xy, 0.0);
+ object = coords;
+
+ camera = vec3(co.xy, -co.z);
+ window = (gl_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;
+}
+
/* textures */
void node_tex_gradient(vec3 co, out vec4 color, out float fac)
@@ -2362,17 +2457,34 @@ void node_tex_clouds(vec3 co, float size, out vec4 color, out float fac)
fac = 1.0;
}
-void node_tex_environment(vec3 co, sampler2D ima, out vec4 color)
+void node_tex_environment_equirectangular(vec3 co, sampler2D ima, out vec4 color)
+{
+ vec3 nco = normalize(co);
+ 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));
+}
+
+void node_tex_environment_mirror_ball(vec3 co, sampler2D ima, out vec4 color)
{
- float u = (atan(co.y, co.x) + M_PI)/(2.0*M_PI);
- float v = atan(co.z, hypot(co.x, co.y))/M_PI + 0.5;
+ vec3 nco = normalize(co);
+
+ nco.y -= 1.0;
+
+ float div = 2.0*sqrt(max(-0.5*nco.y, 0.0));
+ if(div > 0.0)
+ nco /= div;
+
+ float u = 0.5*(nco.x + 1.0);
+ float v = 0.5*(nco.z + 1.0);
color = texture2D(ima, vec2(u, v));
}
void node_tex_environment_empty(vec3 co, out vec4 color)
{
- color = vec4(0.0);
+ color = vec4(1.0, 0.0, 1.0, 1.0);
}
void node_tex_image(vec3 co, sampler2D ima, out vec4 color, out float alpha)
@@ -2480,6 +2592,11 @@ void node_output_material(vec4 surface, vec4 volume, float displacement, out vec
result = surface;
}
+void node_output_world(vec4 surface, vec4 volume, out vec4 result)
+{
+ result = surface;
+}
+
/* ********************** matcap style render ******************** */
void material_preview_matcap(vec4 color, sampler2D ima, vec4 N, vec4 mask, out vec4 result)
@@ -2487,6 +2604,7 @@ void material_preview_matcap(vec4 color, sampler2D ima, vec4 N, vec4 mask, out v
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);
@@ -2494,6 +2612,10 @@ void material_preview_matcap(vec4 color, sampler2D ima, vec4 N, vec4 mask, out v
normal.z = 0.0;
}
normal = normalize(normal);
+#else
+ normal = inpt.v.normal;
+ mask = vec4(1.0, 1.0, 1.0, 1.0);
+#endif
tex.x = 0.5 + 0.49 * normal.x;
tex.y = 0.5 + 0.49 * normal.y;
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 978b6db1b9a..5f406c959f1 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
@@ -10,7 +10,7 @@ void main()
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 += texture2D( textureSource, gl_TexCoord[0].st + vec2(3.0 * ScaleU.x, 3.0 * ScaleU.y ) ) * 0.015625;
gl_FragColor = color;
}
diff --git a/source/blender/gpu/shaders/gpu_shader_vertex.glsl b/source/blender/gpu/shaders/gpu_shader_vertex.glsl
index b5d8dcc0f35..7e332706695 100644
--- a/source/blender/gpu/shaders/gpu_shader_vertex.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_vertex.glsl
@@ -1,3 +1,11 @@
+#ifdef USE_OPENSUBDIV
+in vec3 normal;
+in vec4 position;
+
+out block {
+ VertexData v;
+} outpt;
+#endif
varying vec3 varposition;
varying vec3 varnormal;
@@ -8,10 +16,15 @@ varying float gl_ClipDistance[6];
void main()
{
- vec4 co = gl_ModelViewMatrix * gl_Vertex;
+#ifndef USE_OPENSUBDIV
+ vec4 position = gl_Vertex;
+ vec3 normal = gl_Normal;
+#endif
+
+ vec4 co = gl_ModelViewMatrix * position;
varposition = co.xyz;
- varnormal = normalize(gl_NormalMatrix * gl_Normal);
+ varnormal = normalize(gl_NormalMatrix * normal);
gl_Position = gl_ProjectionMatrix * co;
#ifdef CLIP_WORKAROUND
@@ -24,3 +37,7 @@ void main()
gl_ClipVertex = co;
#endif
+#ifdef USE_OPENSUBDIV
+ outpt.v.position = co;
+ outpt.v.normal = varnormal;
+#endif
diff --git a/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl b/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl
new file mode 100644
index 00000000000..9dbcaeb7a32
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl
@@ -0,0 +1,13 @@
+
+varying vec3 varposition;
+varying vec3 varnormal;
+
+void main()
+{
+ /* position does not need to be transformed, we already have it */
+ gl_Position = gl_Vertex;
+
+ varposition = gl_Vertex.xyz;
+
+ varnormal = normalize(-varposition);
+