Use a 3D transform in the tile vertex shaders.

This opens the door to caching tiles at different zoom levels (issue #191).
This commit is contained in:
Patrick Walton 2019-06-25 11:32:39 -07:00
parent 4cdded74b4
commit 222fa89b23
12 changed files with 70 additions and 97 deletions

View File

@ -306,6 +306,11 @@ impl Transform3DF {
pub fn as_ptr(&self) -> *const f32 {
(&self.c0) as *const F32x4 as *const f32
}
#[inline]
pub fn to_columns(&self) -> [F32x4; 4] {
[self.c0, self.c1, self.c2, self.c3]
}
}
impl Add<Matrix2x2F> for Matrix2x2F {

View File

@ -473,17 +473,23 @@ where
self.buffered_fills.clear();
}
fn tile_transform(&self) -> Transform3DF {
let draw_viewport = self.draw_viewport().size().to_f32();
let scale = F32x4::new(2.0 / draw_viewport.x(), -2.0 / draw_viewport.y(), 1.0, 1.0);
let transform = Transform3DF::from_scale(scale.x(), scale.y(), 1.0);
Transform3DF::from_translation(-1.0, 1.0, 0.0).post_mul(&transform)
}
fn draw_alpha_tiles(&mut self, count: u32) {
let clear_color = self.clear_color_for_draw_operation();
let alpha_tile_vertex_array = self.alpha_tile_vertex_array();
let alpha_tile_program = self.alpha_tile_program();
let draw_viewport = self.draw_viewport();
let mut textures = vec![self.device.framebuffer_texture(&self.mask_framebuffer)];
let mut uniforms = vec![
(&alpha_tile_program.framebuffer_size_uniform,
UniformData::Vec2(draw_viewport.size().to_f32().0)),
(&alpha_tile_program.transform_uniform,
UniformData::Mat4(self.tile_transform().to_columns())),
(&alpha_tile_program.tile_size_uniform,
UniformData::Vec2(I32x4::new(TILE_WIDTH as i32,
TILE_HEIGHT as i32,
@ -495,8 +501,6 @@ where
MASK_FRAMEBUFFER_HEIGHT,
0,
0).to_f32x4())),
// FIXME(pcwalton): Fill this in properly!
(&alpha_tile_program.view_box_origin_uniform, UniformData::Vec2(F32x4::default())),
];
match self.render_mode {
@ -528,7 +532,7 @@ where
primitive: Primitive::Triangles,
textures: &textures,
uniforms: &uniforms,
viewport: draw_viewport,
viewport: self.draw_viewport(),
options: RenderOptions {
blend: BlendState::RGBSrcAlphaAlphaOneMinusSrcAlpha,
stencil: self.stencil_state(),
@ -546,18 +550,15 @@ where
let solid_tile_vertex_array = self.solid_tile_vertex_array();
let solid_tile_program = self.solid_tile_program();
let draw_viewport = self.draw_viewport();
let mut textures = vec![];
let mut uniforms = vec![
(&solid_tile_program.framebuffer_size_uniform,
UniformData::Vec2(draw_viewport.size().0.to_f32x4())),
(&solid_tile_program.transform_uniform,
UniformData::Mat4(self.tile_transform().to_columns())),
(&solid_tile_program.tile_size_uniform,
UniformData::Vec2(I32x4::new(TILE_WIDTH as i32,
TILE_HEIGHT as i32,
0,
0).to_f32x4())),
// FIXME(pcwalton): Fill this in properly!
(&solid_tile_program.view_box_origin_uniform, UniformData::Vec2(F32x4::default())),
];
match self.render_mode {
@ -589,7 +590,7 @@ where
primitive: Primitive::Triangles,
textures: &textures,
uniforms: &uniforms,
viewport: draw_viewport,
viewport: self.draw_viewport(),
options: RenderOptions {
stencil: self.stencil_state(),
clear_ops: ClearOps { color: clear_color, ..ClearOps::default() },
@ -1217,9 +1218,8 @@ where
D: Device,
{
program: D::Program,
framebuffer_size_uniform: D::Uniform,
transform_uniform: D::Uniform,
tile_size_uniform: D::Uniform,
view_box_origin_uniform: D::Uniform,
}
impl<D> SolidTileProgram<D>
@ -1233,15 +1233,9 @@ where
program_name,
"tile_solid",
);
let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
let transform_uniform = device.get_uniform(&program, "Transform");
let tile_size_uniform = device.get_uniform(&program, "TileSize");
let view_box_origin_uniform = device.get_uniform(&program, "ViewBoxOrigin");
SolidTileProgram {
program,
framebuffer_size_uniform,
tile_size_uniform,
view_box_origin_uniform,
}
SolidTileProgram { program, transform_uniform, tile_size_uniform }
}
}
@ -1299,11 +1293,10 @@ where
D: Device,
{
program: D::Program,
framebuffer_size_uniform: D::Uniform,
transform_uniform: D::Uniform,
tile_size_uniform: D::Uniform,
stencil_texture_uniform: D::Uniform,
stencil_texture_size_uniform: D::Uniform,
view_box_origin_uniform: D::Uniform,
}
impl<D> AlphaTileProgram<D>
@ -1317,18 +1310,16 @@ where
program_name,
"tile_alpha",
);
let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
let transform_uniform = device.get_uniform(&program, "Transform");
let tile_size_uniform = device.get_uniform(&program, "TileSize");
let stencil_texture_uniform = device.get_uniform(&program, "StencilTexture");
let stencil_texture_size_uniform = device.get_uniform(&program, "StencilTextureSize");
let view_box_origin_uniform = device.get_uniform(&program, "ViewBoxOrigin");
AlphaTileProgram {
program,
framebuffer_size_uniform,
transform_uniform,
tile_size_uniform,
stencil_texture_uniform,
stencil_texture_size_uniform,
view_box_origin_uniform,
}
}
}

View File

@ -27,10 +27,9 @@ precision highp float;
uniform vec2 uFramebufferSize;
uniform mat4 uTransform;
uniform vec2 uTileSize;
uniform vec2 uStencilTextureSize;
uniform vec2 uViewBoxOrigin;
in uvec2 aTessCoord;
in uvec3 aTileOrigin;
@ -51,15 +50,14 @@ vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth){
void computeVaryings(){
vec2 origin = vec2(aTileOrigin . xy)+ vec2(aTileOrigin . z & 15u, aTileOrigin . z >> 4u)* 256.0;
vec2 pixelPosition =(origin + vec2(aTessCoord))* uTileSize + uViewBoxOrigin;
vec2 position =(pixelPosition / uFramebufferSize * 2.0 - 1.0)* vec2(1.0, - 1.0);
vec2 position =(origin + vec2(aTessCoord))* uTileSize;
vec2 maskTexCoordOrigin = computeTileOffset(uint(aTileIndex), uStencilTextureSize . x);
vec2 maskTexCoord = maskTexCoordOrigin + aTessCoord * uTileSize;
vTexCoord = maskTexCoord / uStencilTextureSize;
vBackdrop = float(aBackdrop);
vColor = getColor();
gl_Position = vec4(position, 0.0, 1.0);
gl_Position = uTransform * vec4(position, 0.0, 1.0);
}

View File

@ -27,10 +27,9 @@ precision highp float;
uniform vec2 uFramebufferSize;
uniform mat4 uTransform;
uniform vec2 uTileSize;
uniform vec2 uStencilTextureSize;
uniform vec2 uViewBoxOrigin;
in uvec2 aTessCoord;
in uvec3 aTileOrigin;
@ -51,15 +50,14 @@ vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth){
void computeVaryings(){
vec2 origin = vec2(aTileOrigin . xy)+ vec2(aTileOrigin . z & 15u, aTileOrigin . z >> 4u)* 256.0;
vec2 pixelPosition =(origin + vec2(aTessCoord))* uTileSize + uViewBoxOrigin;
vec2 position =(pixelPosition / uFramebufferSize * 2.0 - 1.0)* vec2(1.0, - 1.0);
vec2 position =(origin + vec2(aTessCoord))* uTileSize;
vec2 maskTexCoordOrigin = computeTileOffset(uint(aTileIndex), uStencilTextureSize . x);
vec2 maskTexCoord = maskTexCoordOrigin + aTessCoord * uTileSize;
vTexCoord = maskTexCoord / uStencilTextureSize;
vBackdrop = float(aBackdrop);
vColor = getColor();
gl_Position = vec4(position, 0.0, 1.0);
gl_Position = uTransform * vec4(position, 0.0, 1.0);
}

View File

@ -27,9 +27,8 @@ precision highp float;
uniform vec2 uFramebufferSize;
uniform mat4 uTransform;
uniform vec2 uTileSize;
uniform vec2 uViewBoxOrigin;
in uvec2 aTessCoord;
in ivec2 aTileOrigin;
@ -39,11 +38,9 @@ out vec4 vColor;
vec4 getColor();
void computeVaryings(){
vec2 pixelPosition = vec2(aTileOrigin + ivec2(aTessCoord))* uTileSize + uViewBoxOrigin;
vec2 position =(pixelPosition / uFramebufferSize * 2.0 - 1.0)* vec2(1.0, - 1.0);
vec2 position = vec2(aTileOrigin + ivec2(aTessCoord))* uTileSize;
vColor = getColor();
gl_Position = vec4(position, 0.0, 1.0);
gl_Position = uTransform * vec4(position, 0.0, 1.0);
}

View File

@ -27,9 +27,8 @@ precision highp float;
uniform vec2 uFramebufferSize;
uniform mat4 uTransform;
uniform vec2 uTileSize;
uniform vec2 uViewBoxOrigin;
in uvec2 aTessCoord;
in ivec2 aTileOrigin;
@ -39,11 +38,9 @@ out vec4 vColor;
vec4 getColor();
void computeVaryings(){
vec2 pixelPosition = vec2(aTileOrigin + ivec2(aTessCoord))* uTileSize + uViewBoxOrigin;
vec2 position =(pixelPosition / uFramebufferSize * 2.0 - 1.0)* vec2(1.0, - 1.0);
vec2 position = vec2(aTileOrigin + ivec2(aTessCoord))* uTileSize;
vColor = getColor();
gl_Position = vec4(position, 0.0, 1.0);
gl_Position = uTransform * vec4(position, 0.0, 1.0);
}

View File

@ -9,10 +9,9 @@ using namespace metal;
struct spvDescriptorSetBuffer0
{
constant float2* uTileSize [[id(0)]];
constant float2* uViewBoxOrigin [[id(1)]];
constant float2* uFramebufferSize [[id(2)]];
constant float2* uStencilTextureSize [[id(3)]];
constant float4* uColor [[id(4)]];
constant float2* uStencilTextureSize [[id(1)]];
constant float4x4* uTransform [[id(2)]];
constant float4* uColor [[id(3)]];
};
struct main0_out
@ -43,11 +42,10 @@ float4 getColor(thread float4 uColor)
return uColor;
}
void computeVaryings(thread float2 uTileSize, thread uint3& aTileOrigin, thread uint2& aTessCoord, thread float2 uViewBoxOrigin, thread float2 uFramebufferSize, thread int& aTileIndex, thread float2 uStencilTextureSize, thread float2& vTexCoord, thread float& vBackdrop, thread int& aBackdrop, thread float4& vColor, thread float4& gl_Position, thread float4 uColor)
void computeVaryings(thread float2 uTileSize, thread uint3& aTileOrigin, thread uint2& aTessCoord, thread int& aTileIndex, thread float2 uStencilTextureSize, thread float2& vTexCoord, thread float& vBackdrop, thread int& aBackdrop, thread float4& vColor, thread float4& gl_Position, thread float4x4 uTransform, thread float4 uColor)
{
float2 origin = float2(aTileOrigin.xy) + (float2(float(aTileOrigin.z & 15u), float(aTileOrigin.z >> 4u)) * 256.0);
float2 pixelPosition = ((origin + float2(aTessCoord)) * uTileSize) + uViewBoxOrigin;
float2 position = (((pixelPosition / uFramebufferSize) * 2.0) - float2(1.0)) * float2(1.0, -1.0);
float2 position = (origin + float2(aTessCoord)) * uTileSize;
uint param = uint(aTileIndex);
float param_1 = uStencilTextureSize.x;
float2 maskTexCoordOrigin = computeTileOffset(param, param_1, uTileSize);
@ -55,13 +53,13 @@ void computeVaryings(thread float2 uTileSize, thread uint3& aTileOrigin, thread
vTexCoord = maskTexCoord / uStencilTextureSize;
vBackdrop = float(aBackdrop);
vColor = getColor(uColor);
gl_Position = float4(position, 0.0, 1.0);
gl_Position = uTransform * float4(position, 0.0, 1.0);
}
vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
{
main0_out out = {};
computeVaryings((*spvDescriptorSet0.uTileSize), in.aTileOrigin, in.aTessCoord, (*spvDescriptorSet0.uViewBoxOrigin), (*spvDescriptorSet0.uFramebufferSize), in.aTileIndex, (*spvDescriptorSet0.uStencilTextureSize), out.vTexCoord, out.vBackdrop, in.aBackdrop, out.vColor, out.gl_Position, (*spvDescriptorSet0.uColor));
computeVaryings((*spvDescriptorSet0.uTileSize), in.aTileOrigin, in.aTessCoord, in.aTileIndex, (*spvDescriptorSet0.uStencilTextureSize), out.vTexCoord, out.vBackdrop, in.aBackdrop, out.vColor, out.gl_Position, (*spvDescriptorSet0.uTransform), (*spvDescriptorSet0.uColor));
return out;
}

View File

@ -9,11 +9,10 @@ using namespace metal;
struct spvDescriptorSetBuffer0
{
constant float2* uTileSize [[id(0)]];
constant float2* uViewBoxOrigin [[id(1)]];
constant float2* uFramebufferSize [[id(2)]];
constant float2* uStencilTextureSize [[id(3)]];
texture2d<float> uPaintTexture [[id(4)]];
sampler uPaintTextureSmplr [[id(5)]];
constant float2* uStencilTextureSize [[id(1)]];
constant float4x4* uTransform [[id(2)]];
texture2d<float> uPaintTexture [[id(3)]];
sampler uPaintTextureSmplr [[id(4)]];
};
struct main0_out
@ -45,11 +44,10 @@ float4 getColor(thread texture2d<float> uPaintTexture, thread const sampler uPai
return uPaintTexture.sample(uPaintTextureSmplr, aColorTexCoord, level(0.0));
}
void computeVaryings(thread float2 uTileSize, thread uint3& aTileOrigin, thread uint2& aTessCoord, thread float2 uViewBoxOrigin, thread float2 uFramebufferSize, thread int& aTileIndex, thread float2 uStencilTextureSize, thread float2& vTexCoord, thread float& vBackdrop, thread int& aBackdrop, thread float4& vColor, thread float4& gl_Position, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& aColorTexCoord)
void computeVaryings(thread float2 uTileSize, thread uint3& aTileOrigin, thread uint2& aTessCoord, thread int& aTileIndex, thread float2 uStencilTextureSize, thread float2& vTexCoord, thread float& vBackdrop, thread int& aBackdrop, thread float4& vColor, thread float4& gl_Position, thread float4x4 uTransform, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& aColorTexCoord)
{
float2 origin = float2(aTileOrigin.xy) + (float2(float(aTileOrigin.z & 15u), float(aTileOrigin.z >> 4u)) * 256.0);
float2 pixelPosition = ((origin + float2(aTessCoord)) * uTileSize) + uViewBoxOrigin;
float2 position = (((pixelPosition / uFramebufferSize) * 2.0) - float2(1.0)) * float2(1.0, -1.0);
float2 position = (origin + float2(aTessCoord)) * uTileSize;
uint param = uint(aTileIndex);
float param_1 = uStencilTextureSize.x;
float2 maskTexCoordOrigin = computeTileOffset(param, param_1, uTileSize);
@ -57,13 +55,13 @@ void computeVaryings(thread float2 uTileSize, thread uint3& aTileOrigin, thread
vTexCoord = maskTexCoord / uStencilTextureSize;
vBackdrop = float(aBackdrop);
vColor = getColor(uPaintTexture, uPaintTextureSmplr, aColorTexCoord);
gl_Position = float4(position, 0.0, 1.0);
gl_Position = uTransform * float4(position, 0.0, 1.0);
}
vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
{
main0_out out = {};
computeVaryings((*spvDescriptorSet0.uTileSize), in.aTileOrigin, in.aTessCoord, (*spvDescriptorSet0.uViewBoxOrigin), (*spvDescriptorSet0.uFramebufferSize), in.aTileIndex, (*spvDescriptorSet0.uStencilTextureSize), out.vTexCoord, out.vBackdrop, in.aBackdrop, out.vColor, out.gl_Position, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.aColorTexCoord);
computeVaryings((*spvDescriptorSet0.uTileSize), in.aTileOrigin, in.aTessCoord, in.aTileIndex, (*spvDescriptorSet0.uStencilTextureSize), out.vTexCoord, out.vBackdrop, in.aBackdrop, out.vColor, out.gl_Position, (*spvDescriptorSet0.uTransform), spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.aColorTexCoord);
return out;
}

View File

@ -9,9 +9,8 @@ using namespace metal;
struct spvDescriptorSetBuffer0
{
constant float2* uTileSize [[id(0)]];
constant float2* uViewBoxOrigin [[id(1)]];
constant float2* uFramebufferSize [[id(2)]];
constant float4* uColor [[id(3)]];
constant float4x4* uTransform [[id(1)]];
constant float4* uColor [[id(2)]];
};
struct main0_out
@ -31,18 +30,17 @@ float4 getColor(thread float4 uColor)
return uColor;
}
void computeVaryings(thread int2& aTileOrigin, thread uint2& aTessCoord, thread float2 uTileSize, thread float2 uViewBoxOrigin, thread float2 uFramebufferSize, thread float4& vColor, thread float4& gl_Position, thread float4 uColor)
void computeVaryings(thread int2& aTileOrigin, thread uint2& aTessCoord, thread float2 uTileSize, thread float4& vColor, thread float4& gl_Position, thread float4x4 uTransform, thread float4 uColor)
{
float2 pixelPosition = (float2(aTileOrigin + int2(aTessCoord)) * uTileSize) + uViewBoxOrigin;
float2 position = (((pixelPosition / uFramebufferSize) * 2.0) - float2(1.0)) * float2(1.0, -1.0);
float2 position = float2(aTileOrigin + int2(aTessCoord)) * uTileSize;
vColor = getColor(uColor);
gl_Position = float4(position, 0.0, 1.0);
gl_Position = uTransform * float4(position, 0.0, 1.0);
}
vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
{
main0_out out = {};
computeVaryings(in.aTileOrigin, in.aTessCoord, (*spvDescriptorSet0.uTileSize), (*spvDescriptorSet0.uViewBoxOrigin), (*spvDescriptorSet0.uFramebufferSize), out.vColor, out.gl_Position, (*spvDescriptorSet0.uColor));
computeVaryings(in.aTileOrigin, in.aTessCoord, (*spvDescriptorSet0.uTileSize), out.vColor, out.gl_Position, (*spvDescriptorSet0.uTransform), (*spvDescriptorSet0.uColor));
return out;
}

View File

@ -9,10 +9,9 @@ using namespace metal;
struct spvDescriptorSetBuffer0
{
constant float2* uTileSize [[id(0)]];
constant float2* uViewBoxOrigin [[id(1)]];
constant float2* uFramebufferSize [[id(2)]];
texture2d<float> uPaintTexture [[id(3)]];
sampler uPaintTextureSmplr [[id(4)]];
constant float4x4* uTransform [[id(1)]];
texture2d<float> uPaintTexture [[id(2)]];
sampler uPaintTextureSmplr [[id(3)]];
};
struct main0_out
@ -33,18 +32,17 @@ float4 getColor(thread texture2d<float> uPaintTexture, thread const sampler uPai
return uPaintTexture.sample(uPaintTextureSmplr, aColorTexCoord, level(0.0));
}
void computeVaryings(thread int2& aTileOrigin, thread uint2& aTessCoord, thread float2 uTileSize, thread float2 uViewBoxOrigin, thread float2 uFramebufferSize, thread float4& vColor, thread float4& gl_Position, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& aColorTexCoord)
void computeVaryings(thread int2& aTileOrigin, thread uint2& aTessCoord, thread float2 uTileSize, thread float4& vColor, thread float4& gl_Position, thread float4x4 uTransform, thread texture2d<float> uPaintTexture, thread const sampler uPaintTextureSmplr, thread float2& aColorTexCoord)
{
float2 pixelPosition = (float2(aTileOrigin + int2(aTessCoord)) * uTileSize) + uViewBoxOrigin;
float2 position = (((pixelPosition / uFramebufferSize) * 2.0) - float2(1.0)) * float2(1.0, -1.0);
float2 position = float2(aTileOrigin + int2(aTessCoord)) * uTileSize;
vColor = getColor(uPaintTexture, uPaintTextureSmplr, aColorTexCoord);
gl_Position = float4(position, 0.0, 1.0);
gl_Position = uTransform * float4(position, 0.0, 1.0);
}
vertex main0_out main0(main0_in in [[stage_in]], constant spvDescriptorSetBuffer0& spvDescriptorSet0 [[buffer(0)]])
{
main0_out out = {};
computeVaryings(in.aTileOrigin, in.aTessCoord, (*spvDescriptorSet0.uTileSize), (*spvDescriptorSet0.uViewBoxOrigin), (*spvDescriptorSet0.uFramebufferSize), out.vColor, out.gl_Position, spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.aColorTexCoord);
computeVaryings(in.aTileOrigin, in.aTessCoord, (*spvDescriptorSet0.uTileSize), out.vColor, out.gl_Position, (*spvDescriptorSet0.uTransform), spvDescriptorSet0.uPaintTexture, spvDescriptorSet0.uPaintTextureSmplr, in.aColorTexCoord);
return out;
}

View File

@ -8,10 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
uniform vec2 uFramebufferSize;
uniform mat4 uTransform;
uniform vec2 uTileSize;
uniform vec2 uStencilTextureSize;
uniform vec2 uViewBoxOrigin;
in uvec2 aTessCoord;
in uvec3 aTileOrigin;
@ -32,14 +31,13 @@ vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) {
void computeVaryings() {
vec2 origin = vec2(aTileOrigin.xy) + vec2(aTileOrigin.z & 15u, aTileOrigin.z >> 4u) * 256.0;
vec2 pixelPosition = (origin + vec2(aTessCoord)) * uTileSize + uViewBoxOrigin;
vec2 position = (pixelPosition / uFramebufferSize * 2.0 - 1.0) * vec2(1.0, -1.0);
vec2 position = (origin + vec2(aTessCoord)) * uTileSize;
vec2 maskTexCoordOrigin = computeTileOffset(uint(aTileIndex), uStencilTextureSize.x);
vec2 maskTexCoord = maskTexCoordOrigin + aTessCoord * uTileSize;
vTexCoord = maskTexCoord / uStencilTextureSize;
vBackdrop = float(aBackdrop);
vColor = getColor();
gl_Position = vec4(position, 0.0, 1.0);
gl_Position = uTransform * vec4(position, 0.0, 1.0);
}

View File

@ -8,9 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
uniform vec2 uFramebufferSize;
uniform mat4 uTransform;
uniform vec2 uTileSize;
uniform vec2 uViewBoxOrigin;
in uvec2 aTessCoord;
in ivec2 aTileOrigin;
@ -20,9 +19,7 @@ out vec4 vColor;
vec4 getColor();
void computeVaryings() {
vec2 pixelPosition = vec2(aTileOrigin + ivec2(aTessCoord)) * uTileSize + uViewBoxOrigin;
vec2 position = (pixelPosition / uFramebufferSize * 2.0 - 1.0) * vec2(1.0, -1.0);
vec2 position = vec2(aTileOrigin + ivec2(aTessCoord)) * uTileSize;
vColor = getColor();
gl_Position = vec4(position, 0.0, 1.0);
gl_Position = uTransform * vec4(position, 0.0, 1.0);
}