Rotate sampler2D texture using fragment shader - opengl

As per my previous question here, what if I want to rotate a sampler2D texture inside the fragment shader?
In that question I rotated the texture inside vertex shader
#version 120
attribute vec3 a_position;
attribute vec2 a_texCoord;
varying vec2 v_texCoord;
void main()
{
const float w = 1.57;
mat3 A = mat3(cos(w), -sin(w), 0.0,
sin(w), cos(w), 0.0,
0.0, 0.0, 1.0);
gl_Position = vec4(A * a_position, 1.0);
v_texCoord = a_texCoord;
}
but my the fragment shader applies an heavy modification that was thought for a rotated clockwise texture, so using the vertex shader I have an horizontal effect that is applied to vertical coordinates by fragment shader.
Is it possible to rotate a sampler2D before apply the modification?

You cannot rotate a sampler2D, however you can rotated the texture coordinates:
#version 120
attribute vec3 a_position;
attribute vec2 a_texCoord;
varying vec2 v_texCoord;
void main()
{
const float w = 1.57;
mat2 uvRotate = mat2(cos(w), -sin(w),
sin(w), cos(w));
gl_Position = vec4(a_position, 1.0);
v_texCoord = uvRotate * a_texCoord;
}

Related

Color only the face red that is in front of camera?

I am pretty newbie to GLSL and I have been struggling with trying to find a way to color the face of my rotating cube red. I have achieved drawing red on one of the faces getting the normal x but my objective is to make the cube draw a red face to whatever face is facing front to the camera.
Fragment Shader
#version 330
in vec3 normal;
out vec4 fragColor;
in vec4 color;
in vec4 vertexColor;
void main() {
vec3 nor = normalize(normal);
fragColor = vec4(nor.x, 0.0, 0.0, 1.0);
}
Vertex Shader
#version 330
uniform mat4 u_m_matrix;
uniform mat4 u_vp_matrix;
layout (location=0) in vec3 a_position;
layout (location=1) in vec3 a_normal;
out vec3 normal;
out vec4 fragColor;
out vec4 vertexColor;
out vec4 color;
void main()
{
normal = a_normal;
gl_Position = u_vp_matrix * u_m_matrix * vec4(a_position, 1.0);
}
I tried messing with the dot product with normals and the direction at which the camera is looking (0, 0, 1) but I have not achieved anything yet.
This would be the desired effect:
I do in fact think it involves some mathematics ( dot product ), maybe getting the cosTetha and seeing if the vector is completdly perpendicular or not and depending on that drawing the faces red or black?
I view space, the z axis points out of the view port. When a side of the cube faces the camera, then the normal vector in view space is (0, 0, 1). The red color can be get form the z component of the normal vector.
But the normal vector has to be transformed from modle space to view space (in the vertex shader). For that you have to know the view matrix:
mat3 normalMat = inverse(transpose(mat3(u_v_matrix * u_m_matrix)));
normal = normalMat * a_normal;
In the fragment shader, the red color channel can be get from the z component:
vec3 nor = normalize(normal);
fragColor = vec4(nor.z, 0.0, 0.0, 1.0);
You can approximate a normal vector in normalized device space, by transforming with mat3(u_vp_matrix * u_m_matrix). That's inaccurate, but it tints the faces dependent on its orientation, too. In normalized device space, the z axis points into the viewport. e.g:
Vertex shader:
#version 330
uniform mat4 u_m_matrix;
uniform mat4 u_vp_matrix;
layout (location=0) in vec3 a_position;
layout (location=1) in vec3 a_normal;
out vec3 normal;
void main()
{
normal = mat3(u_vp_matrix * u_m_matrix) * a_normal;
gl_Position = u_vp_matrix * u_m_matrix * vec4(a_position, 1.0);
}
Fragment shader:
#version 330
in vec3 normal;
out vec4 fragColor;
void main() {
vec3 nor = normalize(normal);
fragColor = vec4(-nor.z, 0.0, 0.0, 1.0);
}
If you just want to color the face which that faces the camera, then you have to compare the cosine of the angle between the normal vector of the face and the view space z axis by the cosine of 45°. step compares a value to a edge and returns 0.0 or 1.0, dependent on the result:
Vertex shader:
mat3 normalMat = inverse(transpose(mat3(u_v_matrix * u_m_matrix)));
normal = normalMat * a_normal;
Fragment shader:
vec3 nor = normalize(normal);
//float red = step(0.707, abs(dot(nor, vec3(0.0, 0.0, 1.0))));
float red = step(0.707, dot(nor, vec3(0.0, 0.0, 1.0)));
fragColor = vec4(red, 0.0, 0.0, 1.0);

Scale 2D Texture to model scaling to prevent streching

I have an OpenGL 3.3 program whichts has different objects in, for example a simple cube. The cube's dimensions are 1x1x1 (vertices from -0.5, -0.5, -0.5 to 0.5, 0.5, 0.5) and is textured with one 2D texture on each side. The texture is repeatable (seamless).
With my actual code the model scaling looks like this (ignore the actual texture):
After scaling like this:
In this case the texture in should stay at size in z-direction but repeate over the z-axis.
Is there a good way to scale the texture properly to the model's scaling to prevent it from stretching? Or do I have to create a 3D texture?
The problem i found is that in my shader I get only the (scaled) point of the cube, for example -0.5, -1,5, -0.5 but the texture's coordinates are only 2D (0.0, 0.0) and I don't know which side of the texture I have to scale since I don't know which side it will currently be rendered on.
For for the sake of completeness, however, the vertex shader code:
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoord;
out vec2 TexCoord;
out vec3 FragPos;
out vec3 Normal;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
FragPos = vec3(model * vec4(aPos, 1.0));
Normal = mat3(transpose(inverse(model))) * aNormal;
TexCoord = aTexCoord;
gl_Position = projection * view * model * vec4(aPos, 1.0);
//gl_Position = projection * view * model * vec4(aPos, 1.0f);
//TexCoord = aTexCoord;
}
The fragment shader looks like this:
out vec4 FragColor;
in vec2 TexCoord;
// texture samplers
uniform sampler2D texture_diffuse1;
uniform vec4 color;
void main()
{
FragColor = color + texture(texture_diffuse1, TexCoord);
}

How to make a retro/neon/glow effect using shaders?

Let's say the concept is to create a map consisting of cubes with a neon aesthetic, such as:
Currently I have this vertex shader:
// Uniforms
uniform mat4 u_projection;
uniform mat4 u_view;
uniform mat4 u_model;
// Vertex atributes
in vec3 a_position;
in vec3 a_normal;
in vec2 a_texture;
vec3 u_light_direction = vec3(1.0, 2.0, 3.0);
// Vertex shader outputs
out vec2 v_texture;
out float v_intensity;
void main()
{
vec3 normal = normalize((u_model * vec4(a_normal, 0.0)).xyz);
vec3 light_dir = normalize(u_light_direction);
v_intensity = max(0.0, dot(normal, light_dir));
v_texture = a_texture;
gl_Position = u_projection * u_view * u_model * vec4(a_position, 1.0);
}
And this pixel shader:
in float v_intensity;
in vec2 v_texture;
uniform sampler2D u_texture;
out vec4 fragColor;
void main()
{
fragColor = texture(u_texture, v_texture) * vec4(v_intensity, v_intensity, v_intensity, 1.0);
}
How would I use this to create a neon effect such as in the example for 3D cubes? The cubes are simply models with a mesh/material. The only change would be to set the material color to black and the outlines to a bright pink or blue (maybe with a glow).
Any help is appreciated. :)
You'd normally implement this as a post-processing effect. First render with bright, saturated colours into a texture, then apply a bloom effect, when drawing that texture to screen.

GLSL shader that scroll texture

How to scrolling a texture on a plane?
So I have a plane with a texture, can I use a shader to scroll left from right (infinite) the texture on it?
Setup the texture wrapping mode using
glTexParameteri(TextureID, L_TEXTURE_WRAP_S, GL_REPEAT)
Add the float uniform named Time to your texturing shader
Use something like texture2D(sampler, u + Time, v) while fetching texture sample.
Update the Time uniform using some timer in your code.
Here's a GLSL shader:
/*VERTEX_PROGRAM*/
in vec4 in_Vertex;
in vec4 in_TexCoord;
uniform mat4 ModelViewMatrix;
uniform mat4 ProjectionMatrix;
out vec2 TexCoord;
void main()
{
gl_Position = ProjectionMatrix * ModelViewMatrix * in_Vertex;
TexCoord = vec2( in_TexCoord );
}
/*FRAGMENT_PROGRAM*/
in vec2 TexCoord;
uniform sampler2D Texture0;
/// Updated in external code
uniform float Time;
out vec4 out_FragColor;
void main()
{
/// "u" coordinate is altered
out_FragColor = texture( Texture0, vec2(TexCoord.x + Time, TexCoord.y) );
}

Flip upside down vertex shader (GLES)

Given the next vertex shader, what is the simplest, most efficient and fastest way to flip the coordinates upside down, so the fragment shader will produce and upside down image?
attribute vec4 a_position;
attribute vec2 a_texcoord;
varying vec2 v_texcoord;
void main()
{
v_texcoord = a_texcoord.st;
gl_Position = a_position;
}
Just flip v_texcoord. So e.g.
v_texcoord = a_texcoord.st * vec2(1.0, -1.0);
Or, I guess:
v_texcoord = vec2(a_texcoord.s, 1.0 - a_texcoord.t);
Depending on what exactly you want to happen to the range of .t.