I am trying to implement some simple image processing in glsl like creating a gray and negative texture from an image but it seems I can't figure out why this doesn't work in the fragment shader. Style 2 which should turn the picture into gray works as intended but style 3 which should create a negative image just render a blank image.
#version 140
in vec2 textureCoords;
out vec4 out_Color;
uniform sampler2D guiTexture;
uniform int style;
void main(void)
{
if(style==1)
{
out_Color = texture(guiTexture,textureCoords);
}
else if(style==2)
{
out_Color = texture(guiTexture,textureCoords);
float grayscale = (out_Color.x+out_Color.y + out_Color.z)/3;
out_Color = vec4(grayscale,grayscale,grayscale,out_Color.w);
}
else if(style==3)
{
out_Color = texture(guiTexture,textureCoords);
float Newr = (255.0 - out_Color.x);
float Newg = (255.0 - out_Color.y);
float Newb = (255.0 - out_Color.z);
out_Color =vec4( Newr, Newg, Newb , out_Color.w);
}
}
Related
The first is model texture
The code in fs :
void main(void){
if (drawWireframe)
{
float ef = edgeFactor();
color = mix(wireColor, newFaceColor, ef);
}
float depth = logisticDepth(gl_FragCoord.z);
fragColor = vec4(vec3(depth), 1.0f);}
This is contour shader picture:
The code is
float linearizeDepth(float depth)
{
return (2.0 * near * far) / (far + near - (depth * 2.0 - 1.0) * (far - near));
}
float logisticDepth(float depth, float steepness = 0.1f, float offset = 5.0f)
{
float zVal = linearizeDepth(depth);
return (1 / (1 + exp(-steepness * (zVal - offset))));
}
void main(void)
{
float depth = logisticDepth(gl_FragCoord.z);
fragColor = vec4(vec3(depth,depth,depth), 1.0f);//-vec4(0,0,0.1,0);
}
Now the output like this:
And the code is like this
#version 410
out vec4 FragColor;
in vec3 ourColor;
in vec2 TexCoord;
uniform sampler2D texture1;
uniform sampler2D texture2;
uniform int width;
uniform int height;
int half_size=3;
void main()
{
vec4 color1 = texture(texture1, TexCoord);
vec4 color2 = texture(texture2, TexCoord);
vec4 color3;
if(color2.g<=color1.g &&color2.g!=1)
color3.rgb=vec3(1,0,0);
else //if(color2.r==1)
color3.rgb=vec3(1,1,1);
FragColor = color2;
}
But I need the output lines are same weight
I have the following fragment shader to draw a grid
#version 450 core
layout(location = 0) in vec2 position;
layout(location = 0) out vec4 fragColor;
layout(binding = 0) uniform ubo
{
mat4 uCameraView;
vec4 uGridColor;
float uTileSize;
float uGridBorderSize;
};
void main()
{
vec2 uv = mod(position, uTileSize);
vec2 border = mod(uv + (uGridBorderSize / 2.0), uTileSize);
border -= mod(uv - (uGridBorderSize / 2.0), uTileSize);
if (length(border) > uTileSize - uGridBorderSize)
{
fragColor = uGridColor;
}
else
{
fragColor = vec4(0.0);
}
}
This works fine until I change the zoom, the issue appears when the camera gets far away and the uGridBorderSize is smaller than a pixel in the screen, then I get this ugly effect, where lines appear and disappear when the zoom changes.
So I wonder, is it possible to apply antialising to this lines so they appear consistently?
In the end I found this fragment shader that draws antialiased grid lines
void main()
{
// https://madebyevan.com/shaders/grid/
vec2 uv = fragCoord / uTileSize;
vec2 grid = abs(fract(uv - 0.5) - 0.5) / fwidth(uv);
float line = (min(grid.x, grid.y) * uGridBorderSize) / uScaleFactor;
float color = 1.0 - min(line, 1.0);
fragColor = uGridColor * color;
}
I'm using a shader that swaps colors/palettes on a texture. The shader checks a pixel for transparency and then sets the pixel if not transparent. Is there an efficient way to ignore 0 alpha pixels other than a potential branch? In this case, where I set pixel = newPixel:
uniform bool alternate;
uniform sampler2D texture;
void main()
{
vec4 pixel = texture2D(bitmap, openfl_TextureCoordv);
if(alternate)
{
vec4 newPixel = texture2D(texture, vec2(pixel.r, pixel.b));
if(newPixel.a != 0.0)
pixel = newPixel;
}
gl_FragColor = pixel;
}
You can use mix and step:
void main()
{
vec4 pixel = texture2D(bitmap, openfl_TextureCoordv);
vec4 newPixel = texture2D(texture, vec2(pixel.r, pixel.b));
gl_FragColor = mix(pixel, newPixel,
float(alternate) * (1.0 - step(newPixel.a, 0.0)));
}
You may want to make a smooth transition depending on the alpha channel. In this case you only need mix:
gl_FragColor = mix(pixel, newPixel, float(alternate) * newPixel.a);
I would look into the step function. You can express the if statement as a product of two conditions.
For example:
if (a >= 0) {
b = c;
}
Is equivalent to
b = (step(a, 0)*c) + (1.0 - step(a, 0)*b);
In the code mentioned below, I want to accept 2 arguments colors & activeColor. colors array contains the list of allowed colors to be drawn in the image, activeColor is the selected color which is yet to be painted on image. I am using HTML5 canvas to paint on the top of image and WebGLShader to convert pixel colors as per the use-case.
While drawing(painting on canvas) a color my use-case is to change other colors if present to activeColor.
Written a basic logic below but it's not syntactically right. Help needed.
colors: dynamic Float32Array of colors ex: [0,0,0,1, 1,1,1,1] represents black & white color array
activeColor: dynamic Float32Array of color ex: [0,0,0,1] represents black color
uniform sampler2D texture;
varying float colors;
varying float activeColor;
varying vec2 texCoord;
void main() {
vec4 color = texture2D(texture, texCoord);
for (int i = 0; i < colors.length; i+=3){
vec4 c = vec4(colors[i], colors[i+1], colors[i+2], colors[i+3]);
if(color.a > 0 && color.rgb != c) {
color.rgb = vec4(activeColor[0], activeColor[1], activeColor[2], activeColor[3]);
}
}
gl_FragColor = color;
}
The code doesn't make a lot of sense
varying float colors;
varying float activeColor;
Those are type float so they only old 1 value. They are not colors (vec4s) nor are they arrays.
colors.length
There is no such thing someArray.length in GLSL. In GLSL you can't pass variable sized arrays. They must be a fixed size. Similarly you can't pass in arrays as varying.
It's not clear what you're trying to do
Your code appears to be trying to draw activeColor everywhere the image does not contain the colors in colors.
You could do something like this
#define MAX_COLORS 10
uniform sampler2D texture;
uniform vec4 colors[MAX_COLORS];
uniform int numColors;
uniform vec4 activeColor;
varying vec2 texCoord;
void main() {
vec4 color = texture2D(texture, texCoord);
for (int i = 0; i < MAX_COLORS; ++i) {
if (i >= numColors) {
break;
}
vec4 c = colors[i];
if(color.a > 0 && color.rgb != c) {
color.rgb = activeColor.rgb;
break;
}
}
gl_FragColor = color;
}
There's a limit on the number of uniform vec4s you can have. It's between 29 and 4096 through looking at the stats you probably want to stay under 221.
It's more common to pass in arrays of data as textures.
uniform sampler2D texture;
uniform sampler2D colors; // texture holding colors
uniform vec2 colorsSize; // size of texture
uniform int numColors;
uniform vec4 activeColor;
varying vec2 texCoord;
vec4 getColor(int i) {
vec2 pixelCoord = vec2(mod(float(i), colorsSize.x,
floor(float(i) / colorsSize.x));
return texture2D(colors, vec2(pixelCoord + 0.5 / colorsSize));
}
void main() {
vec4 color = texture2D(texture, texCoord);
for (int i = 0; i < MAX_COLORS; ++i) {
if (i >= numColors) {
break;
}
vec4 c = getColor(i);
if(color.a > 0 && color.rgb != c) {
color.rgb = activeColor.rgb;
break;
}
}
gl_FragColor = color;
}
Now you can pass in the colors as a texture.
You might find these tutorials useful.
You might also find this technique semi related to your problem (replacing colors) for which there is a live example here and another explanation of the technique here
I have a problem with my fragment shader.
I want to get the size of a texture (which is loaded from an image).
I know that it is possible to use textureSize(sampler) to get an ivec2 which contains the texture size. But i don't know why this isn't working (it doesn't compile):
#version 120
uniform sampler2D tex;
float textureSize;
float texelSize;
void main()
{
textureSize = textureSize(tex).x;//first line
//textureSize = 512.0;//if i set the above line as comment and use this one the shader compiles.
texelSize = 1.0 / textureSize;
vec4 color = texture2D(tex,gl_TexCoord[0].st);
gl_FragColor = color * gl_Color;
}
Th problem was that my GLSL version was to low (implemented in 1.30) and that i was missing a parameter.
Here the working version:
#version 130
uniform sampler2D tex;
float textureSize;
float texelSize;
void main()
{
ivec2 textureSize2d = textureSize(tex,0);
textureSize = float(textureSize2d.x);
texelSize = 1.0 / textureSize;
vec4 color = texture2D(tex,gl_TexCoord[0].st);
gl_FragColor = color * gl_Color;
}