nuclide/base/glsl/defaultskin.glsl
Marco Cawthorne d41b90c081 Base: Give some love to base/
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
2025-01-02 18:53:55 -08:00

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