diff options
Diffstat (limited to 'source/blender/gpu/shaders')
8 files changed, 358 insertions, 35 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_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_lib.glsl b/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl index 6c4bf3bb7a0..1dc49b52be1 100644 --- a/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl +++ b/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl @@ -1,11 +1,3 @@ -vec3 calculate_view_space_normal(in vec3 viewposition) -{ - vec3 normal = cross(normalize(dFdx(viewposition)), - normalize(dFdy(viewposition))); - normalize(normal); - return normal; -} - /* 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 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 5e2512b6a46..494a74dcdf8 100644 --- a/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl @@ -15,7 +15,7 @@ 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 vec4 ssao_sample_params; +uniform vec3 ssao_sample_params; uniform vec4 ssao_color; /* store the view space vectors for the corners of the view frustum here. @@ -23,10 +23,18 @@ uniform vec4 ssao_color; * 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.zw).rg; + 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 */ diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 945b7ef303f..8edffe787eb 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -698,22 +698,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) @@ -2114,18 +2099,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) |