webgl: Implement linear RGB gradients
This commit is contained in:
parent
c30453c144
commit
09ca11f788
|
@ -478,3 +478,20 @@ pub fn unmultiply_alpha_rgba(rgba: &mut [u8]) {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Converts an RGBA color from sRGB space to linear color space.
|
||||
pub fn srgb_to_linear(color: [f32; 4]) -> [f32; 4] {
|
||||
fn to_linear_channel(n: f32) -> f32 {
|
||||
if n <= 0.04045 {
|
||||
n / 12.92
|
||||
} else {
|
||||
f32::powf((n + 0.055) / 1.055, 2.4)
|
||||
}
|
||||
}
|
||||
[
|
||||
to_linear_channel(color[0]),
|
||||
to_linear_channel(color[1]),
|
||||
to_linear_channel(color[2]),
|
||||
color[3],
|
||||
]
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ use lyon::tessellation::{
|
|||
FillAttributes, FillTessellator, StrokeAttributes, StrokeTessellator, StrokeVertexConstructor,
|
||||
};
|
||||
use lyon::tessellation::{FillOptions, StrokeOptions};
|
||||
use ruffle_core::backend::render::swf::{self, FillStyle, Twips};
|
||||
use ruffle_core::backend::render::swf::{self, FillStyle, GradientInterpolation, Twips};
|
||||
use ruffle_core::shape_utils::{DistilledShape, DrawCommand, DrawPath};
|
||||
|
||||
pub struct ShapeTessellator {
|
||||
|
@ -102,6 +102,7 @@ impl ShapeTessellator {
|
|||
matrix: swf_to_gl_matrix(gradient.matrix),
|
||||
repeat_mode: gradient.spread,
|
||||
focal_point: 0.0,
|
||||
interpolation: gradient.interpolation,
|
||||
};
|
||||
|
||||
flush_draw(DrawType::Gradient(gradient), &mut mesh, &mut lyon_mesh);
|
||||
|
@ -144,6 +145,7 @@ impl ShapeTessellator {
|
|||
matrix: swf_to_gl_matrix(gradient.matrix),
|
||||
repeat_mode: gradient.spread,
|
||||
focal_point: 0.0,
|
||||
interpolation: gradient.interpolation,
|
||||
};
|
||||
|
||||
flush_draw(DrawType::Gradient(gradient), &mut mesh, &mut lyon_mesh);
|
||||
|
@ -189,6 +191,7 @@ impl ShapeTessellator {
|
|||
matrix: swf_to_gl_matrix(gradient.matrix),
|
||||
repeat_mode: gradient.spread,
|
||||
focal_point: *focal_point,
|
||||
interpolation: gradient.interpolation,
|
||||
};
|
||||
|
||||
flush_draw(DrawType::Gradient(gradient), &mut mesh, &mut lyon_mesh);
|
||||
|
@ -319,6 +322,7 @@ pub struct Gradient {
|
|||
pub num_colors: u32,
|
||||
pub repeat_mode: GradientSpread,
|
||||
pub focal_point: f32,
|
||||
pub interpolation: GradientInterpolation,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
|
|
|
@ -13,9 +13,18 @@ uniform vec4 u_colors[8];
|
|||
uniform int u_num_colors;
|
||||
uniform int u_repeat_mode;
|
||||
uniform float u_focal_point;
|
||||
uniform int u_interpolation;
|
||||
|
||||
varying vec2 frag_uv;
|
||||
|
||||
vec3 linear_to_srgb(vec3 linear)
|
||||
{
|
||||
vec3 a = 12.92 * linear;
|
||||
vec3 b = 1.055 * pow(linear, vec3(1.0 / 2.4)) - 0.055;
|
||||
vec3 c = step(vec3(0.0031308), linear);
|
||||
return mix(a, b, c);
|
||||
}
|
||||
|
||||
void main() {
|
||||
float t;
|
||||
if( u_gradient_type == 0 )
|
||||
|
@ -90,5 +99,10 @@ void main() {
|
|||
color = u_colors[7];
|
||||
}
|
||||
|
||||
gl_FragColor = mult_color * color + add_color;
|
||||
if( u_interpolation != 0 ) {
|
||||
color = vec4(linear_to_srgb(vec3(color)), color.a);
|
||||
}
|
||||
|
||||
gl_FragColor = mult_color * color + add_color;;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use ruffle_core::backend::render::swf::{self, FillStyle};
|
||||
use ruffle_core::backend::render::{
|
||||
Bitmap, BitmapFormat, BitmapHandle, BitmapInfo, Color, Letterbox, RenderBackend, ShapeHandle,
|
||||
Transform,
|
||||
srgb_to_linear, Bitmap, BitmapFormat, BitmapHandle, BitmapInfo, Color, Letterbox,
|
||||
RenderBackend, ShapeHandle, Transform,
|
||||
};
|
||||
use ruffle_core::shape_utils::DistilledShape;
|
||||
use ruffle_render_common_tess::{GradientSpread, GradientType, ShapeTessellator, Vertex};
|
||||
|
@ -74,7 +74,6 @@ impl WebGlRenderBackend {
|
|||
("antialias", JsValue::FALSE),
|
||||
("depth", JsValue::FALSE),
|
||||
];
|
||||
|
||||
let context_options = js_sys::Object::new();
|
||||
for (name, value) in options.iter() {
|
||||
js_sys::Reflect::set(&context_options, &JsValue::from(*name), value).warn_on_error();
|
||||
|
@ -484,6 +483,12 @@ impl WebGlRenderBackend {
|
|||
let num_colors = gradient.num_colors as usize;
|
||||
ratios[..num_colors].copy_from_slice(&gradient.ratios[..num_colors]);
|
||||
colors[..num_colors].copy_from_slice(&gradient.colors[..num_colors]);
|
||||
// Convert to linear color space if this is a linear-interpolated gradient.
|
||||
if gradient.interpolation == swf::GradientInterpolation::LinearRGB {
|
||||
for color in &mut colors[..num_colors] {
|
||||
*color = srgb_to_linear(*color);
|
||||
}
|
||||
}
|
||||
for i in num_colors..8 {
|
||||
ratios[i] = ratios[i - 1];
|
||||
colors[i] = colors[i - 1];
|
||||
|
@ -504,6 +509,7 @@ impl WebGlRenderBackend {
|
|||
GradientSpread::Reflect => 2,
|
||||
},
|
||||
focal_point: gradient.focal_point,
|
||||
interpolation: gradient.interpolation,
|
||||
};
|
||||
(
|
||||
&self.gradient_program,
|
||||
|
@ -1032,6 +1038,11 @@ impl RenderBackend for WebGlRenderBackend {
|
|||
ShaderUniform::GradientFocalPoint,
|
||||
gradient.focal_point,
|
||||
);
|
||||
program.uniform1i(
|
||||
&self.gl,
|
||||
ShaderUniform::GradientInterpolation,
|
||||
(gradient.interpolation == swf::GradientInterpolation::LinearRGB) as i32,
|
||||
);
|
||||
}
|
||||
DrawType::Bitmap(bitmap) => {
|
||||
let texture = &self
|
||||
|
@ -1186,6 +1197,7 @@ struct Gradient {
|
|||
num_colors: u32,
|
||||
repeat_mode: i32,
|
||||
focal_point: f32,
|
||||
interpolation: swf::GradientInterpolation,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
@ -1235,7 +1247,7 @@ struct ShaderProgram {
|
|||
}
|
||||
|
||||
// These should match the uniform names in the shaders.
|
||||
const NUM_UNIFORMS: usize = 12;
|
||||
const NUM_UNIFORMS: usize = 13;
|
||||
const UNIFORM_NAMES: [&str; NUM_UNIFORMS] = [
|
||||
"world_matrix",
|
||||
"view_matrix",
|
||||
|
@ -1248,6 +1260,7 @@ const UNIFORM_NAMES: [&str; NUM_UNIFORMS] = [
|
|||
"u_num_colors",
|
||||
"u_repeat_mode",
|
||||
"u_focal_point",
|
||||
"u_interpolation",
|
||||
"u_texture",
|
||||
];
|
||||
|
||||
|
@ -1263,6 +1276,7 @@ enum ShaderUniform {
|
|||
GradientNumColors,
|
||||
GradientRepeatMode,
|
||||
GradientFocalPoint,
|
||||
GradientInterpolation,
|
||||
BitmapTexture,
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue