GLSL Shader Error "Constructor calls may not have precision" - ios

GLSL Shader Error
ERROR: 0:1: '(' : syntax error: Constructor calls may not have precision
I'm seeing this error with Xcode 6 on an iOS 8 app based on GLPaint demo... (works fine in iOS7)
I also noticed they no longer use the "STRINGIFY" thing in version 1.13 of GLPaint demo.
.vsh
static const char* BaseVS = STRINGIFY
(
attribute highp vec4 inVertex;
uniform highp mat4 MVP;
uniform highp float pointSize;
uniform highp vec4 vertexColor;
uniform highp float brushRotation;
varying highp vec4 color;
void main()
{
gl_Position = MVP * inVertex;
gl_PointSize = pointSize;
color = vertexColor;
}
);
.fsh
static const char* BaseFS = STRINGIFY
(
uniform sampler2D texture;
uniform sampler2D normalMap;
uniform highp float brushRotation;
varying highp vec4 color;
varying highp vec3 normal;
varying highp vec3 lightDir;
varying highp vec3 eyeVec;
precision highp float;
void main (void)
{
highp float vRotation = (brushRotation/180.0)*3.14;;
highp float mid = 0.5;
highp vec2 rotated = vec2(cos(vRotation) * (gl_PointCoord.x - mid) + sin(vRotation) * (gl_PointCoord.y - mid) + mid,
cos(vRotation) * (gl_PointCoord.y - mid) - sin(vRotation) * (gl_PointCoord.x - mid) + mid);
highp vec4 rotatedTexture = texture2D( texture, rotated);
gl_FragColor = color * rotatedTexture;
}
);

The problem was in a method used for random generation. I removed the "high" before the vec2() construction. (Sigh)
highp float rand(highp vec2 co)
{
return fract(sin(dot(co.xy ,highp vec2(12.9898,78.233))) * 43758.5453);
}

Related

Webgl - How to make Specular Light not change size

I am trying to implement specular lighting (thats coming from the front) but the light is always changing size in an unnatural way. How do I fix this?
I hardcoded viewerPos to test. I'm using a halfway vector "shortcut" so I have to calculate less things as explained here: https://webglfundamentals.org/webgl/lessons/webgl-3d-lighting-point.html
Video with my lighting implemented: https://streamable.com/j95bz7
// Vertex shader program
const vsSource = `
attribute vec4 aVertexPosition;
attribute vec3 aVertexNormal;
attribute vec2 aTextureCoord;
uniform mat4 uNormalMatrix;
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;
uniform highp vec3 uViewPos;
varying highp vec2 vTextureCoord;
varying highp vec4 vNormal;
varying highp mat4 vModelViewMatrix;
varying highp vec3 vPos;
void main(void) {
gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
vTextureCoord = aTextureCoord; //Textura
vModelViewMatrix = uModelViewMatrix;
vPos = (uModelViewMatrix * aVertexPosition).xyz;
vNormal = uNormalMatrix * vec4(aVertexNormal, 1.0);
}
`;
// Fragment shader program
const fsSource = `
varying highp vec2 vTextureCoord;
varying highp vec4 vNormal;
varying highp mat4 vModelViewMatrix;
varying highp vec3 vPos;
uniform sampler2D uSampler;
void main(void) {
// Apply lighting effect
highp vec4 texelColor = texture2D(uSampler, vTextureCoord);
//Luz Ambiente
highp vec3 ambientLight = 0.3 * vec3(1.0, 1.0, 1.0);
//Luz Difusa
highp vec3 directionalLightColor = vec3(1, 1, 1);
highp vec3 directionalVector = vec3(0.0, 0.0, 1.0);
highp float directional = max(dot(vNormal.xyz, normalize(directionalVector)), 0.0);
//Luz Especular
highp vec3 viewerPos = vec3(0, 0, -6); //NOTA: PASSAR PARA SHADERS, NAO DAR HARDCODE
highp vec3 surfaceToLightDirection = (-1.0 * directionalVector);
highp vec3 surfaceToViewDirection = (vPos - viewerPos);
highp vec3 halfVector = normalize(surfaceToLightDirection + surfaceToViewDirection);
highp float specular = max(dot(vNormal.xyz, halfVector), 0.0);
highp vec3 vLighting = ambientLight;// + (directionalLightColor * directional);
gl_FragColor = vec4(texelColor.rgb * vLighting + (specular * 0.5), texelColor.a);
}
`;

How to pass OpenGL Shader 'sampler2d' in GPUImage?

I am writing a custom shader and I want to pass & change sampler2d property in OpenGL Shader in GPUImage at run time.
varying highp vec2 centerLocation;
varying highp float pointSpacing;
uniform sampler2D inputImageTexture;
void main()
{
mediump vec4 fragmentColor = texture2D(inputImageTexture, gl_PointCoord);
gl_FragColor = fragmentColor;
}

WebGL attribute is always null

I'm trying to make a graphic engine in WebGL, but I'm having lots of trouble.
One of this problems is about attributes being null or -1 when I call them with "gl.getUniformLocation".
My main problem with this right now is "aVertexTextureCoords", which is always -1.
I leave here my shaders, just in case they're the problem.
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec3 aVertexNormal;
attribute vec4 aVertexColor;
attribute vec2 aVertexTextureCoords;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform mat4 uNMatrix;
uniform float uAlpha;
const int NUM_LIGHTS = 4;
uniform vec4 uMaterialDiffuse;
uniform vec3 uLightPosition[NUM_LIGHTS];
//varyings
varying vec4 vColor;
varying vec2 vTextureCoord;
varying vec3 vNormal;
varying vec3 vLightRay[NUM_LIGHTS];
void main(void) {
//Transformed vertex position
vec4 vertex = uMVMatrix * vec4(aVertexPosition, 1.0);
//Transformed normal position
vNormal = vec3(uNMatrix * vec4(aVertexNormal, 1.0));
//Calculate light ray per each light
for(int i=0; i < NUM_LIGHTS; i++){
vec4 lightPosition = uMVMatrix * vec4(uLightPosition[i], 1.0);
vLightRay[i] = vertex.xyz - lightPosition.xyz;
}
//Final vertex position
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
vTextureCoord = aVertexTextureCoords;
}
</script>
<script id="shader-fs" type="x-shader/x-fragment">
#ifdef GL_ES
precision highp float;
#endif
//object uniforms
uniform bool uWireframe;
uniform vec4 uMaterialAmbient;
uniform vec4 uMaterialDiffuse;
//Incluimos un uniform que asociara la textura a un uniform
uniform sampler2D uSampler;
//light uniforms
const int NUM_LIGHTS = 4;
uniform bool uLightSource;
uniform vec4 uLightAmbient;
uniform vec4 uLightDiffuse[NUM_LIGHTS];
uniform float uCutOff;
//varyings
varying vec2 vTextureCoord;
varying vec3 vNormal;
varying vec3 vLightRay[NUM_LIGHTS];
void main(void)
{
if(uWireframe || uLightSource){
gl_FragColor = uMaterialDiffuse;
}
else{
vec4 Ia = uLightAmbient * uMaterialAmbient; //Ambient component: one for all
vec4 finalColor = vec4(0.0,0.0,0.0,1.0); //Color that will be assigned to gl_FragColor
vec3 N = normalize(vNormal);
vec3 L = vec3(0.0);
float lambertTerm = 0.0;
for(int i = 0; i < NUM_LIGHTS; i++){ //For each light
L = normalize(vLightRay[i]); //Calculate reflexion
lambertTerm = dot(N, -L);
if (lambertTerm > uCutOff){
finalColor += uLightDiffuse[i] * uMaterialDiffuse *lambertTerm; //Add diffuse component, one per light
}
}
//Final color
finalColor += Ia;
finalColor.a = 1.0; //Add ambient component: one for all
gl_FragColor = finalColor * texture2D(uSampler, vTextureCoord); //The alpha value in this example will be 1.0
}
}
</script>
Can somebody tell me what I'm doing wrong?
Calling gl.getUniformLocation for a vertex attribute is wrong because it's an attribute, not a uniform. Replace the call with gl.getAttribLocation.

How to create a filter with four input textures using GPUImage

I have a fragment shader code that requires four input textures like this:
precision lowp float;
varying highp vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
uniform sampler2D inputImageTexture3;
uniform sampler2D inputImageTexture4;
void main()
{
vec4 texel = texture2D(inputImageTexture, textureCoordinate);
vec3 bbTexel = texture2D(inputImageTexture2, textureCoordinate).rgb;
texel.r = texture2D(inputImageTexture3, vec2(bbTexel.r, texel.r)).r;
texel.g = texture2D(inputImageTexture3, vec2(bbTexel.g, texel.g)).g;
texel.b = texture2D(inputImageTexture3, vec2(bbTexel.b, texel.b)).b;
vec4 mapped;
mapped.r = texture2D(inputImageTexture4, vec2(texel.r, .16666)).r;
mapped.g = texture2D(inputImageTexture4, vec2(texel.g, .5)).g;
mapped.b = texture2D(inputImageTexture4, vec2(texel.b, .83333)).b;
mapped.a = 1.0;
gl_FragColor = mapped;
}
and as the GPUImage only provide GPUImageThreeInputFilter at most, how do I write a filter with four input texture ? I have read the IFImageFilter which is available for more than 3 input textures (up to 6 input textures), but it can not be compiled with latest GPUImage.

Remove black and white effect from halftone filter

In Brad Larson's excellent GPUImage, there is a halftone filter which also turns the picture black and white. I am just wanting the halftone effect without the black and white and I was wondering can anyone tell me how what I can remove from the following code to fix this? Have been playing around with it, but virtually have no experience in openGL and am not sure what to eliminate.
NSString *const kGPUImageHalftoneFragmentShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
uniform highp float fractionalWidthOfPixel;
uniform highp float aspectRatio;
uniform highp float dotScaling;
const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);
void main()
{
highp vec2 sampleDivisor = vec2(fractionalWidthOfPixel, fractionalWidthOfPixel / aspectRatio);
highp vec2 samplePos = textureCoordinate - mod(textureCoordinate, sampleDivisor) + 0.5 * sampleDivisor;
highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio));
highp vec2 adjustedSamplePos = vec2(samplePos.x, (samplePos.y * aspectRatio + 0.5 - 0.5 * aspectRatio));
highp float distanceFromSamplePoint = distance(adjustedSamplePos, textureCoordinateToUse);
lowp vec3 sampledColor = texture2D(inputImageTexture, samplePos ).rgb;
highp float dotScaling = 1.0 - dot(sampledColor, W);
lowp float checkForPresenceWithinDot = 1.0 - step(distanceFromSamplePoint, (fractionalWidthOfPixel * 0.5) * dotScaling);
gl_FragColor = vec4(vec3(checkForPresenceWithinDot), 1.0);
}
);
You can change the last line to
gl_FragColor = vec4(checkForPresenceWithinDot * sampledColor, 1.0);
This will make the effect have color instead of black and white only.

Resources