New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add shaders for filter() constants, and use them by default in P2D #6324
Changes from 14 commits
568c4ec
9f15a50
e2f123d
bd8dab4
9a02645
5bbb980
c1bfee4
ef397a1
197c905
1e34031
4bf2565
ed40a78
fc4181e
a94936e
586e933
1e02d7f
e0deeeb
5dc1056
72f7895
10e0cac
9ae66c5
7b71bc3
2897670
aa1a7e0
4f1b62c
e734106
88830eb
cb6af67
89aa499
23c3db5
92c7244
41cf4ba
6c2e9ce
9dc8887
b1a76ec
bafee00
3c4afc5
02d187b
b5d533c
ec41c1f
8ccfe59
347401b
39def40
0e6a95b
be09142
3e22945
eca2c76
b0ef928
547578b
44d8f2c
b7454db
f04ddf8
d0a2fe9
b3583f7
1bfe9c7
121137f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// Single-pass blur filter, taken from Adam Ferriss' repo of shader examples: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How does the output of this blur compare to the cpu one? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here's a sketch for comparison, although bricks.jpg isn't the best example to compare blur: |
||
// https://github.com/aferriss/p5jsShaderExamples/blob/gh-pages/4_image-effects/4-9_single-pass-blur/effect.frag | ||
|
||
precision highp float; | ||
|
||
// lets grab texcoords just for fun | ||
varying vec2 vTexCoord; | ||
|
||
// our texture coming from p5 | ||
uniform sampler2D tex0; | ||
uniform vec2 texelSize; | ||
uniform float filterParameter; | ||
|
||
void main() { | ||
|
||
vec2 uv = vTexCoord; | ||
|
||
// a single pass blur works by sampling all the neighbor pixels and averaging them up | ||
// this is somewhat inefficient because we have to sample the texture 9 times -- texture2D calls are slow :( | ||
// check out the two-pass-blur example for a better blur approach | ||
// get the webcam as a vec4 using texture2D | ||
|
||
// spread controls how far away from the center we should pull a sample from | ||
// you will start to see artifacts if you crank this up too high | ||
float spread = 4.0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lets just simplify this whole block to |
||
if (filterParameter > 0.0) { | ||
spread = filterParameter; | ||
} | ||
|
||
// create our offset variable by multiplying the size of a texel with spread | ||
vec2 offset = texelSize * spread; | ||
|
||
// get all the neighbor pixels! | ||
vec4 tex = texture2D(tex0, uv); // middle middle -- the actual texel / pixel | ||
tex += texture2D(tex0, uv + vec2(-offset.x, -offset.y)); // top left | ||
tex += texture2D(tex0, uv + vec2(0.0, -offset.y)); // top middle | ||
tex += texture2D(tex0, uv + vec2(offset.x, -offset.y)); // top right | ||
|
||
tex += texture2D(tex0, uv + vec2(-offset.x, 0.0)); //middle left | ||
tex += texture2D(tex0, uv + vec2(offset.x, 0.0)); //middle right | ||
|
||
tex += texture2D(tex0, uv + vec2(-offset.x, offset.y)); // bottom left | ||
tex += texture2D(tex0, uv + vec2(0.0, offset.y)); // bottom middle | ||
tex += texture2D(tex0, uv + vec2(offset.x, offset.y)); // bottom right | ||
|
||
// we added 9 textures together, so we will divide by 9 to average them out and move the values back into a 0 - 1 range | ||
tex /= 9.0; | ||
|
||
gl_FragColor = tex; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
attribute vec3 aPosition; | ||
// texcoords only come from p5 to vertex shader | ||
// so pass texcoords on to the fragment shader in a varying variable | ||
attribute vec2 aTexCoord; | ||
varying vec2 vTexCoord; | ||
|
||
void main() { | ||
// transferring texcoords for the frag shader | ||
vTexCoord = aTexCoord; | ||
|
||
// copy position with a fourth coordinate for projection (1.0 is normal) | ||
vec4 positionVec4 = vec4(aPosition, 1.0); | ||
// scale by two and center to achieve correct positioning | ||
positionVec4.xy = positionVec4.xy * 2.0 - 1.0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should change this shader to use the model view projection matrix instead. See my issue here #6367 where this shader is causing trouble because of the depth testing. |
||
|
||
gl_Position = positionVec4; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// Increase the bright areas in an image | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that this shader can be simplified and maybe doesn't need the luma calculation. Let me know if I'm wrong but take a look here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same for erode, but it will be a min instead of max There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Not sure if that's more desired or not. The results look similar though There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think either way is fine, if the luma calculation is more accurate to the CPU mode then disregard my comment! |
||
|
||
precision highp float; | ||
|
||
varying vec2 vTexCoord; | ||
|
||
uniform sampler2D tex0; | ||
uniform vec2 texelSize; | ||
|
||
float luma(vec3 color) { | ||
// based on constants 77, 151, 28 from DILATE in filters.js, | ||
// even though that's different than the luminance constants used in GRAY | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is fine, haha. Probably just different implementers There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jwong I think that having it match what is expected for the non-webgl filters feels best, glad to see you leave a comment about it here, I think it's helpful context. |
||
return dot(color, vec3(0.3008, 0.5898, 0.1094)); | ||
} | ||
|
||
void main() { | ||
vec4 curColor = texture2D(tex0, vTexCoord); | ||
float curLuminance = luma(curColor.rgb); | ||
|
||
// set current color as the neighbor color with highest luminance | ||
|
||
vec4 neighbors[4]; | ||
neighbors[0] = texture2D(tex0, vTexCoord + vec2( texelSize.x, 0.0)); | ||
neighbors[1] = texture2D(tex0, vTexCoord + vec2(-texelSize.x, 0.0)); | ||
neighbors[2] = texture2D(tex0, vTexCoord + vec2(0.0, texelSize.y)); | ||
neighbors[3] = texture2D(tex0, vTexCoord + vec2(0.0, -texelSize.y)); | ||
|
||
for (int i = 0; i < 4; i++) { | ||
vec4 color = neighbors[i]; | ||
float lum = luma(color.rgb); | ||
if (lum > curLuminance) { | ||
curColor = color; | ||
curLuminance = lum; | ||
} | ||
} | ||
|
||
gl_FragColor = curColor; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// Reduces the bright areas in an image | ||
|
||
precision highp float; | ||
|
||
varying vec2 vTexCoord; | ||
|
||
uniform sampler2D tex0; | ||
uniform vec2 texelSize; | ||
|
||
float luma(vec3 color) { | ||
// based on constants 77, 151, 28 from ERODE in filters.js, | ||
// even though that's different than the luminance constants used in GRAY | ||
return dot(color, vec3(0.3008, 0.5898, 0.1094)); | ||
} | ||
|
||
void main() { | ||
vec4 curColor = texture2D(tex0, vTexCoord); | ||
float curLuminance = luma(curColor.rgb); | ||
|
||
// set current color as the neighbor color with lowest luminance | ||
|
||
vec4 neighbors[4]; | ||
neighbors[0] = texture2D(tex0, vTexCoord + vec2( texelSize.x, 0.0)); | ||
neighbors[1] = texture2D(tex0, vTexCoord + vec2(-texelSize.x, 0.0)); | ||
neighbors[2] = texture2D(tex0, vTexCoord + vec2(0.0, texelSize.y)); | ||
neighbors[3] = texture2D(tex0, vTexCoord + vec2(0.0, -texelSize.y)); | ||
|
||
for (int i = 0; i < 4; i++) { | ||
vec4 color = neighbors[i]; | ||
float lum = luma(color.rgb); | ||
if (lum < curLuminance) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if the |
||
curColor = color; | ||
curLuminance = lum; | ||
} | ||
} | ||
|
||
gl_FragColor = curColor; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
precision highp float; | ||
|
||
varying vec2 vTexCoord; | ||
|
||
uniform sampler2D tex0; | ||
|
||
float luma(vec3 color) { | ||
// weighted grayscale with luminance values | ||
return dot(color, vec3(0.2126, 0.7152, 0.0722)); | ||
} | ||
|
||
void main() { | ||
vec4 tex = texture2D(tex0, vTexCoord); | ||
float gray = luma(tex.rgb); | ||
gl_FragColor = vec4(gray, gray, gray, tex.a); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we add
texelSize
to the documentation forcreateFilterShader
?