#version 460
#extension GL_GOOGLE_include_directive : enable
#include <light.h>
#include <transform.h>
#include "shdr-common.h"
#include "shdr-generic-lighting.h"
layout ( binding = BIND_UNI_COMMON ) uniform UC
{
Shdr_Uni_Common uc;
};
bvec2 debug_bool = bvec2( bool(uc.debug_bool.x), bool(uc.debug_bool.y) );
float debug_float = uc.debug_float;
layout ( binding = BIND_BALLS_POS ) buffer Balls_Pos { vec4 balls_pos[]; };
#ifdef _VERTEX_SHADER_
layout ( location = LOC_IN_INT4 ) in ivec4 in_indices;
layout ( location = 0 ) out Data_to_GS
{
vec4 vertex_c;
vec3 normal_e;
vec4 vertex_e;
vec2 tcoor;
vec4 vertex_e_upper;
vec4 vertex_c_upper;
vec3 radial_e;
ivec3 indices;
} Out;
void
vs_main_triangles()
{
const float spiral_radius = 0.5;
const float omega = 10;
const int bidx = in_indices.x;
const int ti = in_indices.y;
const bool inner = in_indices.z == 1;
const int radial_idx = bidx * uc.opt_segments + ti;
const float delta_t = 1.0 / uc.opt_segments;
const float t = float(ti) * delta_t;
const float theta = delta_t * radial_idx * omega;
vec3 pos1 = balls_pos[bidx-1].xyz;
vec3 pos2 = balls_pos[bidx].xyz;
vec3 v12 = pos2.xyz - pos1.xyz;
vec3 ax =
normalize(v12.x == 0 ? vec3(0,v12.z,-v12.y) : vec3(v12.y,-v12.x,0));
vec3 ay = normalize(cross(v12,ax));
vec3 vx = ax * spiral_radius;
vec3 vy = ay * spiral_radius;
vec3 p = pos1 + t * v12;
vec3 radial = vx * cos(theta) + vy * sin(theta);
vec3 p_outer = p + radial;
const float inner_frac = 0.5;
vec3 p_inner = p + inner_frac * radial;
vec3 tangial = -omega * vx * sin(theta) + omega * vy * cos(theta);
vec3 tang = v12 + tangial;
vec3 tang_inner = v12 + inner_frac * tangial;
vec3 norm = normalize(cross(radial,tang));
vec3 norm_inner = normalize(cross(radial,tang_inner));
vec4 vertex_o = vec4( inner ? p_inner : p_outer, 1 );
vec3 normal_o = inner ? norm_inner : norm;
Out.vertex_c = ut.clip_from_object * vertex_o;
Out.normal_e = mat3(ut.eye_from_object) * normal_o;
Out.vertex_e = ut.eye_from_object * vertex_o;
float tex_zoom = 0.5;
const float du = 0.5 * tex_zoom / uc.chain_length;
const float u = float(bidx) * du;
Out.tcoor.x = tex_zoom * t;
Out.tcoor.y = 0.18 + u + (inner ? du : 0 );
vec3 v12n = normalize(v12);
vec3 depth_vector = 0.1f * v12n;
vec4 vertex_o_upper = vertex_o + vec4(depth_vector,0);
Out.vertex_c_upper = ut.clip_from_object * vertex_o_upper;
Out.vertex_e_upper = ut.eye_from_object * vertex_o_upper;
Out.indices = in_indices.xyz;
Out.radial_e = mat3(ut.eye_from_object) * radial;
}
#endif
#ifdef _GEOMETRY_SHADER_
layout ( location = 0 ) in Data_to_GS
{
vec4 vertex_c;
vec3 normal_e;
vec4 vertex_e;
vec2 tcoor;
vec4 vertex_e_upper;
vec4 vertex_c_upper;
vec3 radial_e;
ivec3 indices;
} In[];
layout ( location = 0 ) out Data_to_FS
{
vec3 normal_e;
vec4 vertex_e;
vec2 tcoor;
flat int is_edge; } Out;
layout ( triangles ) in;
layout ( triangle_strip, max_vertices = 12 ) out;
void
gs_main_triangles()
{
for ( int level=0; level<2; level++ )
{
const bool upper = level == 1;
for ( int i=0; i<3; i++ )
{
Out.normal_e = In[i].normal_e;
Out.vertex_e = upper ? In[i].vertex_e_upper : In[i].vertex_e;
gl_Position = upper ? In[i].vertex_c_upper : In[i].vertex_c;
Out.tcoor = In[i].tcoor;
Out.is_edge = 0;
EmitVertex();
}
EndPrimitive();
}
int idx[2];
if ( In[0].indices.z == In[1].indices.z ) { idx[0] = 0; idx[1] = 1; }
else if ( In[0].indices.z == In[2].indices.z ) { idx[0] = 0; idx[1] = 2; }
else { idx[0] = 1; idx[1] = 2; }
bool is_inner = In[idx[0]].indices.z == 1;
for ( int i=0; i<2; i++ )
{
const int v = idx[i];
Out.vertex_e = In[v].vertex_e;
gl_Position = In[v].vertex_c;
Out.normal_e = is_inner ? -In[v].radial_e : In[v].radial_e;
Out.is_edge = 1;
EmitVertex();
Out.vertex_e = In[v].vertex_e_upper;
gl_Position = In[v].vertex_c_upper;
Out.normal_e = is_inner ? -In[v].radial_e : In[v].radial_e;
Out.is_edge = 1;
EmitVertex();
}
EndPrimitive();
}
#endif
#ifdef _FRAGMENT_SHADER_
layout ( location = 0 ) in Data_to_FS
{
vec3 normal_e;
vec4 vertex_e;
vec2 tcoor;
flat int is_edge;
} In;
layout ( binding = BIND_TEXUNIT ) uniform sampler2D tex_unit_0;
layout ( location = 0 ) out vec4 out_frag_color;
void
fs_main()
{
vec4 color =
bool(In.is_edge) ? uc.color_edge :
gl_FrontFacing ? uc.color_front : uc.color_back;
vec4 texel = bool(In.is_edge) ? vec4(1,1,1,1) : texture(tex_unit_0,In.tcoor);
bool hole = texel.r + texel.g + texel.b < 0.05;
if ( hole ) discard;
out_frag_color =
texel * generic_lighting(In.vertex_e, color, normalize(In.normal_e));
}
#endif