public SingleChannelSdf(CanvasToShaderSharedResource canvasShareResource) : base(canvasShareResource) { //credit: https://www.mapbox.com/blog/text-signed-distance-fields/ string vs = @" attribute vec4 a_position; attribute vec2 a_texCoord; uniform mat4 u_mvpMatrix; varying vec2 v_texCoord; void main() { gl_Position = u_mvpMatrix* a_position; v_texCoord = a_texCoord; } "; string fs = @" precision mediump float; uniform sampler2D s_texture; uniform vec4 u_color; uniform float u_buffer; uniform float u_gamma; varying vec2 v_texCoord; void main() { float dist = texture2D(s_texture, v_texCoord).r; float alpha = smoothstep(u_buffer - u_gamma, u_buffer + u_gamma, dist); gl_FragColor = vec4(u_color.rgb, alpha * u_color.a); } "; BuildProgram(vs, fs); }
public GdiImageTextureWithWhiteTransparentShader(CanvasToShaderSharedResource canvasShareResource) : base(canvasShareResource) { string vs = @" attribute vec4 a_position; attribute vec2 a_texCoord; uniform mat4 u_mvpMatrix; varying vec2 v_texCoord; void main() { gl_Position = u_mvpMatrix* a_position; v_texCoord = a_texCoord; } "; //in fs, angle on windows //we need to switch color component //because we store value in memory as BGRA //and gl expect input in RGBA string fs = @" precision mediump float; varying vec2 v_texCoord; uniform sampler2D s_texture; void main() { vec4 c = texture2D(s_texture, v_texCoord); if((c[2] ==1.0) && (c[1]==1.0) && (c[0]== 1.0) && (c[3] == 1.0)){ discard; }else{ gl_FragColor = vec4(c[2],c[1],c[0],c[3]); } } "; BuildProgram(vs, fs); }
public BasicFillShader(CanvasToShaderSharedResource canvasShareResource) : base(canvasShareResource) { //---------------- //vertex shader source string vs = @" attribute vec2 a_position; uniform mat4 u_mvpMatrix; uniform vec4 u_solidColor; varying vec4 v_color; void main() { gl_Position = u_mvpMatrix* vec4(a_position[0],a_position[1],0,1); v_color= u_solidColor; } "; //fragment source string fs = @" precision mediump float; varying vec4 v_color; void main() { gl_FragColor = v_color; } "; if (!shaderProgram.Build(vs, fs)) { throw new NotSupportedException(); } a_position = shaderProgram.GetAttrV2f("a_position"); u_matrix = shaderProgram.GetUniformMat4("u_mvpMatrix"); u_solidColor = shaderProgram.GetUniform4("u_solidColor"); }
public OpenGLESTextureShader(CanvasToShaderSharedResource canvasShareResource) : base(canvasShareResource) { //-------------------------------------------------------------------------- string vs = @" attribute vec4 a_position; attribute vec2 a_texCoord; uniform mat4 u_mvpMatrix; varying vec2 v_texCoord; void main() { gl_Position = u_mvpMatrix* a_position; v_texCoord = a_texCoord; } "; //this case we not need to swap string fs = @" precision mediump float; varying vec2 v_texCoord; uniform sampler2D s_texture; void main() { gl_FragColor = texture2D(s_texture, v_texCoord); } "; BuildProgram(vs, fs); }
FrameBuffer _currentFrameBuffer;//default = null, system provide frame buffer internal CanvasGL2d(int canvasW, int canvasH) { this.canvasW = canvasW; this.canvasH = canvasH; ////setup viewport size int max = Math.Max(canvasW, canvasH); ////square viewport orthoView = MyMat4.ortho(0, max, 0, max, 0, 1); flipVerticalView = MyMat4.scale(1, -1) * MyMat4.translate(new OpenTK.Vector3(0, -max, 0)); orthoAndFlip = orthoView * flipVerticalView; //----------------------------------------------------------------------- shaderRes = new CanvasToShaderSharedResource(); shaderRes.OrthoView = orthoView; //----------------------------------------------------------------------- basicFillShader = new BasicFillShader(shaderRes); smoothLineShader = new SmoothLineShader(shaderRes); rectFillShader = new RectFillShader(shaderRes); gdiImgTextureShader = new GdiImageTextureShader(shaderRes); gdiImgTextureWithWhiteTransparentShader = new GdiImageTextureWithWhiteTransparentShader(shaderRes); textureSubPixRendering = new ImageTextureWithSubPixelRenderingShader(shaderRes); blurShader = new BlurShader(shaderRes); glesTextureShader = new OpenGLESTextureShader(shaderRes); invertAlphaFragmentShader = new InvertAlphaLineSmoothShader(shaderRes); //used with stencil *** // tessListener.Connect(tess, //Tesselate.Tesselator.WindingRuleType.Odd, true); conv3x3TextureShader = new Conv3x3TextureShader(shaderRes); msdfShader = new DrawingGL.MultiChannelSdf(shaderRes); msdfSubPixelRenderingShader = new DrawingGL.MultiChannelSubPixelRenderingSdf(shaderRes); sdfShader = new DrawingGL.SingleChannelSdf(shaderRes); //---- Tesselator tess = new Tesselator(); tess.WindingRule = Tesselator.WindingRuleType.Odd; tessTool = new TessTool(tess); //----------------------------------------------------------------------- //GL.Enable(EnableCap.CullFace); //GL.FrontFace(FrontFaceDirection.Cw); //GL.CullFace(CullFaceMode.Back); GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);//original ** //GL.BlendFunc(BlendingFactorSrc.SrcColor, BlendingFactorDest.One);// not apply alpha to src //GL.BlendFuncSeparate(BlendingFactorSrc.SrcColor, BlendingFactorDest.OneMinusSrcAlpha, // BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); //GL.BlendFuncSeparate(BlendingFactorSrc.SrcColor, BlendingFactorDest.OneMinusSrcColor, BlendingFactorSrc.SrcAlpha, BlendingFactorDest.Zero); GL.ClearColor(1, 1, 1, 1); //------------------------------------------------------------------------------- GL.Viewport(0, 0, canvasW, canvasH); }
FrameBuffer _currentFrameBuffer;//default = null, system provide frame buffer internal CanvasGL2d(int canvasW, int canvasH) { this.canvasW = canvasW; this.canvasH = canvasH; ////setup viewport size int max = Math.Max(canvasW, canvasH); ////square viewport orthoView = MyMat4.ortho(0, max, 0, max, 0, 1); //----------------------------------------------------------------------- shaderRes = new CanvasToShaderSharedResource(); shaderRes.OrthoView = orthoView; //----------------------------------------------------------------------- basicFillShader = new BasicFillShader(shaderRes); smoothLineShader = new SmoothLineShader(shaderRes); rectFillShader = new RectFillShader(shaderRes); gdiImgTextureShader = new GdiImageTextureShader(shaderRes); gdiImgTextureWithWhiteTransparentShader = new GdiImageTextureWithWhiteTransparentShader(shaderRes); blurShader = new BlurShader(shaderRes); glesTextureShader = new OpenGLESTextureShader(shaderRes); invertAlphaFragmentShader = new InvertAlphaLineSmoothShader(shaderRes); //used with stencil *** // tessListener.Connect(tess, //Tesselate.Tesselator.WindingRuleType.Odd, true); conv3x3TextureShader = new Conv3x3TextureShader(shaderRes); msdfShader = new DrawingGL.MultiChannelSdf(shaderRes); msdfSubPixelRenderingShader = new DrawingGL.MultiChannelSubPixelRenderingSdf(shaderRes); sdfShader = new DrawingGL.SingleChannelSdf(shaderRes); //---- Tesselator tess = new Tesselator(); tess.WindingRule = Tesselator.WindingRuleType.Odd; tessTool = new TessTool(tess); //----------------------------------------------------------------------- //GL.Enable(EnableCap.CullFace); //GL.FrontFace(FrontFaceDirection.Cw); //GL.CullFace(CullFaceMode.Back); GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GL.ClearColor(1, 1, 1, 1); //------------------------------------------------------------------------------- GL.Viewport(0, 0, canvasW, canvasH); }
ShaderUniformVar4 _d_color; //drawing color public ImageTextureWithSubPixelRenderingShader(CanvasToShaderSharedResource canvasShareResource) : base(canvasShareResource) { string vs = @" attribute vec4 a_position; attribute vec2 a_texCoord; uniform mat4 u_mvpMatrix; varying vec2 v_texCoord; void main() { gl_Position = u_mvpMatrix* a_position; v_texCoord = a_texCoord; } "; //in fs, angle on windows //we need to switch color component //because we store value in memory as BGRA //and gl expect input in RGBA string fs = @" precision mediump float; uniform sampler2D s_texture; uniform int isBigEndian; uniform int c_compo; uniform vec4 d_color; uniform float c_intensity; varying vec2 v_texCoord; void main() { float v_texCoord0 =v_texCoord[0]; float v_texCoord1= v_texCoord[1]; vec4 c= texture2D(s_texture,vec2(v_texCoord0 ,v_texCoord1)); if(c_compo==0){ gl_FragColor = vec4(d_color[0],d_color[1],d_color[2],(c[0]* d_color[3])*c_intensity); }else if(c_compo==1){ gl_FragColor = vec4(d_color[0],d_color[1],d_color[2],(c[1]* d_color[3])*c_intensity); }else{ gl_FragColor = vec4(d_color[0],d_color[1],d_color[2],(c[2]* d_color[3])*c_intensity); } } "; BuildProgram(vs, fs); }
public MultiChannelSdf(CanvasToShaderSharedResource canvasShareResource) : base(canvasShareResource) { //credit: https://github.com/Chlumsky/msdfgen string vs = @" attribute vec4 a_position; attribute vec2 a_texCoord; uniform mat4 u_mvpMatrix; varying vec2 v_texCoord; void main() { gl_Position = u_mvpMatrix* a_position; v_texCoord = a_texCoord; } "; //enable derivative extension for fwidth() function //see //https://www.khronos.org/registry/gles/extensions/OES/OES_standard_derivatives.txt //https://github.com/AnalyticalGraphicsInc/cesium/issues/745 //https://developer.mozilla.org/en-US/docs/Web/API/OES_standard_derivatives //https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Using_Extensions string fs = @" #ifdef GL_OES_standard_derivatives #extension GL_OES_standard_derivatives : enable #endif precision mediump float; varying vec2 v_texCoord; uniform sampler2D s_texture; //msdf texture uniform vec4 fgColor; float median(float r, float g, float b) { return max(min(r, g), min(max(r, g), b)); } void main() { vec4 sample = texture2D(s_texture, v_texCoord); float sigDist = median(sample[0], sample[1], sample[2]) - 0.5; float opacity = clamp(sigDist/fwidth(sigDist) + 0.5, 0.0, 1.0); vec4 finalColor=vec4(fgColor[0],fgColor[1],fgColor[2],opacity); //mix(bgColor, fgColor, opacity); gl_FragColor= finalColor; } "; BuildProgram(vs, fs); }
public SimpleRectTextureShader(CanvasToShaderSharedResource canvasShareResource) : base(canvasShareResource) { }
public MultiChannelSubPixelRenderingSdf(CanvasToShaderSharedResource canvasShareResource) : base(canvasShareResource) { BuildProgramV1(); //BuildProgramV2(); }
public ShaderBase(CanvasToShaderSharedResource canvasShareResource) { _canvasShareResource = canvasShareResource; }
public SmoothLineShader(CanvasToShaderSharedResource canvasShareResource) : base(canvasShareResource) { string vs = @" attribute vec4 a_position; uniform mat4 u_mvpMatrix; uniform vec4 u_solidColor; uniform float u_linewidth; varying vec4 v_color; varying float v_distance; varying float p0; void main() { float rad = a_position[3]; v_distance= a_position[2]; float n_x = sin(rad); float n_y = cos(rad); vec4 delta; if(v_distance <1.0){ delta = vec4(-n_x * u_linewidth,n_y * u_linewidth,0,0); }else{ delta = vec4(n_x * u_linewidth,-n_y * u_linewidth,0,0); } if(u_linewidth <= 0.5){ p0 = 0.5; }else if(u_linewidth <=1.0){ p0 = 0.45; }else if(u_linewidth>1.0 && u_linewidth<3.0){ p0 = 0.25; }else{ p0= 0.1; } vec4 pos = vec4(a_position[0],a_position[1],0,1) + delta; gl_Position = u_mvpMatrix* pos; v_color= u_solidColor; } "; //fragment source string fs = @" precision mediump float; varying vec4 v_color; varying float v_distance; varying float p0; void main() { float d0= v_distance; float p1= 1.0-p0; float factor= 1.0 /p0; if(d0 < p0){ gl_FragColor =vec4(v_color[0],v_color[1],v_color[2], v_color[3] *(d0 * factor)); }else if(d0> p1){ gl_FragColor =vec4(v_color[0],v_color[1],v_color[2], v_color[3] *((1.0-d0)* factor)); } else{ gl_FragColor =v_color; } } "; //--------------------- if (!shaderProgram.Build(vs, fs)) { return; } //----------------------- a_position = shaderProgram.GetAttrV4f("a_position"); u_matrix = shaderProgram.GetUniformMat4("u_mvpMatrix"); u_solidColor = shaderProgram.GetUniform4("u_solidColor"); u_linewidth = shaderProgram.GetUniform1("u_linewidth"); }
public BlurShader(CanvasToShaderSharedResource canvasShareResource) : base(canvasShareResource) { BuildShaderV3(); }
public Conv3x3TextureShader(CanvasToShaderSharedResource canvasShareResource) : base(canvasShareResource) { //-------------------------------------------------------------------------- string vs = @" attribute vec4 a_position; attribute vec2 a_texCoord; uniform mat4 u_mvpMatrix; varying vec2 v_texCoord; void main() { gl_Position = u_mvpMatrix* a_position; v_texCoord = a_texCoord; } "; //in fs, angle on windows //we need to switch color component //because we store value in memory as BGRA //and gl expect input in RGBA string fs = @" precision mediump float; uniform sampler2D s_texture; uniform int isBigEndian; uniform mat3 convKernel; uniform float kernelWeight; uniform vec2 onepix_xy; varying vec2 v_texCoord; void main() { vec4 c = vec4(0.0); float v_texCoord1= v_texCoord[1]; float v_texCoord0 =v_texCoord[0]; float one_x=onepix_xy[0]; float one_y=onepix_xy[1]; c += texture2D(s_texture,vec2(v_texCoord0-one_x,v_texCoord1+one_y))*convKernel[0][0]; c += texture2D(s_texture,vec2(v_texCoord0 ,v_texCoord1+one_y))*convKernel[0][1]; c += texture2D(s_texture,vec2(v_texCoord0+one_x,v_texCoord1+one_y))*convKernel[0][2]; c += texture2D(s_texture,vec2(v_texCoord0-one_x,v_texCoord1))*convKernel[1][0]; c += texture2D(s_texture,vec2(v_texCoord0 ,v_texCoord1))*convKernel[1][1]; c += texture2D(s_texture,vec2(v_texCoord0+one_x,v_texCoord1))*convKernel[1][2]; c += texture2D(s_texture,vec2(v_texCoord0-one_x,v_texCoord1-one_y))*convKernel[2][0]; c += texture2D(s_texture,vec2(v_texCoord0 ,v_texCoord1-one_y))*convKernel[2][1]; c += texture2D(s_texture,vec2(v_texCoord0+one_x,v_texCoord1-one_y))*convKernel[2][2]; c= c / kernelWeight; if(isBigEndian ==1){ gl_FragColor = vec4(c[0],c[1],c[2],1); }else{ gl_FragColor = vec4(c[2],c[1],c[0],1); } } "; BuildProgram(vs, fs); SetConvolutionKernel(Mat3x3ConvGen.gaussianBlur); }
public InvertAlphaLineSmoothShader(CanvasToShaderSharedResource canvasShareResource) : base(canvasShareResource) { //------------------------------------------------------------------------------- string vs = @" attribute vec4 a_position; uniform mat4 u_mvpMatrix; uniform vec4 u_solidColor; uniform float u_linewidth; varying vec4 v_color; varying float v_distance; varying float p0; void main() { float rad = a_position[3]; v_distance= a_position[2]; float n_x = sin(rad); float n_y = cos(rad); vec4 delta; if(v_distance <1.0){ delta = vec4(-n_x * u_linewidth,n_y * u_linewidth,0,0); }else{ delta = vec4(n_x * u_linewidth,-n_y * u_linewidth,0,0); } if(u_linewidth <= 0.5){ p0 = 0.5; }else if(u_linewidth <=1.0){ p0 = 0.45; }else if(u_linewidth>1.0 && u_linewidth<3.0){ p0 = 0.25; }else{ p0= 0.1; } vec4 pos = vec4(a_position[0],a_position[1],0,1) + delta; gl_Position = u_mvpMatrix* pos; v_color= u_solidColor; } "; //fragment source //this is invert fragment shader *** //so we string fs = @" precision mediump float; varying vec4 v_color; varying float v_distance; varying float p0; void main() { float d0= v_distance; float p1= 1.0-p0; float factor= 1.0 /p0; if(d0 < p0){ gl_FragColor = vec4(v_color[0],v_color[1],v_color[2], 1.0 -(v_color[3] *(d0 * factor))); }else if(d0> p1){ gl_FragColor= vec4(v_color[0],v_color[1],v_color[2],1.0-(v_color[3] *((1.0-d0)* factor))); } else{ gl_FragColor = vec4(0,0,0,0); } } "; //--------------------- if (!shaderProgram.Build(vs, fs)) { return; } //----------------------- a_position = shaderProgram.GetAttrV4f("a_position"); u_matrix = shaderProgram.GetUniformMat4("u_mvpMatrix"); u_solidColor = shaderProgram.GetUniform4("u_solidColor"); u_linewidth = shaderProgram.GetUniform1("u_linewidth"); _strokeColor = Drawing.Color.Black; }