GPUImage shader crashing with “ERROR: One or more attached shaders not successfully compiled”

匆匆过客 提交于 2019-12-24 13:27:53

问题


I'm trying to build a Vibrance filter for GPUImage based on this Javascript:

/**
 * @filter       Vibrance
 * @description  Modifies the saturation of desaturated colors, leaving saturated colors unmodified.
 * @param amount -1 to 1 (-1 is minimum vibrance, 0 is no change, and 1 is maximum vibrance)
 */
function vibrance(amount) {
    gl.vibrance = gl.vibrance || new Shader(null, '\
        uniform sampler2D texture;\
        uniform float amount;\
        varying vec2 texCoord;\
        void main() {\
            vec4 color = texture2D(texture, texCoord);\
            float average = (color.r + color.g + color.b) / 3.0;\
            float mx = max(color.r, max(color.g, color.b));\
            float amt = (mx - average) * (-amount * 3.0);\
            color.rgb = mix(color.rgb, vec3(mx), amt);\
            gl_FragColor = color;\
        }\
    ');

    simpleShader.call(this, gl.vibrance, {
        amount: clamp(-1, amount, 1)
    });

    return this;
}

One would think I should be able to more/less copy paste the shader block:

GPUImageVibranceFilter.h

@interface GPUImageVibranceFilter : GPUImageFilter
{
    GLint vibranceUniform;
}

// Modifies the saturation of desaturated colors, leaving saturated colors unmodified.
// Value -1 to 1 (-1 is minimum vibrance, 0 is no change, and 1 is maximum vibrance)
@property (readwrite, nonatomic) CGFloat vibrance;

@end

GPUImageVibranceFilter.m

#import "GPUImageVibranceFilter.h"

#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageVibranceFragmentShaderString = SHADER_STRING
(
    uniform sampler2D inputImageTexture;
    uniform float vibrance;
    varying highp vec2 textureCoordinate;
    void main() {
        vec4 color = texture2D(inputImageTexture, textureCoordinate);
        float average = (color.r + color.g + color.b) / 3.0;
        float mx = max(color.r, max(color.g, color.b));
        float amt = (mx - average) * (-vibrance * 3.0);
        color.rgb = mix(color.rgb, vec3(mx), amt);
        gl_FragColor = color;
    }
);
#else
NSString *const kGPUImageVibranceFragmentShaderString = SHADER_STRING
(
    uniform sampler2D inputImageTexture;
    uniform float vibrance;
    varying vec2 textureCoordinate;
    void main() {
        vec4 color = texture2D(inputImageTexture, textureCoordinate);
        float average = (color.r + color.g + color.b) / 3.0;
        float mx = max(color.r, max(color.g, color.b));
        float amt = (mx - average) * (-vibrance * 3.0);
        color.rgb = mix(color.rgb, vec3(mx), amt);
        gl_FragColor = color;
    }
);
#endif

@implementation GPUImageVibranceFilter

@synthesize vibrance = _vibrance;

#pragma mark -
#pragma mark Initialization and teardown

- (id)init;
{
    if (!(self = [super initWithFragmentShaderFromString:kGPUImageVibranceFragmentShaderString]))
    {
        return nil;
    }

    vibranceUniform = [filterProgram uniformIndex:@"vibrance"];
    self.vibrance = 0.0;

    return self;
}

#pragma mark -
#pragma mark Accessors

- (void)setVibrance:(CGFloat)vibrance;
{
    _vibrance = vibrance;

    [self setFloat:_vibrance forUniform:vibranceUniform program:filterProgram];
}

@end

But that doesn't compile, crashing with:

Failed to compile fragment shader
Program link log: ERROR: One or more attached shaders not successfully compiled
Fragment shader compile log: (null)
Vertex shader compile log: (null)

The error is certainly clear, but being inexperienced with OpenGL ES shaders, I have no idea what the problem actually is.


回答1:


One would think I should be able to more/less copy paste the shader block.

This might be the case in desktop GLSL, but in OpenGL ES you cannot declare a float variable (this includes types derived from float such as vec2 or mat4 as well) without first setting the precision - there is no pre-defined default precision for float in the fragment shader.

Implementations guarantee support for mediump and lowp floating-point precision in the fragment shader. You will have to check before setting highp as the default, however.

This whole problem screams "missing precision" to me, but why the compiler is not telling you this in the compile log I really do not know.

        Brush up on 4.5.3 Default Precision Qualifiers (pp. 35-36)


Side-note regarding your use of CGFloat:

Be careful using CGFloat.

Depending on your compile target (whether the host machine is 32-bit or 64-bit), that type will either be single-precision or double-precision. If you are passing something declared CGFloat to GL, stop that =P

Use GLfloat instead, because that will always be single-precision as GL requires.

       See a related answer I wrote for more details.



来源:https://stackoverflow.com/questions/31997762/gpuimage-shader-crashing-with-error-one-or-more-attached-shaders-not-successfu

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!