GPUImage着色器与“错误:一个或多个附加着色器未成功编译”
我想基于这个Javascript为GPUImage构build一个Vibrancefilter:
/** * @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; }
有人会认为我应该能够更多/更less地复制粘贴着色器块:
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
但是,这不会编译,崩溃:
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)
这个错误当然很清楚,但是对OpenGL ES着色器没有经验,我不知道这个问题实际上是什么。
有人会认为我应该能够更多/更less地复制粘贴着色器块。
在桌面GLSL中可能会出现这种情况,但在OpenGL ES中,如果不首先设置精度,则无法声明float
variables(包括从float
等派生的types,例如vec2
或mat4
) – float
没有预先定义的默认精度在片段着色器中。
实现保证片段着色器支持mediump
和lowp
浮点精度。 但是,在将highp
设置为默认值之前,您必须先进行检查。
这整个问题尖叫“缺less精度”给我,但为什么编译器没有告诉你这个在编译日志我真的不知道。
刷上4.5.3默认精度限定符 (第35-36页)
关于您使用CGFloat
的附注:
小心使用CGFloat
。
根据您的编译目标(主机是32位还是64位),该types将是单精度或双精度。 如果你传递一个声明CGFloat
东西给GL,停止那个= P
而是使用GLfloat
,因为GL总是需要单精度的。
看到我写的更多细节相关的答案 。