Implement depth interpolation, not working yet
This commit is contained in:
parent
661a865508
commit
9af3bac11f
|
@ -634,10 +634,13 @@ fn build_scene(scene: &Scene, build_options: BuildOptions, jobs: Option<usize>)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let built_options = render_options.prepare(scene.bounds);
|
||||||
|
let quad = built_options.quad();
|
||||||
|
|
||||||
let built_objects = panic::catch_unwind(|| {
|
let built_objects = panic::catch_unwind(|| {
|
||||||
match jobs {
|
match jobs {
|
||||||
Some(1) => scene.build_objects_sequentially(render_options, &z_buffer),
|
Some(1) => scene.build_objects_sequentially(built_options, &z_buffer),
|
||||||
_ => scene.build_objects(render_options, &z_buffer),
|
_ => scene.build_objects(built_options, &z_buffer),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -650,7 +653,7 @@ fn build_scene(scene: &Scene, build_options: BuildOptions, jobs: Option<usize>)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut built_scene = BuiltScene::new(scene.view_box);
|
let mut built_scene = BuiltScene::new(scene.view_box, &quad);
|
||||||
built_scene.shaders = scene.build_shaders();
|
built_scene.shaders = scene.build_shaders();
|
||||||
|
|
||||||
let mut scene_builder = SceneBuilder::new(built_objects, z_buffer, scene.view_box);
|
let mut scene_builder = SceneBuilder::new(built_objects, z_buffer, scene.view_box);
|
||||||
|
|
|
@ -84,6 +84,12 @@ impl Point2DF32 {
|
||||||
self.x() * other.y() - self.y() * other.x()
|
self.x() * other.y() - self.y() * other.x()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn dot(&self, other: Point2DF32) -> f32 {
|
||||||
|
let xy = self.0 * other.0;
|
||||||
|
xy.x() + xy.y()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn scale(&self, x: f32) -> Point2DF32 {
|
pub fn scale(&self, x: f32) -> Point2DF32 {
|
||||||
Point2DF32(self.0 * F32x4::splat(x))
|
Point2DF32(self.0 * F32x4::splat(x))
|
||||||
|
|
|
@ -132,12 +132,12 @@ impl Renderer {
|
||||||
self.upload_shaders(&built_scene.shaders);
|
self.upload_shaders(&built_scene.shaders);
|
||||||
|
|
||||||
self.upload_solid_tiles(&built_scene.solid_tiles);
|
self.upload_solid_tiles(&built_scene.solid_tiles);
|
||||||
self.draw_solid_tiles(&built_scene.solid_tiles);
|
self.draw_solid_tiles(&built_scene);
|
||||||
|
|
||||||
for batch in &built_scene.batches {
|
for batch in &built_scene.batches {
|
||||||
self.upload_batch(batch);
|
self.upload_batch(batch);
|
||||||
self.draw_batch_fills(batch);
|
self.draw_batch_fills(batch);
|
||||||
self.draw_batch_mask_tiles(batch);
|
self.draw_batch_mask_tiles(&built_scene, batch);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.postprocessing_needed() {
|
if self.postprocessing_needed() {
|
||||||
|
@ -245,7 +245,7 @@ impl Renderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_batch_mask_tiles(&mut self, batch: &Batch) {
|
fn draw_batch_mask_tiles(&mut self, built_scene: &BuiltScene, batch: &Batch) {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.bind_draw_framebuffer();
|
self.bind_draw_framebuffer();
|
||||||
self.set_main_viewport();
|
self.set_main_viewport();
|
||||||
|
@ -270,6 +270,22 @@ impl Renderer {
|
||||||
FILL_COLORS_TEXTURE_HEIGHT as GLfloat);
|
FILL_COLORS_TEXTURE_HEIGHT as GLfloat);
|
||||||
// FIXME(pcwalton): Fill this in properly!
|
// FIXME(pcwalton): Fill this in properly!
|
||||||
gl::Uniform2f(self.mask_tile_program.view_box_origin_uniform.location, 0.0, 0.0);
|
gl::Uniform2f(self.mask_tile_program.view_box_origin_uniform.location, 0.0, 0.0);
|
||||||
|
gl::Uniform3f(self.mask_tile_program.quad_p0_uniform.location,
|
||||||
|
built_scene.quad[0].x(),
|
||||||
|
built_scene.quad[0].y(),
|
||||||
|
built_scene.quad[0].z());
|
||||||
|
gl::Uniform3f(self.mask_tile_program.quad_p1_uniform.location,
|
||||||
|
built_scene.quad[1].x(),
|
||||||
|
built_scene.quad[1].y(),
|
||||||
|
built_scene.quad[1].z());
|
||||||
|
gl::Uniform3f(self.mask_tile_program.quad_p2_uniform.location,
|
||||||
|
built_scene.quad[2].x(),
|
||||||
|
built_scene.quad[2].y(),
|
||||||
|
built_scene.quad[2].z());
|
||||||
|
gl::Uniform3f(self.mask_tile_program.quad_p3_uniform.location,
|
||||||
|
built_scene.quad[3].x(),
|
||||||
|
built_scene.quad[3].y(),
|
||||||
|
built_scene.quad[3].z());
|
||||||
self.enable_blending();
|
self.enable_blending();
|
||||||
self.enable_depth_test();
|
self.enable_depth_test();
|
||||||
gl::DrawArraysInstanced(gl::TRIANGLE_FAN, 0, 4, batch.mask_tiles.len() as GLint);
|
gl::DrawArraysInstanced(gl::TRIANGLE_FAN, 0, 4, batch.mask_tiles.len() as GLint);
|
||||||
|
@ -277,7 +293,7 @@ impl Renderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_solid_tiles(&mut self, solid_tiles: &[SolidTileScenePrimitive]) {
|
fn draw_solid_tiles(&mut self, built_scene: &BuiltScene) {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.bind_draw_framebuffer();
|
self.bind_draw_framebuffer();
|
||||||
self.set_main_viewport();
|
self.set_main_viewport();
|
||||||
|
@ -297,11 +313,28 @@ impl Renderer {
|
||||||
FILL_COLORS_TEXTURE_HEIGHT as GLfloat);
|
FILL_COLORS_TEXTURE_HEIGHT as GLfloat);
|
||||||
// FIXME(pcwalton): Fill this in properly!
|
// FIXME(pcwalton): Fill this in properly!
|
||||||
gl::Uniform2f(self.solid_tile_program.view_box_origin_uniform.location, 0.0, 0.0);
|
gl::Uniform2f(self.solid_tile_program.view_box_origin_uniform.location, 0.0, 0.0);
|
||||||
|
gl::Uniform3f(self.solid_tile_program.quad_p0_uniform.location,
|
||||||
|
built_scene.quad[0].x(),
|
||||||
|
built_scene.quad[0].y(),
|
||||||
|
built_scene.quad[0].z());
|
||||||
|
gl::Uniform3f(self.solid_tile_program.quad_p1_uniform.location,
|
||||||
|
built_scene.quad[1].x(),
|
||||||
|
built_scene.quad[1].y(),
|
||||||
|
built_scene.quad[1].z());
|
||||||
|
gl::Uniform3f(self.solid_tile_program.quad_p2_uniform.location,
|
||||||
|
built_scene.quad[2].x(),
|
||||||
|
built_scene.quad[2].y(),
|
||||||
|
built_scene.quad[2].z());
|
||||||
|
gl::Uniform3f(self.solid_tile_program.quad_p3_uniform.location,
|
||||||
|
built_scene.quad[3].x(),
|
||||||
|
built_scene.quad[3].y(),
|
||||||
|
built_scene.quad[3].z());
|
||||||
gl::Disable(gl::BLEND);
|
gl::Disable(gl::BLEND);
|
||||||
gl::DepthMask(gl::FALSE);
|
gl::DepthMask(gl::FALSE);
|
||||||
gl::Enable(gl::DEPTH_TEST);
|
gl::Enable(gl::DEPTH_TEST);
|
||||||
gl::Disable(gl::STENCIL_TEST);
|
gl::Disable(gl::STENCIL_TEST);
|
||||||
gl::DrawArraysInstanced(gl::TRIANGLE_FAN, 0, 4, solid_tiles.len() as GLint);
|
let count = built_scene.solid_tiles.len();
|
||||||
|
gl::DrawArraysInstanced(gl::TRIANGLE_FAN, 0, 4, count as GLint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,6 +572,10 @@ struct SolidTileProgram {
|
||||||
fill_colors_texture_uniform: Uniform,
|
fill_colors_texture_uniform: Uniform,
|
||||||
fill_colors_texture_size_uniform: Uniform,
|
fill_colors_texture_size_uniform: Uniform,
|
||||||
view_box_origin_uniform: Uniform,
|
view_box_origin_uniform: Uniform,
|
||||||
|
quad_p0_uniform: Uniform,
|
||||||
|
quad_p1_uniform: Uniform,
|
||||||
|
quad_p2_uniform: Uniform,
|
||||||
|
quad_p3_uniform: Uniform,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SolidTileProgram {
|
impl SolidTileProgram {
|
||||||
|
@ -549,6 +586,10 @@ impl SolidTileProgram {
|
||||||
let fill_colors_texture_uniform = Uniform::new(&program, "FillColorsTexture");
|
let fill_colors_texture_uniform = Uniform::new(&program, "FillColorsTexture");
|
||||||
let fill_colors_texture_size_uniform = Uniform::new(&program, "FillColorsTextureSize");
|
let fill_colors_texture_size_uniform = Uniform::new(&program, "FillColorsTextureSize");
|
||||||
let view_box_origin_uniform = Uniform::new(&program, "ViewBoxOrigin");
|
let view_box_origin_uniform = Uniform::new(&program, "ViewBoxOrigin");
|
||||||
|
let quad_p0_uniform = Uniform::new(&program, "QuadP0");
|
||||||
|
let quad_p1_uniform = Uniform::new(&program, "QuadP1");
|
||||||
|
let quad_p2_uniform = Uniform::new(&program, "QuadP2");
|
||||||
|
let quad_p3_uniform = Uniform::new(&program, "QuadP3");
|
||||||
SolidTileProgram {
|
SolidTileProgram {
|
||||||
program,
|
program,
|
||||||
framebuffer_size_uniform,
|
framebuffer_size_uniform,
|
||||||
|
@ -556,6 +597,10 @@ impl SolidTileProgram {
|
||||||
fill_colors_texture_uniform,
|
fill_colors_texture_uniform,
|
||||||
fill_colors_texture_size_uniform,
|
fill_colors_texture_size_uniform,
|
||||||
view_box_origin_uniform,
|
view_box_origin_uniform,
|
||||||
|
quad_p0_uniform,
|
||||||
|
quad_p1_uniform,
|
||||||
|
quad_p2_uniform,
|
||||||
|
quad_p3_uniform,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -569,6 +614,10 @@ struct MaskTileProgram {
|
||||||
fill_colors_texture_uniform: Uniform,
|
fill_colors_texture_uniform: Uniform,
|
||||||
fill_colors_texture_size_uniform: Uniform,
|
fill_colors_texture_size_uniform: Uniform,
|
||||||
view_box_origin_uniform: Uniform,
|
view_box_origin_uniform: Uniform,
|
||||||
|
quad_p0_uniform: Uniform,
|
||||||
|
quad_p1_uniform: Uniform,
|
||||||
|
quad_p2_uniform: Uniform,
|
||||||
|
quad_p3_uniform: Uniform,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MaskTileProgram {
|
impl MaskTileProgram {
|
||||||
|
@ -581,6 +630,10 @@ impl MaskTileProgram {
|
||||||
let fill_colors_texture_uniform = Uniform::new(&program, "FillColorsTexture");
|
let fill_colors_texture_uniform = Uniform::new(&program, "FillColorsTexture");
|
||||||
let fill_colors_texture_size_uniform = Uniform::new(&program, "FillColorsTextureSize");
|
let fill_colors_texture_size_uniform = Uniform::new(&program, "FillColorsTextureSize");
|
||||||
let view_box_origin_uniform = Uniform::new(&program, "ViewBoxOrigin");
|
let view_box_origin_uniform = Uniform::new(&program, "ViewBoxOrigin");
|
||||||
|
let quad_p0_uniform = Uniform::new(&program, "QuadP0");
|
||||||
|
let quad_p1_uniform = Uniform::new(&program, "QuadP1");
|
||||||
|
let quad_p2_uniform = Uniform::new(&program, "QuadP2");
|
||||||
|
let quad_p3_uniform = Uniform::new(&program, "QuadP3");
|
||||||
MaskTileProgram {
|
MaskTileProgram {
|
||||||
program,
|
program,
|
||||||
framebuffer_size_uniform,
|
framebuffer_size_uniform,
|
||||||
|
@ -590,6 +643,10 @@ impl MaskTileProgram {
|
||||||
fill_colors_texture_uniform,
|
fill_colors_texture_uniform,
|
||||||
fill_colors_texture_size_uniform,
|
fill_colors_texture_size_uniform,
|
||||||
view_box_origin_uniform,
|
view_box_origin_uniform,
|
||||||
|
quad_p0_uniform,
|
||||||
|
quad_p1_uniform,
|
||||||
|
quad_p2_uniform,
|
||||||
|
quad_p3_uniform,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ use crate::gpu_data::{MaskTileBatchPrimitive, SolidTileScenePrimitive};
|
||||||
use crate::scene;
|
use crate::scene;
|
||||||
use crate::tiles;
|
use crate::tiles;
|
||||||
use crate::z_buffer::ZBuffer;
|
use crate::z_buffer::ZBuffer;
|
||||||
use pathfinder_geometry::basic::point::Point2DF32;
|
use pathfinder_geometry::basic::point::{Point2DF32, Point3DF32};
|
||||||
use pathfinder_geometry::basic::rect::{RectF32, RectI32};
|
use pathfinder_geometry::basic::rect::{RectF32, RectI32};
|
||||||
use pathfinder_geometry::basic::transform2d::Transform2DF32;
|
use pathfinder_geometry::basic::transform2d::Transform2DF32;
|
||||||
use pathfinder_geometry::basic::transform3d::Perspective;
|
use pathfinder_geometry::basic::transform3d::Perspective;
|
||||||
|
@ -173,17 +173,47 @@ impl RenderTransform {
|
||||||
for point in &mut points {
|
for point in &mut points {
|
||||||
*point = perspective.transform.transform_point(*point);
|
*point = perspective.transform.transform_point(*point);
|
||||||
}
|
}
|
||||||
//println!("... PERSPECTIVE quad={:?}", points);
|
println!("... PERSPECTIVE quad={:?}", points);
|
||||||
|
|
||||||
|
// Compute depth.
|
||||||
|
let quad = [
|
||||||
|
points[0].perspective_divide(),
|
||||||
|
points[1].perspective_divide(),
|
||||||
|
points[2].perspective_divide(),
|
||||||
|
points[3].perspective_divide(),
|
||||||
|
];
|
||||||
|
println!("barycentric(0, 0) = {:?}", compute_barycentric(&[
|
||||||
|
quad[0].to_2d(),
|
||||||
|
quad[1].to_2d(),
|
||||||
|
quad[2].to_2d(),
|
||||||
|
quad[3].to_2d(),
|
||||||
|
], Point2DF32::new(0.0, 0.0)));
|
||||||
|
|
||||||
points = PolygonClipper3D::new(points).clip();
|
points = PolygonClipper3D::new(points).clip();
|
||||||
//println!("... CLIPPED quad={:?}", points);
|
//println!("... CLIPPED quad={:?}", points);
|
||||||
for point in &mut points {
|
for point in &mut points {
|
||||||
*point = point.perspective_divide()
|
*point = point.perspective_divide()
|
||||||
}
|
}
|
||||||
|
|
||||||
let inverse_transform = perspective.transform.inverse();
|
let inverse_transform = perspective.transform.inverse();
|
||||||
let clip_polygon = points.into_iter().map(|point| {
|
let clip_polygon = points.into_iter().map(|point| {
|
||||||
inverse_transform.transform_point(point).perspective_divide().to_2d()
|
inverse_transform.transform_point(point).perspective_divide().to_2d()
|
||||||
}).collect();
|
}).collect();
|
||||||
PreparedRenderTransform::Perspective { perspective, clip_polygon }
|
return PreparedRenderTransform::Perspective { perspective, clip_polygon, quad };
|
||||||
|
|
||||||
|
fn compute_barycentric(quad: &[Point2DF32], point: Point2DF32) -> [f32; 4] {
|
||||||
|
let (s0, s1) = (quad[0] - point, quad[1] - point);
|
||||||
|
let (s2, s3) = (quad[2] - point, quad[3] - point);
|
||||||
|
let (a0, a1, a2, a3) = (s0.det(s1), s1.det(s2), s2.det(s3), s3.det(s0));
|
||||||
|
let (d0, d1, d2, d3) = (s0.dot(s1), s1.dot(s2), s2.dot(s3), s3.dot(s0));
|
||||||
|
let (r0, r1, r2, r3) = (s0.length(), s1.length(), s2.length(), s3.length());
|
||||||
|
let (t0, t1) = ((r0 * r1 - d0) / a0, (r1 * r2 - d1) / a1);
|
||||||
|
let (t2, t3) = ((r2 * r3 - d2) / a2, (r3 * r0 - d3) / a3);
|
||||||
|
let (u0, u1) = ((t3 + t0) / r0, (t2 + t1) / r1);
|
||||||
|
let (u2, u3) = ((t0 + t2) / r2, (t0 + t3) / r3);
|
||||||
|
let sum = u0 + u1 + u2 + u3;
|
||||||
|
[u0 / sum, u1 / sum, u2 / sum, u3 / sum]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,8 +222,19 @@ pub struct PreparedRenderOptions {
|
||||||
pub dilation: Point2DF32,
|
pub dilation: Point2DF32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PreparedRenderOptions {
|
||||||
|
#[inline]
|
||||||
|
pub fn quad(&self) -> [Point3DF32; 4] {
|
||||||
|
match self.transform {
|
||||||
|
PreparedRenderTransform::Perspective { quad, .. } => quad,
|
||||||
|
_ => [Point3DF32::default(); 4],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub enum PreparedRenderTransform {
|
pub enum PreparedRenderTransform {
|
||||||
None,
|
None,
|
||||||
Transform2D(Transform2DF32),
|
Transform2D(Transform2DF32),
|
||||||
Perspective { perspective: Perspective, clip_polygon: Vec<Point2DF32> }
|
Perspective { perspective: Perspective, clip_polygon: Vec<Point2DF32>, quad: [Point3DF32; 4] }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ use crate::paint::{ObjectShader, ShaderId};
|
||||||
use crate::tiles::{self, TILE_HEIGHT, TILE_WIDTH};
|
use crate::tiles::{self, TILE_HEIGHT, TILE_WIDTH};
|
||||||
use fixedbitset::FixedBitSet;
|
use fixedbitset::FixedBitSet;
|
||||||
use pathfinder_geometry::basic::line_segment::{LineSegmentF32, LineSegmentU4, LineSegmentU8};
|
use pathfinder_geometry::basic::line_segment::{LineSegmentF32, LineSegmentU4, LineSegmentU8};
|
||||||
use pathfinder_geometry::basic::point::Point2DF32;
|
use pathfinder_geometry::basic::point::{Point2DF32, Point3DF32};
|
||||||
use pathfinder_geometry::basic::rect::{RectF32, RectI32};
|
use pathfinder_geometry::basic::rect::{RectF32, RectI32};
|
||||||
use pathfinder_geometry::util;
|
use pathfinder_geometry::util;
|
||||||
use pathfinder_simd::default::{F32x4, I32x4};
|
use pathfinder_simd::default::{F32x4, I32x4};
|
||||||
|
@ -32,6 +32,7 @@ pub struct BuiltObject {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct BuiltScene {
|
pub struct BuiltScene {
|
||||||
pub view_box: RectF32,
|
pub view_box: RectF32,
|
||||||
|
pub quad: [Point3DF32; 4],
|
||||||
pub batches: Vec<Batch>,
|
pub batches: Vec<Batch>,
|
||||||
pub solid_tiles: Vec<SolidTileScenePrimitive>,
|
pub solid_tiles: Vec<SolidTileScenePrimitive>,
|
||||||
pub shaders: Vec<ObjectShader>,
|
pub shaders: Vec<ObjectShader>,
|
||||||
|
@ -249,8 +250,8 @@ impl BuiltObject {
|
||||||
|
|
||||||
impl BuiltScene {
|
impl BuiltScene {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(view_box: RectF32) -> BuiltScene {
|
pub fn new(view_box: RectF32, quad: &[Point3DF32; 4]) -> BuiltScene {
|
||||||
BuiltScene { view_box, batches: vec![], solid_tiles: vec![], shaders: vec![] }
|
BuiltScene { view_box, quad: *quad, batches: vec![], solid_tiles: vec![], shaders: vec![] }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
//! A set of paths to be rendered.
|
//! A set of paths to be rendered.
|
||||||
|
|
||||||
use crate::builder::{PreparedRenderOptions, PreparedRenderTransform, RenderOptions};
|
use crate::builder::{PreparedRenderOptions, PreparedRenderTransform};
|
||||||
use crate::gpu_data::BuiltObject;
|
use crate::gpu_data::BuiltObject;
|
||||||
use crate::paint::{ObjectShader, Paint, PaintId, ShaderId};
|
use crate::paint::{ObjectShader, Paint, PaintId, ShaderId};
|
||||||
use crate::tiles::Tiler;
|
use crate::tiles::Tiler;
|
||||||
|
@ -63,9 +63,10 @@ impl Scene {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_objects_sequentially(&self, options: RenderOptions, z_buffer: &ZBuffer)
|
pub fn build_objects_sequentially(&self,
|
||||||
|
built_options: PreparedRenderOptions,
|
||||||
|
z_buffer: &ZBuffer)
|
||||||
-> Vec<BuiltObject> {
|
-> Vec<BuiltObject> {
|
||||||
let built_options = options.prepare(self.bounds);
|
|
||||||
self.objects
|
self.objects
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
|
@ -84,8 +85,8 @@ impl Scene {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_objects(&self, options: RenderOptions, z_buffer: &ZBuffer) -> Vec<BuiltObject> {
|
pub fn build_objects(&self, built_options: PreparedRenderOptions, z_buffer: &ZBuffer)
|
||||||
let built_options = options.prepare(self.bounds);
|
-> Vec<BuiltObject> {
|
||||||
self.objects
|
self.objects
|
||||||
.par_iter()
|
.par_iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
|
@ -108,7 +109,7 @@ impl Scene {
|
||||||
-> Outline {
|
-> Outline {
|
||||||
let mut outline;
|
let mut outline;
|
||||||
match options.transform {
|
match options.transform {
|
||||||
PreparedRenderTransform::Perspective { ref perspective, ref clip_polygon } => {
|
PreparedRenderTransform::Perspective { ref perspective, ref clip_polygon, .. } => {
|
||||||
if original_outline.is_outside_polygon(clip_polygon) {
|
if original_outline.is_outside_polygon(clip_polygon) {
|
||||||
outline = Outline::new();
|
outline = Outline::new();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -18,6 +18,10 @@ uniform vec2 uStencilTextureSize;
|
||||||
uniform sampler2D uFillColorsTexture;
|
uniform sampler2D uFillColorsTexture;
|
||||||
uniform vec2 uFillColorsTextureSize;
|
uniform vec2 uFillColorsTextureSize;
|
||||||
uniform vec2 uViewBoxOrigin;
|
uniform vec2 uViewBoxOrigin;
|
||||||
|
uniform vec3 uQuadP0;
|
||||||
|
uniform vec3 uQuadP1;
|
||||||
|
uniform vec3 uQuadP2;
|
||||||
|
uniform vec3 uQuadP3;
|
||||||
|
|
||||||
in vec2 aTessCoord;
|
in vec2 aTessCoord;
|
||||||
in vec2 aTileOrigin;
|
in vec2 aTileOrigin;
|
||||||
|
@ -28,6 +32,21 @@ out vec2 vTexCoord;
|
||||||
out float vBackdrop;
|
out float vBackdrop;
|
||||||
out vec4 vColor;
|
out vec4 vColor;
|
||||||
|
|
||||||
|
float wedge(vec2 a, vec2 b) {
|
||||||
|
return a.x * b.y - a.y * b.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
// From "A Quadrilateral Rendering Primitive", Hormann and Tarini 2004.
|
||||||
|
vec4 barycentricQuad(vec2 p) {
|
||||||
|
vec2 s0 = uQuadP0.xy - p, s1 = uQuadP1.xy - p, s2 = uQuadP2.xy - p, s3 = uQuadP3.xy - p;
|
||||||
|
vec4 a = vec4(wedge(s0, s1), wedge(s1, s2), wedge(s2, s3), wedge(s3, s0));
|
||||||
|
vec4 d = vec4(dot(s0, s1), dot(s1, s2), dot(s2, s3), dot(s3, s0));
|
||||||
|
vec4 r = vec4(length(s0), length(s1), length(s2), length(s3));
|
||||||
|
vec4 t = (r * r.yzwx - d) / a;
|
||||||
|
vec4 u = (t.wxyz + t) / r;
|
||||||
|
return u / dot(u, vec4(1.0));
|
||||||
|
}
|
||||||
|
|
||||||
vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) {
|
vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) {
|
||||||
uint tilesPerRow = uint(stencilTextureWidth / uTileSize.x);
|
uint tilesPerRow = uint(stencilTextureWidth / uTileSize.x);
|
||||||
uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow);
|
uvec2 tileOffset = uvec2(tileIndex % tilesPerRow, tileIndex / tilesPerRow);
|
||||||
|
@ -41,11 +60,17 @@ vec2 computeFillColorTexCoord(uint object, vec2 textureSize) {
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
uint tileIndex = uint(gl_InstanceID);
|
uint tileIndex = uint(gl_InstanceID);
|
||||||
vec2 position = (aTileOrigin + aTessCoord) * uTileSize + uViewBoxOrigin;
|
vec2 pixelPosition = (aTileOrigin + aTessCoord) * uTileSize + uViewBoxOrigin;
|
||||||
|
vec2 position = (pixelPosition / uFramebufferSize * 2.0 - 1.0) * vec2(1.0, -1.0);
|
||||||
|
|
||||||
|
vec4 depths = vec4(uQuadP0.z, uQuadP1.z, uQuadP2.z, uQuadP3.z);
|
||||||
|
float depth = dot(barycentricQuad(position), depths);
|
||||||
|
|
||||||
vec2 texCoord = computeTileOffset(tileIndex, uStencilTextureSize.x) + aTessCoord * uTileSize;
|
vec2 texCoord = computeTileOffset(tileIndex, uStencilTextureSize.x) + aTessCoord * uTileSize;
|
||||||
vec2 colorTexCoord = computeFillColorTexCoord(aObject, uFillColorsTextureSize);
|
vec2 colorTexCoord = computeFillColorTexCoord(aObject, uFillColorsTextureSize);
|
||||||
|
|
||||||
vTexCoord = texCoord / uStencilTextureSize;
|
vTexCoord = texCoord / uStencilTextureSize;
|
||||||
vBackdrop = float(aBackdrop);
|
vBackdrop = float(aBackdrop);
|
||||||
vColor = texture(uFillColorsTexture, colorTexCoord);
|
vColor = texture(uFillColorsTexture, colorTexCoord);
|
||||||
gl_Position = vec4((position / uFramebufferSize * 2.0 - 1.0) * vec2(1.0, -1.0), 0.0, 1.0);
|
gl_Position = vec4(position, depth, 1.0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,10 @@ uniform vec2 uTileSize;
|
||||||
uniform sampler2D uFillColorsTexture;
|
uniform sampler2D uFillColorsTexture;
|
||||||
uniform vec2 uFillColorsTextureSize;
|
uniform vec2 uFillColorsTextureSize;
|
||||||
uniform vec2 uViewBoxOrigin;
|
uniform vec2 uViewBoxOrigin;
|
||||||
|
uniform vec3 uQuadP0;
|
||||||
|
uniform vec3 uQuadP1;
|
||||||
|
uniform vec3 uQuadP2;
|
||||||
|
uniform vec3 uQuadP3;
|
||||||
|
|
||||||
in vec2 aTessCoord;
|
in vec2 aTessCoord;
|
||||||
in vec2 aTileOrigin;
|
in vec2 aTileOrigin;
|
||||||
|
@ -24,14 +28,35 @@ in uint aObject;
|
||||||
|
|
||||||
out vec4 vColor;
|
out vec4 vColor;
|
||||||
|
|
||||||
|
float wedge(vec2 a, vec2 b) {
|
||||||
|
return a.x * b.y - a.y * b.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
// From "A Quadrilateral Rendering Primitive", Hormann and Tarini 2004.
|
||||||
|
vec4 barycentricQuad(vec2 p) {
|
||||||
|
vec2 s0 = uQuadP0.xy - p, s1 = uQuadP1.xy - p, s2 = uQuadP2.xy - p, s3 = uQuadP3.xy - p;
|
||||||
|
vec4 a = vec4(wedge(s0, s1), wedge(s1, s2), wedge(s2, s3), wedge(s3, s0));
|
||||||
|
vec4 d = vec4(dot(s0, s1), dot(s1, s2), dot(s2, s3), dot(s3, s0));
|
||||||
|
vec4 r = vec4(length(s0), length(s1), length(s2), length(s3));
|
||||||
|
vec4 t = (r * r.yzwx - d) / a;
|
||||||
|
vec4 u = (t.wxyz + t) / r;
|
||||||
|
return u / dot(u, vec4(1.0));
|
||||||
|
}
|
||||||
|
|
||||||
vec2 computeFillColorTexCoord(uint object, vec2 textureSize) {
|
vec2 computeFillColorTexCoord(uint object, vec2 textureSize) {
|
||||||
uint width = uint(textureSize.x);
|
uint width = uint(textureSize.x);
|
||||||
return (vec2(float(object % width), float(object / width)) + vec2(0.5)) / textureSize;
|
return (vec2(float(object % width), float(object / width)) + vec2(0.5)) / textureSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 position = (aTileOrigin + aTessCoord) * uTileSize + uViewBoxOrigin;
|
vec2 pixelPosition = (aTileOrigin + aTessCoord) * uTileSize + uViewBoxOrigin;
|
||||||
|
vec2 position = (pixelPosition / uFramebufferSize * 2.0 - 1.0) * vec2(1.0, -1.0);
|
||||||
|
|
||||||
|
vec4 depths = vec4(uQuadP0.z, uQuadP1.z, uQuadP2.z, uQuadP3.z);
|
||||||
|
float depth = dot(barycentricQuad(position), depths);
|
||||||
|
|
||||||
vec2 colorTexCoord = computeFillColorTexCoord(aObject, uFillColorsTextureSize);
|
vec2 colorTexCoord = computeFillColorTexCoord(aObject, uFillColorsTextureSize);
|
||||||
|
|
||||||
vColor = texture(uFillColorsTexture, colorTexCoord);
|
vColor = texture(uFillColorsTexture, colorTexCoord);
|
||||||
gl_Position = vec4((position / uFramebufferSize * 2.0 - 1.0) * vec2(1.0, -1.0), 0.0, 1.0);
|
gl_Position = vec4(position, depth, 1.0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue