Skip to content

Commit

Permalink
update shaders.
Browse files Browse the repository at this point in the history
  • Loading branch information
hzqst committed Dec 29, 2023
1 parent e7b5442 commit 1557cb1
Show file tree
Hide file tree
Showing 11 changed files with 580 additions and 779 deletions.
4 changes: 0 additions & 4 deletions Build/svencoop/renderer/shader/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,6 @@ struct scene_ubo_t{
float r_lightscale;
vec4 r_filtercolor;
vec4 r_lightstylevalue[64];
float r_studio_shade_specular;
float r_studio_shade_specularpow;
float padding2;
float padding3;
};

struct dlight_ubo_t{
Expand Down
289 changes: 193 additions & 96 deletions Build/svencoop/renderer/shader/studio_shader.fsh
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ layout(binding = 6) uniform usampler2D stencilTex;

/* celshade */

uniform vec2 r_base_specular;
uniform vec4 r_celshade_specular;
uniform float r_celshade_midpoint;
uniform float r_celshade_softness;
uniform vec3 r_celshade_shadow_color;
uniform vec3 r_celshade_head_offset;
uniform vec2 celshade_lightdir_adjust;
uniform vec2 r_celshade_lightdir_adjust;
uniform float r_rimlight_power;
uniform float r_rimlight_smooth;
uniform vec2 r_rimlight_smooth2;
Expand Down Expand Up @@ -96,110 +98,230 @@ vec3 NormalMapping(mat3 TBN, vec2 baseTexcoord)

#endif

//The output is in Linear Space
vec3 R_StudioLightingLinear(vec3 vWorldPos, vec3 vNormal, float specularMask)
{
float illum = StudioUBO.r_ambientlight;
vec3 R_GetAdjustedLightDirection(vec3 vecLightDirection)
{
vec3 vecAdjustedLightDirection = vecLightDirection;

#if defined(STUDIO_NF_FULLBRIGHT)
#if defined(STUDIO_NF_CELSHADE_FACE)

return vec3(1.0, 1.0, 1.0);
vecAdjustedLightDirection.z *= r_celshade_lightdir_adjust.y;

#elif defined(STUDIO_NF_FLATSHADE) || defined(STUDIO_NF_CELSHADE)
#elif defined(STUDIO_NF_CELSHADE)

illum += StudioUBO.r_shadelight * 0.8;
vecAdjustedLightDirection.z *= r_celshade_lightdir_adjust.x;

#else
#endif

float lightcos = dot(vNormal.xyz, StudioUBO.r_plightvec.xyz);
return normalize(vecAdjustedLightDirection);
}

if(SceneUBO.v_lambert < 1.0)
{
lightcos = (SceneUBO.v_lambert - lightcos) / (SceneUBO.v_lambert + 1.0);
illum += StudioUBO.r_shadelight * max(lightcos, 0.0);
}
else
{
illum += StudioUBO.r_shadelight;
lightcos = (lightcos + SceneUBO.v_lambert - 1.0) / SceneUBO.v_lambert;
illum -= StudioUBO.r_shadelight * max(lightcos, 0.0);
}
float R_StudioBaseLight_PhongSpecular(vec3 vWorldPos, vec3 vNormal, float specularMask)
{
float illum = 0.0;

#if defined(STUDIO_NF_FLATSHADE) || defined(STUDIO_NF_CELSHADE)
vec3 vecVertexToEye = normalize(SceneUBO.viewpos.xyz - vWorldPos.xyz);
vec3 vecAdjustedLight = R_GetAdjustedLightDirection(StudioUBO.r_plightvec.xyz);
vec3 vecLightReflect = normalize(reflect(vecAdjustedLight, vNormal.xyz));
float flSpecularFactor = dot(vecVertexToEye, vecLightReflect);

#else
flSpecularFactor = clamp(flSpecularFactor, 0.0, 1.0);
flSpecularFactor = pow(flSpecularFactor, r_base_specular.y) * r_base_specular.x;

#if defined(SPECULARTEXTURE_ENABLED)
illum += StudioUBO.r_shadelight * flSpecularFactor * specularMask;

vec3 VertexToEye = normalize(SceneUBO.viewpos.xyz - vWorldPos.xyz);
vec3 LightReflect = normalize(reflect(StudioUBO.r_plightvec.xyz, vNormal.xyz));
float SpecularFactor = dot(VertexToEye, LightReflect);
SpecularFactor = clamp(SpecularFactor, 0.0, 1.0);
SpecularFactor = pow(SpecularFactor * SceneUBO.r_studio_shade_specular,
SceneUBO.r_studio_shade_specularpow);
return illum;
}

illum += StudioUBO.r_shadelight * SpecularFactor * specularMask;
float GetSteppedValue(float low, float high, float value) {
return mix(mix(0.0, value, step(low, value)), 1.0, step(high, value)) * value;
}

#endif
float R_StudioBaseLight_CelShadeSpecular(vec3 vWorldPos, vec3 vNormal, float specularMask)
{
float illum = 0.0;

#endif
vec3 vecVertexToEye = normalize(SceneUBO.viewpos.xyz - vWorldPos.xyz);
vec3 vecAdjustedLight = R_GetAdjustedLightDirection(StudioUBO.r_plightvec.xyz);
vec3 vecLightReflect = normalize(reflect(vecAdjustedLight, vNormal.xyz));
float flSpecularFactor = dot(vecVertexToEye, vecLightReflect);

flSpecularFactor = clamp(flSpecularFactor, 0.0, 1.0);
flSpecularFactor = pow(flSpecularFactor, r_celshade_specular.y) * r_celshade_specular.x;

flSpecularFactor = GetSteppedValue(r_celshade_specular.z, r_celshade_specular.w, flSpecularFactor);

illum += StudioUBO.r_shadelight * flSpecularFactor * specularMask;

return illum;
}

float R_StudioBaseLight_FlatShading(vec3 vWorldPos, vec3 vNormal, float specularMask)
{
float illum = 0.0;

illum += StudioUBO.r_shadelight * 0.8;

//Layer 1 Specular
#if defined(SPECULARTEXTURE_ENABLED)

illum += R_StudioBaseLight_PhongSpecular(vWorldPos, vNormal, specularMask);

#endif

//Really need to clamp?
//Layer 2 Specular
#if defined(SPECULARTEXTURE_ENABLED) && defined(STUDIO_NF_CELSHADE)

float lv = clamp(illum, 0.0, 255.0) / 255.0;
illum += R_StudioBaseLight_CelShadeSpecular(vWorldPos, vNormal, specularMask);

lv = LightGammaToLinearInternal(lv);
#endif

vec3 color = vec3(lv, lv, lv);
return illum;
}

for(int i = 0; i < StudioUBO.r_numelight.x; ++i)
float R_StudioBaseLight_PhongShading(vec3 vWorldPos, vec3 vNormal, float specularMask)
{
float illum = 0.0;
float lightcos = dot(vNormal.xyz, StudioUBO.r_plightvec.xyz);

if(SceneUBO.v_lambert < 1.0)
{
vec3 ElightDirection = StudioUBO.r_elight_origin[i].xyz - vWorldPos.xyz;

#if defined(STUDIO_NF_FLATSHADE) || defined(STUDIO_NF_CELSHADE)
lightcos = (SceneUBO.v_lambert - lightcos) / (SceneUBO.v_lambert + 1.0);
illum += StudioUBO.r_shadelight * max(lightcos, 0.0);
}
else
{
illum += StudioUBO.r_shadelight;
lightcos = (lightcos + SceneUBO.v_lambert - 1.0) / SceneUBO.v_lambert;
illum -= StudioUBO.r_shadelight * max(lightcos, 0.0);
}

//Layer 1 Specular
#if defined(SPECULARTEXTURE_ENABLED)

illum += R_StudioBaseLight_PhongSpecular(vWorldPos, vNormal, specularMask);

#endif

return illum;
}

vec3 R_StudioEntityLight_PhongSpecular(int i, vec3 vElightDirection, vec3 vWorldPos, vec3 vNormal, float specularMask)
{
vec3 color = vec3(0.0, 0.0, 0.0);

vec3 vecVertexToEye = normalize(SceneUBO.viewpos.xyz - vWorldPos.xyz);
vec3 vecLightReflect = normalize(reflect(vElightDirection, vNormal.xyz));

float flSpecularFactor = dot(vecVertexToEye, vecLightReflect);
flSpecularFactor = clamp(flSpecularFactor, 0.0, 1.0);
flSpecularFactor = pow(flSpecularFactor, r_base_specular.y) * r_base_specular.x;

color.x += StudioUBO.r_elight_color[i].x * flSpecularFactor * specularMask;
color.y += StudioUBO.r_elight_color[i].y * flSpecularFactor * specularMask;
color.z += StudioUBO.r_elight_color[i].z * flSpecularFactor * specularMask;

return color;
}

vec3 R_StudioEntityLight_FlatShading(int i, vec3 vWorldPos, vec3 vNormal, float specularMask)
{
vec3 color = vec3(0.0, 0.0, 0.0);

vec3 ElightDirection = StudioUBO.r_elight_origin[i].xyz - vWorldPos.xyz;

float ElightCosine = 0.8;

float ElightDistance = length(ElightDirection);
float ElightDot = dot(ElightDirection, ElightDirection);

float r2 = StudioUBO.r_elight_radius[i];

r2 = r2 * r2;

float ElightAttenuation = clamp(r2 / (ElightDot * ElightDistance), 0.0, 1.0);

color.x += StudioUBO.r_elight_color[i].x * ElightCosine;
color.y += StudioUBO.r_elight_color[i].y * ElightCosine;
color.z += StudioUBO.r_elight_color[i].z * ElightCosine;

#if defined(SPECULARTEXTURE_ENABLED)

color += R_StudioEntityLight_PhongSpecular(i, ElightDirection, vWorldPos, vNormal, specularMask);

float ElightCosine = 0.8;
#endif

return color;
}

vec3 R_StudioEntityLight_PhongShading(int i, vec3 vWorldPos, vec3 vNormal, float specularMask)
{
vec3 color = vec3(0.0, 0.0, 0.0);

vec3 ElightDirection = StudioUBO.r_elight_origin[i].xyz - vWorldPos.xyz;

#else
float ElightCosine = clamp(dot(vNormal, normalize(ElightDirection)), 0.0, 1.0);
float ElightDistance = length(ElightDirection);
float ElightDot = dot(ElightDirection, ElightDirection);

float ElightCosine = clamp(dot(vNormal, normalize(ElightDirection)), 0.0, 1.0);
float r2 = StudioUBO.r_elight_radius[i];

r2 = r2 * r2;

#endif
float ElightAttenuation = clamp(r2 / (ElightDot * ElightDistance), 0.0, 1.0);

color.x += StudioUBO.r_elight_color[i].x * ElightCosine;
color.y += StudioUBO.r_elight_color[i].y * ElightCosine;
color.z += StudioUBO.r_elight_color[i].z * ElightCosine;

float ElightDistance = length(ElightDirection);
float ElightDot = dot(ElightDirection, ElightDirection);
#if defined(SPECULARTEXTURE_ENABLED)

float r2 = StudioUBO.r_elight_radius[i];
color += R_StudioEntityLight_PhongSpecular(i, ElightDirection, vWorldPos, vNormal, specularMask);

r2 = r2 * r2;
#endif

float ElightAttenuation = clamp(r2 / (ElightDot * ElightDistance), 0.0, 1.0);
return color;
}

color.x += StudioUBO.r_elight_color[i].x * ElightCosine;
color.y += StudioUBO.r_elight_color[i].y * ElightCosine;
color.z += StudioUBO.r_elight_color[i].z * ElightCosine;
//The output is in linear space
vec3 R_StudioLighting(vec3 vWorldPos, vec3 vNormal, float specularMask)
{
float illum = StudioUBO.r_ambientlight;

#if defined(STUDIO_NF_FLATSHADE) || defined(STUDIO_NF_CELSHADE)
#if defined(STUDIO_NF_FULLBRIGHT)

#else
return vec3(1.0, 1.0, 1.0);

#if defined(SPECULARTEXTURE_ENABLED)
#elif defined(STUDIO_NF_FLATSHADE) || defined(STUDIO_NF_CELSHADE)

vec3 EVertexToEye = normalize(SceneUBO.viewpos.xyz - vWorldPos.xyz);
vec3 ELightReflect = normalize(reflect(ElightDirection, vNormal.xyz));
float ESpecularFactor = dot(EVertexToEye, ELightReflect);
ESpecularFactor = clamp(ESpecularFactor, 0.0, 1.0);
ESpecularFactor = pow(ESpecularFactor * SceneUBO.r_studio_shade_specular,
SceneUBO.r_studio_shade_specularpow);
color.x += StudioUBO.r_elight_color[i].x * ESpecularFactor * specularMask;
color.y += StudioUBO.r_elight_color[i].y * ESpecularFactor * specularMask;
color.z += StudioUBO.r_elight_color[i].z * ESpecularFactor * specularMask;
illum += R_StudioBaseLight_FlatShading(vWorldPos, vNormal, specularMask);

#endif
#else

illum += R_StudioBaseLight_PhongShading(vWorldPos, vNormal, specularMask);

#endif

//Really need to clamp?

float lv = clamp(illum, 0.0, 255.0) / 255.0;

lv = LightGammaToLinearInternal(lv);

vec3 color = vec3(lv, lv, lv);

for(int i = 0; i < StudioUBO.r_numelight.x; ++i)
{

#if defined(STUDIO_NF_FLATSHADE) || defined(STUDIO_NF_CELSHADE)

color += R_StudioEntityLight_FlatShading(i, vWorldPos, vNormal, specularMask);

#else

color += R_StudioEntityLight_PhongShading(i, vWorldPos, vNormal, specularMask);

#endif

#endif
}

return color;
Expand Down Expand Up @@ -242,9 +364,7 @@ vec3 R_StudioCelShade(vec3 v_color, vec3 normalWS, vec3 lightdirWS, float specul
vec3 vecForward = v_headfwd;
vec3 vecUp = v_headup;

L.z *= celshade_lightdir_adjust.y;

L = normalize(L);
L = R_GetAdjustedLightDirection(L);

float flFaceCosine = abs(vecForward.z);
flFaceCosine = pow(flFaceCosine, 10.0);
Expand All @@ -257,9 +377,7 @@ vec3 R_StudioCelShade(vec3 v_color, vec3 normalWS, vec3 lightdirWS, float specul

#else

L.z *= celshade_lightdir_adjust.x;

L = normalize(L);
L = R_GetAdjustedLightDirection(L);

#endif

Expand Down Expand Up @@ -365,27 +483,6 @@ vec3 R_StudioCelShade(vec3 v_color, vec3 normalWS, vec3 lightdirWS, float specul

#endif

#endif

#if 0

vec3 halfVec = normalize(L + vec3(0.01, 0.0, 0.0) + SceneUBO.vpn.xyz);

float specular = dot(N, halfVec);

vec3 specularColorMasked = vec3(0.0);
vec3 specularColorSmooth = vec3(0.0);

specularColorMasked.x = pow(v_color.x * specular, 0.8);
specularColorMasked.y = pow(v_color.y * specular, 0.8);
specularColorMasked.z = pow(v_color.z * specular, 0.8);

specularColorSmooth.x = smoothstep(0, 0.01 * 1, specularColorMasked.x);
specularColorSmooth.y = smoothstep(0, 0.01 * 1, specularColorMasked.y);
specularColorSmooth.z = smoothstep(0, 0.01 * 1, specularColorMasked.z);

specularColor += specularColorSmooth;

#endif

return v_color.xyz * litOrShadowColor + rimLightColor + rimDarkColor + specularColor;
Expand Down Expand Up @@ -528,7 +625,7 @@ void main(void)

vec4 lightmapColor = ProcessOtherGammaColor(StudioUBO.r_color);

vec3 lightColorLinear = R_StudioLightingLinear(vWorldPos, vNormal, specularColor.x);
vec3 lightColorLinear = R_StudioLighting(vWorldPos, vNormal, specularColor.x);

#if defined(STUDIO_NF_CELSHADE)
lightColorLinear = R_StudioCelShade(lightColorLinear, vNormal, StudioUBO.r_plightvec.xyz, specularColor.x);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
"celshade_midpoint" "-0.1"
"celshade_softness" "0.05"
"celshade_shadow_color" "160 150 150"
"celshade_head_offset" "3.5 2 0"
"celshade_light_adjust" "0.01 0.001"
"outline_size" "3.0"
"outline_dark" "0.5"
"rimlight_power" "5.0"
Expand Down
Loading

0 comments on commit 1557cb1

Please sign in to comment.