I´ve created a shader that is able to rotate an image about 180° and overlay it with a black gradient but now I want to create real transparency instead of using black as my background color.
This is what I got so far:
// Vertex Shader
uniform highp mat4 u_modelViewMatrix;
uniform highp mat4 u_projectionMatrix;
attribute highp vec4 a_position;
attribute lowp vec4 a_color;
attribute highp vec2 a_texcoord;
varying lowp vec4 v_color;
varying highp vec2 v_texCoord;
uniform int offset;
uniform int space;
uniform int vph;
void main()
{\
highp float h = float(offset)/float(vph);
highp float s = float(space)/1000.0;
highp vec4 pos = a_position;
pos.y = pos.y - (h + s);
gl_Position = (u_projectionMatrix * u_modelViewMatrix) * pos;
v_color = a_color;
v_texCoord = vec2(a_texcoord.x, 1.0 - a_texcoord.y);
}
// Fragment Shader
varying highp vec2 v_texCoord;
uniform sampler2D u_texture0;
uniform int gradient;
void main()
{
lowp vec3 w = vec3(1.0,1.0,1.0);
lowp vec3 b = vec3(0.0,0.0,0.0);
lowp vec3 mix = mix(b, w, (v_texCoord.y-(float(gradient)/10.0)));
gl_FragColor = texture2D(u_texture0,v_texCoord) * vec4(mix, 1.0);
}
replace black color with translucent color in your fragment shader:
void main()
{
lowp vec4 w = vec3(1.0,1.0,1.0,1.0);
lowp vec4 b = vec3(0.0,0.0,0.0,0.0);
lowp vec4 mix = mix(b, w, (v_texCoord.y-(float(gradient)/10.0)));
gl_FragColor = texture2D(u_texture0,v_texCoord) * mix;
}
Related
I'm trying to change texture colors inside the GLSL context - doing so before the beginning of the OpenGL pipeline is not an option.
I have tried the following approach:
Vertex Shader
attribute highp vec2 a_TexCoord;
uniform highp mat3 u_TextureMatrix;
varying highp vec2 v_TexCoord;
highp vec4 calculatePosition();
void main()
{
gl_Position = calculatePosition();
v_TexCoord = (u_TextureMatrix * vec3(a_TexCoord,1.0)).xy;
}
attribute highp vec2 a_Vertex;
uniform highp mat3 u_TransformMatrix;
uniform highp mat3 u_ProjectionMatrix;
highp vec4 calculatePosition() {
return vec4(u_ProjectionMatrix * u_TransformMatrix * vec3(a_Vertex.xy, 1.0), 1.0);
}
Fragment Shader
uniform lowp float u_Opacity;
lowp vec4 calculatePixel();
void main()
{
gl_FragColor = calculatePixel();
gl_FragColor.a *= u_Opacity;
}
varying mediump vec2 v_TexCoord;
uniform lowp vec4 u_Color;
uniform sampler2D u_Tex0;
lowp vec4 calculatePixel() {
vec4 tex = texture2D(u_Tex0, v_TexCoord);
tex.xyz -= (100.0 / 255.0);
if (tex.x < 0.0) { tex.x += 1.0; }
if (tex.y < 0.0) { tex.y += 1.0; }
if (tex.z < 0.0) { tex.z += 1.0; }
return tex * u_Color;
}
This code works EXCEPT for the cases when Interpolation is applied (GL_LINEAR_MIPMAP_LINEAR), when things start to look really bad because the filtering happens before the Fragment Shader so I don't get to change the colors PRIOR when it's reliable to do so.
I'm developing a game that has as requirement supporting really old hardware (from as early as 2008) and that's why I'm using really obsolete GLSL code (version 120 compatible).
Is there a way to change Texture colors anywhere in the pipeline BEFORE the rasterization kicks in?
i have written a fragment shader that works just fine with a single light. Now I am trying to adapt it to work with 8 lights, the implement it in Processing. Clearly I am doing something wrong in the math and I cannot see what it is... I have read other posts about this and try to adapt the answer to my problem, no luck though...
////Fragment/////
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
varying vec4 vertColor;
varying vec3 ecNormal;
varying vec3 lightDir;
void main() {
vec3 direction = normalize(lightDir);
vec3 normal = normalize(ecNormal);
float intensity = max(0.0, dot(direction, normal));
gl_FragColor = vec4(intensity, intensity, intensity, 1) * vertColor;
}
////vertex/////
#define PROCESSING_LIGHT_SHADER
uniform mat4 modelview;
uniform mat4 transform;
uniform mat3 normalMatrix;
uniform vec4 lightPosition;
uniform vec3 lightNormal;
attribute vec4 vertex;
attribute vec4 color;
attribute vec3 normal;
varying vec4 vertColor;
varying vec3 ecNormal;
varying vec3 lightDir;
void main() {
gl_Position = transform * vertex;
vec3 ecVertex = vec3(modelview * vertex);
ecNormal = normalize(normalMatrix * normal);
lightDir = normalize(lightPosition.xyz - ecVertex);
vertColor = color;
}
Just making it compile real quick with an online shader tool (http://shdr.bkcore.com/).
You might need to pass the attributes from the veretex shader to varyings for the fragment shader, but I'm not sure, been a while since I wrote shaders.
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
uniform mat4 modelview;
uniform mat4 normalMatrix;
uniform int lightCount;
uniform vec4 lightPosition[8];
varying vec4 vertex; //was attribute, no such thing in frag shaders
varying vec3 normal; //was attribute
varying vec4 vertColor;
void main() {
vec3 vertexCamera = vec3(modelview * vertex);
vec3 transformedNormal = normalize(normalMatrix * vec4(normal,1)).xyz; //was vec3 = normalize(mat4*vec3);
float intensity = 0.0;
for(int i = 0 ; i<8;i++){ //can't loop over a non-constant variable
if(lightCount<i)
{
vec3 direction = normalize(lightPosition[i].xyz - vertexCamera);
intensity += max(0.0, dot(direction, transformedNormal));
}
}
gl_FragColor = vec4(intensity, intensity, intensity, 1) * vertColor;
}
I am using FragmentShader and VertexShader at present, and works absolutely fine. I cannot get my geometry shader working. I am absolutely new to it, below is what I have tried.
I am using VBO, lighting and textures along with some geometry, but it works fine before using GeometryShader. the only thing I have changed is the variable names as I had to get the input in the geometry shader and give the output. So I have appended 1 at the end of those variable names those which will go out from geometry shader to the fragment shader.
Also I have added headers starting with # which were earlier not there. I am using GL_TRIANGLES to draw.
VertexShader
in vec4 position;
in vec4 color1;
in vec4 normal;
in vec2 texCoord;
uniform sampler2D Tex1;
uniform int use_texture;
out vec4 pcolor;
out vec3 N;
out vec3 L;
out vec3 R;
out vec3 V;
uniform mat4 local2clip;
uniform mat4 local2eye;
uniform mat4 normal_matrix;
uniform mat4 world2eye;
uniform vec4 light_ambient;
uniform vec4 light_diffuse;
uniform vec4 light_specular;
uniform vec4 light_pos;
#version 330 compatibility
uniform vec4 mat_ambient;
uniform vec4 mat_diffuse;
uniform vec4 mat_specular;
uniform float mat_shine;
//varying vec3 v_normal; // vertex normal
out vec4 v_color; // vertex color
out vec4 pos_in_eye; //vertex position in eye space
out vec2 FtexCoord;
void main(){
gl_Position = local2clip * position;
N = normalize(vec3(normal_matrix * normal)); //v_normal
vec4 Lpos = world2eye * light_pos; //light pos. in eye
vec4 Vpos = local2eye * position; //pos_in_eye
L = normalize(vec3(Lpos - Vpos)); //light_vector
R = normalize(reflect(-L, N));
V = normalize(vec3(-Vpos)); //eye vector
vec3 halfv = normalize(L+V);
FtexCoord = texCoord;
//pcolor = color1;
}
This is my FragemntShader
#version 330 compatibility
uniform int use_texture;
in vec4 pcolor;
in vec3 N1;
in vec3 L1;
in vec3 R1;
in vec3 V1;
uniform mat4 local2clip;
uniform mat4 local2eye;
uniform mat4 normal_matrix;
uniform mat4 world2eye;
uniform vec4 light_ambient;
uniform vec4 light_diffuse;
uniform vec4 light_specular;
uniform vec4 light_pos;
uniform vec4 mat_ambient;
uniform vec4 mat_diffuse;
uniform vec4 mat_specular;
uniform float mat_shine;
uniform sampler2D Tex1;
in vec2 FtexCoord1;
void main() {
vec4 ambient = light_ambient * mat_ambient;
float NdotL;
if (dot(N1,L1) <0.0) NdotL = 0.0;
else NdotL = dot(N1, L1);
vec4 diffuse = light_diffuse * mat_diffuse * NdotL;
float RdotV;
RdotV = dot(R1, V1);
if (NdotL == 0.0) RdotV = 0.0;
if (RdotV <0.0) RdotV = 0.0;
vec4 specular = light_specular * mat_specular * pow(RdotV,mat_shine);
vec4 texcolor;
if( use_texture == 1 ) {
texcolor = texture2D(Tex1, FtexCoord1);
gl_FragColor = texcolor;
}
else
gl_FragColor = (diffuse + ambient + specular);
}
This is my GeometryShader
#version 330
layout (triangles) in;
layout (triangles) out;
layout (max_vertices = 3) out;
out vec3 N1;
out vec3 L1;
out vec3 R1;
out vec3 V1;
in vec3 N;
in vec3 L;
in vec3 R;
in vec3 V;
uniform mat4 local2clip;
uniform mat4 local2eye;
uniform mat4 normal_matrix;
uniform mat4 world2eye;
uniform vec4 light_ambient;
uniform vec4 light_diffuse;
uniform vec4 light_specular;
uniform vec4 light_pos;
uniform vec4 mat_ambient;
uniform vec4 mat_diffuse;
uniform vec4 mat_specular;
uniform float mat_shine;
//varying vec3 v_normal; // vertex normal
out vec4 v_color1; // vertex color
out vec4 pos_in_eye1; //vertex position in eye space
out vec2 FtexCoord1;
in vec4 v_color; // vertex color
in vec4 pos_in_eye; //vertex position in eye space
in vec2 FtexCoord;
void main(void)
{
int i;
N1=N;
L1=L;
R1=R;
V1=R;
FtexCoord1=FtexCoord;
v_color1=v_color;
pos_in_eye1=pos_in_eye;
for (i = 0; i < gl_in.length(); i++)
{
gl_Position = gl_in[i].gl_Position;
EmitVertex();
}
EndPrimitive();
}
I just want that what ever was there earlier is passed from vertex shader to fragment shader via geometry shader, so that I can manipulate the shader later. Currently the screen is just black
The core of your problem is that you didn't bother to check for compilation errors when you built your Geometry Shader. I know that because I see several syntax errors for it. In particular:
in vec3 N;
in vec3 L;
in vec3 R;
in vec3 V;
in vec4 v_color; // vertex color
in vec4 pos_in_eye; //vertex position in eye space
in vec2 FtexCoord;
Geometry Shader inputs are always aggregated into arrays. Remember: a geometry shader operates on primitives, which are defined as a collection of one or more vertices. Each GS invocation therefore gets a set of per-vertex input values, one for each vertex in the primitive type defined by your layout in qualifier.
Notice how you loop over the number of vertices in a primitive and use gl_in[i] to get the input value for each vertex in the primitive. That's how you need to access all of your Geometry Shader inputs. And you need to write each one to its corresponding output variable, then call EmitVertex. All in that loop.
I am using FragmentShader and VertexShader at present, and works absolutely fine. I cannot get my geometry shader working proprly. I am absolutely new to it, below is what I have tried.
I am using VBO, lighting and textures along with some geometry, but it works fine before using GeometryShader. The only thing I have changed is the variable names as I had to get the input in the geometry shader and give the output. So I have appended 1 at the end of those variable names those which will go out from geometry shader to the fragment shader.
Also I have added headers starting with # which were earlier not there. I am using GL_TRIANGLES to draw.
VertexShader
uniform mat4 local2clip;
uniform mat4 local2eye;
uniform mat4 normal_matrix;
uniform mat4 world2eye;
uniform vec4 light_ambient;
uniform vec4 light_diffuse;
uniform vec4 light_specular;
uniform vec4 light_pos;
uniform vec4 mat_ambient;
uniform vec4 mat_diffuse;
uniform vec4 mat_specular;
uniform float mat_shine;
//varying vec3 v_normal; // vertex normal
out vec2 FtexCoord;
void main(){
gl_Position = local2clip * position;
N = normalize(vec3(normal_matrix * normal)); //v_normal
vec4 Lpos = world2eye * light_pos; //light pos. in eye
vec4 Vpos = local2eye * position; //pos_in_eye
L = normalize(vec3(Lpos - Vpos)); //light_vector
R = normalize(reflect(-L, N));
V = normalize(vec3(-Vpos)); //eye vector
vec3 halfv = normalize(L+V);
FtexCoord = texCoord;
//pcolor = color1;
}
This is my FragmentShader
#version 330 compatibility
uniform int use_texture;
in vec4 pcolor;
in vec3 N1;
in vec3 L1;
in vec3 R1;
in vec3 V1;
uniform mat4 local2clip;
uniform mat4 local2eye;
uniform mat4 normal_matrix;
uniform mat4 world2eye;
uniform vec4 light_ambient;
uniform vec4 light_diffuse;
uniform vec4 light_specular;
uniform vec4 light_pos;
uniform vec4 mat_ambient;
uniform vec4 mat_diffuse;
uniform vec4 mat_specular;
uniform float mat_shine;
uniform sampler2D Tex1;
in vec2 FtexCoord1;
void main() {
vec4 ambient = light_ambient * mat_ambient;
float NdotL;
if (dot(N1,L1) <0.0) NdotL = 0.0;
else NdotL = dot(N1, L1);
vec4 diffuse = light_diffuse * mat_diffuse * NdotL;
float RdotV;
RdotV = dot(R1, V1);
if (NdotL == 0.0) RdotV = 0.0;
if (RdotV <0.0) RdotV = 0.0;
vec4 specular = light_specular * mat_specular * pow(RdotV,mat_shine);
vec4 texcolor;
if( use_texture == 1 ) {
texcolor = texture2D(Tex1, FtexCoord1);
gl_FragColor = texcolor;
}
else
gl_FragColor = (diffuse + ambient + specular);
}
This is my Geometry Shader
#version 330
layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;
out vec3 N1;
out vec3 L1;
out vec3 R1;
out vec3 V1;
in vec3 N[3];
in vec3 L[3];
in vec3 R[3];
in vec3 V[3];
uniform mat4 local2clip;
uniform mat4 local2eye;
uniform mat4 normal_matrix;
uniform mat4 world2eye;
uniform vec4 light_ambient;
uniform vec4 light_diffuse;
uniform vec4 light_specular;
uniform vec4 light_pos;
uniform vec4 mat_ambient;
uniform vec4 mat_diffuse;
uniform vec4 mat_specular;
uniform float mat_shine;
//varying vec3 v_normal; // vertex normal
out vec2 FtexCoord1;
in vec2 FtexCoord[3];
void main(void)
{
int i;
for (i = 0; i < gl_in.length(); i++)
{
N1=N[i];
L1=L[i];
R1=R[i];
V1=R[i];
FtexCoord1=FtexCoord[i];
gl_Position = gl_in[i].gl_Position;
EmitVertex();
}
EndPrimitive();
}
I just want that what ever was there earlier is passed from vertex shader to fragment shader via geometry shader, so that I can manipulate the shader later. But the light is not showing the same effect.As shown in the pics.
There was a small bug in the code.It should be V1=V[i]; Instead of V1=R[i];
I wrote shaders in #version 150. I have problem with uniforms. If I use any of light uniforms (vec4) my scene disappears.
Extraction of setting uniforms:
typedef struct { float x, y, z, w; } vec4;
//...
class MyClass {
GLuint _id;
vec4 light_diffuse;
};
//...
void MyClass::setUniforms {
//...
GLint location = glGetUniformLocation(_id, "in_light_diffuse");
//...
glUseProgram(_id);
//...
glUniform4fv(location, 1, (const GLfloat *)&light_diffuse);
//...
}
THIS WORKS:
#version 150
in vec4 in_vertex;
in vec3 in_normal;
in vec4 in_color;
uniform mat4 in_mvp_matrix;
uniform vec4 in_light_position;
uniform vec4 in_light_ambient;
uniform vec4 in_light_diffuse;
uniform vec4 in_light_specular;
out vec4 v_color;
void main() {
//vec4 a = in_light_position + in_light_ambient + in_light_diffuse + in_light_specular;
v_color = in_color;
gl_Position = in_mvp_matrix * in_vertex;
}
THIS DOESN'T WORK:
#version 150
in vec4 in_vertex;
in vec3 in_normal;
in vec4 in_color;
uniform mat4 in_mvp_matrix;
uniform vec4 in_light_position;
uniform vec4 in_light_ambient;
uniform vec4 in_light_diffuse;
uniform vec4 in_light_specular;
out vec4 v_color;
void main() {
vec4 a = in_light_position + in_light_ambient + in_light_diffuse + in_light_specular;
v_color = in_color;
gl_Position = in_mvp_matrix * in_vertex;
}
In first case I can see colorful objects, but in the second everything disappears. I don't even use these uniforms for calculation out_flag_color and result is empty screen.
It's simple. If I use one of them (no matter for what) it's empty.
Anybody help?
Solved. I was setting vec4 to uniform mat4 location.