You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
2.1 KiB
88 lines
2.1 KiB
|
6 years ago
|
// created by florian berger (flockaroo) - 2018
|
||
|
|
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
|
||
|
|
|
||
|
|
// oil paint brush drawing
|
||
|
|
|
||
|
|
// generating stroke texture
|
||
|
|
|
||
|
|
#define MULTI_STROKE
|
||
|
|
|
||
|
|
#define Res (iResolution.xy)
|
||
|
|
#define Res0 vec2(textureSize(iChannel0,0))
|
||
|
|
#define Res1 vec2(textureSize(iChannel1,0))
|
||
|
|
#define Res2 vec2(textureSize(iChannel2,0))
|
||
|
|
|
||
|
|
#define PI 3.1415927
|
||
|
|
|
||
|
|
#define N(v) (v.yx*vec2(1,-1))
|
||
|
|
|
||
|
|
uniform float StrokeBend;
|
||
|
|
uniform float StrokeContour;
|
||
|
|
uniform float StrokeDir;
|
||
|
|
|
||
|
|
vec4 getRand(int idx)
|
||
|
|
{
|
||
|
|
ivec2 rres=textureSize(iChannel1,0);
|
||
|
|
idx=idx%(rres.x*rres.y);
|
||
|
|
return texelFetch(iChannel1,ivec2(idx%rres.x,idx/rres.x),0);
|
||
|
|
}
|
||
|
|
|
||
|
|
float getStroke(vec2 uv, int pidx)
|
||
|
|
{
|
||
|
|
vec4 rnd = getRand(pidx);
|
||
|
|
uv-=.5;
|
||
|
|
uv.x-=.035*StrokeBend*1.;
|
||
|
|
uv.x+=uv.y*uv.y*StrokeBend*1.;
|
||
|
|
//uv.x*=1.+.25*abs(StrokeBend);
|
||
|
|
uv.x*=1.2;
|
||
|
|
uv.y+=-StrokeBend*.1*(uv.x)+.05+.01*sin(uv.x*24.+float(pidx)*3.);
|
||
|
|
uv+=.5;
|
||
|
|
uv=clamp(uv,0.,1.);
|
||
|
|
float s=1.;
|
||
|
|
s*=uv.x*(1.-uv.x)*6.;
|
||
|
|
s*=uv.y*(1.-uv.y)*6.;
|
||
|
|
float s0=s;
|
||
|
|
s=(s-.5);
|
||
|
|
vec2 uv0=uv;
|
||
|
|
|
||
|
|
// move noise coord for each brush stroke
|
||
|
|
uv+=rnd.z*vec2(7,5)*303.72;
|
||
|
|
|
||
|
|
// brush hair noise
|
||
|
|
float psc=1.;
|
||
|
|
float pat = textureLod(iChannel1,psc*uv*1.5*sqrt(Res.x/600.)*vec2(.06,.006),.5).x
|
||
|
|
+textureLod(iChannel1,psc*uv*3.0*sqrt(Res.x/600.)*vec2(.06,.006),.5).x;
|
||
|
|
|
||
|
|
s0=s;
|
||
|
|
uv0.y=1.-uv0.y;
|
||
|
|
|
||
|
|
//s=(14.*(1.-uv0.y)*s0)*(exp(-s0*3.5))-uv0.y*.5;
|
||
|
|
s=(14.*(1.-uv0.y)*s0)*(exp(-s0*3.5/(StrokeContour+.01))-uv0.y*.5)-uv0.y*.5;
|
||
|
|
|
||
|
|
s=max(s,(pow(abs(s0),.2)*((s0>0.0)?1.:-1.)+(pat-1.4)-uv0.y*1.)*1.);
|
||
|
|
//s=mix((s0*1.+pat-1.)*1.,s,StrokeContour);
|
||
|
|
|
||
|
|
return s;
|
||
|
|
}
|
||
|
|
|
||
|
|
uniform int strokeSeed;
|
||
|
|
#ifdef MULTI_STROKE
|
||
|
|
uniform vec2 strokeNumXY;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
void mainImage( out vec4 fragColor, vec2 fragCoord )
|
||
|
|
{
|
||
|
|
int seed=strokeSeed;
|
||
|
|
vec2 uv = fragCoord.xy / Res2;
|
||
|
|
#ifdef MULTI_STROKE
|
||
|
|
vec2 xynum=floor(max(vec2i(strokeNumXY),vec2i(1)));
|
||
|
|
vec2 uv2 = fract(uv*xynum);
|
||
|
|
vec2 xy = floor(uv*xynum);
|
||
|
|
uv=uv2;
|
||
|
|
seed+=7*int(xy.y*xynum.x+xy.x);
|
||
|
|
#endif
|
||
|
|
fragColor.xyz =vec3i(0) + getStroke(uv,seed);
|
||
|
|
fragColor.w = 1.;
|
||
|
|
}
|
||
|
|
|