Merge pull request #418 from mapbox/raster-styling

Raster styling
This commit is contained in:
Lauren Budorick
2014-08-13 11:00:04 -07:00
8 changed files with 120 additions and 6 deletions

View File

@@ -88,6 +88,7 @@ public:
void renderLine(LineBucket& bucket, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix);
void renderSymbol(SymbolBucket& bucket, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix);
void renderRaster(RasterBucket& bucket, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix);
std::array<float, 3> spinWeights(float spin_value);
void preparePrerender(RasterBucket &bucket);

View File

@@ -14,6 +14,10 @@ public:
void setImage(int32_t image);
void setOpacity(float opacity);
void setBuffer(float buffer);
void setBrightness(float brightness_low, float brightness_high);
void setSaturation(float saturation_factor);
void setContrast(float contrast_factor);
void setSpin(std::array<float, 3> spin_weights);
private:
int32_t a_pos = -1;
@@ -26,6 +30,22 @@ private:
float buffer = 0;
int32_t u_buffer = -1;
float brightness_low = 0;
int32_t u_brightness_low = -1;
float brightness_high = 0;
int32_t u_brightness_high = -1;
float saturation_factor = 0;
int32_t u_saturation_factor = -1;
float contrast_factor = 1;
int32_t u_contrast_factor = -1;
std::array<float, 3> spin_weights = {{}};
int32_t u_spin_weights = -1;
};
}

View File

@@ -55,6 +55,7 @@ enum class PropertyKey {
RasterOpacity,
RasterHueRotate,
RasterBrightness, // for transitions only
RasterBrightnessLow,
RasterBrightnessHigh,
RasterSaturation,

View File

@@ -34,6 +34,10 @@ void Painter::renderPrerenderedTexture(RasterBucket &bucket, const mat4 &matrix,
rasterShader->setImage(0);
rasterShader->setBuffer(buffer);
rasterShader->setOpacity(properties.opacity);
rasterShader->setBrightness(properties.brightness[0], properties.brightness[1]);
rasterShader->setSaturation(properties.saturation);
rasterShader->setContrast(properties.contrast);
rasterShader->setSpin(spinWeights(properties.hue_rotate));
bucket.texture.bindTexture();
coveringRasterArray.bind(*rasterShader, tileStencilBuffer, BUFFER_OFFSET(0));
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index());

View File

@@ -66,6 +66,10 @@ void Painter::renderRaster(RasterBucket& bucket, std::shared_ptr<StyleLayer> lay
rasterShader->setMatrix(matrix);
rasterShader->setBuffer(0);
rasterShader->setOpacity(properties.opacity);
rasterShader->setBrightness(properties.brightness[0], properties.brightness[1]);
rasterShader->setSaturation(properties.saturation);
rasterShader->setContrast(properties.contrast);
rasterShader->setSpin(spinWeights(properties.hue_rotate));
glDepthRange(strata + strata_epsilon, 1.0f);
@@ -75,3 +79,15 @@ void Painter::renderRaster(RasterBucket& bucket, std::shared_ptr<StyleLayer> lay
}
}
std::array<float, 3> Painter::spinWeights(float spin) {
spin *= M_PI / 180;
float s = std::sin(spin);
float c = std::cos(spin);
std::array<float, 3> spin_weights = {{
(2 * c + 1) / 3,
(-std::sqrt(3.0f) * s - c + 1) / 3,
(std::sqrt(3.0f) * s - c + 1) / 3
}};
return spin_weights;
}

View File

@@ -3,6 +3,34 @@ uniform float u_opacity;
varying vec2 v_pos;
uniform float u_brightness_low;
uniform float u_brightness_high;
uniform float u_saturation_factor;
uniform float u_contrast_factor;
uniform vec3 u_spin_weights;
void main() {
gl_FragColor = texture2D(u_image, v_pos) * u_opacity;
vec4 color = texture2D(u_image, v_pos) * u_opacity;
vec3 rgb = color.rgb;
// spin
rgb = vec3(
dot(rgb, u_spin_weights.xyz),
dot(rgb, u_spin_weights.zxy),
dot(rgb, u_spin_weights.yzx));
// saturation
float average = (color.r + color.g + color.b) / 3.0;
rgb += (average - rgb) * u_saturation_factor;
// contrast
rgb = (rgb - 0.5) * u_contrast_factor + 0.5;
// brightness
vec3 u_high_vec = vec3(u_brightness_low, u_brightness_low, u_brightness_low);
vec3 u_low_vec = vec3(u_brightness_high, u_brightness_high, u_brightness_high);
gl_FragColor = vec4(mix(u_high_vec, u_low_vec, rgb), color.a);
}

View File

@@ -24,6 +24,11 @@ RasterShader::RasterShader()
u_image = glGetUniformLocation(program, "u_image");
u_opacity = glGetUniformLocation(program, "u_opacity");
u_buffer = glGetUniformLocation(program, "u_buffer");
u_brightness_low = glGetUniformLocation(program, "u_brightness_low");
u_brightness_high = glGetUniformLocation(program, "u_brightness_high");
u_saturation_factor = glGetUniformLocation(program, "u_saturation_factor");
u_contrast_factor = glGetUniformLocation(program, "u_contrast_factor");
u_spin_weights = glGetUniformLocation(program, "u_spin_weights");
// fprintf(stderr, "RasterShader:\n");
// fprintf(stderr, " - u_matrix: %d\n", u_matrix);
@@ -57,3 +62,45 @@ void RasterShader::setBuffer(float new_buffer) {
buffer = new_buffer;
}
}
void RasterShader::setBrightness(float new_brightness_low, float new_brightness_high) {
if (brightness_low != new_brightness_low) {
glUniform1f(u_brightness_low, new_brightness_low);
brightness_low = new_brightness_low;
}
if (brightness_high != new_brightness_high) {
glUniform1f(u_brightness_high, new_brightness_high);
brightness_high = new_brightness_high;
}
}
void RasterShader::setSaturation(float new_saturation_factor) {
if (saturation_factor != new_saturation_factor) {
if (new_saturation_factor > 0) {
new_saturation_factor = 1 - 1 / (1.001 - new_saturation_factor);
} else {
new_saturation_factor = -new_saturation_factor;
}
glUniform1f(u_saturation_factor, new_saturation_factor);
saturation_factor = new_saturation_factor;
}
}
void RasterShader::setContrast(float new_contrast_factor) {
if (contrast_factor != new_contrast_factor) {
if (new_contrast_factor > 0) {
new_contrast_factor = 1 / (1 - new_contrast_factor);
} else {
new_contrast_factor = 1 + new_contrast_factor;
}
glUniform1f(u_contrast_factor, new_contrast_factor);
contrast_factor = new_contrast_factor;
}
}
void RasterShader::setSpin(std::array<float, 3> new_spin_weights) {
if (spin_weights != new_spin_weights) {
glUniform3fv(u_spin_weights, 1, new_spin_weights.data());
spin_weights = new_spin_weights;
}
}

View File

@@ -631,15 +631,12 @@ void StyleParser::parseStyle(JSVal value, ClassProperties &klass) {
parseOptionalProperty<Function<float>>("composite-opacity", Key::CompositeOpacity, klass, value);
parseOptionalProperty<PropertyTransition>("transition-composite-opacity", Key::CompositeOpacity, klass, value);
// TODO edit these?:
parseOptionalProperty<Function<float>>("raster-opacity", Key::RasterOpacity, klass, value);
parseOptionalProperty<PropertyTransition>("transition-raster-opacity", Key::RasterOpacity, klass, value);
parseOptionalProperty<Function<float>>("raster-hue-rotate", Key::RasterHueRotate, klass, value);
parseOptionalProperty<PropertyTransition>("transition-raster-hue-rotate", Key::RasterHueRotate, klass, value);
parseOptionalProperty<Function<float>>("raster-brightness-low", Key::RasterBrightnessLow, klass, value);
parseOptionalProperty<PropertyTransition>("transition-raster-brightness-low", Key::RasterBrightnessLow, klass, value);
parseOptionalProperty<Function<float>>("raster-brightness-high", Key::RasterBrightnessHigh, klass, value);
parseOptionalProperty<PropertyTransition>("transition-raster-brightness-high", Key::RasterBrightnessHigh, klass, value);
parseOptionalProperty<Function<float>>("raster-brightness", { Key::RasterBrightnessLow, Key::RasterBrightnessHigh }, klass, value);
parseOptionalProperty<PropertyTransition>("transition-raster-brightness", Key::RasterBrightness, klass, value);
parseOptionalProperty<Function<float>>("raster-saturation", Key::RasterSaturation, klass, value);
parseOptionalProperty<PropertyTransition>("transition-raster-saturation", Key::RasterSaturation, klass, value);
parseOptionalProperty<Function<float>>("raster-contrast", Key::RasterContrast, klass, value);