The code inside my fragment shader is:
"precision mediump float;\n" +
"varying vec2 vTextureCoord;\n" +
"uniform sampler2D sTexture;\n" +
"uniform float Opacity;\n" + // range 0.0 to 1.0
"void main() {\n" +
" gl_FragColor = texture2D(sTexture, vTextureCoord);\n"+
" gl_FragColor.a *= Opacity;\n" +
"}\n";
which works, I tried to add an if inside :
"precision mediump float;\n" +
"varying vec2 vTextureCoord;\n" +
"uniform sampler2D sTexture;\n" +
"uniform float Opacity;\n" + // range 0.0 to 1.0
"void main() {\n" +
" gl_FragColor = texture2D(sTexture, vTextureCoord);\n"+
" gl_FragColor.a *= Opacity;\n" +
" if(gl_FragColor.a < 250){;\n" +
" gl_FragColor.a = 250;\n" +
" }\n" +
"}\n";
and it does not work, I cant figure this one out, I will appreciate some help
Related
I am implementing an android app with OpenGL and C++, I am rendering some triangles with different Y position, all of them are in the X-Z plane, the camera is Orthographic projection with near value 3 for example.
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
The orthographic projection is:
projectionMatrix = glm::ortho(-(width/2.f)/zoom, (width/2.f)/zoom, -(height/2.f)/zoom,(height/2.f)/zoom,near,far);
these values are
projectionMatrix = glm::ortho(-100, 100, -197,197,3,50);
sometimes I get the triangles seem to have Z-Fighting although they have different Y values, the camera looks at them from above.
vertexShader = "#version 300 es\n"
"precision highp float;\n"
"layout (location = 0) in vec3 position;\n"
"layout (location = 1) in vec3 normal;\n"
"layout (location = 2) in vec2 texCoord;\n"
"\n"
"uniform mat4 model;\n"
"uniform mat4 view;\n"
"uniform mat4 projection;\n"
"\n"
"out vec2 TexCoords;\n"
"out vec3 Normal;\n"
"out vec3 FragPos;\n"
"\n"
"void main(){\n"
" Normal = mat3(transpose(inverse(model))) * normal;\n"
" TexCoords = texCoord;\n"
" FragPos = vec3(model * vec4(position, 1.0));\n"
" gl_Position = projection * view * model * vec4(position, 1.0);\n"
"}";
fragmentShader = "#version 300 es\n"
"precision highp float;\n"
"\n"
"struct DirectLight{\n"
" vec3 Direction;"
" vec3 color;\n"
" float intensity;\n"
"};\n"
"out vec4 glFragColor;\n"
"\n"
"in vec2 TexCoords;\n"
"in vec3 Normal;\n"
"in vec3 FragPos;\n"
"\n"
"uniform int hasTexture;\n"
"uniform int hasSpecular;\n"
"uniform float alpha;\n"
"uniform vec3 ViewPos;\n"
"\n"
"uniform sampler2D map_diffuse;\n"
"uniform sampler2D map_specular;\n"
"\n"
"uniform vec3 diffuse;\n"
"uniform vec3 specular;\n"
"uniform float shininess;\n"
"uniform DirectLight Sun1;\n"
"vec3 calcLight(DirectLight light,vec3 diffColor,vec3 specColor){"
" vec3 normal = normalize(Normal);\n"
" vec3 lightDir = normalize(-light.Direction);\n"
" float diffFactor = max(dot(normal,lightDir), 0.0);\n"
" vec3 _diffuse = light.intensity * light.color * diffFactor * diffColor;\n"
" vec3 viewDir = normalize(ViewPos - FragPos);\n"
" vec3 halfwayDir = normalize(lightDir + viewDir);\n"
" float specFactor = pow(max(dot(normal, halfwayDir), 0.0), shininess);\n"
" vec3 _specular = specColor * light.intensity * light.color * specFactor;\n"
" return _diffuse + _specular ;\n"
"}"
"void main(){\n"
" vec4 diffColor;\n"
" vec4 specColor;\n"
" if(hasTexture == 1)\n"
" diffColor = texture(map_diffuse, TexCoords);\n"
" else\n"
" diffColor = vec4(diffuse,alpha);\n"
" if(hasSpecular == 1)\n"
" specColor = texture(map_specular, TexCoords);\n"
" else\n"
" specColor = vec4(specular,alpha);\n"
" vec4 _ambient = vec4(0.4,0.4,0.4,alpha) * diffColor;\n"
" vec4 result = vec4("
" calcLight(Sun1,diffColor.xyz,specColor.xyz),alpha)"
" + _ambient;"
" float gamma = 2.2;\n"
" result = pow(result, vec4(1.0/gamma));\n"
" glFragColor = result;\n"
"}";
I am a freshman with OpenGL. I try to find the solution to my problem. I have recorded a video with alpha mask. The top part of video RGB and bottom is alpha. As I understand need to change my shaders, but I don`t understand how to do this.
Vertex shader
private static final String vertexShaderCode =
"attribute vec4 vPosition;" +
"attribute vec4 vTexCoordinate;" +
"uniform mat4 textureTransform;" +
"varying vec2 v_TexCoordinate;" +
"void main() {" +
" v_TexCoordinate = (textureTransform * vTexCoordinate).xy;" +
" gl_Position = vPosition;" +
"}";
Fragment shader
private static final String fragmentShaderCode =
"#extension GL_OES_EGL_image_external : require\n" +
"precision mediump float;" +
"uniform samplerExternalOES texture;" +
"varying vec2 v_TexCoordinate;" +
"void main () {" +
" vec4 color = texture2D(texture, v_TexCoordinate);" +
" gl_FragColor = color;" +
"}";
To skip fragments you can use the discard keyword in the fragment shader.
You have to do 2 look ups to the texture. The first one in the upper half, to get the RGB color channels and the 2nd one in the lower half to get the mask from the red color channel:
vec2 c_uv = vec2(texture.x, texture.y*0.5);
vec4 color = texture2D(c_uv, v_TexCoordinate);
vec2 m_uv = vec2(texture.x, 0.5 + texture.y*0.5);
float mask = texture2D(m_uv, v_TexCoordinate).r;
The fragment shader may look like this:
#extension GL_OES_EGL_image_external : require
precision mediump float;
uniform samplerExternalOES texture;
varying vec2 v_TexCoordinate;
void main () {
vec2 m_uv = vec2(v_TexCoordinate.x, 0.5 + v_TexCoordinate.y*0.5);
float mask = texture2D(texture, m_uv).r;
if ( mask < 0.5 )
discard;
vec2 c_uv = vec2(v_TexCoordinate.x, v_TexCoordinate.y*0.5);
vec4 color = texture2D(texture, c_uv);
gl_FragColor = color;
}
For my android application, I want to apply brightness and contrast shader on same image.
At present I am using gpuimage plugin. In that I found two separate program for brightness and contrast as per the following.
public static final String CONTRAST_FRAGMENT_SHADER = "" +
"varying highp vec2 textureCoordinate;\n" +
" \n" +
" uniform sampler2D inputImageTexture;\n" +
" uniform lowp float contrast;\n" +
" \n" +
" void main()\n" +
" {\n" +
" lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" +
" \n" +
" gl_FragColor = vec4(((textureColor.rgb - vec3(0.5)) * contrast + vec3(0.5)), textureColor.w);\n" +
" }";
public static final String BRIGHTNESS_FRAGMENT_SHADER = ""
+ "varying highp vec2 textureCoordinate;\n"
+ " \n"
+ " uniform sampler2D inputImageTexture;\n"
+ " uniform lowp float brightness;\n"
+ " \n"
+ " void main()\n"
+ " {\n"
+ " lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n"
+ " \n"
+ " gl_FragColor = vec4((textureColor.rgb + vec3(brightness)), textureColor.w);\n"
+ " }";
Now applying both of the effects I write following code
public static final String CONTRAST_BRIGHTNESS_FRAGMENT_SHADER = ""
+ "varying highp vec2 textureCoordinate;\n"
+ " uniform sampler2D inputImageTexture;\n"
+ "varying highp vec2 textureCoordinate2;\n"
+ " uniform sampler2D inputImageTexture2;\n"
+ " uniform lowp float contrast;\n"
+ " uniform lowp float brightness;\n"
+ " \n"
+ " void main()\n"
+ " {\n"
+ " lowp vec4 textureColorForContrast = texture2D(inputImageTexture, textureCoordinate);\n"
+ " \n"
+ " lowp vec4 contastVec4 = vec4(((textureColorForContrast.rgb - vec3(0.5)) * contrast + vec3(0.5)), textureColorForContrast.w);\n"
+ " lowp vec4 textureColorForBrightness = texture2D(inputImageTexture2, textureCoordinate2);\n"
+ " \n"
+ " lowp vec4 brightnessVec4 = vec4((textureColorForBrightness.rgb + vec3(brightness)), textureColorForBrightness.w);\n"
+ " gl_FragColor = contastVec4 + brightnessVec4;\n" + " }";
Doesn't able to get desire result. I can't able to figure out what I have to do next?
What program I have to write?
Why would you add the 2 results in the end? What you need to do is fetch a texel and do the 2 mathematical operations on it. Try this:
lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
lowp vec3 contrastedColor = ((textureColor.rgb - vec3(0.5)) * contrast + vec3(0.5));
gl_FragColor = vec4((contrastedColor + vec3(brightness)), textureColor.w);
Still this can produce a different result then using the 2 separate shaders so let's analyse a bit what goes on:
grab a texture color
apply contrast method
write colour to buffer (at this point the colour values are clamped in range [.0, 1.0])
grab a texture color
apply brightness
write colour to buffer
So what you should add is clamping the contrast colour contrastedColor to [0,1]. As for what M. Coleman said it is true you need to consider the possibility of the result being different because of fetching multiple texels BUT in your specific case that can NOT produce a different result and you are all good to go with it. As for the blending the assumption is being either disabled or (GL_ONE, GL_ZERO) which is the same thing (some other blending types might work as well).
I have an android app in which I use openGL to make some neat image effects.
The base setup is that I continually draw the buffer to one of two textures, then draw on top of that texture the next frame (essentially a simulation), to give the effect that the same image keeps getting manipulated.
I'm trying to add a fade effect to this, in which I darken the background, then draw on top of that, but I'm getting a very strange artifact from this. Here is my fragment shader:
private final String mCompositeFragmentShader =
"#extension GL_OES_EGL_image_external : require\n" +
"precision mediump float;\n" +
"varying vec2 bTextureCoord;\n" +
"varying vec2 vTextureCoord;\n" +
"uniform samplerExternalOES sTexture;\n" +
"uniform sampler2D bufferTexture;\n" +
"uniform float gamma; \n" +
"void main() {\n" +
" vec4 camera = texture2D(sTexture, vTextureCoord);\n" +
" camera.r = pow(camera.r, 1.0/gamma);\n" +
" camera.g = pow(camera.g, 1.0/gamma);\n" +
" camera.b = pow(camera.b, 1.0/gamma);\n" +
" vec4 bg = texture2D(bufferTexture, bTextureCoord);\n" +
" vec3 color = max(camera.rgb, bg.rgb -vec3(.02, .02, .02));\n"+
" gl_FragColor = vec4(color,1.0);\n" +
"}\n";
with the relevant bit of code being:
vec3 color = max(camera.rgb, bg.rgb -vec3(.02, .02, .02));
So I would expect light areas to eventually fade to black over time. However, instead of black it's fading to a magenta grid:
You can see that the gridding is different for each triangle being drawn on the screen (I'm only drawing two triangles).
Here is the vertex shader, just in case:
"uniform mat4 uMVPMatrix;\n" +
"uniform mat4 uSTMatrix;\n" +
"attribute vec4 aPosition;\n" +
"attribute vec4 aTextureCoord;\n" +
"varying vec4 tempCoords;" +
"varying vec2 vTextureCoord;\n" +
"varying vec2 bTextureCoord;\n" +
"void main() {\n" +
" gl_Position = aPosition;\n" +
" bTextureCoord = aTextureCoord.xy;\n" +
" tempCoords = aTextureCoord;\n" +
" tempCoords.y = aTextureCoord.y * ("+previewSize.height+".0 /"+previewSize.width+".0);\n" +
" vTextureCoord = (uSTMatrix * tempCoords).xy;\n" +
"}\n";
Anyone have any idea what's causing this, and how to fix it?
How can I pass a float value to fragment shader ?
This is my code on android:
int aUseTexture = GLES20.glGetAttribLocation(program, "uUseTexture");
GLES20.glUniform1f(aUseTexture, 1.0f);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
Here is my shader:
String verticesShader =
"uniform mat4 uScreen;\n" +
"attribute vec2 aPosition;\n" +
"attribute vec3 aColor;\n" +
"attribute vec2 aTexPos; \n" +
"varying vec2 vTexPos; \n" +
"varying vec3 vColor;\n" +
"void main() {\n" +
" vTexPos = aTexPos; \n" +
" gl_Position = uScreen * vec4(aPosition.xy, 0.0, 1.0);\n" +
" vColor = aColor;\n" +
"}";
// Our fragment shader. Just return vColor.
// If you look at this source and just said 'WTF?', remember
// that all the attributes are defined in the VERTEX shader and
// all the 'varying' vars are considered OUTPUT of vertex shader
// and INPUT of the fragment shader. Here we just use the color
// we received and add a alpha value of 1.
String fragmentShader =
"uniform float uUseTexture; \n" +
"uniform sampler2D uTexture;\n" +
"precision mediump float;\n"+
"varying vec2 vTexPos; \n" +
"varying vec3 vColor;\n" +
"void main(void)\n" +
"{\n" +
" if ( uUseTexture != 1.0 ) \n" +
" gl_FragColor = vec4(vColor.xyz, 1); \n" +
" else \n" +
" gl_FragColor = texture2D(uTexture, vTexPos); \n" +
//" gl_FragColor = vec4(vColor.xyz, 1);\n" +
"}";
You can see the if statement in the fragment shader , that is the one i tried to check if i pass in 1.0 it should do texture else use color.
You are probably using the wrong function call for "uniform variable". Try glGetUniformLocation() as follow:
int aUseTexture = GLES20.glGetUniformLocation(program, "uUseTexture");
Also, the floating point testing (uUseTexture != 1.0) may not be always reliable all the time. You may want to use an integer type.
As far as I know you have to pass the value through the vertex shader before it can get to the fragment shader. e.g. add "uniform float uUseTexture_in; \n" and "varying float uUseTexture; \n" at the top of the vertex shader, in the main function add "uUseTexture = uUseTexture_in;". And your shader should work