Too many arguments to constructor of TouchDesigner's - glsl

I use TouchDesigner's GLSL. I want to try to make the color transparent like alpha but he will appear too many arguments to constructor of XXX
void main()
{
vec2 r = vUV.st;
vec3 backgroundColor = vec3(1.0,0,0,0);
vec3 axesColor = vec3(0.0, 0.0, 1.0);
vec3 gridColor = vec3(0.5);
// start by setting the background color. If pixel's value
// is not overwritten later, this color will be displayed.
vec3 pixel = backgroundColor;
// Draw the grid lines
// we used "const" because loop variables can only be manipulated
// by constant expressions.
const float tickWidth = 0.1;
for(float i=0.0; i<1.0; i+=tickWidth) {
// "i" is the line coordinate.
if(abs(r.x - i)<0.002) pixel = gridColor;
if(abs(r.y - i)<0.002) pixel = gridColor;
}
// Draw the axes
if( abs(r.x)<0.005 ) pixel = axesColor;
if( abs(r.y)<0.006 ) pixel = axesColor;
fragColor = TDOutputSwizzle(vec4(pixel, 1.0));
}

The issue is the line
vec3 backgroundColor = vec3(1.0,0,0,0);
You have passed 4 arguments to the constructor of vec3. A Vector constructor take the number of values that the vector stores.
Pass 3 singel floating point values to solve the issue:
vec3 backgroundColor = vec3(1.0, 0.0, 0.0);
The alpha channel is the 4th component. If you want to add an alpha channel, then you have to use vec4 instead of vec3:
void main()
{
vec2 r = vUV.st;
vec4 backgroundColor = vec4(1.0, 0.0, 0.0, 0.0); // red: 1, green: 0, blue: 0, alpha: 0
vec4 axesColor = vec3(0.0, 0.0, 1.0, 1.0); // red: 0, green: 0, blue: 1, alpha: 1
vec4 gridColor = vec3(0.5, 0.0, 0.0, 1.0); // red: 0.5, green: 0, blue: 0, alpha: 1
// start by setting the background color. If pixel's value
// is not overwritten later, this color will be displayed.
vec4 pixel = backgroundColor;
// Draw the grid lines
// we used "const" because loop variables can only be manipulated
// by constant expressions.
const float tickWidth = 0.1;
for(float i=0.0; i<1.0; i+=tickWidth) {
// "i" is the line coordinate.
if (abs(r.x - i) < 0.002 || abs(r.y - i) < 0.002)
pixel = gridColor;
}
// Draw the axes
if (abs(r.x) < 0.005 || abs(r.y) < 0.006)
pixel = axesColor;
fragColor = TDOutputSwizzle(pixel);
}

Related

Why drawing a texture using Opengl ( using rust ) is showing border colour

I am drawing this texture using opengl and rust. But for some reason the image has border around it when I draw away from the top left. I think there is something wrong with matrix / viewport. Not entirely sure.
let width = 1280; // Window is initialised to these values. Hard coded for context.
let height = 720;
unsafe {
gl::Viewport(0, 0, width, height);
}
let orth = cgmath::ortho::<f32>(0.0, width as f32, height as f32, 0.0, -1.00, 100.0)
unsafe {
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_BORDER as i32);
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_BORDER as i32);
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR as i32);
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR as i32);
let border_colour = [0.9, 0.2, 0.5, 1.0];
gl::TexParameterfv(gl::TEXTURE_2D, gl::TEXTURE_BORDER_COLOR, border_colour.as_ptr());
gl::TexImage2D(
gl::TEXTURE_2D,
0,
gl::RGBA as i32,
img.width as i32,
img.height as i32,
0,
gl::RGBA,
gl::UNSIGNED_BYTE,
data.as_ptr() as *const c_void,
);
gl::GenerateMipmap(gl::TEXTURE_2D);
}
Before Drawing the texture, I clear the display
pub fn clear_frame_buffer() {
unsafe {
gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
gl::ClearColor(0.0, 0.0, 0.0, 1.0);
}
}
Drawing the texture:
pub fn draw_quad(tex: &Texture2D, program : &Program, mesh : &Mesh, projection : &Matrix4<f32>, position : Vector3<f32>) {
program.bind();
mesh.vao.bind();
tex.bind();
if let Some(location) = program.get_uniform_location("view") {
let camera_transform = Matrix4::<f32>::identity() * Matrix4::from_scale(1.0);
program.set_matrix(location, &[camera_transform]);
}
if let Some(location) = program.get_uniform_location("projection") {
program.set_matrix(location, &[*projection]);
}
if let Some(location) = program.get_uniform_location("model") {
let model = {
let translate = Matrix4::<f32>::from_translation(position);
let (w, h) = tex.get_dimensions();
let scale = Matrix4::<f32>::from_nonuniform_scale(w as f32, h as f32, 1.0);
translate * scale
};
program.set_matrix(location, &[model]);
}
let count = mesh.count as i32;
unsafe {
gl::DrawArrays(gl::TRIANGLES, 0, count);
}
}
Then I move the texture
I know the pink is coming from my color text param. But I shouldn't be able to see it? I should be only drawing the image and not the border.
let quad_vertices: [f32; 30] = [
// Positions // Texcoords
1.0, -1.0, 0.0, 1.0, 0.0,
-1.0, -1.0, 0.0, 0.0, 0.0,
-1.0, 1.0, 0.0, 0.0, 1.0,
1.0, 1.0, 0.0, 1.0, 1.0,
1.0, -1.0, 0.0, 1.0, 0.0,
-1.0, 1.0, 0.0, 0.0, 1.0,
];
Vertex Shader
#version 330 core
layout (location = 0) in vec3 vertex;
layout (location = 2) in vec2 texcoords;
out vec2 TexCoords;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
TexCoords = texcoords;
gl_Position = projection * view * model * vec4(vertex.xy, 0.0, 1.0);
}
Fragment Shader
#version 330 core
in vec2 TexCoords;
out vec4 color;
uniform sampler2D image;
void main()
{
color = texture(image, TexCoords);
}

Quadratic curve stroke width on GPU

I was wondering how can I draw curves using a triangle, so I ended up reading these 2 articles.
http://commaexcess.com/articles/6/vector-graphics-on-the-gpu
http://www.mdk.org.pl/2007/10/27/curvy-blues
As I understand it correctly, the hardware interpolates u and v across three vertices.
Here is my result
My coordinates for the triangle
vec![100.0, 100.0
100.0, 100.0,
200.0, 100.0];
UV coordinates
vec![0.0, 0.0
0.5, 0.0
1.0, 1.0]
My fragment shader looks like this
#version 430 core
out vec4 frag_color;
in vec2 uv;
in vec4 cords;
void main() {
float x = uv.x;
float y = uv.y;
float result = (x*x) - y;
if(result > 0.0) {
frag_color = vec4(1.0, 0.1, 0.5, 1.0);
} else {
frag_color = vec4(2.0, 0.2, 3.0, 1.0);
}
}
I would like to have a good stroke at the middle point. I tried the following.
if(result > 0.01) {
frag_color = vec4(1.0,0.1,0.5, 1.0);
} else if(result < -0.01) {
frag_color = vec4(2.0,0.2,1.0, 1.0);
} else {
frag_color = vec4(2.0, 0.2, 3.0, 0.0); // mid point
}
I got this
But when i try to resize the triangle i get this result
The stroke width is thicker, but I want to keep the width in the previous image.
I have no idea how to achieve this, is it even possible ?

Implementing a gooey effect with a shader (Processing 3)

I'm trying to replicate a web design trick known as "gooey effect" (see it live here).
It's a technique applying SVG filters on moving ellipses in order to get a blob-like motion. The process is rather simple:
apply a gaussian blur
increase the contrast of the alpha channel only
The combination of the two creates a blob effect
The last step (increasing the alpha channel contrast) is usually done through a "color matrix filter".
A color matrix is composed of 5 columns (RGBA + offset) and 4 rows.
The values in the first four columns are multiplied with the source red, green, blue, and alpha values respectively. The fifth column value is added (offset).
In CSS, increasing the alpha channel contrast is as simple as calling a SVG filter and specifying the contrast value (here 18):
<feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -7" result="goo" />
In Processing though, it seems to be a bit more complicated. I believe (I may be wrong) the only way to apply a color matrix filter is to create one in a shader. After a few tries I came up with these (very basic) vertex and fragment shaders for color rendering:
colorvert.glsl
uniform mat4 transform;
attribute vec4 position;
attribute vec4 color;
varying vec4 vertColor;
uniform vec4 o=vec4(0, 0, 0, -9);
uniform lowp mat4 colorMatrix = mat4(1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 60.0);
void main() {
gl_Position = transform * position;
vertColor = (color * colorMatrix) + o ;
}
colorfrag.glsl
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
varying vec4 vertColor;
void main() {
gl_FragColor = vertColor;
}
PROBLEM:
The color matrix is partially working: changing the RGB values do affect the colors but changing the alpha values (last row) don't !
When trying to combine the shader with a Gaussian filter, the drawn ellipse stays blurry even after I set the alpha channel contrast to 60 (like in the codepen example):
PShader colmat;
void setup() {
size(200, 200, P2D);
colmat = loadShader("colorfrag.glsl", "colorvert.glsl");
}
void draw() {
background(100);
shader(colmat);
noStroke();
fill(255, 30, 30);
ellipse(width/2, height/2, 40, 40);
filter(BLUR,6);
}
The same thing happens when I implement the color matrix within #cansik 's Gaussian blur shader (from the PostFX library). I can see the colors changing but not the alpha contrast:
blurFrag.glsl
/ Adapted from:
// http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
#define PROCESSING_TEXTURE_SHADER
uniform sampler2D texture;
uniform vec4 o=vec4(0, 0, 0, 0);
uniform lowp mat4 colorMatrix = mat4(1, 0.0, 0.0, 0.0,
0.0, 1, 0.0, 0.0,
0.0, 0.0, 1, 0.0,
0, 0.0, 0.0, 60.0); //Alpha contrast set to 60
varying vec2 center;
// The inverse of the texture dimensions along X and Y
uniform vec2 texOffset;
varying vec4 vertColor;
varying vec4 vertTexCoord;
uniform int blurSize;
uniform int horizontalPass; // 0 or 1 to indicate vertical or horizontal pass
uniform float sigma; // The sigma value for the gaussian function: higher value means more blur
// A good value for 9x9 is around 3 to 5
// A good value for 7x7 is around 2.5 to 4
// A good value for 5x5 is around 2 to 3.5
// ... play around with this based on what you need <span class="Emoticon Emoticon1"><span>:)</span></span>
const float pi = 3.14159265;
void main() {
float numBlurPixelsPerSide = float(blurSize / 2);
vec2 blurMultiplyVec = 0 < horizontalPass ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
// Incremental Gaussian Coefficent Calculation (See GPU Gems 3 pp. 877 - 889)
vec3 incrementalGaussian;
incrementalGaussian.x = 1.0 / (sqrt(2.0 * pi) * sigma);
incrementalGaussian.y = exp(-0.5 / (sigma * sigma));
incrementalGaussian.z = incrementalGaussian.y * incrementalGaussian.y;
vec4 avgValue = vec4(0.0, 0.0, 0.0, 0.0);
float coefficientSum = 0.0;
// Take the central sample first...
avgValue += texture2D(texture, vertTexCoord.st) * incrementalGaussian.x;
coefficientSum += incrementalGaussian.x;
incrementalGaussian.xy *= incrementalGaussian.yz;
// Go through the remaining 8 vertical samples (4 on each side of the center)
for (float i = 1.0; i <= numBlurPixelsPerSide; i++) {
avgValue += texture2D(texture, vertTexCoord.st - i * texOffset *
blurMultiplyVec) * incrementalGaussian.x;
avgValue += texture2D(texture, vertTexCoord.st + i * texOffset *
blurMultiplyVec) * incrementalGaussian.x;
coefficientSum += 2.0 * incrementalGaussian.x;
incrementalGaussian.xy *= incrementalGaussian.yz;
}
gl_FragColor = (avgValue / coefficientSum ) * colorMatrix;
}
Setting glBlendFunc and enabling glEnable(GL_BLEND) in the main .pde file didn't fix the issue either.
sketch.pde
import ch.bildspur.postfx.builder.*;
import ch.bildspur.postfx.pass.*;
import ch.bildspur.postfx.*;
import processing.opengl.*;
import com.jogamp.opengl.*;
PostFX fx;
void setup() {
size(200, 200, P2D);
fx = new PostFX(this);
}
void draw() {
background(100);
GL gl = ((PJOGL)beginPGL()).gl.getGL();
gl.glEnable(GL.GL_BLEND);
gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE);
gl.glDisable(GL.GL_DEPTH_TEST);
noStroke();
fill(255, 30, 30);
ellipse(width/2, height/2, 40, 40);
fx.render().blur(80, 14).compose();
}
Questions:
Why does the alpha channel contrast not work ? How can I make it work ?
Is there something wrong with the way I implemented the color matrix ?
Do you know a better way to implement that gooey effect ?
Any help would be much appreciated !
Thank you
#noahbuddy from the Processing Forum could find a solution to the problem so I'm posting it here.
To preserve transparency, with or without shaders, use an offscreen
buffer (PGraphics). For example, saving a PNG image with transparent
background.
I removed the contrast matrix from #cansik 's blur shader and instead
put it into a separate filter.
blurfrag.glsl
// Adapted from:
// http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
#define PROCESSING_TEXTURE_SHADER
uniform sampler2D texture;
// The inverse of the texture dimensions along X and Y
uniform vec2 texOffset;
varying vec4 vertColor;
varying vec4 vertTexCoord;
uniform int blurSize;
uniform int horizontalPass; // 0 or 1 to indicate vertical or horizontal pass
uniform float sigma; // The sigma value for the gaussian function: higher value means more blur
// A good value for 9x9 is around 3 to 5
// A good value for 7x7 is around 2.5 to 4
// A good value for 5x5 is around 2 to 3.5
// ... play around with this based on what you need <span class="Emoticon Emoticon1"><span>:)</span></span>
const float pi = 3.14159265;
void main() {
float numBlurPixelsPerSide = float(blurSize / 2);
vec2 blurMultiplyVec = 0 < horizontalPass ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
// Incremental Gaussian Coefficent Calculation (See GPU Gems 3 pp. 877 - 889)
vec3 incrementalGaussian;
incrementalGaussian.x = 1.0 / (sqrt(2.0 * pi) * sigma);
incrementalGaussian.y = exp(-0.5 / (sigma * sigma));
incrementalGaussian.z = incrementalGaussian.y * incrementalGaussian.y;
vec4 avgValue = vec4(0.0, 0.0, 0.0, 0.0);
float coefficientSum = 0.0;
// Take the central sample first...
avgValue += texture2D(texture, vertTexCoord.st) * incrementalGaussian.x;
coefficientSum += incrementalGaussian.x;
incrementalGaussian.xy *= incrementalGaussian.yz;
// Go through the remaining 8 vertical samples (4 on each side of the center)
for (float i = 1.0; i <= numBlurPixelsPerSide; i++) {
avgValue += texture2D(texture, vertTexCoord.st - i * texOffset *
blurMultiplyVec) * incrementalGaussian.x;
avgValue += texture2D(texture, vertTexCoord.st + i * texOffset *
blurMultiplyVec) * incrementalGaussian.x;
coefficientSum += 2.0 * incrementalGaussian.x;
incrementalGaussian.xy *= incrementalGaussian.yz;
}
gl_FragColor = avgValue / coefficientSum;
}
colfrag.glsl
#define PROCESSING_TEXTURE_SHADER
uniform sampler2D texture;
varying vec4 vertTexCoord;
uniform vec4 o = vec4(0, 0, 0, -7.0);
uniform lowp mat4 colorMatrix = mat4(1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 18.0);
void main() {
vec4 pix = texture2D(texture, vertTexCoord.st);
vec4 color = (pix * colorMatrix) + o;
gl_FragColor = color;
}
sketch.pde
PShader contrast, blurry;
PGraphics buf;
void setup() {
size(200, 200, P2D);
buf = createGraphics(width, height, P2D);
contrast = loadShader("colfrag.glsl");
blurry = loadShader("blurFrag.glsl");
// Don't forget to set these
blurry.set("sigma", 4.5);
blurry.set("blurSize", 9);
}
void draw() {
background(100);
buf.beginDraw();
// Reset transparency
// Note, the color used here will affect your edges
// even with zero for alpha
buf.background(100, 0); // set to match main background
buf.noStroke();
buf.fill(255, 30, 30);
buf.ellipse(width/2, height/2, 40, 40);
buf.ellipse(mouseX, mouseY, 40, 40);
blurry.set("horizontalPass", 1);
buf.filter(blurry);
blurry.set("horizontalPass", 0);
buf.filter(blurry);
buf.endDraw();
shader(contrast);
image(buf, 0,0, width,height);
}
Personally I think the sweet spot lies somewhere:
between 8 and 11 for the alpha contrast
between -7 and -9 for the alpha offset
uniform vec4 o = vec4(0, 0, 0, -9.0);
uniform lowp mat4 colorMatrix = mat4(1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
1.0, 1.0, 1.0, 11.0);
bewteen 10 and 15 for "sigma"
bewteen 30 and 40 for "blurSize"
blurry.set("sigma", 14.5)
blurry.set("blurSize", 35)
I've coded 2d metaballs before using signed distance functions and marching square algorithms but I find this solution to be the most efficient one. Performance wise I can display up to 4500 balls at 60 fps on a 800x600 canvas (tested on an entry-level 2012 imac desktop with Python Mode).
Unfortunately I'm not able to debug the exact issue, but I have a couple of ideas that hopefully might help you make some progress:
For a simpler/cheaper effect you can use the dilate filter
You can find other metaballs shaders on shadertoy and tweak the code a bit so you can run it in Processing
For example https://www.shadertoy.com/view/MlcGWn becomes:
// https://www.shadertoy.com/view/MlcGWn
uniform float iTime;
uniform vec2 iResolution;
vec3 Sphere(vec2 uv, vec2 position, float radius)
{
float dist = radius / distance(uv, position);
return vec3(dist * dist);
}
void main()
{
vec2 uv = 2.0 * vec2(gl_FragCoord.xy - 0.5 * iResolution.xy) / iResolution.y;
vec3 pixel = vec3(0.0, 0.0, 0.0);
vec2 positions[4];
positions[0] = vec2(sin(iTime * 1.4) * 1.3, cos(iTime * 2.3) * 0.4);
positions[1] = vec2(sin(iTime * 3.0) * 0.5, cos(iTime * 1.3) * 0.6);
positions[2] = vec2(sin(iTime * 2.1) * 0.1, cos(iTime * 1.9) * 0.8);
positions[3] = vec2(sin(iTime * 1.1) * 1.1, cos(iTime * 2.6) * 0.7);
for (int i = 0; i < 4; i++)
pixel += Sphere(uv, positions[i], 0.22);
pixel = step(1.0, pixel) * pixel;
gl_FragColor = vec4(pixel, 1.0);
}
and in Processing:
PShader shader;
void setup(){
size(900,900,P2D);
shader = loadShader("metaballs.glsl");
shader.set("iResolution",(float)width/2,(float)height/2);
}
void draw(){
shader.set("iTime", millis() * 0.001);
shader(shader);
rect(0,0,width,height);
}
or https://www.shadertoy.com/view/ldtSRX
// https://www.shadertoy.com/view/ldtSRX
uniform vec2 iResolution;
uniform vec2 iMouse;
uniform float iTime;
struct Metaball{
vec2 pos;
float r;
vec3 col;
};
vec4 calcball( Metaball ball, vec2 uv)
{
float dst = ball.r / (pow(abs(uv.x - ball.pos.x), 2.) + pow(abs(uv.y - ball.pos.y), 2.));
return vec4(ball.col * dst, dst);
}
vec3 doballs( vec2 uv )
{
Metaball mouse;
mouse.pos = iMouse.xy / iResolution.yy;
mouse.r = .015;
mouse.col = vec3(.5);
Metaball mb1, mb2, mb3, mb4;
mb1.pos = vec2(1.3, .55+.2*sin(iTime*.5)); mb1.r = .05; mb1.col = vec3(0., 1., 0.);
mb2.pos = vec2(.6, .45); mb2.r = .02; mb2.col = vec3(0., .5, 1.);
mb3.pos = vec2(.85, .65); mb3.r = .035; mb3.col = vec3(1., .2, 0.);
mb4.pos = vec2(1.+.5*sin(iTime), .2); mb4.r = .02; mb4.col = vec3(1., 1., 0.);
vec4 ball1 = calcball(mb1, uv);
vec4 ball2 = calcball(mb2, uv);
vec4 ball3 = calcball(mb3, uv);
vec4 ball4 = calcball(mb4, uv);
vec4 subball1 = calcball(mouse, uv);
float res = ball1.a + ball2.a + ball3.a + ball4.a;
res -= subball1.a;
float threshold = res >= 1.5 ? 1. : 0.;
vec3 color = (ball1.rgb + ball2.rgb + ball3.rgb + ball4.rgb - subball1.rgb) / res;
color *= threshold;
color = clamp(color, 0., 1.);
return color;
}
#define ANTIALIAS 1
void main()
{
vec2 uv = gl_FragCoord.xy / iResolution.yy;
vec3 color = doballs(uv);
#ifdef ANTIALIAS
float uvs = .75 / iResolution.y;
color *= .5;
color += doballs(vec2(uv.x + uvs, uv.y))*.125;
color += doballs(vec2(uv.x - uvs, uv.y))*.125;
color += doballs(vec2(uv.x, uv.y + uvs))*.125;
color += doballs(vec2(uv.x, uv.y - uvs))*.125;
#if ANTIALIAS == 2
color *= .5;
color += doballs(vec2(uv.x + uvs*.85, uv.y + uvs*.85))*.125;
color += doballs(vec2(uv.x - uvs*.85, uv.y + uvs*.85))*.125;
color += doballs(vec2(uv.x - uvs*.85, uv.y - uvs*.85))*.125;
color += doballs(vec2(uv.x + uvs*.85, uv.y - uvs*.85))*.125;
#endif
#endif
gl_FragColor = vec4(color, 1.);
}
and in Processing:
PShader shader;
PVector mouse = new PVector();
void setup(){
size(900,900,P2D);
shader = loadShader("metaballs.glsl");
shader.set("iResolution",(float)width/2,(float)height/2);
}
void draw(){
mouse.set(mouseX,mouseY);
shader.set("iMouse", mouse);
shader.set("iTime", millis() * 0.001);
shader(shader);
rect(0,0,width,height);
}

Strange GLSL behavior

I'm trying to implement tonemap correction in my own graphic engine and I'm using, as reference, the excellent demo from asylum2010 (https://github.com/asylum2010/Asylum_Tutorials)
Now look: this is an adaptation of the shader taken from the aforesaid demo:
#version 150
uniform sampler2D sampler0;
uniform vec2 texelSize;
uniform int prevLevel;
in vec2 tex;
out vec4 my_FragColor0;
void main()
{
const vec3 LUMINANCE_VECTOR = vec3(0.2125, 0.7154, 0.0721);
vec4 sample = texture(sampler0, tex + vec2(-0.5, -0.5) * texelSize);
float dt = dot(sample.rgb, LUMINANCE_VECTOR);
if (sample.r > 0.99 && sample.g > 0.99 && sample.b > 0.99)
{
if (dt > 0.9998)
{
if (log(0.0001 + dt) < 1.0) // <== NOTICE THIS!
my_FragColor0 = vec4(0.1, 0.0, 0.0, 1.0);
else
my_FragColor0 = vec4(1.0, 0.0, 0.0, 1.0);
}
else
my_FragColor0 = vec4(0.0, 0.0, 0.0, 1.0);
}
else
my_FragColor0 = vec4(0.0, 0.0, 0.0, 1.0);
}
and this is the shader I wrote:
#version 150
uniform sampler2D ColorMap;
uniform vec2 TexelSize;
uniform int PreviousLevel;
in vec2 fragmentUV;
out vec4 fragment;
void main()
{
const vec3 LUMINANCE_VECTOR = vec3(0.2125, 0.7154, 0.0721);
vec4 sample = texture(ColorMap, fragmentUV + vec2(-0.5, -0.5) * TexelSize);
float dt = dot(sample.rgb, LUMINANCE_VECTOR);
if (sample.r > 0.99 && sample.g > 0.99 && sample.b > 0.99)
{
if (dt > 0.9998)
{
if (log(0.0001 + dt) < 1.0) // <== NOTICE THIS!
fragment = vec4(0.1, 0.0, 0.0, 1.0);
else
fragment = vec4(1.0, 0.0, 0.0, 1.0);
}
else
fragment = vec4(0.0, 0.0, 0.0, 1.0);
}
else
fragment = vec4(0.0, 0.0, 0.0, 1.0);
}
You may notice that, except for the variable names, the code is exactly the same.
Now when I run the first shader on its own engine, it outputs a full red color for almost white pixels of the passed sampler is almost white (r, g and b > 0.99), meaning the result of the log calculation is greater than 1.0
When I run my own shader (of course passing the same sample and with the same texel size), it outputs a dark red, meaning the log result is lower than 1.0.
It looks to me that the result of the second shader is correct but this is not the point. The point is: how coult the result be different?
Ok for the ones interested I finally found the issue.
The error is actually the dot product. I was passing as ColorMap a texture with internal format GL_RGBA while it is supposed to be a floating point texture in order to store values higher than 1.
Also I would like to know the reason of the downvote I received. Knowing the reason will help me to avoid any mistake I possibly made posting the question.

How to make a shader fade to a color?

This is the current shader I am using. It fades the object by slowly reducing the opacity. I want to fade to purple. How can this be done?
shader.frag:
uniform sampler2D texture;
uniform float opacity;
void main()
{
vec4 pixel = texture2D(texture, gl_TexCoord[0].xy);
gl_FragColor = pixel * vec4(1.0, 1.0, 1.0, opacity);
}
shader.vert:
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
gl_FrontColor = gl_Color;
}
application of shader in main function:
sf::Shader shader;
if (!shader.loadFromFile("shader.vert", "shader.frag"))
return EXIT_FAILURE;
float opacity = 1.0; //transparency of shader
shader.setParameter("texture", sf::Shader::CurrentTexture); //shader.vert
shader.setParameter("opacity", opacity); //shader.frag
////////////////////////////
//Delete Text Display
counter1 = 0;
for (iter8 = textDisplayArray.begin(); iter8 != textDisplayArray.end(); iter8++)
{
if (textDisplayArray[counter1].destroy == true)
{
//shader
opacity -= 0.1;
if (opacity <= 0)
{
textDisplayArray.erase(iter8);
opacity = 1;
}
shader.setParameter("opacity", opacity);
}
The RGB value for purple is vec3( 1.0, 0.0, 1.0 ) (maximum red, minimal green and maximum blue). You have to interpolate between your frgment color and the color value of purpel, similar as you do it with opacity. Use mix for this. mix(x, y, a) performs a linear interpolation between x and y using a to weight between them. The return value is computed as x×(1−a)+y×ax×(1−a)+y×a.
uniform sampler2D texture;
uniform float opacity;
uniform float purpleFac;
void main()
{
vec4 pixel = texture2D(texture, gl_TexCoord[0].xy);
vec3 mixedCol = mix( vec3( 1.0, 0.0, 1.0 ), pixel.rgb, purpleFac );
gl_FragColor = vec4( mixedCol , opacity );
}
Note you have to set uniform purpleFac similar as you do it with opacity. purpleFac shoud be in range [0.0, 1.0]. If purpleFac is 1.0 your fragment is colord purple and if it is 0.0 your fragment colol is the color of the texture only.