#version 460
#extension GL_GOOGLE_include_directive : enable
#include <light.h>
#include <transform.h>
#include "shader-common-generic-lighting.h"
layout (std140, binding = BIND_MATERIAL ) uniform Uni_Material
{
vec4 color_front, color_back;
};
layout ( binding = BIND_BULGE_INFO ) uniform Buldge_Info
{
float bulge_loc;
float bulge_dist_thresh;
float wire_radius;
};
layout ( binding = BIND_HELIX_COORDS ) buffer Helix_Coord
{ vec4 helix_coord[]; };
layout ( binding = BIND_TEXUNIT ) uniform sampler2D tex_unit_0;
#ifdef _VERTEX_SHADER_
layout ( location = LOC_IN_INT1 ) in int helix_index;
layout (location = LOC_IN_NORMAL, component = 0) in vec3 in_normal_o;
layout (location = LOC_IN_TCOOR) in vec2 texcoord;
#define gl_MultiTexCoord0 texcoord
layout (location = 0) out Data
{
int hidx;
vec3 normal_o;
vec2 tex_coord;
};
#endif
#ifdef _GEOMETRY_SHADER_
layout ( triangles ) in;
const int slices = 7;
layout ( triangle_strip, max_vertices = ( slices + 1 ) * 2 ) out;
layout (location = 0) in Data
{
int hidx;
vec3 normal_o;
vec2 tex_coord;
} In[];
layout (location = 0) out Data_GF
{
vec3 normal_e;
vec4 vertex_e;
vec2 tex_coord;
flat vec4 color;
};
#endif
#ifdef _FRAGMENT_SHADER_
layout (location = 0) in Data_GF
{
vec3 normal_e;
vec4 vertex_e;
vec2 tex_coord;
flat vec4 color;
};
layout (location = 0) out vec4 frag_color;
#define gl_FragColor frag_color
#endif
#ifdef _VERTEX_SHADER_
void
vs_main_helix()
{
normal_o = in_normal_o;
hidx = helix_index;
tex_coord = gl_MultiTexCoord0.xy;
}
#endif
#ifdef _GEOMETRY_SHADER_
void
gs_main_helix()
{
smooth
float bulge_dist_0 = abs( bulge_loc - In[0].hidx );
const bool type_a = bool(gl_PrimitiveIDIn & 1);
const vec4 base_shade = type_a ? vec4(1,1,1,1) : vec4(0.625,1,1,1);
if ( bulge_dist_0 > bulge_dist_thresh )
{
for ( int i=0; i<3; i++ )
{
color = vec4(0.8,0.8,0.8,1) * base_shade;
int hidx = In[i].hidx;
vec4 c = helix_coord[hidx];
vec3 norm_o = wire_radius * In[i].normal_o;
vec4 pos_o = c + vec4(norm_o,0);
gl_Position = gl_ModelViewProjectionMatrix * pos_o;
normal_e = gl_NormalMatrix * In[i].normal_o;
vertex_e = gl_ModelViewMatrix * pos_o;
tex_coord = In[i].tex_coord;
EmitVertex();
}
EndPrimitive();
return;
}
int gs_vidx_00;
int gs_vidx_10;
int gs_vidx_11;
if ( In[0].hidx == In[1].hidx )
{ gs_vidx_00 = 2; gs_vidx_10 = 1; gs_vidx_11 = 0; }
else if ( In[0].hidx == In[2].hidx )
{ gs_vidx_00 = 1; gs_vidx_10 = 0; gs_vidx_11 = 2; }
else
{ gs_vidx_00 = 0; gs_vidx_10 = 2; gs_vidx_11 = 1; }
int hidx0 = In[gs_vidx_00].hidx;
int hidx1 = In[gs_vidx_10].hidx;
vec3 c0 = helix_coord[hidx0].xyz;
vec3 c1 = helix_coord[hidx1].xyz;
vec3 delta_c = c0 - c1;
vec3 n0 = In[gs_vidx_00].normal_o;
vec3 n10 = In[gs_vidx_10].normal_o;
vec3 n11 = In[gs_vidx_11].normal_o;
float bulge_rad = 1;
float delta_f = 1.0f/slices;
for ( int i=0; i<=slices; i++ )
{
float f = 1 - i * delta_f;
float hidxx = mix( float(hidx1), float(hidx0), f );
vec3 c = mix( c1, c0, f );
vec3 nx0 = mix( n10, n0, f );
vec3 nx1 = mix( n11, n0, f );
float bulge_dist = abs( bulge_loc - hidxx );
float mult = 1.25f
- 0.25f *
cos( 3.1415f * max(0.0f, ( bulge_rad - bulge_dist ) / bulge_rad ) );
float rx = wire_radius * mult;
vec4 pos0 = vec4( c + rx * nx0, 1);
vec4 pos1 = vec4( c + rx * nx1, 1);
color = base_shade;
gl_Position = gl_ModelViewProjectionMatrix * pos0;
vertex_e = gl_ModelViewMatrix * pos0;
normal_e = gl_NormalMatrix * nx0; tex_coord = vec2(-1,0); EmitVertex();
color = vec4(1,0.8,1,1) * base_shade;
gl_Position = gl_ModelViewProjectionMatrix * pos1;
vertex_e = gl_ModelViewMatrix * pos1;
normal_e = gl_NormalMatrix * nx1; tex_coord = vec2(-1,0); EmitVertex();
}
EndPrimitive();
}
#endif
#ifdef _FRAGMENT_SHADER_
void
fs_main_phong()
{
vec4 texel =
tex_coord.x == -1f ? vec4(1,1,1,1) : texture(tex_unit_0,tex_coord);
vec4 material_color = gl_FrontFacing ? color_front : color_back;
vec4 shaded_color = material_color * color;
vec4 lighted_color = generic_lighting( vertex_e, shaded_color, normal_e);
gl_FragColor = texel * lighted_color;
}
#endif