OpenGL ES 2 squeeze distortion filter like photobooth app - objective-c

I'm tryng to code a squeeze effect like the one in photobooth ios or osx app; I'm new to shaders, but I was able to implement GPUImage library and tweek some shaders; however all that I was able to obtain is a spherical distortion, and the final result is a bit different from what I would like to achieve.
here is some code I modded from #import "GPUImageBulgeDistortionFilter.h"
in particular I was using this code
NSString *const kGPUImageBulgeDistortionFragmentShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
uniform highp vec2 center;
uniform highp float radius;
uniform highp float scale;
void main()
{
highp vec2 textureCoordinateToUse = textureCoordinate;
highp float dist = distance(center, textureCoordinate);
highp float PI = 3.14159265358979323846264;//stone added
textureCoordinateToUse -= center;
textureCoordinateToUse.x = 0.5+textureCoordinateToUse.x*cos(textureCoordinateToUse.x*PI/radius)*scale;
textureCoordinateToUse.y = 0.5 + textureCoordinateToUse.y*cos(textureCoordinateToUse.y*PI/radius)*scale;
gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse );
}
);
This code is using cos and sin and PI so it's definitely in the spherical range; any hint to make it more planar, with a tiny unstretched part in the middle will be a great help !

Related

Shadertoy: How to mix-add-multiply any two shaders?

Are there any crafty tricks to mix two shaders together? i.e. to add the shaders together, else to render one shader in a central square and another as a frame? Can we rename some of the input-output parameters and add them in a final image mix meta-function?
i.e. If i change
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{...}
changed to:
void mainImage( out vec4 A_FragColor, in vec2 fragCoord )
{...}
and
void mainImage( out vec4 B_FragColor, in vec2 fragCoord )
{...}
Perhaps I can mix and lerp the shaders A and B from left to right of the canvas?
You can use the render to texture enabled by Shadertoy buffer tabs and iChannel mapping.
To do it, just add a BufA tab and put your first shader code into it, then do the same with BufB tab and your second shader code.
For example I will generate two gradient images and sum them. BufA will draw some red to black, and BufB will draw some black to green gradient.
// Shader in buffer A returns a red to black gradient
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord / iResolution.xy;
fragColor = vec4(uv.x, 0., 0., 1.);
}
// Shader in buffer B returns a black to green gradient
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord / iResolution.xy;
fragColor = vec4(0., 1. - uv.x, 0., 1.);
}
Enable iChannel0 and iChannel1 in the bottom panel and connect them to BufA and BufB. At this point ShaderToy will render both shaders into iChannel textures, before Image tab main shader is called.
In the Image tab, you can retrieve the textures by accessing iChannel[i] you mapped, and use iChannelResolution[i] to compute uv coordinates.
And you can mix everything the way you want
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// Normalized pixel coordinates (from 0 to 1)
vec2 uvA = fragCoord / iChannelResolution[0].xy;
vec2 uvB = fragCoord / iChannelResolution[1].xy;
// Output to screen
// Fragment is the sum of both gradients: red to green
fragColor = texture(iChannel0, uvA) + texture(iChannel1, uvB);
}
The whole thing should look like this

In Vulkan, the output color of vertices in vertex shader is different than what I am getting in fragment shader

In Vulkan, I had written a simple program to draw lines with fixed color, with simple vertex shader and fragement shader. But the colors input to fragment shaders are different than what is set in vertices. I checked with RenderDoc, and the colors passed to the vertex shader are correct (1,1,1,1) for both vertices of a line and also checked its output, its also same. But in Fragment shader, the colors I am getting are (1,1,0,1). Dont understand why this is happening. Irrespetive of what colors vertex shader emit, the input in fragment shader is always yellow.
Vertex shader:
layout(location = 0) in vec4 position;
layout(location = 1) in vec4 color;
layout(location = 2) in vec2 texcoord;
out vec4 io_color;
out vec2 io_uv;
out vec4 io_position2;
layout(std140, binding = 0) uniform UniformBlock_uTransform
{
mat4 uTransform;
};
layout(std140, binding = 1) uniform UniformBlock_uTransform2
{
mat4 uTransform2;
};
void main ()
{
io_uv = texcoord;
io_color = vec4(1,1,1,1); //Just to debug it
gl_Position = uTransform * position;
io_position2 = uTransform2 * position;
}
//Fragement :
in vec4 io_color;
layout(location = 0) out vec4 result;
void main ()
{
result = io_color;
}
Try adding output and input layout qualifiers to the values you pass from one shader to the other to ensure that they actually point to the same location:
VS:
layout (location = 0) out vec4 io_color;
FS:
layout (location = 0) in vec4 io_color;
I recommend always using that syntax to connect shader out- and inputs.
Check if color write mask is not disabled for blue channel.

Problems with using vertex attribute value in opengl es 2.0

I am struggling for days and i still can't figure out what i am doing wrong.
I have a vertex attribute consisting of a single float and i want to compare it's value with other in an if statement but i always get the statement true even if it is not;
Here is my vertex shader were the problem occur:
attribute vec4 a_Position;
attribute vec3 a_Normal;
attribute vec2 a_TextureCoord;
attribute highp float a_Bone;
uniform mat4 bone_1;
uniform mat4 bone_0;
varying vec2 v_TextureCoord;
void main() {
v_TextureCoord = a_TextureCoord;
vec4 posy;
float a = a_Bone;
if(20.0<a)
posy = bone_0*a_Position;
else
posy = bone_1*a_Position;
gl_Position = posy;
}
if i replace what is in if statement with "true" or "false" all the things work as expected ...but if i'm trying to use that attribute value for comparing the if statement acts as the statement is always true even if when a_Bone value is 1.0 or 2.0 (clearly smaller the 20.0)
We've been using Attributes in the if statemens and the code is working fine on most OpenGL ES 2.0 devices. So it is not a problem in using attributes. Here is a working code of how we have done.
int jointId = int(optionalData1.x);
if(jointId > 0)
finalMatrix = jointTransforms[jointId - 1] * optionalData2.x;
This code is working fine on all iOS and Android devices. optionalData1 is the attribute and we are even using this value to get matrix from a uniform array for bone transform matrix.

GPUImage and Shader Compile Errors

I'm implementing a custom filter creating two strings one as a vertex shader and the other one as a fragment one.
I'm in the early stage and I was just trying to compile and run a program with custom shaders just copying the one used in GPUImage.
Here the shaders:
NSString *const CustomShaderV = SHADER_STRING
(
attribute vec4 position;
attribute vec4 inputTextureCoordinate;
attribute vec4 inputTextureCoordinate2;
varying vec2 textureCoordinate;
varying vec2 textureCoordinate2;
void main()
{
gl_Position = position;
textureCoordinate = inputTextureCoordinate.xy;
textureCoordinate2 = inputTextureCoordinate2.xy;
}
);
NSString *const CustomShaderF = SHADER_STRING
(
varying highp vec2 textureCoordinate;
varying highp vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
uniform highp float bVal;
uniform highp float hVal;
uniform highp float sVal;
void main()
{
lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
lowp vec4 alphaColor = texture2D(inputImageTexture2, textureCoordinate2);
lowp vec4 outputColor;
outputColor = textureColor;
gl_FragColor = outputColor;
}
);
However whenever I initialize a filter with such shaders my app crash with this log.
2013-11-24 17:58:40.243[865:60b] Shader compile log:
ERROR: 0:1: 'CustomShaderV' : syntax error syntax error
2013-11-24 17:58:40.245[865:60b] Failed to compile vertex shader
2013-11-24 17:58:40.248[865:60b] Shader compile log:
ERROR: 0:1: 'CustomShaderF' : syntax error syntax error
2013-11-24 17:58:40.249[865:60b] Failed to compile fragment shader
2013-11-24 17:58:40.250[865:60b] Program link log: ERROR: One or more attached shaders not successfully compiled
2013-11-24 17:58:40.252[865:60b] Fragment shader compile log: (null)
2013-11-24 17:58:40.253[865:60b] Vertex shader compile log: (null)
The shaders are correct to me since are just cut and copy of other working shaders included in the GPUImage projects.
The call inside the code to the two shaders above is as following:
customFilter = [[GPUImageFilter alloc] initWithVertexShaderFromString:#"CustomShaderV" fragmentShaderFromString:#"CustomShaderF"];
My goal is to blend two videos that's why two textures are present in the shaders.
Based on the comment by OP,
here is the call: customFilter = [[GPUImageFilter alloc] initWithVertexShaderFromString:#"CustomShaderV" fragmentShaderFromString:#"CustomShaderF"];
the error was that the variable name was quoted and being used as a string. Fix was:
Change that to: [[GPUImageFilter alloc] initWithVertexShaderFromString:CustomShaderV fragmentShaderFromString:CustomShaderF];

How to active user-attribute in GLSL code? optimize(off) not work

vertex shader:
#version 150
in vec3 MCVertex;
in float pointvar;
uniform mat4 MVMatrix;
uniform mat4 MPMatrix;
void main()
{
gl_Position = MPMatrix * MVMatrix * vec4(MCVertex, 1.0);
}
i need 'pointvar' attribute
but when i call :
glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &numAttributes);
numAttribute = 1;
there are 2 attribute in my code, numAttribute must be 2.
and if i do it like this, i can active this attribute:
gl_Position = MPMatrix * MVMatrix * vec4(MCVertex + vec3(pointvar), 1.0);
then numAttributes = 2, is there any other ways to active this attribute?
i have try to #pragma optimize(off), but not work.
I'm pretty sure that GLSL will "erase/forget" any uniform / attribute not used in it's code.
All the info here.
EDIT:
Like uniforms, attributes can be active or inactive. Attributes that
are unused are inactive; they do not have a binding.