#version 460
#extension GL_GOOGLE_include_directive : enable
#include <light.h>
#include <transform.h>
#include "links-shdr-common.h"
#include "shader-common-generic-lighting.h"
layout ( binding = BIND_SPHERE_POS ) buffer spr { vec4 sphere_pos_rad[]; };
layout ( binding = BIND_SPHERE_ROT ) buffer sr { mat4 sphere_rot[]; };
layout ( binding = BIND_SPHERE_COLOR ) buffer sc { vec4 sphere_color[]; };
layout ( binding = BIND_UNI_COMMON ) uniform Common_Uniform
{
Shdr_Uni_Common com;
};
bool opt_tryout1 = bool(com.tryout.x);
bool opt_tryout2 = bool(com.tryout.y);
float opt_tryoutf = com.tryoutf.x;
float opt_hw03_curl = com.tryoutf.y;
#ifdef _VERTEX_SHADER_
layout ( location = LOC_IN_POS ) in vec4 in_vertex_o;
#ifdef LOC_IN_TCOOR
layout ( location = LOC_IN_TCOOR ) in vec2 in_tex_coor;
#endif
layout ( location = 0 ) out Data_to_GS
{
vec3 normal_e;
vec4 vertex_e;
vec2 tex_coor;
vec4 color;
vec4 vertex_c;
float sphere_radius;
};
void
vs_main_instances_sphere()
{
vec4 pos_rad = sphere_pos_rad[gl_InstanceIndex];
float rad = pos_rad.w;
mat4 rot = sphere_rot[gl_InstanceIndex];
vec4 normr = rot * in_vertex_o;
vec3 normal_o = normr.xyz;
vec4 vertex_o = vec4( pos_rad.xyz + rad * normal_o, 1 );
vertex_c = gl_ModelViewProjectionMatrix * vertex_o;
vertex_e = gl_ModelViewMatrix * vertex_o;
normal_e = normalize(gl_NormalMatrix * normal_o );
tex_coor = in_tex_coor;
color = sphere_color[gl_InstanceIndex];
sphere_radius = rad;
}
#endif
#ifdef _GEOMETRY_SHADER_
layout ( location = 0 ) in Data_to_GS
{
vec3 normal_e;
vec4 vertex_e;
vec2 tex_coor;
vec4 color;
vec4 vertex_c;
float sphere_radius;
} In[];
layout ( location = 0 ) out Data_to_FS
{
vec3 normal_e;
vec4 vertex_e;
vec2 tex_coor;
flat vec4 color;
flat int use_tex;
};
layout ( triangles ) in;
const int slices = 5;
const int max_v = 6 + ( 2 + 4 ) * (slices+1) + 2;
layout ( triangle_strip, max_vertices = max_v ) out;
void
gs_main_shrink()
{
const bool opt_normal_sphere = bool(com.tryout.z);
vec3 ctr_e = vec3(0), cnorm_e = vec3(0);
for ( int i=0; i<3; i++ )
{
ctr_e += In[i].vertex_e.xyz;
cnorm_e += In[i].normal_e;
}
ctr_e *= 0.333333333333f;
cnorm_e *= 0.333333333333f;
float ht0 = In[0].sphere_radius * 0.1;
float ht = ht0 / ( 1 + opt_hw03_curl * ( opt_hw03_curl / 3 - 1 ) );
vec3 vtx_shr_e[3];
for ( int i=0; i<3; i++ )
{
normal_e = mix( In[i].normal_e, cnorm_e, opt_hw03_curl );
vtx_shr_e[i] = vertex_e.xyz =
mix( In[i].vertex_e.xyz, ctr_e, opt_hw03_curl ) + normal_e * ht;
vertex_e.w = 1;
gl_Position = gl_ProjectionMatrix * vertex_e;
tex_coor = In[i].tex_coor;
color = In[i].color;
use_tex = 1;
EmitVertex();
}
EndPrimitive();
vec4 gr_color = vec4( 0.5 * In[0].color.rgb, 1 );
for ( int i=0; i<3; i++ )
{
int i1 = (i+1) % 3;
vec3 vo_0 = In[i].vertex_e.xyz;
vec3 vo_1 = In[i1].vertex_e.xyz;
vec3 vs_0 = vtx_shr_e[i];
vec3 vs_1 = vtx_shr_e[i1];
vec3 n_e = normalize(cross( vs_0 - vo_0, vs_1 - vs_0 ));
vec3 vstrip[] = { vs_0, vo_0, vs_1, vo_1 };
int tstrip[] = { i, i, i1, i1 };
for ( int j=0; j<4; j++ )
{
vertex_e = vec4( vstrip[j], 1 );
normal_e = n_e;
color = gr_color;
use_tex = 1;
tex_coor = In[tstrip[j]].tex_coor;
gl_Position = gl_ProjectionMatrix * vertex_e;
EmitVertex();
}
EndPrimitive();
}
}
void
gs_main_curl()
{
const bool opt_normal_sphere = bool(com.tryout.z);
const bool unworn = false;
if ( unworn )
{
for ( int i=0; i<3; i++ )
{
normal_e = In[opt_normal_sphere?i:0].normal_e;
vertex_e = In[i].vertex_e;
color = In[i].color;
gl_Position = In[i].vertex_c;
tex_coor = In[i].tex_coor;
EmitVertex();
}
EndPrimitive();
return;
}
int v1_idx = 0;
const int v0_idx[2] = { ( v1_idx + 1 ) % 3, ( v1_idx + 2 ) % 3 };
vec4 p1_e = In[v1_idx].vertex_e; vec3 n1_e = In[v1_idx].normal_e; vec2 tc1 = In[v1_idx].tex_coor;
const float p_frac = opt_hw03_curl;
const float f0 = 1 - p_frac;
float fi[] = { 0, f0, 1 };
for ( int i=0; i<3; i++ )
{
const float f = fi[i];
for ( int j=0; j<2; j++ )
{
const int idx = v0_idx[j];
normal_e = mix( In[idx].normal_e, n1_e, f );
vertex_e = mix( In[idx].vertex_e, p1_e, f );
use_tex = i < 1 ? 1 : 0;
color = i < 1 ? In[0].color : In[0].color * vec4(0.5,0.5,0.5,1);
gl_Position = gl_ProjectionMatrix * vertex_e;
tex_coor = mix(In[idx].tex_coor, tc1, f);
EmitVertex();
}
}
EndPrimitive();
const float n_rev = 0.5;
const float two_pi = 2 * 3.14159265;
const float delta_theta = n_rev * p_frac * two_pi / slices;
const float delta_f = p_frac / slices;
vec3 p00_e = In[v0_idx[0]].vertex_e.xyz;
vec3 p01_e = In[v0_idx[1]].vertex_e.xyz;
vec3 ax = normalize(p01_e - p00_e);
vec3 v001 = p1_e.xyz - p00_e;
vec3 az = normalize( cross(ax,v001) );
vec3 ay = cross(az,ax);
const float d = dot(v001,ay);
const float r = d / ( n_rev * two_pi );
vec3 ctr_e = p1_e.xyz - p_frac * d * ay + r * az;
vec3 peel_v[2][slices+1];
vec3 peel_n[slices+1];
for ( int i=0; i<=slices; i++ )
{
const float theta = 1.5f * 3.1415927f + delta_theta * i;
const float f = f0 + delta_f * i;
vec3 nc = ay * cos(theta) + az * sin(theta);
vec3 vc = r * nc;
peel_n[i] = nc;
for ( int j=0; j<2; j++ )
{
const int idx = v0_idx[j];
vec3 p_e = mix( In[idx].vertex_e.xyz, p1_e.xyz, f );
vec3 v_pc = ctr_e - p_e;
vertex_e.xyz = ctr_e + vc - dot(v_pc,ax) * ax;
vertex_e.w = 1;
peel_v[j][i] = vertex_e.xyz;
normal_e = nc;
use_tex = 1;
tex_coor = mix( In[idx].tex_coor, tc1, f );
color = In[0].color;
gl_Position = gl_ProjectionMatrix * vertex_e;
EmitVertex();
}
}
EndPrimitive();
float th = In[0].sphere_radius * .01f;
for ( int j=0; j<2; j++ )
{
for ( int i=0; i<=slices; i++ )
{
int i1 = i < slices ? i+1 : slices-1;
vec3 v0 = peel_v[j][i];
vec3 n0 = peel_n[i];
vec3 v0l = v0 + n0 * th;
vec3 v1 = peel_v[j][i1];
vec3 n1 = peel_n[i];
vec3 v1l = v1 + n1 * th;
vec3 sn = normalize(cross( v1l - v0l, v0 - v0l ));
if ( i == slices ) sn = -sn;
vertex_e = vec4(j==1?v0:v0l,1);
normal_e = sn;
use_tex = 0;
color = vec4(0.2,0.2,0.2,1);
gl_Position = gl_ProjectionMatrix * vertex_e;
EmitVertex();
vertex_e = vec4(j==1?v0l:v0,1);
normal_e = sn;
use_tex = 0;
color = vec4(0.2,0.2,0.2,1);
gl_Position = gl_ProjectionMatrix * vertex_e;
EmitVertex();
}
EndPrimitive();
}
}
#endif
#ifdef _FRAGMENT_SHADER_
#ifdef BIND_TEXUNIT
layout ( binding = BIND_TEXUNIT ) uniform sampler2D tex_unit_0;
#endif
layout ( location = 0 ) in Data_to_FS
{
vec3 normal_e;
vec4 vertex_e;
vec2 tex_coor;
flat vec4 color;
flat int use_tex;
};
layout ( location = 0 ) out vec4 frag_color;
void
fs_main_common()
{
#ifdef BIND_TEXUNIT
vec4 texel = gl_FrontFacing && use_tex == 1
? texture(tex_unit_0,tex_coor) : vec4(1,1,1,1);
#else
vec4 texel = vec4(1,1,1,1);
#endif
vec4 color2 = true || gl_FrontFacing ? color : vec4(0.5,0,0,1);
frag_color = texel * generic_lighting(vertex_e, color2, normal_e);
}
#endif