mirror of
https://github.com/ManimCommunity/manim.git
synced 2026-06-22 10:01:47 +00:00
Formatting shaders
This commit is contained in:
parent
b830b7d63e
commit
e18fdd2e74
16 changed files with 199 additions and 189 deletions
1
.clang-format
Normal file
1
.clang-format
Normal file
|
|
@ -0,0 +1 @@
|
|||
BasedOnStyle: Microsoft
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
uniform vec4 u_color;
|
||||
out vec4 frag_color;
|
||||
|
||||
void main() {
|
||||
frag_color = u_color;
|
||||
void main()
|
||||
{
|
||||
frag_color = u_color;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ uniform mat4 u_model_matrix;
|
|||
uniform mat4 u_view_matrix;
|
||||
uniform mat4 u_projection_matrix;
|
||||
|
||||
void main() {
|
||||
void main()
|
||||
{
|
||||
gl_Position = u_projection_matrix * u_view_matrix * u_model_matrix * vec4(in_vert, 1.0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef CAMERA_GLSL
|
||||
#define CAMERA_GLSL
|
||||
layout (std140) uniform ubo_camera {
|
||||
layout(std140) uniform ubo_camera
|
||||
{
|
||||
// mat4 u_projection_view_matrix; # TODO: convert to mat4 instead of the following...
|
||||
vec2 frame_shape;
|
||||
vec3 camera_center;
|
||||
|
|
|
|||
|
|
@ -1,29 +1,22 @@
|
|||
#ifndef FINALIZE_COLOR_GLSL
|
||||
#define FINALIZE_COLOR_GLSL
|
||||
|
||||
vec3 float_to_color(float value, float min_val, float max_val, vec3[9] colormap_data){
|
||||
vec3 float_to_color(float value, float min_val, float max_val, vec3[9] colormap_data)
|
||||
{
|
||||
float alpha = clamp((value - min_val) / (max_val - min_val), 0.0, 1.0);
|
||||
int disc_alpha = min(int(alpha * 8), 7);
|
||||
return mix(
|
||||
colormap_data[disc_alpha],
|
||||
colormap_data[disc_alpha + 1],
|
||||
8.0 * alpha - disc_alpha
|
||||
);
|
||||
return mix(colormap_data[disc_alpha], colormap_data[disc_alpha + 1], 8.0 * alpha - disc_alpha);
|
||||
}
|
||||
|
||||
|
||||
vec4 add_light(vec4 color,
|
||||
vec3 point,
|
||||
vec3 unit_normal,
|
||||
vec3 light_coords,
|
||||
float gloss,
|
||||
float shadow){
|
||||
vec4 add_light(vec4 color, vec3 point, vec3 unit_normal, vec3 light_coords, float gloss, float shadow)
|
||||
{
|
||||
if (gloss == 0.0 && shadow == 0.0 && reflectiveness == 0.0)
|
||||
return color;
|
||||
|
||||
// TODO, do we actually want this? It effectively treats surfaces as two-sided
|
||||
if(unit_normal.z < 0){
|
||||
unit_normal *= -1;
|
||||
if (unit_normal.z < 0)
|
||||
{
|
||||
unit_normal *= -1;
|
||||
}
|
||||
|
||||
// TODO, read this in as a uniform?
|
||||
|
|
@ -36,18 +29,11 @@ vec4 add_light(vec4 color,
|
|||
float shine = gloss * exp(-3 * pow(1 - dot_prod, 2));
|
||||
float dp2 = dot(normalize(to_light), unit_normal);
|
||||
float darkening = mix(1, max(dp2, 0), shadow);
|
||||
return vec4(
|
||||
darkening * mix(color.rgb, vec3(1.0), shine),
|
||||
color.a
|
||||
);
|
||||
return vec4(darkening * mix(color.rgb, vec3(1.0), shine), color.a);
|
||||
}
|
||||
|
||||
vec4 finalize_color(vec4 color,
|
||||
vec3 point,
|
||||
vec3 unit_normal,
|
||||
vec3 light_coords,
|
||||
float gloss,
|
||||
float shadow){
|
||||
vec4 finalize_color(vec4 color, vec3 point, vec3 unit_normal, vec3 light_coords, float gloss, float shadow)
|
||||
{
|
||||
///// INSERT COLOR FUNCTION HERE /////
|
||||
// The line above may be replaced by arbitrary code snippets, as per
|
||||
// the method Mobject.set_color_by_code
|
||||
|
|
|
|||
|
|
@ -6,29 +6,35 @@
|
|||
|
||||
const vec2 DEFAULT_FRAME_SHAPE = vec2(8.0 * 16.0 / 9.0, 8.0);
|
||||
|
||||
float perspective_scale_factor(float z, float focal_distance) {
|
||||
return max(0.0, focal_distance / (focal_distance - z));
|
||||
float perspective_scale_factor(float z, float focal_distance)
|
||||
{
|
||||
return max(0.0, focal_distance / (focal_distance - z));
|
||||
}
|
||||
|
||||
vec4 get_gl_Position(vec3 point) {
|
||||
vec4 result = vec4(point, 1.0);
|
||||
if (!bool(is_fixed_in_frame)) {
|
||||
result.x *= 2.0 / frame_shape.x;
|
||||
result.y *= 2.0 / frame_shape.y;
|
||||
float psf = perspective_scale_factor(result.z, focal_distance);
|
||||
if (psf > 0) {
|
||||
result.xy *= psf;
|
||||
// TODO, what's the better way to do this?
|
||||
// This is to keep vertices too far out of frame from getting cut.
|
||||
// TODO This will be done by the clipping plane in the future with the
|
||||
// transformation matrix result.z += z_shift;
|
||||
result.z *= (1.0 / 100.0);
|
||||
vec4 get_gl_Position(vec3 point)
|
||||
{
|
||||
vec4 result = vec4(point, 1.0);
|
||||
if (!bool(is_fixed_in_frame))
|
||||
{
|
||||
result.x *= 2.0 / frame_shape.x;
|
||||
result.y *= 2.0 / frame_shape.y;
|
||||
float psf = perspective_scale_factor(result.z, focal_distance);
|
||||
if (psf > 0)
|
||||
{
|
||||
result.xy *= psf;
|
||||
// TODO, what's the better way to do this?
|
||||
// This is to keep vertices too far out of frame from getting cut.
|
||||
// TODO This will be done by the clipping plane in the future with the
|
||||
// transformation matrix result.z += z_shift;
|
||||
result.z *= (1.0 / 100.0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result.x *= 2.0 / DEFAULT_FRAME_SHAPE.x;
|
||||
result.y *= 2.0 / DEFAULT_FRAME_SHAPE.y;
|
||||
}
|
||||
result.z *= -1;
|
||||
return result;
|
||||
else
|
||||
{
|
||||
result.x *= 2.0 / DEFAULT_FRAME_SHAPE.x;
|
||||
result.y *= 2.0 / DEFAULT_FRAME_SHAPE.y;
|
||||
}
|
||||
result.z *= -1;
|
||||
return result;
|
||||
}
|
||||
#endif // GET_GL_POSITION_GLSL
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
#ifndef MOBJECT_GLSL
|
||||
#define MOBJECT_GLSL
|
||||
|
||||
layout (std140) uniform ubo_mobject {
|
||||
layout(std140) uniform ubo_mobject
|
||||
{
|
||||
vec3 light_source_position;
|
||||
float gloss;
|
||||
float shadow;
|
||||
|
|
|
|||
|
|
@ -4,19 +4,23 @@
|
|||
#include "./camera_uniform_declarations.glsl"
|
||||
#include "./mobject_uniform_declarations.glsl"
|
||||
|
||||
vec3 rotate_point_into_frame(vec3 point){
|
||||
if(bool(is_fixed_in_frame)){
|
||||
vec3 rotate_point_into_frame(vec3 point)
|
||||
{
|
||||
if (bool(is_fixed_in_frame))
|
||||
{
|
||||
return point;
|
||||
}
|
||||
return camera_rotation * point;
|
||||
}
|
||||
|
||||
|
||||
vec3 position_point_into_frame(vec3 point){
|
||||
if(bool(is_fixed_in_frame)){
|
||||
vec3 position_point_into_frame(vec3 point)
|
||||
{
|
||||
if (bool(is_fixed_in_frame))
|
||||
{
|
||||
return point;
|
||||
}
|
||||
if(bool(is_fixed_orientation)){
|
||||
if (bool(is_fixed_orientation))
|
||||
{
|
||||
vec3 new_center = rotate_point_into_frame(fixed_orientation_center);
|
||||
return point + (new_center - fixed_orientation_center);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ uniform vec2 pixel_shape;
|
|||
uniform float index;
|
||||
|
||||
in vec4 color;
|
||||
in float fill_all; // Either 0 or 1e
|
||||
in float fill_all; // Either 0 or 1e
|
||||
|
||||
in float orientation;
|
||||
in vec2 uv_coords;
|
||||
|
|
@ -18,8 +18,10 @@ layout(location = 1) out vec4 stencil_value;
|
|||
|
||||
#define ANTI_ALIASING
|
||||
|
||||
float sdf(){
|
||||
if(bezier_degree < 2){
|
||||
float sdf()
|
||||
{
|
||||
if (bezier_degree < 2)
|
||||
{
|
||||
return abs(uv_coords[1]);
|
||||
}
|
||||
vec2 p = uv_coords;
|
||||
|
|
@ -33,10 +35,11 @@ float sdf(){
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
void main() {
|
||||
void main()
|
||||
{
|
||||
gl_FragDepth = gl_FragCoord.z;
|
||||
if (color.a == 0) discard;
|
||||
if (color.a == 0)
|
||||
discard;
|
||||
|
||||
float previous_index =
|
||||
texture2D(stencil_texture, vec2(gl_FragCoord.x / pixel_shape.x, gl_FragCoord.y / pixel_shape.y)).r;
|
||||
|
|
@ -55,7 +58,8 @@ void main() {
|
|||
stencil_value.rgb = vec3(index);
|
||||
stencil_value.a = 1.0;
|
||||
frag_color = color;
|
||||
if (fill_all == 1.0) return;
|
||||
if (fill_all == 1.0)
|
||||
return;
|
||||
#ifdef ANTI_ALIASING
|
||||
float fac = max(0.0, min(1.0, 0.5 - sdf()));
|
||||
frag_color.a *= fac; // Anti-aliasing
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#version 330
|
||||
|
||||
layout (triangles) in;
|
||||
layout (triangle_strip, max_vertices = 5) out;
|
||||
layout(triangles) in;
|
||||
layout(triangle_strip, max_vertices = 5) out;
|
||||
|
||||
// Needed for get_gl_Position
|
||||
// uniform vec2 frame_shape;
|
||||
|
|
@ -20,12 +20,12 @@ out vec2 uv_coords;
|
|||
out float bezier_degree;
|
||||
|
||||
// Analog of import for manim only
|
||||
#include "../include/mobject_uniform_declarations.glsl"
|
||||
#include "../include/camera_uniform_declarations.glsl"
|
||||
#include "../include/quadratic_bezier_geometry_functions.glsl"
|
||||
#include "../include/finalize_color.glsl"
|
||||
#include "../include/get_gl_Position.glsl"
|
||||
#include "../include/get_unit_normal.glsl"
|
||||
#include "../include/finalize_color.glsl"
|
||||
#include "../include/mobject_uniform_declarations.glsl"
|
||||
#include "../include/quadratic_bezier_geometry_functions.glsl"
|
||||
|
||||
const vec2 uv_coords_arr[3] = vec2[3](vec2(0, 0), vec2(0.5, 0), vec2(1, 1));
|
||||
|
||||
|
|
@ -39,21 +39,20 @@ void emit_vertex_wrapper(vec3 point, int index)
|
|||
|
||||
void emit_simple_triangle()
|
||||
{
|
||||
for(int i = 0; i < 3; i++)
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
emit_vertex_wrapper(bp[i], i);
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
|
||||
void main(){
|
||||
void main()
|
||||
{
|
||||
// If vert indices are sequential, don't fill all
|
||||
fill_all = float(
|
||||
(v_vert_index[1] - v_vert_index[0]) != 1.0 ||
|
||||
(v_vert_index[2] - v_vert_index[1]) != 1.0
|
||||
);
|
||||
fill_all = float((v_vert_index[1] - v_vert_index[0]) != 1.0 || (v_vert_index[2] - v_vert_index[1]) != 1.0);
|
||||
|
||||
if(fill_all == 1.0){
|
||||
if (fill_all == 1.0)
|
||||
{
|
||||
emit_simple_triangle();
|
||||
return;
|
||||
}
|
||||
|
|
@ -63,7 +62,8 @@ void main(){
|
|||
vec3 local_unit_normal = get_unit_normal(new_bp);
|
||||
orientation = sign(dot(v_global_unit_normal[0], local_unit_normal));
|
||||
|
||||
if(bezier_degree >= 1){
|
||||
if (bezier_degree >= 1)
|
||||
{
|
||||
emit_simple_triangle();
|
||||
}
|
||||
// Don't emit any vertices for bezier_degree 0
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "../include/camera_uniform_declarations.glsl"
|
||||
#include "../include/mobject_uniform_declarations.glsl"
|
||||
#include "../include/position_point_into_frame.glsl"
|
||||
|
||||
in vec3 point;
|
||||
in vec3 unit_normal;
|
||||
|
|
@ -13,10 +14,8 @@ out vec4 v_color;
|
|||
out float v_vert_index;
|
||||
out vec3 v_global_unit_normal;
|
||||
|
||||
// Analog of import for manim only
|
||||
#include "../include/position_point_into_frame.glsl"
|
||||
|
||||
void main(){
|
||||
void main()
|
||||
{
|
||||
bp = position_point_into_frame(point.xyz);
|
||||
v_global_unit_normal = rotate_point_into_frame(unit_normal);
|
||||
v_color = color;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ uniform float disable_stencil;
|
|||
in vec2 uv_coords;
|
||||
in vec2 uv_b2;
|
||||
|
||||
|
||||
in float uv_stroke_width;
|
||||
in vec4 color;
|
||||
in float uv_anti_alias_width;
|
||||
|
|
@ -28,23 +27,25 @@ uniform sampler2D stencil_texture;
|
|||
layout(location = 0) out vec4 frag_color;
|
||||
layout(location = 1) out vec4 stencil_value;
|
||||
|
||||
float cross2d(vec2 v, vec2 w){
|
||||
float cross2d(vec2 v, vec2 w)
|
||||
{
|
||||
return v.x * w.y - w.x * v.y;
|
||||
}
|
||||
|
||||
float modify_distance_for_endpoints(vec2 p, float dist, float t){
|
||||
float modify_distance_for_endpoints(vec2 p, float dist, float t)
|
||||
{
|
||||
float buff = 0.5 * uv_stroke_width - uv_anti_alias_width;
|
||||
// Check the beginning of the curve
|
||||
if(t == 0){
|
||||
if (t == 0)
|
||||
{
|
||||
// Clip the start
|
||||
if(has_prev == 0) return max(dist, -p.x + buff);
|
||||
if (has_prev == 0)
|
||||
return max(dist, -p.x + buff);
|
||||
// Bevel start
|
||||
if(bevel_start == 1){
|
||||
if (bevel_start == 1)
|
||||
{
|
||||
float a = angle_from_prev;
|
||||
mat2 rot = mat2(
|
||||
cos(a), sin(a),
|
||||
-sin(a), cos(a)
|
||||
);
|
||||
mat2 rot = mat2(cos(a), sin(a), -sin(a), cos(a));
|
||||
// Dist for intersection of two lines
|
||||
float bevel_d = max(abs(p.y), abs((rot * p).y));
|
||||
// Dist for union of this intersection with the real curve
|
||||
|
|
@ -53,30 +54,29 @@ float modify_distance_for_endpoints(vec2 p, float dist, float t){
|
|||
return max(min(dist, bevel_d), dist / 2);
|
||||
}
|
||||
// Otherwise, start will be rounded off
|
||||
}else if(t == 1){
|
||||
}
|
||||
else if (t == 1)
|
||||
{
|
||||
// Check the end of the curve
|
||||
// TODO, too much code repetition
|
||||
vec2 v21 = (bezier_degree == 2) ? vec2(1, 0) - uv_b2 : vec2(-1, 0);
|
||||
float len_v21 = length(v21);
|
||||
if(len_v21 == 0){
|
||||
if (len_v21 == 0)
|
||||
{
|
||||
v21 = -uv_b2;
|
||||
len_v21 = length(v21);
|
||||
}
|
||||
|
||||
float perp_dist = dot(p - uv_b2, v21) / len_v21;
|
||||
if(has_next == 0) return max(dist, -perp_dist + buff);
|
||||
if (has_next == 0)
|
||||
return max(dist, -perp_dist + buff);
|
||||
// Bevel end
|
||||
if(bevel_end == 1){
|
||||
if (bevel_end == 1)
|
||||
{
|
||||
float a = -angle_to_next;
|
||||
mat2 rot = mat2(
|
||||
cos(a), sin(a),
|
||||
-sin(a), cos(a)
|
||||
);
|
||||
mat2 rot = mat2(cos(a), sin(a), -sin(a), cos(a));
|
||||
vec2 v21_unit = v21 / length(v21);
|
||||
float bevel_d = max(
|
||||
abs(cross2d(p - uv_b2, v21_unit)),
|
||||
abs(cross2d((rot * (p - uv_b2)), v21_unit))
|
||||
);
|
||||
float bevel_d = max(abs(cross2d(p - uv_b2, v21_unit)), abs(cross2d((rot * (p - uv_b2)), v21_unit)));
|
||||
return max(min(dist, bevel_d), dist / 2);
|
||||
}
|
||||
// Otherwise, end will be rounded off
|
||||
|
|
@ -84,12 +84,15 @@ float modify_distance_for_endpoints(vec2 p, float dist, float t){
|
|||
return dist;
|
||||
}
|
||||
|
||||
|
||||
void main() {
|
||||
void main()
|
||||
{
|
||||
// Use the default value as standard output
|
||||
if(disable_stencil==1.0){
|
||||
if (disable_stencil == 1.0)
|
||||
{
|
||||
stencil_value = vec4(0.0);
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
stencil_value.rgb = vec3(index);
|
||||
stencil_value.a = 1.0;
|
||||
}
|
||||
|
|
@ -97,8 +100,8 @@ void main() {
|
|||
// Get the previous index that was written to this fragment
|
||||
float previous_index =
|
||||
texture2D(stencil_texture, vec2(gl_FragCoord.x / pixel_shape.x, gl_FragCoord.y / pixel_shape.y)).r;
|
||||
// If the index is the same that means we are overlapping with the fill and crossing through so we push the stroke
|
||||
// forward a tiny bit
|
||||
// If the index is the same that means we are overlapping with the fill and
|
||||
// crossing through so we push the stroke forward a tiny bit
|
||||
if (previous_index < index && previous_index != 0)
|
||||
{
|
||||
gl_FragDepth = gl_FragCoord.z - 1.7 * index / 1000.0;
|
||||
|
|
@ -107,18 +110,22 @@ void main() {
|
|||
{
|
||||
gl_FragDepth = gl_FragCoord.z - index / 1000.0;
|
||||
}
|
||||
// If the stroke is overlapping with a shape that is of higher index that means it is behind another mobject on the
|
||||
// same plane so we discard the fragment
|
||||
// If the stroke is overlapping with a shape that is of higher index that
|
||||
// means it is behind another mobject on the same plane so we discard the
|
||||
// fragment
|
||||
if (previous_index > index)
|
||||
{
|
||||
// But for stroke transparency we shouldn't discard but move the stroke in front so it is not discarded by the depth test
|
||||
// TODO: This is highly experimental and should later be rethought and if no good solution is found it should just be a discard;
|
||||
// But for stroke transparency we shouldn't discard but move the stroke in
|
||||
// front so it is not discarded by the depth test
|
||||
// TODO: This is highly experimental and should later be rethought and if no
|
||||
// good solution is found it should just be a discard;
|
||||
if (color.a == 1.0)
|
||||
discard;
|
||||
else
|
||||
gl_FragDepth = gl_FragCoord.z + index / 1000.0;
|
||||
}
|
||||
if(disable_stencil==1.0){
|
||||
if (disable_stencil == 1.0)
|
||||
{
|
||||
gl_FragDepth = gl_FragCoord.z + 4.5 * index / 1000.0;
|
||||
}
|
||||
if (uv_stroke_width == 0)
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
#version 330
|
||||
|
||||
#include "../include/mobject_uniform_declarations.glsl"
|
||||
#include "../include/camera_uniform_declarations.glsl"
|
||||
#include "../include/quadratic_bezier_geometry_functions.glsl"
|
||||
#include "../include/finalize_color.glsl"
|
||||
#include "../include/get_gl_Position.glsl"
|
||||
#include "../include/get_unit_normal.glsl"
|
||||
#include "../include/finalize_color.glsl"
|
||||
#include "../include/mobject_uniform_declarations.glsl"
|
||||
#include "../include/quadratic_bezier_geometry_functions.glsl"
|
||||
|
||||
layout (triangles) in;
|
||||
layout (triangle_strip, max_vertices = 5) out;
|
||||
layout(triangles) in;
|
||||
layout(triangle_strip, max_vertices = 5) out;
|
||||
|
||||
uniform float anti_alias_width;
|
||||
|
||||
|
|
@ -43,50 +43,56 @@ const float BEVEL_JOINT = 2;
|
|||
const float MITER_JOINT = 3;
|
||||
const float PI = 3.141592653;
|
||||
|
||||
|
||||
|
||||
void flatten_points(in vec3[3] points, out vec2[3] flat_points){
|
||||
for(int i = 0; i < 3; i++){
|
||||
void flatten_points(in vec3[3] points, out vec2[3] flat_points)
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
float sf = perspective_scale_factor(points[i].z, focal_distance);
|
||||
flat_points[i] = sf * points[i].xy;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float angle_between_vectors(vec2 v1, vec2 v2){
|
||||
float angle_between_vectors(vec2 v1, vec2 v2)
|
||||
{
|
||||
float v1_norm = length(v1);
|
||||
float v2_norm = length(v2);
|
||||
if(v1_norm == 0 || v2_norm == 0) return 0.0;
|
||||
if (v1_norm == 0 || v2_norm == 0)
|
||||
return 0.0;
|
||||
float dp = dot(v1, v2) / (v1_norm * v2_norm);
|
||||
float angle = acos(clamp(dp, -1.0, 1.0));
|
||||
float sn = sign(cross2d(v1, v2));
|
||||
return sn * angle;
|
||||
}
|
||||
|
||||
|
||||
bool find_intersection(vec2 p0, vec2 v0, vec2 p1, vec2 v1, out vec2 intersection){
|
||||
bool find_intersection(vec2 p0, vec2 v0, vec2 p1, vec2 v1, out vec2 intersection)
|
||||
{
|
||||
// Find the intersection of a line passing through
|
||||
// p0 in the direction v0 and one passing through p1 in
|
||||
// the direction p1.
|
||||
// That is, find a solutoin to p0 + v0 * t = p1 + v1 * s
|
||||
float det = -v0.x * v1.y + v1.x * v0.y;
|
||||
if(det == 0) return false;
|
||||
if (det == 0)
|
||||
return false;
|
||||
float t = cross2d(p0 - p1, v1) / det;
|
||||
intersection = p0 + v0 * t;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void create_joint(float angle, vec2 unit_tan, float buff,
|
||||
vec2 static_c0, out vec2 changing_c0,
|
||||
vec2 static_c1, out vec2 changing_c1){
|
||||
void create_joint(float angle, vec2 unit_tan, float buff, vec2 static_c0, out vec2 changing_c0, vec2 static_c1,
|
||||
out vec2 changing_c1)
|
||||
{
|
||||
float shift;
|
||||
if(abs(angle) < 1e-3){
|
||||
if (abs(angle) < 1e-3)
|
||||
{
|
||||
// No joint
|
||||
shift = 0;
|
||||
}else if(joint_type == MITER_JOINT){
|
||||
}
|
||||
else if (joint_type == MITER_JOINT)
|
||||
{
|
||||
shift = buff * (-1.0 - cos(angle)) / sin(angle);
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
// For a Bevel joint
|
||||
shift = buff * (1.0 - cos(angle)) / sin(angle);
|
||||
}
|
||||
|
|
@ -94,11 +100,11 @@ void create_joint(float angle, vec2 unit_tan, float buff,
|
|||
changing_c1 = static_c1 + shift * unit_tan;
|
||||
}
|
||||
|
||||
|
||||
// This function is responsible for finding the corners of
|
||||
// a bounding region around the bezier curve, which can be
|
||||
// emitted as a triangle fan
|
||||
int get_corners(vec2 controls[3], int degree, float stroke_widths[3], out vec2 corners[5]){
|
||||
int get_corners(vec2 controls[3], int degree, float stroke_widths[3], out vec2 corners[5])
|
||||
{
|
||||
vec2 p0 = controls[0];
|
||||
vec2 p1 = controls[1];
|
||||
vec2 p2 = controls[2];
|
||||
|
|
@ -109,8 +115,8 @@ int get_corners(vec2 controls[3], int degree, float stroke_widths[3], out vec2 c
|
|||
vec2 v01 = -v10;
|
||||
vec2 v21 = -v12;
|
||||
|
||||
vec2 p0_perp = vec2(-v01.y, v01.x); // Pointing to the left of the curve from p0
|
||||
vec2 p2_perp = vec2(-v12.y, v12.x); // Pointing to the left of the curve from p2
|
||||
vec2 p0_perp = vec2(-v01.y, v01.x); // Pointing to the left of the curve from p0
|
||||
vec2 p2_perp = vec2(-v12.y, v12.x); // Pointing to the left of the curve from p2
|
||||
|
||||
// aaw is the added width given around the polygon for antialiasing.
|
||||
// In case the normal is faced away from (0, 0, 1), the vector to the
|
||||
|
|
@ -127,85 +133,80 @@ int get_corners(vec2 controls[3], int degree, float stroke_widths[3], out vec2 c
|
|||
vec2 c3 = p2 - buff2 * p2_perp + aaw2 * v12;
|
||||
|
||||
// Account for previous and next control points
|
||||
if(has_prev > 0) create_joint(angle_from_prev, v01, buff0, c0, c0, c1, c1);
|
||||
if(has_next > 0) create_joint(angle_to_next, v21, buff2, c3, c3, c2, c2);
|
||||
if (has_prev > 0)
|
||||
create_joint(angle_from_prev, v01, buff0, c0, c0, c1, c1);
|
||||
if (has_next > 0)
|
||||
create_joint(angle_to_next, v21, buff2, c3, c3, c2, c2);
|
||||
|
||||
// Linear case is the simplest
|
||||
if(degree == 1){
|
||||
if (degree == 1)
|
||||
{
|
||||
// The order of corners should be for a triangle_strip. Last entry is a dummy
|
||||
corners = vec2[5](c0, c1, c3, c2, vec2(0.0));
|
||||
return 4;
|
||||
}
|
||||
// Otherwise, form a pentagon around the curve
|
||||
float orientation = sign(cross2d(v01, v12)); // Positive for ccw curves
|
||||
if(orientation > 0) corners = vec2[5](c0, c1, p1, c2, c3);
|
||||
else corners = vec2[5](c1, c0, p1, c3, c2);
|
||||
float orientation = sign(cross2d(v01, v12)); // Positive for ccw curves
|
||||
if (orientation > 0)
|
||||
corners = vec2[5](c0, c1, p1, c2, c3);
|
||||
else
|
||||
corners = vec2[5](c1, c0, p1, c3, c2);
|
||||
// Replace corner[2] with convex hull point accounting for stroke width
|
||||
find_intersection(corners[0], v01, corners[4], v21, corners[2]);
|
||||
return 5;
|
||||
}
|
||||
|
||||
|
||||
void set_adjascent_info(vec2 c0, vec2 tangent,
|
||||
int degree,
|
||||
vec2 adj[3],
|
||||
out float bevel,
|
||||
out float angle
|
||||
){
|
||||
void set_adjascent_info(vec2 c0, vec2 tangent, int degree, vec2 adj[3], out float bevel, out float angle)
|
||||
{
|
||||
bool linear_adj = (angle_between_vectors(adj[1] - adj[0], adj[2] - adj[1]) < 1e-3);
|
||||
angle = angle_between_vectors(c0 - adj[1], tangent);
|
||||
// Decide on joint type
|
||||
bool one_linear = (degree == 1 || linear_adj);
|
||||
bool should_bevel = (
|
||||
(joint_type == AUTO_JOINT && one_linear) ||
|
||||
joint_type == BEVEL_JOINT
|
||||
);
|
||||
bool should_bevel = ((joint_type == AUTO_JOINT && one_linear) || joint_type == BEVEL_JOINT);
|
||||
bevel = should_bevel ? 1.0 : 0.0;
|
||||
}
|
||||
|
||||
|
||||
void find_joint_info(vec2 controls[3], vec2 prev[3], vec2 next[3], int degree){
|
||||
void find_joint_info(vec2 controls[3], vec2 prev[3], vec2 next[3], int degree)
|
||||
{
|
||||
float tol = 1e-6;
|
||||
|
||||
// Made as floats not bools so they can be passed to the frag shader
|
||||
has_prev = float(distance(prev[2], controls[0]) < tol);
|
||||
has_next = float(distance(next[0], controls[2]) < tol);
|
||||
|
||||
if(bool(has_prev)){
|
||||
if (bool(has_prev))
|
||||
{
|
||||
vec2 tangent = controls[1] - controls[0];
|
||||
set_adjascent_info(
|
||||
controls[0], tangent, degree, prev,
|
||||
bevel_start, angle_from_prev
|
||||
);
|
||||
set_adjascent_info(controls[0], tangent, degree, prev, bevel_start, angle_from_prev);
|
||||
}
|
||||
if(bool(has_next)){
|
||||
if (bool(has_next))
|
||||
{
|
||||
vec2 tangent = controls[1] - controls[2];
|
||||
set_adjascent_info(
|
||||
controls[2], tangent, degree, next,
|
||||
bevel_end, angle_to_next
|
||||
);
|
||||
set_adjascent_info(controls[2], tangent, degree, next, bevel_end, angle_to_next);
|
||||
angle_to_next *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void main() {
|
||||
void main()
|
||||
{
|
||||
// Convert control points to a standard form if they are linear or null
|
||||
vec3 controls[3];
|
||||
vec3 prev[3];
|
||||
vec3 next[3];
|
||||
bezier_degree = get_reduced_control_points(vec3[3](bp[0], bp[1], bp[2]), controls);
|
||||
if(bezier_degree == 0.0) return; // Null curve
|
||||
if (bezier_degree == 0.0)
|
||||
return; // Null curve
|
||||
int degree = int(bezier_degree);
|
||||
get_reduced_control_points(vec3[3](prev_bp[0], prev_bp[1], prev_bp[2]), prev);
|
||||
get_reduced_control_points(vec3[3](next_bp[0], next_bp[1], next_bp[2]), next);
|
||||
|
||||
|
||||
// Adjust stroke width based on distance from the camera
|
||||
float scaled_strokes[3];
|
||||
for(int i = 0; i < 3; i++){
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
float sf = perspective_scale_factor(controls[i].z, focal_distance);
|
||||
if(bool(flat_stroke)){
|
||||
if (bool(flat_stroke))
|
||||
{
|
||||
vec3 to_cam = normalize(vec3(0.0, 0.0, focal_distance) - controls[i]);
|
||||
sf *= abs(dot(v_global_unit_normal[i], to_cam));
|
||||
}
|
||||
|
|
@ -229,7 +230,8 @@ void main() {
|
|||
int n_corners = get_corners(flat_controls, degree, scaled_strokes, corners);
|
||||
|
||||
int index_map[5] = int[5](0, 0, 1, 2, 2);
|
||||
if(n_corners == 4) index_map[2] = 2;
|
||||
if (n_corners == 4)
|
||||
index_map[2] = 2;
|
||||
|
||||
// Find uv conversion matrix
|
||||
mat3 xy_to_uv = get_xy_to_uv(flat_controls[0], flat_controls[1]);
|
||||
|
|
@ -238,20 +240,15 @@ void main() {
|
|||
uv_b2 = (xy_to_uv * vec3(flat_controls[2], 1.0)).xy;
|
||||
|
||||
// Emit each corner
|
||||
for(int i = 0; i < n_corners; i++){
|
||||
for (int i = 0; i < n_corners; i++)
|
||||
{
|
||||
uv_coords = (xy_to_uv * vec3(corners[i], 1.0)).xy;
|
||||
uv_stroke_width = scaled_strokes[index_map[i]] / scale_factor;
|
||||
// Apply some lighting to the color before sending out.
|
||||
// vec3 xyz_coords = vec3(corners[i], controls[index_map[i]].z);
|
||||
vec3 xyz_coords = vec3(corners[i], controls[index_map[i]].z);
|
||||
color = finalize_color(
|
||||
v_color[index_map[i]],
|
||||
xyz_coords,
|
||||
v_global_unit_normal[index_map[i]],
|
||||
light_source_position,
|
||||
gloss,
|
||||
shadow
|
||||
);
|
||||
color = finalize_color(v_color[index_map[i]], xyz_coords, v_global_unit_normal[index_map[i]],
|
||||
light_source_position, gloss, shadow);
|
||||
gl_Position = vec4(get_gl_Position(vec3(corners[i], 0.0)).xy, get_gl_Position(controls[index_map[i]]).zw);
|
||||
EmitVertex();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ out vec4 v_color;
|
|||
|
||||
const float STROKE_WIDTH_CONVERSION = 0.01;
|
||||
|
||||
|
||||
void main(){
|
||||
void main()
|
||||
{
|
||||
bp = position_point_into_frame(point);
|
||||
prev_bp = position_point_into_frame(prev_point);
|
||||
next_bp = position_point_into_frame(next_point);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ in vec2 f_uv;
|
|||
|
||||
out vec4 frag_color;
|
||||
|
||||
void main() {
|
||||
void main()
|
||||
{
|
||||
frag_color = texture(tex, f_uv);
|
||||
frag_color.a = 1.0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ in vec2 uv;
|
|||
|
||||
out vec2 f_uv;
|
||||
|
||||
void main() {
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(pos, 0.0, 1.0);
|
||||
f_uv = uv;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue