VGUI-Menu: friendList, chat backend, textview class proto SurfaceProps: Flesh impacts recognition PropData: BreakModels now use a bodyque to limit possible physics overhead PMove: falldamage, liquids can now be configured via external decl NSWeapon: added alternative punchangle based on springs, 'punchSpring X Y Z' in decl API: Team class management APIS NSPhysicsEntity: Optimised, optimised, optimised. New cvar: phys_lowspec. Scraping, impact effects etc have been added. More polish everywhere else
213 lines
4.8 KiB
GLSL
213 lines
4.8 KiB
GLSL
//======= Copyright (c) 2015-2021 Vera Visions LLC. All rights reserved. =======
|
|
//
|
|
// Purpose:
|
|
//
|
|
// Skinned objects, aka rigged objects are handled here.
|
|
// Skeletal operations are performed on the GPU (hopefully) and we don't care
|
|
// about lightmaps, but query the engine for a dir + ambient term which may
|
|
// come from the lightgrid or not exist at all. At that point it should be
|
|
// the rtlight shader doing the major work though.
|
|
//==============================================================================
|
|
|
|
!!ver 100 150
|
|
|
|
!!permu FOG
|
|
!!permu BUMP
|
|
!!permu DELUXE
|
|
!!permu SPECULAR
|
|
!!permu FULLBRIGHT
|
|
!!permu FAKESHADOWS
|
|
!!permu OFFSETMAPPING
|
|
!!permu SKELETAL
|
|
!!permu UPPERLOWER
|
|
|
|
!!samps diffuse
|
|
!!samps =BUMP normalmap
|
|
!!samps =SPECULAR specular reflectcube
|
|
!!samps =FULLBRIGHT fullbright
|
|
!!samps =UPPERLOWER upper lower
|
|
!!samps =FAKESHADOWS shadowmap
|
|
|
|
!!permu FAKESHADOWS
|
|
!!cvardf r_glsl_pcf
|
|
!!samps =FAKESHADOWS shadowmap
|
|
|
|
!!cvarf r_glsl_offsetmapping_scale
|
|
!!cvarf gl_specular
|
|
|
|
#ifndef FRESNEL
|
|
#define FRESNEL 0.25f
|
|
#endif
|
|
|
|
#include "sys/defs.h"
|
|
|
|
// always required
|
|
varying vec2 tc;
|
|
varying vec3 lightvector;
|
|
varying vec3 light;
|
|
|
|
// from this point forth, if we check for SPECULAR this means we're in PBR territory
|
|
#ifdef BUMP
|
|
varying vec3 eyevector;
|
|
varying mat3 invsurface;
|
|
#define PBR
|
|
#endif
|
|
|
|
// r_shadows 2
|
|
#ifdef FAKESHADOWS
|
|
varying vec4 vtexprojcoord;
|
|
#endif
|
|
|
|
// our basic vertex shader
|
|
#ifdef VERTEX_SHADER
|
|
#include "sys/skeletal.h"
|
|
|
|
float lambert( vec3 normal, vec3 dir ) {
|
|
return dot( normal, dir );
|
|
}
|
|
float halflambert( vec3 normal, vec3 dir ) {
|
|
return ( dot( normal, dir ) * 0.5 ) + 0.5;
|
|
}
|
|
|
|
void main ()
|
|
{
|
|
vec3 n, s, t, w;
|
|
gl_Position = skeletaltransform_wnst(w,n,s,t);
|
|
|
|
#ifdef PBR
|
|
vec3 eyeminusvertex = e_eyepos - w.xyz;
|
|
eyevector.x = dot(eyeminusvertex, s.xyz);
|
|
eyevector.y = dot(eyeminusvertex, t.xyz);
|
|
eyevector.z = dot(eyeminusvertex, n.xyz);
|
|
invsurface[0] = s;
|
|
invsurface[1] = t;
|
|
invsurface[2] = n;
|
|
#endif
|
|
|
|
light = e_light_ambient + (e_light_mul * lambert(n, e_light_dir));
|
|
|
|
tc = v_texcoord;
|
|
lightvector.x = dot(e_light_dir, s.xyz);
|
|
lightvector.y = dot(e_light_dir, t.xyz);
|
|
lightvector.z = dot(e_light_dir, n.xyz);
|
|
|
|
#ifdef FAKESHADOWS
|
|
vtexprojcoord = (l_cubematrix*vec4(v_position.xyz, 1.0));
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
#ifdef FRAGMENT_SHADER
|
|
#include "sys/fog.h"
|
|
|
|
#if defined(SPECULAR)
|
|
uniform float cvar_gl_specular;
|
|
#endif
|
|
|
|
#ifdef FAKESHADOWS
|
|
#include "sys/pcf.h"
|
|
#endif
|
|
|
|
#ifdef OFFSETMAPPING
|
|
#include "sys/offsetmapping.h"
|
|
#endif
|
|
|
|
float LightingFuncGGX(vec3 N, vec3 V, vec3 L, float roughness, float F0)
|
|
{
|
|
float alpha = roughness*roughness;
|
|
|
|
vec3 H = normalize(V+L);
|
|
|
|
float dotNL = clamp(dot(N,L), 0.0, 1.0);
|
|
float dotLH = clamp(dot(L,H), 0.0, 1.0);
|
|
float dotNH = clamp(dot(N,H), 0.0, 1.0);
|
|
|
|
float F, D, vis;
|
|
|
|
// D
|
|
float alphaSqr = alpha*alpha;
|
|
float pi = 3.14159f;
|
|
float denom = dotNH * dotNH *(alphaSqr-1.0) + 1.0f;
|
|
D = alphaSqr/(pi * denom * denom);
|
|
|
|
// F
|
|
float dotLH5 = pow(1.0f-dotLH,5);
|
|
F = F0 + (1.0-F0)*(dotLH5);
|
|
|
|
// V
|
|
float k = alpha/2.0f;
|
|
float k2 = k*k;
|
|
float invK2 = 1.0f-k2;
|
|
vis = 1.0/(dotLH*dotLH*invK2 + k2);
|
|
|
|
float specular = dotNL * D * F * vis;
|
|
return specular;
|
|
}
|
|
|
|
void main ()
|
|
{
|
|
#ifdef OFFSETMAPPING
|
|
vec2 tcoffsetmap = offsetmap(s_normalmap, tc, eyevector);
|
|
#define tc tcoffsetmap
|
|
#endif
|
|
|
|
vec4 albedo_f = texture2D(s_diffuse, tc);
|
|
|
|
#ifdef BUMP
|
|
vec3 normal_f = normalize(texture2D(s_normalmap, tc).rgb - 0.5);
|
|
#else
|
|
vec3 normal_f = vec3(0.0, 0.0, 1.0);
|
|
#endif
|
|
|
|
#ifdef UPPER
|
|
vec4 uc = texture2D(s_upper, tc);
|
|
albedo_f.rgb += uc.rgb * e_uppercolour * uc.a;
|
|
#endif
|
|
|
|
#ifdef LOWER
|
|
vec4 lc = texture2D(s_lower, tc);
|
|
albedo_f.rgb += lc.rgb * e_lowercolour * lc.a;
|
|
#endif
|
|
|
|
#ifdef PBR
|
|
float metalness_f = texture2D(s_specular, tc).r;
|
|
float roughness_f = texture2D(s_specular, tc).g;
|
|
float ao = texture2D(s_specular, tc).b;
|
|
|
|
/* coords */
|
|
vec3 cube_c;
|
|
|
|
/* calculate cubemap texcoords */
|
|
cube_c = reflect(-normalize(eyevector), normal_f.rgb);
|
|
cube_c = cube_c.x * invsurface[0] + cube_c.y * invsurface[1] + cube_c.z * invsurface[2];
|
|
cube_c = (m_model * vec4(cube_c.xyz, 0.0)).xyz;
|
|
|
|
/* do PBR reflection using cubemap */
|
|
gl_FragColor = albedo_f + (metalness_f * textureCube(s_reflectcube, cube_c));
|
|
|
|
/* do PBR specular using our handy function */
|
|
gl_FragColor += (LightingFuncGGX(normal_f, normalize(eyevector), normalize(lightvector), roughness_f, FRESNEL) * gl_FragColor);
|
|
#else
|
|
gl_FragColor = albedo_f;
|
|
#endif
|
|
|
|
/* this isn't necessary if we're not doing lightgrid terms */
|
|
gl_FragColor.rgb *= light * e_lmscale.rgb;
|
|
|
|
/* r_shadows 2 */
|
|
#ifdef FAKESHADOWS
|
|
gl_FragColor.rgb *= ShadowmapFilter(s_shadowmap, vtexprojcoord);
|
|
#endif
|
|
|
|
#ifdef PBR
|
|
gl_FragColor.rgb *= ao;
|
|
#endif
|
|
|
|
#ifdef FULLBRIGHT
|
|
vec4 fb = texture2D(s_fullbright, tc);
|
|
gl_FragColor.rgb += fb.rgb * fb.a * e_glowmod.rgb;
|
|
#endif
|
|
|
|
gl_FragColor = fog4(gl_FragColor * e_colourident);
|
|
}
|
|
#endif
|