GPUImage shader crashing with "ERROR: One or more attached shaders not successfully compiled"
GPUImage shader crashing with "ERROR: One or more attached shaders not successfully compiled"
我正在尝试基于 this Javascript:
为 GPUImage 构建一个 Vibrance 滤镜
/**
* @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;
}
有人认为我应该能够more/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 着色器的经验,我不知道到底是什么问题。
One would think I should be able to more/less copy paste the shader block.
在桌面 GLSL 中可能是这种情况,但在 OpenGL ES 中您不能声明 float
变量(这包括派生自 float
的类型,例如 vec2
或 mat4
)而不先设置精度 - 片段着色器中 float
没有预定义的默认精度。
实现保证在片段着色器中支持 mediump
和 lowp
浮点精度。但是,在将 highp
设置为默认值之前,您必须进行检查。
整个问题让我尖叫 "missing precision",但我真的不知道为什么编译器没有在编译日志中告诉你这个。
复习 4.5.3 Default Precision Qualifiers(第 35-36 页)
关于您使用 CGFloat
的附注:
小心使用CGFloat
。
根据您的编译目标(主机是 32 位还是 64 位),该类型将是单精度或双精度。如果您将声明为 CGFloat
的内容传递给 GL,请停止 =P
改用 GLfloat
,因为它始终是 GL 要求的单精度。
有关详细信息,请参阅 related answer I wrote。
我正在尝试基于 this Javascript:
为 GPUImage 构建一个 Vibrance 滤镜/**
* @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;
}
有人认为我应该能够more/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 着色器的经验,我不知道到底是什么问题。
One would think I should be able to more/less copy paste the shader block.
在桌面 GLSL 中可能是这种情况,但在 OpenGL ES 中您不能声明 float
变量(这包括派生自 float
的类型,例如 vec2
或 mat4
)而不先设置精度 - 片段着色器中 float
没有预定义的默认精度。
实现保证在片段着色器中支持 mediump
和 lowp
浮点精度。但是,在将 highp
设置为默认值之前,您必须进行检查。
整个问题让我尖叫 "missing precision",但我真的不知道为什么编译器没有在编译日志中告诉你这个。
复习 4.5.3 Default Precision Qualifiers(第 35-36 页)
关于您使用 CGFloat
的附注:
小心使用CGFloat
。
根据您的编译目标(主机是 32 位还是 64 位),该类型将是单精度或双精度。如果您将声明为 CGFloat
的内容传递给 GL,请停止 =P
改用 GLfloat
,因为它始终是 GL 要求的单精度。
有关详细信息,请参阅 related answer I wrote。