From cb4f5a17a85317a432b05aacf16eacac4b911a7a Mon Sep 17 00:00:00 2001 From: callumok2004 Date: Tue, 20 Oct 2026 02:12:08 +0100 Subject: [PATCH 1/3] Reverse FindVar --- Source.MaterialSystem/Material.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Source.MaterialSystem/Material.cs b/Source.MaterialSystem/Material.cs index dff33b0d..0ec9caa9 100644 --- a/Source.MaterialSystem/Material.cs +++ b/Source.MaterialSystem/Material.cs @@ -193,10 +193,11 @@ public IMaterialVar FindVar(ReadOnlySpan varName, out bool found, bool com Span lowercased = stackalloc char[varName.Length]; varName.ToLowerInvariant(lowercased); ReadOnlySpan lowercasedROS = lowercased; // Need to make a version of that that works on Span... - foreach (var shaderParam in Vars) { - if (shaderParam.GetName().Hash() == lowercasedROS.Hash()) { + Span vars = Vars; + for (int i = vars.Length; --i >= 0;) { + if (vars[i].GetName().Hash() == lowercasedROS.Hash()) { found = true; - return shaderParam; + return vars[i]; } } found = false; From d0c0af4145f72d16a276c6fe49146279b607d136 Mon Sep 17 00:00:00 2001 From: callumok2004 Date: Tue, 20 Oct 2026 02:12:32 +0100 Subject: [PATCH 2/3] gmod shaders --- Game.Assets/sdn/shaders/g_bloom_gl460.fs | 26 ++++ Game.Assets/sdn/shaders/g_blurx_gl460.fs | 25 ++++ Game.Assets/sdn/shaders/g_blury_gl460.fs | 25 ++++ Game.Assets/sdn/shaders/g_bokehblur_gl460.fs | 78 +++++++++++ .../sdn/shaders/g_colourmodify_gl460.fs | 51 +++++++ Game.Assets/sdn/shaders/g_downsample_gl460.fs | 33 +++++ .../sdn/shaders/g_premultiplied_gl460.fs | 12 ++ Game.Assets/sdn/shaders/g_refract_gl460.fs | 27 ++++ Game.Assets/sdn/shaders/g_screenquad_gl460.vs | 21 +++ Game.Assets/sdn/shaders/g_sharpen_gl460.fs | 23 ++++ Game.Assets/sdn/shaders/g_sobel_gl460.fs | 40 ++++++ Game.Assets/sdn/shaders/g_sobel_gl460.vs | 21 +++ Game.Assets/sdn/shaders/g_sunbeams_gl460.fs | 35 +++++ Game.Assets/sdn/shaders/g_texturize_gl460.fs | 34 +++++ Source.StdShader.Gl46/Sobel.cs | 116 ++++++++++++++++ Source.StdShader.Gl46/g_bloom.cs | 121 ++++++++++++++++ Source.StdShader.Gl46/g_blurx.cs | 110 +++++++++++++++ Source.StdShader.Gl46/g_blury.cs | 110 +++++++++++++++ Source.StdShader.Gl46/g_bokehblur.cs | 114 +++++++++++++++ Source.StdShader.Gl46/g_colourmodify.cs | 130 ++++++++++++++++++ Source.StdShader.Gl46/g_downsample.cs | 119 ++++++++++++++++ Source.StdShader.Gl46/g_premultiplied.cs | 40 ++++++ Source.StdShader.Gl46/g_refract.cs | 116 ++++++++++++++++ Source.StdShader.Gl46/g_sharpen.cs | 114 +++++++++++++++ Source.StdShader.Gl46/g_sunbeams.cs | 118 ++++++++++++++++ Source.StdShader.Gl46/g_texturize.cs | 117 ++++++++++++++++ 26 files changed, 1776 insertions(+) create mode 100644 Game.Assets/sdn/shaders/g_bloom_gl460.fs create mode 100644 Game.Assets/sdn/shaders/g_blurx_gl460.fs create mode 100644 Game.Assets/sdn/shaders/g_blury_gl460.fs create mode 100644 Game.Assets/sdn/shaders/g_bokehblur_gl460.fs create mode 100644 Game.Assets/sdn/shaders/g_colourmodify_gl460.fs create mode 100644 Game.Assets/sdn/shaders/g_downsample_gl460.fs create mode 100644 Game.Assets/sdn/shaders/g_premultiplied_gl460.fs create mode 100644 Game.Assets/sdn/shaders/g_refract_gl460.fs create mode 100644 Game.Assets/sdn/shaders/g_screenquad_gl460.vs create mode 100644 Game.Assets/sdn/shaders/g_sharpen_gl460.fs create mode 100644 Game.Assets/sdn/shaders/g_sobel_gl460.fs create mode 100644 Game.Assets/sdn/shaders/g_sobel_gl460.vs create mode 100644 Game.Assets/sdn/shaders/g_sunbeams_gl460.fs create mode 100644 Game.Assets/sdn/shaders/g_texturize_gl460.fs create mode 100644 Source.StdShader.Gl46/Sobel.cs create mode 100644 Source.StdShader.Gl46/g_bloom.cs create mode 100644 Source.StdShader.Gl46/g_blurx.cs create mode 100644 Source.StdShader.Gl46/g_blury.cs create mode 100644 Source.StdShader.Gl46/g_bokehblur.cs create mode 100644 Source.StdShader.Gl46/g_colourmodify.cs create mode 100644 Source.StdShader.Gl46/g_downsample.cs create mode 100644 Source.StdShader.Gl46/g_premultiplied.cs create mode 100644 Source.StdShader.Gl46/g_refract.cs create mode 100644 Source.StdShader.Gl46/g_sharpen.cs create mode 100644 Source.StdShader.Gl46/g_sunbeams.cs create mode 100644 Source.StdShader.Gl46/g_texturize.cs diff --git a/Game.Assets/sdn/shaders/g_bloom_gl460.fs b/Game.Assets/sdn/shaders/g_bloom_gl460.fs new file mode 100644 index 00000000..6d59521b --- /dev/null +++ b/Game.Assets/sdn/shaders/g_bloom_gl460.fs @@ -0,0 +1,26 @@ +#version 460 + +layout(location = 0) in vec2 vs_TexCoord; + +layout(std140, binding = 6) uniform source_ps_constants { + vec4 ps_const[256]; +}; + +out vec4 fragColor; + +layout(binding = 0) uniform sampler2D Bloom; + +#define LevelR ps_const[0].x +#define LevelG ps_const[1].x +#define LevelB ps_const[2].x +#define ColorMul ps_const[3].x + +void main() +{ + vec4 color = texture(Bloom, vs_TexCoord); + vec3 level = color.xyz * vec3(LevelR, LevelG, LevelB); + + float grey = (level.r + level.g + level.b) * 0.333333343 * (1.0 - ColorMul); + + fragColor = vec4(level * ColorMul + grey, 1.0); +} diff --git a/Game.Assets/sdn/shaders/g_blurx_gl460.fs b/Game.Assets/sdn/shaders/g_blurx_gl460.fs new file mode 100644 index 00000000..51495b41 --- /dev/null +++ b/Game.Assets/sdn/shaders/g_blurx_gl460.fs @@ -0,0 +1,25 @@ +#version 460 + +layout(location = 0) in vec2 vs_TexCoord; + +layout(std140, binding = 6) uniform source_ps_constants { + vec4 ps_const[256]; +}; + +out vec4 fragColor; + +layout(binding = 0) uniform sampler2D BaseTextureSampler; + +#define BlurSizeH ps_const[0].x + +const float tapOffsets[13] = float[](-5.0, -6.0, -4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0); +const float tapWeights[13] = float[](0.00876399968, 0.00221600011, 0.0269949995, 0.0647590011, 0.120985001, 0.176033005, 0.199470997, 0.176033005, 0.120985001, 0.0647590011, 0.0269949995, 0.00876399968, 0.00221600011); + +void main() +{ + vec4 color = vec4(0.0); + for (int i = 0; i < 13; i++) + color += texture(BaseTextureSampler, vs_TexCoord + vec2(BlurSizeH * tapOffsets[i], 0.0)) * tapWeights[i]; + + fragColor = color; +} diff --git a/Game.Assets/sdn/shaders/g_blury_gl460.fs b/Game.Assets/sdn/shaders/g_blury_gl460.fs new file mode 100644 index 00000000..fb8aa6fe --- /dev/null +++ b/Game.Assets/sdn/shaders/g_blury_gl460.fs @@ -0,0 +1,25 @@ +#version 460 + +layout(location = 0) in vec2 vs_TexCoord; + +layout(std140, binding = 6) uniform source_ps_constants { + vec4 ps_const[256]; +}; + +out vec4 fragColor; + +layout(binding = 0) uniform sampler2D BaseTextureSampler; + +#define BlurSizeV ps_const[0].x + +const float tapOffsets[13] = float[](-5.0, -6.0, -4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0); +const float tapWeights[13] = float[](0.00876399968, 0.00221600011, 0.0269949995, 0.0647590011, 0.120985001, 0.176033005, 0.199470997, 0.176033005, 0.120985001, 0.0647590011, 0.0269949995, 0.00876399968, 0.00221600011); + +void main() +{ + vec4 color = vec4(0.0); + for (int i = 0; i < 13; i++) + color += texture(BaseTextureSampler, vs_TexCoord + vec2(0.0, BlurSizeV * tapOffsets[i])) * tapWeights[i]; + + fragColor = color; +} diff --git a/Game.Assets/sdn/shaders/g_bokehblur_gl460.fs b/Game.Assets/sdn/shaders/g_bokehblur_gl460.fs new file mode 100644 index 00000000..cb960b0f --- /dev/null +++ b/Game.Assets/sdn/shaders/g_bokehblur_gl460.fs @@ -0,0 +1,78 @@ +#version 460 + +layout(location = 0) in vec2 vs_TexCoord; + +layout(std140, binding = 6) uniform source_ps_constants { + vec4 ps_const[256]; +}; + +out vec4 fragColor; + +layout(binding = 0) uniform sampler2D _Sampler; +layout(binding = 1) uniform sampler2D _Depth; + +#define g_TexelSize ps_const[0].xy +#define g_Radius ps_const[1].x +#define g_FocusPoint ps_const[2].x +#define g_FocusRadius ps_const[3].x + +const vec3 lumWeights = vec3(0.212599993, 0.715200007, 0.0722000003); + +const vec3 kernel[60] = vec3[]( + vec3(0.216499999, 0.125, 1.0), vec3(0.0, 0.25, 1.0), vec3(-0.216499999, 0.125, 1.0), + vec3(-0.216499999, -0.125, 1.0), vec3(0.0, -0.25, 1.0), vec3(0.216499999, -0.125, 1.0), + vec3(0.432999998, 0.25, 1.0), vec3(0.0, 0.5, 1.0), vec3(-0.432999998, 0.25, 1.0), + vec3(-0.432999998, -0.25, 1.0), vec3(0.0, -0.5, 1.0), vec3(0.432999998, -0.25, 1.0), + vec3(0.649500012, 0.375, 1.0), vec3(0.0, 0.75, 1.0), vec3(-0.649500012, 0.375, 1.0), + vec3(-0.649500012, -0.375, 1.0), vec3(0.0, -0.75, 1.0), vec3(0.649500012, -0.375, 1.0), + vec3(0.865999997, 0.5, 1.0), vec3(0.0, 1.0, 1.0), vec3(-0.865999997, 0.5, 1.0), + vec3(-0.865999997, -0.5, 1.0), vec3(0.0, -1.0, 1.0), vec3(0.865999997, -0.5, 1.0), + vec3(0.216299996, 0.375400007, 0.866999984), vec3(-0.216999993, 0.375, 0.866999984), vec3(-0.433299989, -0.00039999999, 0.866999984), + vec3(-0.216299996, -0.375400007, 0.866999984), vec3(0.216999993, -0.375, 0.866999984), vec3(0.433299989, 0.00039999999, 0.866999984), + vec3(0.432799995, 0.500400007, 0.8847), vec3(-0.216999993, 0.625, 0.8847), vec3(-0.649800003, 0.124600001, 0.8847), + vec3(-0.432799995, -0.500400007, 0.8847), vec3(0.216999993, -0.625, 0.8847), vec3(0.649800003, -0.124600001, 0.8847), + vec3(0.649299979, 0.625400007, 0.906499982), vec3(-0.216999993, 0.875, 0.906499982), vec3(-0.866299987, 0.249599993, 0.906499982), + vec3(-0.649299979, -0.625400007, 0.906499982), vec3(0.216999993, -0.875, 0.906499982), vec3(0.866299987, -0.249599993, 0.906499982), + vec3(0.216000006, 0.625899971, 0.885100007), vec3(-0.433999985, 0.5, 0.885100007), vec3(-0.649999976, -0.1259, 0.885100007), + vec3(-0.216000006, -0.625899971, 0.885100007), vec3(0.433999985, -0.5, 0.885100007), vec3(0.649999976, 0.1259, 0.885100007), + vec3(0.432500005, 0.750899971, 0.866999984), vec3(-0.433999985, 0.75, 0.866999984), vec3(-0.86650002, -0.000899999985, 0.866999984), + vec3(-0.432500005, -0.750899971, 0.866999984), vec3(0.433999985, -0.75, 0.866999984), vec3(0.86650002, 0.000899999985, 0.866999984), + vec3(0.215800002, 0.876299977, 0.907000005), vec3(-0.651000023, 0.625, 0.907000005), vec3(-0.86680001, -0.251300007, 0.907000005), + vec3(-0.215800002, -0.876299977, 0.907000005), vec3(0.651000023, -0.625, 0.907000005), vec3(0.86680001, 0.251300007, 0.907000005) +); + +float CircleOfConfusion(vec2 uv) +{ + return pow(abs(texture(_Depth, uv).x - g_FocusPoint), g_FocusRadius) * g_Radius; +} + +void main() +{ + vec4 center = texture(_Sampler, vs_TexCoord); + float centerCoc = CircleOfConfusion(vs_TexCoord); + float maxRadius = centerCoc * 2.0; + vec2 scale = maxRadius * g_TexelSize; + + float centerWeight = max(dot(center.xyz + 0.00999999978, lumWeights) / (maxRadius * maxRadius + 1.0), 0.0); + vec3 color = center.xyz * centerWeight; + float totalWeight = centerWeight; + + for (int i = 0; i < 60; i++) { + vec2 uv = vs_TexCoord + scale * kernel[i].xy; + vec3 tap = texture(_Sampler, uv).xyz; + + float coc = CircleOfConfusion(uv); + if (centerCoc < 0.0) + coc = max(abs(maxRadius), coc); + + float edge = coc * kernel[i].z; + float t = clamp((abs(maxRadius) * length(kernel[i].xy) - edge) / (edge * 0.100000001), 0.0, 1.0); + float falloff = clamp(1.0 - t * t * (3.0 - 2.0 * t), 0.0, 1.0); + + float weight = max(dot(tap + 0.00999999978, lumWeights) / (coc * coc + 1.0) * falloff, 0.0); + color += tap * weight; + totalWeight += weight; + } + + fragColor = vec4(color / totalWeight, 1.0); +} diff --git a/Game.Assets/sdn/shaders/g_colourmodify_gl460.fs b/Game.Assets/sdn/shaders/g_colourmodify_gl460.fs new file mode 100644 index 00000000..81c51807 --- /dev/null +++ b/Game.Assets/sdn/shaders/g_colourmodify_gl460.fs @@ -0,0 +1,51 @@ +#version 460 + +layout(location = 0) in vec2 vs_TexCoord; + +layout(std140, binding = 6) uniform source_ps_constants { + vec4 ps_const[256]; +}; + +out vec4 fragColor; + +layout(binding = 0) uniform sampler2D FullScreen; + +#define LevelR ps_const[0].x +#define LevelG ps_const[1].x +#define LevelB ps_const[2].x +#define Brightness ps_const[3].x +#define Contrast ps_const[4].x +#define Colour ps_const[5].x +#define LevelRmp ps_const[6].x +#define LevelGmp ps_const[7].x +#define LevelBmp ps_const[8].x +#define InvertCol ps_const[9].x + +void main() +{ + vec4 color = texture(FullScreen, vs_TexCoord); + vec3 level = color.xyz + vec3(LevelR, LevelG, LevelB); + + float red = level.g - level.r >= 0.0 ? 0.0 : level.r - level.g; + float green = level.r - level.g >= 0.0 ? 0.0 : level.g - level.r; + float blue = level.r - level.b >= 0.0 ? 0.0 : level.b - level.r; + + if (level.b - level.r < 0.0) + red += level.r - level.b; + if (level.b - level.g < 0.0) + green += level.g - level.b; + if (level.g - level.b < 0.0) + blue += level.b - level.g; + + float grey = (level.r + level.g + level.b) * 0.333333343 * (1.0 - Colour); + + color.xyz = level * Colour + grey; + color.xyz += vec3(red * red * LevelRmp, green * green * LevelGmp, blue * blue * LevelBmp); + color.xyz += Brightness; + color.xyz *= Contrast; + + if (-InvertCol < 0.0) + color = InvertCol * (color * -2.0 + 1.0) + color; + + fragColor = color; +} diff --git a/Game.Assets/sdn/shaders/g_downsample_gl460.fs b/Game.Assets/sdn/shaders/g_downsample_gl460.fs new file mode 100644 index 00000000..794d7dbb --- /dev/null +++ b/Game.Assets/sdn/shaders/g_downsample_gl460.fs @@ -0,0 +1,33 @@ +#version 460 + +layout(location = 0) in vec2 vs_TexCoord; + +layout(std140, binding = 6) uniform source_ps_constants { + vec4 ps_const[256]; +}; + +out vec4 fragColor; + +layout(binding = 0) uniform sampler2D BaseTextureSampler; + +#define g_darken ps_const[0].x +#define g_multiply ps_const[1].x +#define g_sizex ps_const[2].x +#define g_sizey ps_const[3].x + +void main() +{ + vec3 color = texture(BaseTextureSampler, vs_TexCoord).xyz * 2.0; + color += texture(BaseTextureSampler, vs_TexCoord + vec2(g_sizex, -g_sizey)).xyz; + color += texture(BaseTextureSampler, vs_TexCoord + vec2(g_sizex, g_sizey)).xyz; + color += texture(BaseTextureSampler, vs_TexCoord + vec2(-g_sizex, -g_sizey)).xyz; + color += texture(BaseTextureSampler, vs_TexCoord + vec2(-g_sizex, g_sizey)).xyz; + color += texture(BaseTextureSampler, vs_TexCoord + vec2(0.0, -g_sizey)).xyz; + color += texture(BaseTextureSampler, vs_TexCoord + vec2(0.0, g_sizey)).xyz; + color += texture(BaseTextureSampler, vs_TexCoord + vec2(g_sizex, 0.0)).xyz; + color += texture(BaseTextureSampler, vs_TexCoord + vec2(-g_sizex, 0.0)).xyz; + + color = max(color * 0.100000001 - g_darken, 0.0) * g_multiply; + + fragColor = vec4(color, 1.0); +} diff --git a/Game.Assets/sdn/shaders/g_premultiplied_gl460.fs b/Game.Assets/sdn/shaders/g_premultiplied_gl460.fs new file mode 100644 index 00000000..b3e9bfd2 --- /dev/null +++ b/Game.Assets/sdn/shaders/g_premultiplied_gl460.fs @@ -0,0 +1,12 @@ +#version 460 + +layout(location = 0) in vec2 vs_TexCoord; + +out vec4 fragColor; + +layout(binding = 0) uniform sampler2D RT; + +void main() +{ + fragColor = texture(RT, vs_TexCoord); +} diff --git a/Game.Assets/sdn/shaders/g_refract_gl460.fs b/Game.Assets/sdn/shaders/g_refract_gl460.fs new file mode 100644 index 00000000..a27d835b --- /dev/null +++ b/Game.Assets/sdn/shaders/g_refract_gl460.fs @@ -0,0 +1,27 @@ +#version 460 + +layout(location = 0) in vec2 vs_TexCoord; + +layout(std140, binding = 6) uniform source_ps_constants { + vec4 ps_const[256]; +}; + +out vec4 fragColor; + +layout(binding = 0) uniform sampler2D NormBuf; +layout(binding = 1) uniform sampler2D BackBuf; + +#define RefractAmount ps_const[0].x + +void main() +{ + vec2 normal = texture(NormBuf, vs_TexCoord).xy * 2.0; + normal += texture(NormBuf, vs_TexCoord + 0.00100000005).xy; + normal += texture(NormBuf, vs_TexCoord - 0.00100000005).xy; + normal += texture(NormBuf, vs_TexCoord + vec2(0.00100000005, -0.00100000005)).xy; + normal += texture(NormBuf, vs_TexCoord + vec2(-0.00100000005, 0.00100000005)).xy; + + normal = normal * 0.166666672 - 0.501960814; + + fragColor = texture(BackBuf, vs_TexCoord + normal * (RefractAmount * 0.25)); +} diff --git a/Game.Assets/sdn/shaders/g_screenquad_gl460.vs b/Game.Assets/sdn/shaders/g_screenquad_gl460.vs new file mode 100644 index 00000000..74d6f696 --- /dev/null +++ b/Game.Assets/sdn/shaders/g_screenquad_gl460.vs @@ -0,0 +1,21 @@ +#version 460 + +layout(location = 0) in vec3 v_Position; +layout(location = 10) in vec2 v_TexCoord; + +layout(std140, binding = 0) uniform source_matrices { + mat4 viewMatrix; + mat4 projectionMatrix; + mat4 modelMatrix; +}; + +layout(location = 0) out vec2 vs_TexCoord; + +#include "common_clipplanes_gl460.vs" + +void main() +{ + gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(v_Position, 1.0); + WriteUserClipDistances(gl_Position); + vs_TexCoord = vec2(v_TexCoord.x, 1.0 - v_TexCoord.y); +} diff --git a/Game.Assets/sdn/shaders/g_sharpen_gl460.fs b/Game.Assets/sdn/shaders/g_sharpen_gl460.fs new file mode 100644 index 00000000..7ff094a9 --- /dev/null +++ b/Game.Assets/sdn/shaders/g_sharpen_gl460.fs @@ -0,0 +1,23 @@ +#version 460 + +layout(location = 0) in vec2 vs_TexCoord; + +layout(std140, binding = 6) uniform source_ps_constants { + vec4 ps_const[256]; +}; + +out vec4 fragColor; + +layout(binding = 0) uniform sampler2D FullScreen; + +#define Contrast ps_const[0].x +#define Distance ps_const[1].x + +void main() +{ + vec4 color = texture(FullScreen, vs_TexCoord); + color += texture(FullScreen, vs_TexCoord + Distance) * Contrast; + color -= texture(FullScreen, vs_TexCoord - Distance) * Contrast; + + fragColor = color; +} diff --git a/Game.Assets/sdn/shaders/g_sobel_gl460.fs b/Game.Assets/sdn/shaders/g_sobel_gl460.fs new file mode 100644 index 00000000..9180d161 --- /dev/null +++ b/Game.Assets/sdn/shaders/g_sobel_gl460.fs @@ -0,0 +1,40 @@ +#version 460 + +layout(location = 0) in vec2 vs_TexCoord; + +layout(std140, binding = 6) uniform source_ps_constants { + vec4 ps_const[256]; +}; + +out vec4 fragColor; + +layout(binding = 0) uniform sampler2D ScreenSampler; + +#define Threshold ps_const[2].x + +const float texel = 0.00156250002; +const vec3 lumWeights = vec3(0.300000012, 0.589999974, 0.109999999); + +float Luminance(vec2 offset) +{ + return dot(texture(ScreenSampler, vs_TexCoord + offset).xyz, lumWeights); +} + +void main() +{ + float bottom = Luminance(vec2(0.0, -texel)); + float bottomLeft = Luminance(vec2(-texel, -texel)); + float bottomRight = Luminance(vec2(texel, -texel)); + float topLeft = Luminance(vec2(-texel, texel)); + float top = Luminance(vec2(0.0, texel)); + float topRight = Luminance(vec2(texel, texel)); + float right = Luminance(vec2(texel, 0.00139999995)); + float left = Luminance(vec2(-texel, 0.0)); + + float edgeX = bottom * 2.0 + bottomLeft + bottomRight - topLeft - top * 2.0 - topRight; + float edgeY = bottomRight + topRight + right * 2.0 - topLeft - left * 2.0 - bottomLeft; + + float edge = edgeY * edgeY + edgeX * edgeX - Threshold >= 0.0 ? 0.0 : 1.0; + + fragColor = texture(ScreenSampler, vs_TexCoord) * edge; +} diff --git a/Game.Assets/sdn/shaders/g_sobel_gl460.vs b/Game.Assets/sdn/shaders/g_sobel_gl460.vs new file mode 100644 index 00000000..06206fbc --- /dev/null +++ b/Game.Assets/sdn/shaders/g_sobel_gl460.vs @@ -0,0 +1,21 @@ +#version 460 + +layout(location = 0) in vec3 v_Position; +layout(location = 10) in vec2 v_TexCoord; + +layout(std140, binding = 0) uniform source_matrices { + mat4 viewMatrix; + mat4 projectionMatrix; + mat4 modelMatrix; +}; + +layout(location = 0) out vec2 vs_TexCoord; + +#include "common_clipplanes_gl460.vs" + +void main() +{ + gl_Position = projectionMatrix * viewMatrix * vec4(v_Position, 1.0); + WriteUserClipDistances(gl_Position); + vs_TexCoord = vec2(v_TexCoord.x, 1.0 - v_TexCoord.y); +} diff --git a/Game.Assets/sdn/shaders/g_sunbeams_gl460.fs b/Game.Assets/sdn/shaders/g_sunbeams_gl460.fs new file mode 100644 index 00000000..2385442e --- /dev/null +++ b/Game.Assets/sdn/shaders/g_sunbeams_gl460.fs @@ -0,0 +1,35 @@ +#version 460 + +layout(location = 0) in vec2 vs_TexCoord; + +layout(std140, binding = 6) uniform source_ps_constants { + vec4 ps_const[256]; +}; + +out vec4 fragColor; + +layout(binding = 0) uniform sampler2D FullScreen; + +#define Darken ps_const[0].x +#define Multiply ps_const[1].x +#define SunSize_C ps_const[2].x +#define SunX ps_const[3].x +#define SunY ps_const[4].x + +void main() +{ + vec4 color = texture(FullScreen, vs_TexCoord); + vec2 sun = vec2(SunX, SunY); + + vec2 delta = vs_TexCoord - sun; + float dist = 1.0 / inversesqrt(dot(delta, delta)); + vec2 step = delta * inversesqrt(dot(delta, delta)) * min(SunSize_C, dist); + float fade = 1.0 - dist; + + for (int i = 0; i < 8; i++) { + vec4 tap = texture(FullScreen, sun + step * (float(i) * 0.125)); + color += clamp(tap - Darken, 0.0, 10.0) * fade * Multiply; + } + + fragColor = color; +} diff --git a/Game.Assets/sdn/shaders/g_texturize_gl460.fs b/Game.Assets/sdn/shaders/g_texturize_gl460.fs new file mode 100644 index 00000000..4cded794 --- /dev/null +++ b/Game.Assets/sdn/shaders/g_texturize_gl460.fs @@ -0,0 +1,34 @@ +#version 460 + +layout(location = 0) in vec2 vs_TexCoord; + +layout(std140, binding = 6) uniform source_ps_constants { + vec4 ps_const[256]; +}; + +out vec4 fragColor; + +layout(binding = 0) uniform sampler2D FullScreen; +layout(binding = 1) uniform sampler2D SourceTexture; + +#define scalex ps_const[0].x +#define scaley ps_const[1].x + +float SignedFrac(float sign, float value) +{ + return sign >= 0.0 ? fract(abs(value)) : -fract(abs(value)); +} + +void main() +{ + vec3 color = texture(FullScreen, vs_TexCoord).xyz; + float brightness = (color.r + color.g + color.b) * 2.66666675; + float band = min(floor(brightness) * 0.125, 0.875); + + float y = vs_TexCoord.y * scaley; + float x = vs_TexCoord.x * scalex; + + vec2 uv = vec2(SignedFrac(x, x), SignedFrac(y, y * 8.0) * 0.125 + band); + + fragColor = vec4(texture(SourceTexture, uv).xyz, 1.0); +} diff --git a/Source.StdShader.Gl46/Sobel.cs b/Source.StdShader.Gl46/Sobel.cs new file mode 100644 index 00000000..17e9ecdb --- /dev/null +++ b/Source.StdShader.Gl46/Sobel.cs @@ -0,0 +1,116 @@ +#if GMOD_DLL +using Source.Common.MaterialSystem; +using Source.Common.ShaderAPI; +using Source.Common.ShaderLib; + +namespace Source.StdShader.Gl46; + +public class Sobel : BaseVSShader +{ + public static string HelpString = "Help for Sobel"; + public static ShaderFlags Flags = ShaderFlags.None; + public static List ShaderParams = []; + public static ShaderParam[] ShaderParamOverrides = new ShaderParam[(int)ShaderMaterialVars.Count]; + + public class ShaderParam + { + public readonly ShaderParamInfo Info; + public readonly int Index; + public ShaderParam(ShaderMaterialVars var, ShaderParamType type, ReadOnlySpan defaultParam, ReadOnlySpan help, ShaderParamFlags flags) { + Info.Name = "override"; + Info.Type = type; + Info.DefaultValue = new(defaultParam); + Info.Help = new(help); + Info.Flags = flags; + + if (ShaderParamOverrides[(int)var] == null) { + + } + else { + AssertMsg(false, "ShaderParamOverrides at var index had null value"); + } + + ShaderParamOverrides[(int)var] = this; + Index = (int)var; + } + public ShaderParam(string name, ShaderParamType type, ReadOnlySpan defaultParam, ReadOnlySpan help, ShaderParamFlags flags = 0) { + Info.Name = name; + Info.Type = type; + Info.DefaultValue = new(defaultParam); + Info.Help = new(help); + Info.Flags = flags; + Index = (int)ShaderMaterialVars.Count + ShaderParams.Count; + ShaderParams.Add(this); + } + public static implicit operator int(ShaderParam param) => param.Index; + public ReadOnlySpan GetName() => Info.Name; + public ShaderParamType GetType() => Info.Type; + public ReadOnlySpan GetDefaultValue() => Info.DefaultValue; + public ShaderParamFlags GetFlags() => Info.Flags; + public ReadOnlySpan GetHelp() => Info.Help; + } + + public static readonly ShaderParam FBTEXTURE = new($"${nameof(FBTEXTURE)}", ShaderParamType.Texture, "_rt_FullFrameFB", ""); + public static readonly ShaderParam THRESHOLD = new($"${nameof(THRESHOLD)}", ShaderParamType.Float, "0.11", ""); + + public override string? GetFallbackShader(IMaterialVar[] vars) => null; + public override ShaderFlags GetFlags() => Flags; + public override int GetNumParams() => base.GetNumParams() + ShaderParams.Count; + public override ReadOnlySpan GetParamName(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamName(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetName(); + } + public override ReadOnlySpan GetParamHelp(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamHelp(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetHelp(); + } + public override ShaderParamType GetParamType(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamType(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetType(); + } + public override ReadOnlySpan GetParamDefault(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamDefault(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetDefaultValue(); + } + + protected override void OnInitShaderParams(IMaterialVar[] vars, ReadOnlySpan materialName) { + if (!vars[THRESHOLD].IsDefined()) + vars[THRESHOLD].SetFloatValue(0.11f); + } + + protected override void OnInitShaderInstance(IMaterialVar[] vars, ReadOnlySpan materialName) { + if (vars[FBTEXTURE].IsDefined()) + LoadTexture(FBTEXTURE); + } + + protected override void OnDrawElements(IMaterialVar[] vars, IShaderDynamicAPI shaderAPI, VertexCompressionType vertexCompression) { + if (IsSnapshotting()) { + ShaderShadow.EnableDepthWrites(false); + ShaderShadow.EnableTexture(Sampler.Sampler0, true); + ShaderShadow.VertexShaderVertexFormat(VertexFormat.Position, 1, null, 0); + ShaderShadow.SetVertexShader("g_sobel", 0); + ShaderShadow.SetPixelShader("g_sobel", 0); + } + else { + shaderAPI.SetPixelShaderConstant(2, [vars[THRESHOLD].GetFloatValue(), 0, 0, 0], 1, true); + + BindTexture(Sampler.Sampler0, FBTEXTURE, -1); + shaderAPI.SetVertexShaderIndex(0); + shaderAPI.SetPixelShaderIndex(0); + } + Draw(); + } +} +#endif diff --git a/Source.StdShader.Gl46/g_bloom.cs b/Source.StdShader.Gl46/g_bloom.cs new file mode 100644 index 00000000..86bc93b7 --- /dev/null +++ b/Source.StdShader.Gl46/g_bloom.cs @@ -0,0 +1,121 @@ +#if GMOD_DLL +using Source.Common.MaterialSystem; +using Source.Common.ShaderAPI; +using Source.Common.ShaderLib; + +namespace Source.StdShader.Gl46; + +public class g_bloom : BaseVSShader +{ + public static string HelpString = "Help for g_bloom"; + public static ShaderFlags Flags = ShaderFlags.None; + public static List ShaderParams = []; + public static ShaderParam[] ShaderParamOverrides = new ShaderParam[(int)ShaderMaterialVars.Count]; + + public class ShaderParam + { + public readonly ShaderParamInfo Info; + public readonly int Index; + public ShaderParam(ShaderMaterialVars var, ShaderParamType type, ReadOnlySpan defaultParam, ReadOnlySpan help, ShaderParamFlags flags) { + Info.Name = "override"; + Info.Type = type; + Info.DefaultValue = new(defaultParam); + Info.Help = new(help); + Info.Flags = flags; + + if (ShaderParamOverrides[(int)var] == null) { + + } + else { + AssertMsg(false, "ShaderParamOverrides at var index had null value"); + } + + ShaderParamOverrides[(int)var] = this; + Index = (int)var; + } + public ShaderParam(string name, ShaderParamType type, ReadOnlySpan defaultParam, ReadOnlySpan help, ShaderParamFlags flags = 0) { + Info.Name = name; + Info.Type = type; + Info.DefaultValue = new(defaultParam); + Info.Help = new(help); + Info.Flags = flags; + Index = (int)ShaderMaterialVars.Count + ShaderParams.Count; + ShaderParams.Add(this); + } + public static implicit operator int(ShaderParam param) => param.Index; + public ReadOnlySpan GetName() => Info.Name; + public ShaderParamType GetType() => Info.Type; + public ReadOnlySpan GetDefaultValue() => Info.DefaultValue; + public ShaderParamFlags GetFlags() => Info.Flags; + public ReadOnlySpan GetHelp() => Info.Help; + } + + public static readonly ShaderParam LEVELR = new($"${nameof(LEVELR)}", ShaderParamType.Float, "0.5", "Red Level"); + public static readonly ShaderParam LEVELG = new($"${nameof(LEVELG)}", ShaderParamType.Float, "0.5", "Green Level"); + public static readonly ShaderParam LEVELB = new($"${nameof(LEVELB)}", ShaderParamType.Float, "0.5", "Blue Level"); + public static readonly ShaderParam COLORMUL = new($"${nameof(COLORMUL)}", ShaderParamType.Float, "1.0", "Color Multiplier"); + + public override string? GetFallbackShader(IMaterialVar[] vars) { + if (HardwareConfig.GetDXSupportLevel() < 90) + return "Wireframe"; + return null; + } + public override ShaderFlags GetFlags() => Flags; + public override int GetNumParams() => base.GetNumParams() + ShaderParams.Count; + public override ReadOnlySpan GetParamName(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamName(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetName(); + } + public override ReadOnlySpan GetParamHelp(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamHelp(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetHelp(); + } + public override ShaderParamType GetParamType(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamType(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetType(); + } + public override ReadOnlySpan GetParamDefault(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamDefault(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetDefaultValue(); + } + + protected override void OnInitShaderInstance(IMaterialVar[] vars, ReadOnlySpan materialName) { + LoadTexture((int)ShaderMaterialVars.BaseTexture); + } + + protected override void OnDrawElements(IMaterialVar[] vars, IShaderDynamicAPI shaderAPI, VertexCompressionType vertexCompression) { + if (IsSnapshotting()) { + ShaderShadow.EnableDepthWrites(false); + ShaderShadow.EnableTexture(Sampler.Sampler0, true); + ShaderShadow.VertexShaderVertexFormat(VertexFormat.Position, 1, null, 0); + ShaderShadow.SetVertexShader("g_screenquad", 0); + ShaderShadow.SetPixelShader("g_bloom", 0); + ShaderShadow.EnableBlending(true); + ShaderShadow.BlendFunc(ShaderBlendFactor.One, ShaderBlendFactor.One); + DefaultFog(); + } + else { + shaderAPI.SetPixelShaderConstant(0, [vars[LEVELR].GetFloatValue(), 0, 0, 0], 1); + shaderAPI.SetPixelShaderConstant(1, [vars[LEVELG].GetFloatValue(), 0, 0, 0], 1); + shaderAPI.SetPixelShaderConstant(2, [vars[LEVELB].GetFloatValue(), 0, 0, 0], 1); + shaderAPI.SetPixelShaderConstant(3, [vars[COLORMUL].GetFloatValue(), 0, 0, 0], 1); + + BindTexture(Sampler.Sampler0, (int)ShaderMaterialVars.BaseTexture, -1); + shaderAPI.SetVertexShaderIndex(0); + } + Draw(); + } +} +#endif diff --git a/Source.StdShader.Gl46/g_blurx.cs b/Source.StdShader.Gl46/g_blurx.cs new file mode 100644 index 00000000..a739bf81 --- /dev/null +++ b/Source.StdShader.Gl46/g_blurx.cs @@ -0,0 +1,110 @@ +#if GMOD_DLL +using Source.Common.MaterialSystem; +using Source.Common.ShaderAPI; +using Source.Common.ShaderLib; + +namespace Source.StdShader.Gl46; + +public class g_blurx : BaseVSShader +{ + public static string HelpString = "Help for g_blurx"; + public static ShaderFlags Flags = ShaderFlags.None; + public static List ShaderParams = []; + public static ShaderParam[] ShaderParamOverrides = new ShaderParam[(int)ShaderMaterialVars.Count]; + + public class ShaderParam + { + public readonly ShaderParamInfo Info; + public readonly int Index; + public ShaderParam(ShaderMaterialVars var, ShaderParamType type, ReadOnlySpan defaultParam, ReadOnlySpan help, ShaderParamFlags flags) { + Info.Name = "override"; + Info.Type = type; + Info.DefaultValue = new(defaultParam); + Info.Help = new(help); + Info.Flags = flags; + + if (ShaderParamOverrides[(int)var] == null) { + + } + else { + AssertMsg(false, "ShaderParamOverrides at var index had null value"); + } + + ShaderParamOverrides[(int)var] = this; + Index = (int)var; + } + public ShaderParam(string name, ShaderParamType type, ReadOnlySpan defaultParam, ReadOnlySpan help, ShaderParamFlags flags = 0) { + Info.Name = name; + Info.Type = type; + Info.DefaultValue = new(defaultParam); + Info.Help = new(help); + Info.Flags = flags; + Index = (int)ShaderMaterialVars.Count + ShaderParams.Count; + ShaderParams.Add(this); + } + public static implicit operator int(ShaderParam param) => param.Index; + public ReadOnlySpan GetName() => Info.Name; + public ShaderParamType GetType() => Info.Type; + public ReadOnlySpan GetDefaultValue() => Info.DefaultValue; + public ShaderParamFlags GetFlags() => Info.Flags; + public ReadOnlySpan GetHelp() => Info.Help; + } + + public static readonly ShaderParam SIZE = new($"${nameof(SIZE)}", ShaderParamType.Float, "4.0", "Blur Size"); + + public override string? GetFallbackShader(IMaterialVar[] vars) => null; + public override ShaderFlags GetFlags() => Flags; + public override int GetNumParams() => base.GetNumParams() + ShaderParams.Count; + public override ReadOnlySpan GetParamName(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamName(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetName(); + } + public override ReadOnlySpan GetParamHelp(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamHelp(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetHelp(); + } + public override ShaderParamType GetParamType(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamType(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetType(); + } + public override ReadOnlySpan GetParamDefault(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamDefault(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetDefaultValue(); + } + + protected override void OnInitShaderInstance(IMaterialVar[] vars, ReadOnlySpan materialName) { + LoadTexture((int)ShaderMaterialVars.BaseTexture); + } + + protected override void OnDrawElements(IMaterialVar[] vars, IShaderDynamicAPI shaderAPI, VertexCompressionType vertexCompression) { + if (IsSnapshotting()) { + ShaderShadow.EnableTexture(Sampler.Sampler0, true); + ShaderShadow.EnableDepthWrites(false); + ShaderShadow.VertexShaderVertexFormat(VertexFormat.Position, 1, null, 0); + ShaderShadow.SetVertexShader("g_screenquad", 0); + ShaderShadow.SetPixelShader("g_blurx", 0); + DefaultFog(); + } + else { + shaderAPI.GetBackBufferDimensions(out int width, out _); + shaderAPI.SetPixelShaderConstant(0, [vars[SIZE].GetFloatValue() / width, 0, 0, 0], 1); + + BindTexture(Sampler.Sampler0, (int)ShaderMaterialVars.BaseTexture, -1); + shaderAPI.SetVertexShaderIndex(0); + } + Draw(); + } +} +#endif diff --git a/Source.StdShader.Gl46/g_blury.cs b/Source.StdShader.Gl46/g_blury.cs new file mode 100644 index 00000000..9756b85c --- /dev/null +++ b/Source.StdShader.Gl46/g_blury.cs @@ -0,0 +1,110 @@ +#if GMOD_DLL +using Source.Common.MaterialSystem; +using Source.Common.ShaderAPI; +using Source.Common.ShaderLib; + +namespace Source.StdShader.Gl46; + +public class g_blury : BaseVSShader +{ + public static string HelpString = "Help for g_blury"; + public static ShaderFlags Flags = ShaderFlags.None; + public static List ShaderParams = []; + public static ShaderParam[] ShaderParamOverrides = new ShaderParam[(int)ShaderMaterialVars.Count]; + + public class ShaderParam + { + public readonly ShaderParamInfo Info; + public readonly int Index; + public ShaderParam(ShaderMaterialVars var, ShaderParamType type, ReadOnlySpan defaultParam, ReadOnlySpan help, ShaderParamFlags flags) { + Info.Name = "override"; + Info.Type = type; + Info.DefaultValue = new(defaultParam); + Info.Help = new(help); + Info.Flags = flags; + + if (ShaderParamOverrides[(int)var] == null) { + + } + else { + AssertMsg(false, "ShaderParamOverrides at var index had null value"); + } + + ShaderParamOverrides[(int)var] = this; + Index = (int)var; + } + public ShaderParam(string name, ShaderParamType type, ReadOnlySpan defaultParam, ReadOnlySpan help, ShaderParamFlags flags = 0) { + Info.Name = name; + Info.Type = type; + Info.DefaultValue = new(defaultParam); + Info.Help = new(help); + Info.Flags = flags; + Index = (int)ShaderMaterialVars.Count + ShaderParams.Count; + ShaderParams.Add(this); + } + public static implicit operator int(ShaderParam param) => param.Index; + public ReadOnlySpan GetName() => Info.Name; + public ShaderParamType GetType() => Info.Type; + public ReadOnlySpan GetDefaultValue() => Info.DefaultValue; + public ShaderParamFlags GetFlags() => Info.Flags; + public ReadOnlySpan GetHelp() => Info.Help; + } + + public static readonly ShaderParam SIZE = new($"${nameof(SIZE)}", ShaderParamType.Float, "4.0", "Blur Size"); + + public override string? GetFallbackShader(IMaterialVar[] vars) => null; + public override ShaderFlags GetFlags() => Flags; + public override int GetNumParams() => base.GetNumParams() + ShaderParams.Count; + public override ReadOnlySpan GetParamName(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamName(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetName(); + } + public override ReadOnlySpan GetParamHelp(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamHelp(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetHelp(); + } + public override ShaderParamType GetParamType(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamType(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetType(); + } + public override ReadOnlySpan GetParamDefault(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamDefault(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetDefaultValue(); + } + + protected override void OnInitShaderInstance(IMaterialVar[] vars, ReadOnlySpan materialName) { + LoadTexture((int)ShaderMaterialVars.BaseTexture); + } + + protected override void OnDrawElements(IMaterialVar[] vars, IShaderDynamicAPI shaderAPI, VertexCompressionType vertexCompression) { + if (IsSnapshotting()) { + ShaderShadow.EnableTexture(Sampler.Sampler0, true); + ShaderShadow.EnableDepthWrites(false); + ShaderShadow.VertexShaderVertexFormat(VertexFormat.Position, 1, null, 0); + ShaderShadow.SetVertexShader("g_screenquad", 0); + ShaderShadow.SetPixelShader("g_blury", 0); + DefaultFog(); + } + else { + shaderAPI.GetBackBufferDimensions(out _, out int height); + shaderAPI.SetPixelShaderConstant(0, [vars[SIZE].GetFloatValue() / height, 0, 0, 0], 1); + + BindTexture(Sampler.Sampler0, (int)ShaderMaterialVars.BaseTexture, -1); + shaderAPI.SetVertexShaderIndex(0); + } + Draw(); + } +} +#endif diff --git a/Source.StdShader.Gl46/g_bokehblur.cs b/Source.StdShader.Gl46/g_bokehblur.cs new file mode 100644 index 00000000..395e0297 --- /dev/null +++ b/Source.StdShader.Gl46/g_bokehblur.cs @@ -0,0 +1,114 @@ +#if GMOD_DLL +using Source.Common.MaterialSystem; +using Source.Common.ShaderAPI; +using Source.Common.ShaderLib; + +namespace Source.StdShader.Gl46; + +public class g_bokehblur : BaseVSShader +{ + public static string HelpString = "Help for g_bokehblur"; + public static ShaderFlags Flags = ShaderFlags.None; + public static List ShaderParams = []; + public static ShaderParam[] ShaderParamOverrides = new ShaderParam[(int)ShaderMaterialVars.Count]; + + public class ShaderParam + { + public readonly ShaderParamInfo Info; + public readonly int Index; + public ShaderParam(ShaderMaterialVars var, ShaderParamType type, ReadOnlySpan defaultParam, ReadOnlySpan help, ShaderParamFlags flags) { + Info.Name = "override"; + Info.Type = type; + Info.DefaultValue = new(defaultParam); + Info.Help = new(help); + Info.Flags = flags; + + if (ShaderParamOverrides[(int)var] == null) { + + } + else { + AssertMsg(false, "ShaderParamOverrides at var index had null value"); + } + + ShaderParamOverrides[(int)var] = this; + Index = (int)var; + } + public ShaderParam(string name, ShaderParamType type, ReadOnlySpan defaultParam, ReadOnlySpan help, ShaderParamFlags flags = 0) { + Info.Name = name; + Info.Type = type; + Info.DefaultValue = new(defaultParam); + Info.Help = new(help); + Info.Flags = flags; + Index = (int)ShaderMaterialVars.Count + ShaderParams.Count; + ShaderParams.Add(this); + } + public static implicit operator int(ShaderParam param) => param.Index; + public ReadOnlySpan GetName() => Info.Name; + public ShaderParamType GetType() => Info.Type; + public ReadOnlySpan GetDefaultValue() => Info.DefaultValue; + public ShaderParamFlags GetFlags() => Info.Flags; + public ReadOnlySpan GetHelp() => Info.Help; + } + + public static readonly ShaderParam DEPTHTEXTURE = new($"${nameof(DEPTHTEXTURE)}", ShaderParamType.Texture, "_rt_FullFrameFB", ""); + public static readonly ShaderParam SIZE = new($"${nameof(SIZE)}", ShaderParamType.Float, "7.0", "Blur Size"); + public static readonly ShaderParam FOCUS = new($"${nameof(FOCUS)}", ShaderParamType.Float, "0.1", "Blur Size"); + public static readonly ShaderParam FOCUSRADIUS = new($"${nameof(FOCUSRADIUS)}", ShaderParamType.Float, "1.0", "Blur Size"); + + public override string? GetFallbackShader(IMaterialVar[] vars) => null; + public override ShaderFlags GetFlags() => Flags; + public override int GetNumParams() => base.GetNumParams() + ShaderParams.Count; + public override ReadOnlySpan GetParamName(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamName(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetName(); + } + public override ReadOnlySpan GetParamHelp(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamHelp(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetHelp(); + } + public override ShaderParamType GetParamType(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamType(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetType(); + } + public override ReadOnlySpan GetParamDefault(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamDefault(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetDefaultValue(); + } + + protected override void OnDrawElements(IMaterialVar[] vars, IShaderDynamicAPI shaderAPI, VertexCompressionType vertexCompression) { + if (IsSnapshotting()) { + ShaderShadow.EnableTexture(Sampler.Sampler0, true); + ShaderShadow.EnableTexture(Sampler.Sampler1, true); + ShaderShadow.EnableDepthWrites(false); + ShaderShadow.VertexShaderVertexFormat(VertexFormat.Position, 1, null, 0); + ShaderShadow.SetVertexShader("g_screenquad", 0); + ShaderShadow.SetPixelShader("g_bokehblur", 0); + DefaultFog(); + } + else { + shaderAPI.GetBackBufferDimensions(out int width, out int height); + shaderAPI.SetPixelShaderConstant(0, [1.0f / width, 1.0f / height, 0, 0], 1); + shaderAPI.SetPixelShaderConstant(1, [vars[SIZE].GetFloatValue(), 0, 0, 0], 1); + shaderAPI.SetPixelShaderConstant(2, [vars[FOCUS].GetFloatValue(), 0, 0, 0], 1); + shaderAPI.SetPixelShaderConstant(3, [vars[FOCUSRADIUS].GetFloatValue(), 0, 0, 0], 1); + + BindTexture(Sampler.Sampler0, (int)ShaderMaterialVars.BaseTexture, -1); + BindTexture(Sampler.Sampler1, DEPTHTEXTURE, -1); + shaderAPI.SetVertexShaderIndex(0); + } + Draw(); + } +} +#endif diff --git a/Source.StdShader.Gl46/g_colourmodify.cs b/Source.StdShader.Gl46/g_colourmodify.cs new file mode 100644 index 00000000..608267be --- /dev/null +++ b/Source.StdShader.Gl46/g_colourmodify.cs @@ -0,0 +1,130 @@ +#if GMOD_DLL +using Source.Common.MaterialSystem; +using Source.Common.ShaderAPI; +using Source.Common.ShaderLib; + +namespace Source.StdShader.Gl46; + +public class g_colourmodify : BaseVSShader +{ + public static string HelpString = "Help for g_colourmodify"; + public static ShaderFlags Flags = ShaderFlags.None; + public static List ShaderParams = []; + public static ShaderParam[] ShaderParamOverrides = new ShaderParam[(int)ShaderMaterialVars.Count]; + + public class ShaderParam + { + public readonly ShaderParamInfo Info; + public readonly int Index; + public ShaderParam(ShaderMaterialVars var, ShaderParamType type, ReadOnlySpan defaultParam, ReadOnlySpan help, ShaderParamFlags flags) { + Info.Name = "override"; + Info.Type = type; + Info.DefaultValue = new(defaultParam); + Info.Help = new(help); + Info.Flags = flags; + + if (ShaderParamOverrides[(int)var] == null) { + + } + else { + AssertMsg(false, "ShaderParamOverrides at var index had null value"); + } + + ShaderParamOverrides[(int)var] = this; + Index = (int)var; + } + public ShaderParam(string name, ShaderParamType type, ReadOnlySpan defaultParam, ReadOnlySpan help, ShaderParamFlags flags = 0) { + Info.Name = name; + Info.Type = type; + Info.DefaultValue = new(defaultParam); + Info.Help = new(help); + Info.Flags = flags; + Index = (int)ShaderMaterialVars.Count + ShaderParams.Count; + ShaderParams.Add(this); + } + public static implicit operator int(ShaderParam param) => param.Index; + public ReadOnlySpan GetName() => Info.Name; + public ShaderParamType GetType() => Info.Type; + public ReadOnlySpan GetDefaultValue() => Info.DefaultValue; + public ShaderParamFlags GetFlags() => Info.Flags; + public ReadOnlySpan GetHelp() => Info.Help; + } + + public static readonly ShaderParam FBTEXTURE = new($"${nameof(FBTEXTURE)}", ShaderParamType.Texture, "_rt_FullFrameFB", ""); + public static readonly ShaderParam pp_colour_addr = new($"${nameof(pp_colour_addr)}", ShaderParamType.Float, "0.0", "pp_colour_addr"); + public static readonly ShaderParam pp_colour_addg = new($"${nameof(pp_colour_addg)}", ShaderParamType.Float, "0.0", "pp_colour_addg"); + public static readonly ShaderParam pp_colour_addb = new($"${nameof(pp_colour_addb)}", ShaderParamType.Float, "0.0", "pp_colour_addb"); + public static readonly ShaderParam pp_colour_brightness = new($"${nameof(pp_colour_brightness)}", ShaderParamType.Float, "0.0", "pp_colour_brightness"); + public static readonly ShaderParam pp_colour_contrast = new($"${nameof(pp_colour_contrast)}", ShaderParamType.Float, "1", "pp_colour_contrast"); + public static readonly ShaderParam pp_colour_colour = new($"${nameof(pp_colour_colour)}", ShaderParamType.Float, "1", "pp_colour_colour"); + public static readonly ShaderParam pp_colour_mulr = new($"${nameof(pp_colour_mulr)}", ShaderParamType.Float, "0", "pp_colour_mulr"); + public static readonly ShaderParam pp_colour_mulg = new($"${nameof(pp_colour_mulg)}", ShaderParamType.Float, "0", "pp_colour_mulg"); + public static readonly ShaderParam pp_colour_mulb = new($"${nameof(pp_colour_mulb)}", ShaderParamType.Float, "0", "pp_colour_mulb"); + public static readonly ShaderParam pp_colour_inv = new($"${nameof(pp_colour_inv)}", ShaderParamType.Float, "0", "pp_colour_inv"); + + public override string? GetFallbackShader(IMaterialVar[] vars) => null; + public override ShaderFlags GetFlags() => Flags; + public override int GetNumParams() => base.GetNumParams() + ShaderParams.Count; + public override ReadOnlySpan GetParamName(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamName(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetName(); + } + public override ReadOnlySpan GetParamHelp(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamHelp(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetHelp(); + } + public override ShaderParamType GetParamType(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamType(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetType(); + } + public override ReadOnlySpan GetParamDefault(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamDefault(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetDefaultValue(); + } + + protected override void OnInitShaderInstance(IMaterialVar[] vars, ReadOnlySpan materialName) { + LoadTexture(FBTEXTURE); + } + + protected override void OnDrawElements(IMaterialVar[] vars, IShaderDynamicAPI shaderAPI, VertexCompressionType vertexCompression) { + if (IsSnapshotting()) { + ShaderShadow.EnableTexture(Sampler.Sampler0, true); + ShaderShadow.EnableDepthWrites(false); + ShaderShadow.VertexShaderVertexFormat(VertexFormat.Position, 1, null, 0); + ShaderShadow.SetVertexShader("g_screenquad", 0); + ShaderShadow.SetPixelShader("g_colourmodify", 0); + ShaderShadow.EnableSRGBRead(Sampler.Sampler0, false); + ShaderShadow.EnableSRGBWrite(false); + DefaultFog(); + } + else { + shaderAPI.SetPixelShaderConstant(0, [vars[pp_colour_addr].GetFloatValue(), 0, 0, 0], 1); + shaderAPI.SetPixelShaderConstant(1, [vars[pp_colour_addg].GetFloatValue(), 0, 0, 0], 1); + shaderAPI.SetPixelShaderConstant(2, [vars[pp_colour_addb].GetFloatValue(), 0, 0, 0], 1); + shaderAPI.SetPixelShaderConstant(3, [vars[pp_colour_brightness].GetFloatValue(), 0, 0, 0], 1); + shaderAPI.SetPixelShaderConstant(4, [vars[pp_colour_contrast].GetFloatValue(), 0, 0, 0], 1); + shaderAPI.SetPixelShaderConstant(5, [vars[pp_colour_colour].GetFloatValue(), 0, 0, 0], 1); + shaderAPI.SetPixelShaderConstant(6, [vars[pp_colour_mulr].GetFloatValue(), 0, 0, 0], 1); + shaderAPI.SetPixelShaderConstant(7, [vars[pp_colour_mulg].GetFloatValue(), 0, 0, 0], 1); + shaderAPI.SetPixelShaderConstant(8, [vars[pp_colour_mulb].GetFloatValue(), 0, 0, 0], 1); + shaderAPI.SetPixelShaderConstant(9, [vars[pp_colour_inv].GetFloatValue(), 0, 0, 0], 1); + + BindTexture(Sampler.Sampler0, FBTEXTURE, -1); + shaderAPI.SetVertexShaderIndex(0); + } + Draw(); + } +} +#endif diff --git a/Source.StdShader.Gl46/g_downsample.cs b/Source.StdShader.Gl46/g_downsample.cs new file mode 100644 index 00000000..16e5426d --- /dev/null +++ b/Source.StdShader.Gl46/g_downsample.cs @@ -0,0 +1,119 @@ +#if GMOD_DLL +using Source.Common.MaterialSystem; +using Source.Common.ShaderAPI; +using Source.Common.ShaderLib; + +namespace Source.StdShader.Gl46; + +public class g_downsample : BaseVSShader +{ + public static string HelpString = "Help for g_downsample"; + public static ShaderFlags Flags = ShaderFlags.None; + public static List ShaderParams = []; + public static ShaderParam[] ShaderParamOverrides = new ShaderParam[(int)ShaderMaterialVars.Count]; + + public class ShaderParam + { + public readonly ShaderParamInfo Info; + public readonly int Index; + public ShaderParam(ShaderMaterialVars var, ShaderParamType type, ReadOnlySpan defaultParam, ReadOnlySpan help, ShaderParamFlags flags) { + Info.Name = "override"; + Info.Type = type; + Info.DefaultValue = new(defaultParam); + Info.Help = new(help); + Info.Flags = flags; + + if (ShaderParamOverrides[(int)var] == null) { + + } + else { + AssertMsg(false, "ShaderParamOverrides at var index had null value"); + } + + ShaderParamOverrides[(int)var] = this; + Index = (int)var; + } + public ShaderParam(string name, ShaderParamType type, ReadOnlySpan defaultParam, ReadOnlySpan help, ShaderParamFlags flags = 0) { + Info.Name = name; + Info.Type = type; + Info.DefaultValue = new(defaultParam); + Info.Help = new(help); + Info.Flags = flags; + Index = (int)ShaderMaterialVars.Count + ShaderParams.Count; + ShaderParams.Add(this); + } + public static implicit operator int(ShaderParam param) => param.Index; + public ReadOnlySpan GetName() => Info.Name; + public ShaderParamType GetType() => Info.Type; + public ReadOnlySpan GetDefaultValue() => Info.DefaultValue; + public ShaderParamFlags GetFlags() => Info.Flags; + public ReadOnlySpan GetHelp() => Info.Help; + } + + public static readonly ShaderParam FBTEXTURE = new($"${nameof(FBTEXTURE)}", ShaderParamType.Texture, "_rt_FullFrameFB", ""); + public static readonly ShaderParam DARKEN = new($"${nameof(DARKEN)}", ShaderParamType.Float, "0", "Amount to darken"); + public static readonly ShaderParam MULTIPLY = new($"${nameof(MULTIPLY)}", ShaderParamType.Float, "1", "Amount to multiply (to contrast)"); + public static readonly ShaderParam SCALE = new($"${nameof(SCALE)}", ShaderParamType.Float, "1", "Sample Scale"); + + public override string? GetFallbackShader(IMaterialVar[] vars) => null; + public override ShaderFlags GetFlags() => Flags; + public override int GetNumParams() => base.GetNumParams() + ShaderParams.Count; + public override ReadOnlySpan GetParamName(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamName(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetName(); + } + public override ReadOnlySpan GetParamHelp(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamHelp(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetHelp(); + } + public override ShaderParamType GetParamType(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamType(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetType(); + } + public override ReadOnlySpan GetParamDefault(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamDefault(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetDefaultValue(); + } + + protected override void OnInitShaderInstance(IMaterialVar[] vars, ReadOnlySpan materialName) { + LoadTexture(FBTEXTURE); + } + + protected override void OnDrawElements(IMaterialVar[] vars, IShaderDynamicAPI shaderAPI, VertexCompressionType vertexCompression) { + if (IsSnapshotting()) { + ShaderShadow.EnableTexture(Sampler.Sampler0, true); + ShaderShadow.EnableDepthWrites(false); + ShaderShadow.VertexShaderVertexFormat(VertexFormat.Position, 1, null, 0); + ShaderShadow.SetVertexShader("g_screenquad", 0); + ShaderShadow.SetPixelShader("g_downsample", 0); + ShaderShadow.EnableSRGBRead(Sampler.Sampler0, false); + ShaderShadow.EnableSRGBWrite(false); + DefaultFog(); + } + else { + shaderAPI.SetPixelShaderConstant(0, [vars[DARKEN].GetFloatValue(), 0, 0, 0], 1); + shaderAPI.SetPixelShaderConstant(1, [vars[MULTIPLY].GetFloatValue(), 0, 0, 0], 1); + + ITexture texture = vars[FBTEXTURE].GetTextureValue()!; + shaderAPI.SetPixelShaderConstant(2, [vars[SCALE].GetFloatValue() / texture.GetActualWidth(), 0, 0, 0], 1); + shaderAPI.SetPixelShaderConstant(3, [vars[SCALE].GetFloatValue() / texture.GetActualHeight(), 0, 0, 0], 1); + + BindTexture(Sampler.Sampler0, FBTEXTURE, -1); + shaderAPI.SetVertexShaderIndex(0); + } + Draw(); + } +} +#endif diff --git a/Source.StdShader.Gl46/g_premultiplied.cs b/Source.StdShader.Gl46/g_premultiplied.cs new file mode 100644 index 00000000..40c13c49 --- /dev/null +++ b/Source.StdShader.Gl46/g_premultiplied.cs @@ -0,0 +1,40 @@ +#if GMOD_DLL +using Source.Common.MaterialSystem; +using Source.Common.ShaderAPI; +using Source.Common.ShaderLib; + +namespace Source.StdShader.Gl46; + +public class g_premultiplied : BaseVSShader +{ + public static string HelpString = "Help for g_premultiplied"; + public static ShaderFlags Flags = ShaderFlags.None; + + public override string? GetFallbackShader(IMaterialVar[] vars) => null; + public override ShaderFlags GetFlags() => Flags; + + protected override void OnInitShaderInstance(IMaterialVar[] vars, ReadOnlySpan materialName) { + LoadTexture((int)ShaderMaterialVars.BaseTexture); + } + + protected override void OnDrawElements(IMaterialVar[] vars, IShaderDynamicAPI shaderAPI, VertexCompressionType vertexCompression) { + if (IsSnapshotting()) { + ShaderShadow.EnableTexture(Sampler.Sampler0, true); + ShaderShadow.EnableDepthWrites(false); + ShaderShadow.VertexShaderVertexFormat(VertexFormat.Position, 1, null, 0); + ShaderShadow.SetVertexShader("g_screenquad", 0); + ShaderShadow.SetPixelShader("g_premultiplied", 0); + ShaderShadow.EnableBlending(true); + ShaderShadow.BlendFunc(ShaderBlendFactor.One, ShaderBlendFactor.OneMinusSrcAlpha); + ShaderShadow.EnableBlendingSeparateAlpha(true); + ShaderShadow.BlendFuncSeparateAlpha(ShaderBlendFactor.SrcAlpha, ShaderBlendFactor.OneMinusSrcAlpha); + DefaultFog(); + } + else { + BindTexture(Sampler.Sampler0, (int)ShaderMaterialVars.BaseTexture, -1); + shaderAPI.SetVertexShaderIndex(0); + } + Draw(); + } +} +#endif diff --git a/Source.StdShader.Gl46/g_refract.cs b/Source.StdShader.Gl46/g_refract.cs new file mode 100644 index 00000000..7dcbd4d9 --- /dev/null +++ b/Source.StdShader.Gl46/g_refract.cs @@ -0,0 +1,116 @@ +#if GMOD_DLL +using Source.Common.MaterialSystem; +using Source.Common.ShaderAPI; +using Source.Common.ShaderLib; + +namespace Source.StdShader.Gl46; + +public class g_refract : BaseVSShader +{ + public static string HelpString = "Help for g_refract"; + public static ShaderFlags Flags = ShaderFlags.None; + public static List ShaderParams = []; + public static ShaderParam[] ShaderParamOverrides = new ShaderParam[(int)ShaderMaterialVars.Count]; + + public class ShaderParam + { + public readonly ShaderParamInfo Info; + public readonly int Index; + public ShaderParam(ShaderMaterialVars var, ShaderParamType type, ReadOnlySpan defaultParam, ReadOnlySpan help, ShaderParamFlags flags) { + Info.Name = "override"; + Info.Type = type; + Info.DefaultValue = new(defaultParam); + Info.Help = new(help); + Info.Flags = flags; + + if (ShaderParamOverrides[(int)var] == null) { + + } + else { + AssertMsg(false, "ShaderParamOverrides at var index had null value"); + } + + ShaderParamOverrides[(int)var] = this; + Index = (int)var; + } + public ShaderParam(string name, ShaderParamType type, ReadOnlySpan defaultParam, ReadOnlySpan help, ShaderParamFlags flags = 0) { + Info.Name = name; + Info.Type = type; + Info.DefaultValue = new(defaultParam); + Info.Help = new(help); + Info.Flags = flags; + Index = (int)ShaderMaterialVars.Count + ShaderParams.Count; + ShaderParams.Add(this); + } + public static implicit operator int(ShaderParam param) => param.Index; + public ReadOnlySpan GetName() => Info.Name; + public ShaderParamType GetType() => Info.Type; + public ReadOnlySpan GetDefaultValue() => Info.DefaultValue; + public ShaderParamFlags GetFlags() => Info.Flags; + public ReadOnlySpan GetHelp() => Info.Help; + } + + public static readonly ShaderParam FBTEXTURE = new($"${nameof(FBTEXTURE)}", ShaderParamType.Texture, "_rt_FullFrameFB", ""); + public static readonly ShaderParam REFRACTAMOUNT = new($"${nameof(REFRACTAMOUNT)}", ShaderParamType.Float, "0.5", "Refract Amount"); + public static readonly ShaderParam NORMALMAP = new($"${nameof(NORMALMAP)}", ShaderParamType.Texture, "shadertest/WorldDiffuseBumpMap_bump", "Huh texture"); + + public override string? GetFallbackShader(IMaterialVar[] vars) => null; + public override ShaderFlags GetFlags() => Flags; + public override int GetNumParams() => base.GetNumParams() + ShaderParams.Count; + public override ReadOnlySpan GetParamName(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamName(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetName(); + } + public override ReadOnlySpan GetParamHelp(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamHelp(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetHelp(); + } + public override ShaderParamType GetParamType(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamType(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetType(); + } + public override ReadOnlySpan GetParamDefault(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamDefault(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetDefaultValue(); + } + + protected override void OnInitShaderInstance(IMaterialVar[] vars, ReadOnlySpan materialName) { + LoadTexture(NORMALMAP); + LoadTexture(FBTEXTURE); + } + + protected override void OnDrawElements(IMaterialVar[] vars, IShaderDynamicAPI shaderAPI, VertexCompressionType vertexCompression) { + if (IsSnapshotting()) { + ShaderShadow.EnableTexture(Sampler.Sampler0, true); + ShaderShadow.EnableTexture(Sampler.Sampler1, true); + ShaderShadow.EnableDepthWrites(false); + ShaderShadow.VertexShaderVertexFormat(VertexFormat.Position, 1, null, 0); + ShaderShadow.SetVertexShader("g_screenquad", 0); + ShaderShadow.SetPixelShader("g_refract", 0); + ShaderShadow.EnableSRGBRead(Sampler.Sampler0, false); + ShaderShadow.EnableSRGBWrite(false); + DefaultFog(); + } + else { + shaderAPI.SetPixelShaderConstant(0, [vars[REFRACTAMOUNT].GetFloatValue(), 0, 0, 0], 1); + + BindTexture(Sampler.Sampler0, NORMALMAP, -1); + BindTexture(Sampler.Sampler1, FBTEXTURE, -1); + shaderAPI.SetVertexShaderIndex(0); + } + Draw(); + } +} +#endif diff --git a/Source.StdShader.Gl46/g_sharpen.cs b/Source.StdShader.Gl46/g_sharpen.cs new file mode 100644 index 00000000..94f6022c --- /dev/null +++ b/Source.StdShader.Gl46/g_sharpen.cs @@ -0,0 +1,114 @@ +#if GMOD_DLL +using Source.Common.MaterialSystem; +using Source.Common.ShaderAPI; +using Source.Common.ShaderLib; + +namespace Source.StdShader.Gl46; + +public class g_sharpen : BaseVSShader +{ + public static string HelpString = "Help for g_sharpen"; + public static ShaderFlags Flags = ShaderFlags.None; + public static List ShaderParams = []; + public static ShaderParam[] ShaderParamOverrides = new ShaderParam[(int)ShaderMaterialVars.Count]; + + public class ShaderParam + { + public readonly ShaderParamInfo Info; + public readonly int Index; + public ShaderParam(ShaderMaterialVars var, ShaderParamType type, ReadOnlySpan defaultParam, ReadOnlySpan help, ShaderParamFlags flags) { + Info.Name = "override"; + Info.Type = type; + Info.DefaultValue = new(defaultParam); + Info.Help = new(help); + Info.Flags = flags; + + if (ShaderParamOverrides[(int)var] == null) { + + } + else { + AssertMsg(false, "ShaderParamOverrides at var index had null value"); + } + + ShaderParamOverrides[(int)var] = this; + Index = (int)var; + } + public ShaderParam(string name, ShaderParamType type, ReadOnlySpan defaultParam, ReadOnlySpan help, ShaderParamFlags flags = 0) { + Info.Name = name; + Info.Type = type; + Info.DefaultValue = new(defaultParam); + Info.Help = new(help); + Info.Flags = flags; + Index = (int)ShaderMaterialVars.Count + ShaderParams.Count; + ShaderParams.Add(this); + } + public static implicit operator int(ShaderParam param) => param.Index; + public ReadOnlySpan GetName() => Info.Name; + public ShaderParamType GetType() => Info.Type; + public ReadOnlySpan GetDefaultValue() => Info.DefaultValue; + public ShaderParamFlags GetFlags() => Info.Flags; + public ReadOnlySpan GetHelp() => Info.Help; + } + + public static readonly ShaderParam FBTEXTURE = new($"${nameof(FBTEXTURE)}", ShaderParamType.Texture, "_rt_FullFrameFB", ""); + public static readonly ShaderParam contrast = new($"${nameof(contrast)}", ShaderParamType.Float, "1.0", "contrast"); + public static readonly ShaderParam distance = new($"${nameof(distance)}", ShaderParamType.Float, "1.0", "distance"); + + public override string? GetFallbackShader(IMaterialVar[] vars) => null; + public override ShaderFlags GetFlags() => Flags; + public override int GetNumParams() => base.GetNumParams() + ShaderParams.Count; + public override ReadOnlySpan GetParamName(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamName(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetName(); + } + public override ReadOnlySpan GetParamHelp(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamHelp(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetHelp(); + } + public override ShaderParamType GetParamType(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamType(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetType(); + } + public override ReadOnlySpan GetParamDefault(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamDefault(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetDefaultValue(); + } + + protected override void OnInitShaderInstance(IMaterialVar[] vars, ReadOnlySpan materialName) { + LoadTexture(FBTEXTURE); + } + + protected override void OnDrawElements(IMaterialVar[] vars, IShaderDynamicAPI shaderAPI, VertexCompressionType vertexCompression) { + if (IsSnapshotting()) { + ShaderShadow.EnableTexture(Sampler.Sampler0, true); + ShaderShadow.EnableSRGBRead(Sampler.Sampler0, false); + ShaderShadow.EnableSRGBWrite(false); + ShaderShadow.EnableDepthWrites(false); + ShaderShadow.VertexShaderVertexFormat(VertexFormat.Position, 1, null, 0); + ShaderShadow.SetVertexShader("g_screenquad", 0); + ShaderShadow.SetPixelShader("g_sharpen", 0); + DefaultFog(); + } + else { + shaderAPI.SetPixelShaderConstant(0, [vars[contrast].GetFloatValue(), 0, 0, 0], 1); + shaderAPI.SetPixelShaderConstant(1, [vars[distance].GetFloatValue(), 0, 0, 0], 1); + + BindTexture(Sampler.Sampler0, FBTEXTURE, -1); + shaderAPI.SetVertexShaderIndex(0); + } + Draw(); + } +} +#endif diff --git a/Source.StdShader.Gl46/g_sunbeams.cs b/Source.StdShader.Gl46/g_sunbeams.cs new file mode 100644 index 00000000..6e5f52e6 --- /dev/null +++ b/Source.StdShader.Gl46/g_sunbeams.cs @@ -0,0 +1,118 @@ +#if GMOD_DLL +using Source.Common.MaterialSystem; +using Source.Common.ShaderAPI; +using Source.Common.ShaderLib; + +namespace Source.StdShader.Gl46; + +public class g_sunbeams : BaseVSShader +{ + public static string HelpString = "Help for g_sunbeams"; + public static ShaderFlags Flags = ShaderFlags.None; + public static List ShaderParams = []; + public static ShaderParam[] ShaderParamOverrides = new ShaderParam[(int)ShaderMaterialVars.Count]; + + public class ShaderParam + { + public readonly ShaderParamInfo Info; + public readonly int Index; + public ShaderParam(ShaderMaterialVars var, ShaderParamType type, ReadOnlySpan defaultParam, ReadOnlySpan help, ShaderParamFlags flags) { + Info.Name = "override"; + Info.Type = type; + Info.DefaultValue = new(defaultParam); + Info.Help = new(help); + Info.Flags = flags; + + if (ShaderParamOverrides[(int)var] == null) { + + } + else { + AssertMsg(false, "ShaderParamOverrides at var index had null value"); + } + + ShaderParamOverrides[(int)var] = this; + Index = (int)var; + } + public ShaderParam(string name, ShaderParamType type, ReadOnlySpan defaultParam, ReadOnlySpan help, ShaderParamFlags flags = 0) { + Info.Name = name; + Info.Type = type; + Info.DefaultValue = new(defaultParam); + Info.Help = new(help); + Info.Flags = flags; + Index = (int)ShaderMaterialVars.Count + ShaderParams.Count; + ShaderParams.Add(this); + } + public static implicit operator int(ShaderParam param) => param.Index; + public ReadOnlySpan GetName() => Info.Name; + public ShaderParamType GetType() => Info.Type; + public ReadOnlySpan GetDefaultValue() => Info.DefaultValue; + public ShaderParamFlags GetFlags() => Info.Flags; + public ReadOnlySpan GetHelp() => Info.Help; + } + + public static readonly ShaderParam FBTEXTURE = new($"${nameof(FBTEXTURE)}", ShaderParamType.Texture, "_rt_FullFrameFB", ""); + public static readonly ShaderParam darken = new($"${nameof(darken)}", ShaderParamType.Float, "0.9", "darken"); + public static readonly ShaderParam multiply = new($"${nameof(multiply)}", ShaderParamType.Float, "0.6", "multiply"); + public static readonly ShaderParam sunsize = new($"${nameof(sunsize)}", ShaderParamType.Float, "0.06", "sunsize"); + public static readonly ShaderParam sunx = new($"${nameof(sunx)}", ShaderParamType.Float, "0.5", "sunx"); + public static readonly ShaderParam suny = new($"${nameof(suny)}", ShaderParamType.Float, "0.2", "suny"); + + public override string? GetFallbackShader(IMaterialVar[] vars) => null; + public override ShaderFlags GetFlags() => Flags; + public override int GetNumParams() => base.GetNumParams() + ShaderParams.Count; + public override ReadOnlySpan GetParamName(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamName(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetName(); + } + public override ReadOnlySpan GetParamHelp(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamHelp(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetHelp(); + } + public override ShaderParamType GetParamType(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamType(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetType(); + } + public override ReadOnlySpan GetParamDefault(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamDefault(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetDefaultValue(); + } + + protected override void OnInitShaderInstance(IMaterialVar[] vars, ReadOnlySpan materialName) { + LoadTexture(FBTEXTURE); + } + + protected override void OnDrawElements(IMaterialVar[] vars, IShaderDynamicAPI shaderAPI, VertexCompressionType vertexCompression) { + if (IsSnapshotting()) { + ShaderShadow.EnableTexture(Sampler.Sampler0, true); + ShaderShadow.EnableDepthWrites(false); + ShaderShadow.VertexShaderVertexFormat(VertexFormat.Position, 1, null, 0); + ShaderShadow.SetVertexShader("g_screenquad", 0); + ShaderShadow.SetPixelShader("g_sunbeams", 0); + DefaultFog(); + } + else { + shaderAPI.SetPixelShaderConstant(0, [vars[darken].GetFloatValue(), 0, 0, 0], 1); + shaderAPI.SetPixelShaderConstant(1, [vars[multiply].GetFloatValue(), 0, 0, 0], 1); + shaderAPI.SetPixelShaderConstant(2, [vars[sunsize].GetFloatValue(), 0, 0, 0], 1); + shaderAPI.SetPixelShaderConstant(3, [vars[sunx].GetFloatValue(), 0, 0, 0], 1); + shaderAPI.SetPixelShaderConstant(4, [vars[suny].GetFloatValue(), 0, 0, 0], 1); + + BindTexture(Sampler.Sampler0, FBTEXTURE, -1); + shaderAPI.SetVertexShaderIndex(0); + } + Draw(); + } +} +#endif diff --git a/Source.StdShader.Gl46/g_texturize.cs b/Source.StdShader.Gl46/g_texturize.cs new file mode 100644 index 00000000..ca0d87d2 --- /dev/null +++ b/Source.StdShader.Gl46/g_texturize.cs @@ -0,0 +1,117 @@ +#if GMOD_DLL +using Source.Common.MaterialSystem; +using Source.Common.ShaderAPI; +using Source.Common.ShaderLib; + +namespace Source.StdShader.Gl46; + +public class g_texturize : BaseVSShader +{ + public static string HelpString = "Help for g_texturize"; + public static ShaderFlags Flags = ShaderFlags.None; + public static List ShaderParams = []; + public static ShaderParam[] ShaderParamOverrides = new ShaderParam[(int)ShaderMaterialVars.Count]; + + public class ShaderParam + { + public readonly ShaderParamInfo Info; + public readonly int Index; + public ShaderParam(ShaderMaterialVars var, ShaderParamType type, ReadOnlySpan defaultParam, ReadOnlySpan help, ShaderParamFlags flags) { + Info.Name = "override"; + Info.Type = type; + Info.DefaultValue = new(defaultParam); + Info.Help = new(help); + Info.Flags = flags; + + if (ShaderParamOverrides[(int)var] == null) { + + } + else { + AssertMsg(false, "ShaderParamOverrides at var index had null value"); + } + + ShaderParamOverrides[(int)var] = this; + Index = (int)var; + } + public ShaderParam(string name, ShaderParamType type, ReadOnlySpan defaultParam, ReadOnlySpan help, ShaderParamFlags flags = 0) { + Info.Name = name; + Info.Type = type; + Info.DefaultValue = new(defaultParam); + Info.Help = new(help); + Info.Flags = flags; + Index = (int)ShaderMaterialVars.Count + ShaderParams.Count; + ShaderParams.Add(this); + } + public static implicit operator int(ShaderParam param) => param.Index; + public ReadOnlySpan GetName() => Info.Name; + public ShaderParamType GetType() => Info.Type; + public ReadOnlySpan GetDefaultValue() => Info.DefaultValue; + public ShaderParamFlags GetFlags() => Info.Flags; + public ReadOnlySpan GetHelp() => Info.Help; + } + + public static readonly ShaderParam FBTEXTURE = new($"${nameof(FBTEXTURE)}", ShaderParamType.Texture, "_rt_FullFrameFB", ""); + public static readonly ShaderParam BASETEXTURE = new($"${nameof(BASETEXTURE)}", ShaderParamType.Texture, "_rt_FullFrameFB", ""); + public static readonly ShaderParam scalex = new($"${nameof(scalex)}", ShaderParamType.Float, "30", "scalex"); + public static readonly ShaderParam scaley = new($"${nameof(scaley)}", ShaderParamType.Float, "30", "scaley"); + + public override string? GetFallbackShader(IMaterialVar[] vars) => null; + public override ShaderFlags GetFlags() => Flags; + public override int GetNumParams() => base.GetNumParams() + ShaderParams.Count; + public override ReadOnlySpan GetParamName(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamName(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetName(); + } + public override ReadOnlySpan GetParamHelp(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamHelp(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetHelp(); + } + public override ShaderParamType GetParamType(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamType(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetType(); + } + public override ReadOnlySpan GetParamDefault(int paramIndex) { + int baseClassParamCount = base.GetNumParams(); + if (paramIndex < baseClassParamCount) + return base.GetParamDefault(paramIndex); + else + return ShaderParams[paramIndex - baseClassParamCount].GetDefaultValue(); + } + + protected override void OnInitShaderInstance(IMaterialVar[] vars, ReadOnlySpan materialName) { + LoadTexture(FBTEXTURE); + } + + protected override void OnDrawElements(IMaterialVar[] vars, IShaderDynamicAPI shaderAPI, VertexCompressionType vertexCompression) { + if (IsSnapshotting()) { + ShaderShadow.EnableTexture(Sampler.Sampler0, true); + ShaderShadow.EnableTexture(Sampler.Sampler1, true); + ShaderShadow.EnableDepthWrites(false); + ShaderShadow.VertexShaderVertexFormat(VertexFormat.Position, 1, null, 0); + ShaderShadow.SetVertexShader("g_screenquad", 0); + ShaderShadow.SetPixelShader("g_texturize", 0); + ShaderShadow.EnableSRGBRead(Sampler.Sampler0, false); + ShaderShadow.EnableSRGBWrite(false); + DefaultFog(); + } + else { + shaderAPI.SetPixelShaderConstant(0, [vars[scalex].GetFloatValue(), 0, 0, 0], 1); + shaderAPI.SetPixelShaderConstant(1, [vars[scaley].GetFloatValue(), 0, 0, 0], 1); + + BindTexture(Sampler.Sampler0, FBTEXTURE, -1); + BindTexture(Sampler.Sampler1, BASETEXTURE, -1); + shaderAPI.SetVertexShaderIndex(0); + } + Draw(); + } +} +#endif From be123ee1e2728c1f62c4eb9c7b55f79fc56cb6fc Mon Sep 17 00:00:00 2001 From: callumok2004 Date: Tue, 20 Oct 2026 03:00:01 +0100 Subject: [PATCH 3/3] g_sky --- Game.Assets/sdn/shaders/g_sky_gl460.fs | 73 +++++++++++ Game.Assets/sdn/shaders/g_sky_gl460.vs | 20 +++ Game.Client/C_BaseEntity.cs | 10 +- Game.Client/GarrysMod/MaterialProxy.cs | 112 +++++++++++++++++ Game.Client/HLClient.cs | 3 +- Game.Client/ToolFrameworkClient.cs | 8 +- Game.Shared/GarrysMod/GarrysMod.cs | 1 + Game.Shared/GarrysMod/LuaGameSystem.cs | 6 + Game.Shared/GarrysMod/LuaHelper.cs | 22 ++++ Game.Shared/GarrysMod/SENT_Point.cs | 29 ++++- .../MaterialSystem/MaterialReference.cs | 4 +- Source.MaterialSystem/Material.cs | 10 ++ Source.StdShader.Gl46/g_Sky.cs | 115 ++++++++++++------ 13 files changed, 372 insertions(+), 41 deletions(-) create mode 100644 Game.Assets/sdn/shaders/g_sky_gl460.fs create mode 100644 Game.Assets/sdn/shaders/g_sky_gl460.vs create mode 100644 Game.Client/GarrysMod/MaterialProxy.cs diff --git a/Game.Assets/sdn/shaders/g_sky_gl460.fs b/Game.Assets/sdn/shaders/g_sky_gl460.fs new file mode 100644 index 00000000..6c3614b6 --- /dev/null +++ b/Game.Assets/sdn/shaders/g_sky_gl460.fs @@ -0,0 +1,73 @@ +#version 460 +// STATIC: "SKY_LAYERS" "0..4" + +layout(location = 0) in vec3 vs_WorldPos; + +layout(std140, binding = 6) uniform source_ps_constants { + vec4 ps_const[256]; +}; + +out vec4 fragColor; + +layout(binding = 0) uniform sampler2D StarSampler; + +#define g_EyePos ps_const[0].xyz +#define g_TopColor ps_const[1] +#define g_BottomColor ps_const[2] +#define g_FadeBias ps_const[3].x +#define g_HDRScale ps_const[4].x +#define g_SunNormal ps_const[5].xyz +#define g_DuskColor ps_const[6] +#define g_DuskSize ps_const[7].x +#define g_DuskPower ps_const[8].x +#define g_SunColor ps_const[9] +#define g_SunSize ps_const[10].x +#define g_StarFade ps_const[11].x +#define g_StarScale ps_const[12].x +#define g_StarPos ps_const[13].x +#define cLightScale ps_const[30] + +float StarCoord(float d, float horizon) +{ + return asin(d) + sin(d) * horizon; +} + +void main() +{ + vec3 dir = normalize(vs_WorldPos - g_EyePos); + float horizon = 1.0 - abs(dir.z); + + float sunDot = length(g_SunNormal) - 0.00100000005 >= 0.0 ? dot(normalize(g_SunNormal), dir) : 0.0; + float dusk = (horizon * 8.0 + sunDot) * 0.111111112; + float duskAmount = pow(abs(dusk), g_DuskSize * -5.0 + 10.0) * g_DuskPower; + + vec3 sky = mix(g_BottomColor.xyz, g_TopColor.xyz, pow(abs(dir.z), g_FadeBias)); + + if (dusk > 0.0) + sky = sky - sky * duskAmount * 0.5 + g_DuskColor.xyz * duskAmount; + + if (sunDot > 0.0 && g_SunSize > 0.0) + sky += g_SunColor.xyz * pow(abs(sunDot), 1.0 / (g_SunSize * 0.0500000007)); + + sky *= g_HDRScale; + +#if SKY_LAYERS > 0 + float starAmount = pow(abs(dir.z), 1.0 / g_StarFade); + vec2 starCoord = vec2(StarCoord(dir.x, horizon) + g_StarPos, StarCoord(dir.y, horizon)); + + vec3 stars = texture(StarSampler, starCoord * g_StarScale).xyz * starAmount; +#if SKY_LAYERS > 1 + starCoord.x -= g_StarPos * 0.00999999978 + 1.0; + stars += texture(StarSampler, starCoord * g_StarScale).xyz * starAmount * 0.5; +#endif +#if SKY_LAYERS > 2 + starCoord.x -= g_StarPos * 0.0199999996 + 1.0; + stars += texture(StarSampler, starCoord * g_StarScale).xyz * starAmount * 0.75; +#endif + + if (dir.z > 0.0) + sky += stars; +#endif + + fragColor = vec4(sky * cLightScale.x, 1.0); +} diff --git a/Game.Assets/sdn/shaders/g_sky_gl460.vs b/Game.Assets/sdn/shaders/g_sky_gl460.vs new file mode 100644 index 00000000..1bf310e0 --- /dev/null +++ b/Game.Assets/sdn/shaders/g_sky_gl460.vs @@ -0,0 +1,20 @@ +#version 460 + +layout(location = 0) in vec3 v_Position; + +layout(std140, binding = 0) uniform source_matrices { + mat4 viewMatrix; + mat4 projectionMatrix; + mat4 modelMatrix; +}; + +layout(location = 0) out vec3 vs_WorldPos; + +#include "common_clipplanes_gl460.vs" + +void main() +{ + gl_Position = projectionMatrix * viewMatrix * vec4(v_Position, 1.0); + WriteUserClipDistances(gl_Position); + vs_WorldPos = v_Position; +} diff --git a/Game.Client/C_BaseEntity.cs b/Game.Client/C_BaseEntity.cs index a8189db8..7ef1c539 100644 --- a/Game.Client/C_BaseEntity.cs +++ b/Game.Client/C_BaseEntity.cs @@ -190,12 +190,20 @@ public partial class C_BaseEntity : IClientEntity public virtual bool IsBaseCombatWeapon() => false; public virtual bool IsCombatItem() => false; + string? Classname; + public void SetClassname(ReadOnlySpan classname) { - // todo + Classname = new(classname); } static readonly char[] GetClassname__outstr = new char[256]; public ReadOnlySpan GetClassname() { + if (!string.IsNullOrEmpty(Classname)) + return Classname; +#if GMOD_DLL + if (!GetLuaScriptName().IsEmpty) + return GetLuaScriptName(); +#endif GetClassname__outstr[0] = '\0'; bool gotname = false; if (GetPredDescMap() != null) { diff --git a/Game.Client/GarrysMod/MaterialProxy.cs b/Game.Client/GarrysMod/MaterialProxy.cs new file mode 100644 index 00000000..df4ca5a5 --- /dev/null +++ b/Game.Client/GarrysMod/MaterialProxy.cs @@ -0,0 +1,112 @@ +using Source.Common; +using Source.Common.Commands; +using Source.Common.Formats.Keyvalues; +using Source.Common.GarrysMod.Lua; +using Source.Common.MaterialSystem; + +namespace Game.Client.GarrysMod; + +public class MaterialProxy : IMaterialProxy +{ + public static readonly ConVar lua_matproxy = new("lua_matproxy", "1", 0, "Whether to enable Lua material proxies or not."); + + readonly MaterialReference Material = new(); + readonly string Name; + string UniqueName = ""; + readonly bool HasBind; + + public MaterialProxy(ReadOnlySpan name, bool hasBind) { + Name = new(name); + HasBind = hasBind; + } + + public bool Init(IMaterial material, KeyValues keyValues) { + UniqueName = $"{Name}{material.GetName()}"; + Material.Init(material); + + if (g_Lua != null && ThreadInMainThread()) { + LuaTable values = new(null, 0); + LuaHelper.KeyValuesToTable(keyValues, values, false); + if (LuaHelper.PushLibraryFunction(g_Lua, "matproxy", "Init")) { + g_Lua.PushString(Name); + g_Lua.PushString(UniqueName); + LuaMaterial.Push(Material.Get()); + values.Push(); + g_Lua.CallInternalNoReturns(4); + } + values.UnReference(); + } + return true; + } + + public void OnBind(object? o) { + C_BaseEntity? entity = null; + if (o is IClientRenderable renderable) + entity = renderable.GetIClientUnknown().GetBaseEntity(); + + CallBind(entity); + + if (ToolsEnabled()) + ToolFramework_RecordMaterialParams(GetMaterial()); + } + + void CallBind(C_BaseEntity? entity) { + if (!HasBind) + return; + + if (lua_matproxy.GetInt() != 0 && g_Lua != null && LuaHelper.PushLibraryFunction(g_Lua, "matproxy", "Call")) { + g_Lua.PushString(UniqueName); + g_Lua.PushNil(); + LuaEntity.Push_Entity(entity); + g_Lua.CallInternalNoReturns(3); + } + } + + public void Release() => Material.Shutdown(); + + public IMaterial GetMaterial() => Material.Get()!; +} + +public class MaterialProxyFactory : IMaterialProxyFactory +{ + public static IMaterialProxyFactory? OldFactory; + public static MaterialProxyFactory? Factory; + + public static void Init() { + OldFactory = materials.GetMaterialProxyFactory(); + if (OldFactory == null) + Error("GetMaterialProxyFactory returned NULL!"); + if (Factory != null) + Error("MaterialProxyFactory isn't NULL!"); + + Factory = new(); + materials.SetMaterialProxyFactory(Factory); + } + + public static void Shutdown() { + materials.SetMaterialProxyFactory(OldFactory); + Factory = null; + OldFactory = null; + } + + public IMaterialProxy? CreateProxy(ReadOnlySpan proxyName) { + if (OldFactory == null) + return null; + if (!ThreadInMainThread()) + return null; + + if (g_Lua != null && LuaHelper.PushLibraryFunction(g_Lua, "matproxy", "ShouldOverrideProxy")) { + g_Lua.PushString(proxyName); + if (g_Lua.CallInternal(1, 2)) { + ILuaObject shouldOverride = g_Lua.GetReturn(1); + ILuaObject noBind = g_Lua.GetReturn(0); + if (shouldOverride.isBool() && shouldOverride.GetBool()) + return new MaterialProxy(proxyName, !noBind.isBool() || !noBind.GetBool()); + } + } + + return OldFactory.CreateProxy(proxyName); + } + + public void DeleteProxy(IMaterialProxy proxy) => OldFactory?.DeleteProxy(proxy); +} diff --git a/Game.Client/HLClient.cs b/Game.Client/HLClient.cs index 1c56b8c2..eed5f9b6 100644 --- a/Game.Client/HLClient.cs +++ b/Game.Client/HLClient.cs @@ -211,10 +211,11 @@ public bool Init() { public void Shutdown() { ClientVoiceMgr_Shutdown(); - Game.Client.GarrysMod.GarrysMod.Lua.Kill(); #if GMOD_DLL + Game.Client.GarrysMod.GarrysMod.Lua.Kill(); get.MenuSystem()?.Shutdown(); get.HTML()?.Shutdown(); + Game.Client.GarrysMod.MaterialProxyFactory.Shutdown(); #endif } diff --git a/Game.Client/ToolFrameworkClient.cs b/Game.Client/ToolFrameworkClient.cs index 4bdd008e..cf56cb13 100644 --- a/Game.Client/ToolFrameworkClient.cs +++ b/Game.Client/ToolFrameworkClient.cs @@ -1,8 +1,14 @@ global using static Game.Client.ToolFrameworkClient; - namespace Game.Client; +using Source.Common.MaterialSystem; + +namespace Game.Client; public class ToolFrameworkClient { public static bool ToolsEnabled() => false; + + public static void ToolFramework_RecordMaterialParams(IMaterial material) { + // todo + } } diff --git a/Game.Shared/GarrysMod/GarrysMod.cs b/Game.Shared/GarrysMod/GarrysMod.cs index 21f3127b..6c291d78 100644 --- a/Game.Shared/GarrysMod/GarrysMod.cs +++ b/Game.Shared/GarrysMod/GarrysMod.cs @@ -113,6 +113,7 @@ public void InitializeMod(IServiceProvider services) { // todo: convar defaults #endif #if CLIENT_DLL + MaterialProxyFactory.Init(); string absPath = $"{engine.GetGameDirectory()}/cache"; #else // TODO: This is really stupid. Why is server different here in the interface. This deserves deviation. Span path = stackalloc char[MAX_PATH]; diff --git a/Game.Shared/GarrysMod/LuaGameSystem.cs b/Game.Shared/GarrysMod/LuaGameSystem.cs index 381fcd19..4b64449c 100644 --- a/Game.Shared/GarrysMod/LuaGameSystem.cs +++ b/Game.Shared/GarrysMod/LuaGameSystem.cs @@ -41,6 +41,12 @@ public override void LevelInitPreEntity() { gGM.LoadGamemode(Gamemode, false); gGM.SetGamemode(Gamemode, true); } + RecacheMaterials(); + } + + static void RecacheMaterials() { + materials.UncacheAllMaterials(); + materials.CacheUsedMaterials(); } public override void Update(double frametime) { // RemoveQueuedRenderTargets(); diff --git a/Game.Shared/GarrysMod/LuaHelper.cs b/Game.Shared/GarrysMod/LuaHelper.cs index a9e0228b..8c5b9923 100644 --- a/Game.Shared/GarrysMod/LuaHelper.cs +++ b/Game.Shared/GarrysMod/LuaHelper.cs @@ -20,6 +20,28 @@ public static class LuaHelper public static long cvttsd2si64(double value) => double.IsNaN(value) || value >= 9223372036854775808.0 || value < -9223372036854775808.0 ? long.MinValue : (long)value; + public static bool PushLibraryFunction(ILuaInterface lua, ReadOnlySpan library, ReadOnlySpan function) { + LuaObject lib = new(); + lib.SetFromGlobal(library); + bool found; + if (!lib.isTable()) { + Warning($"'{library}' is not a table!\n"); + found = false; + } + else { + LuaObject func = new(); + lib.GetMember(function, func); + found = func.isFunction(); + if (found) + func.Push(); + else + Warning($"'{library}.{function}' is not a function!\n"); + func.UnReference(); + } + lib.UnReference(); + return found; + } + public static void KeyValuesToTable(KeyValues kv, ILuaObject table, bool preserveKeyCase) { for (KeyValues? sub = kv.GetFirstSubKey(); sub != null; sub = sub.GetNextKey()) { string name = sub.Name.Length > 511 ? sub.Name[..511] : sub.Name; diff --git a/Game.Shared/GarrysMod/SENT_Point.cs b/Game.Shared/GarrysMod/SENT_Point.cs index 3c95b308..8727e988 100644 --- a/Game.Shared/GarrysMod/SENT_Point.cs +++ b/Game.Shared/GarrysMod/SENT_Point.cs @@ -1,4 +1,5 @@ -#if (CLIENT_DLL || GAME_DLL) && GMOD_DLL +using Source.Common.Engine; +#if (CLIENT_DLL || GAME_DLL) && GMOD_DLL using Source.Common; using Game.Shared; using Source; @@ -71,12 +72,38 @@ public override void InitializeScriptedEntity(ReadOnlySpan name) { ScriptedEntity.StartLua(); } +#if GAME_DLL + public override EdictFlags UpdateTransmitState() { + if (ScriptedEntity.StartFunction((int)LUA_POOLEDSTRING.UpdateTransmitState) && ScriptedEntity.Call(0, 1)) { + int transmit = g_Lua!.GetReturn(0).GetInt(); + if (transmit == 0) + return SetTransmitState(EdictFlags.Always); + if (transmit != 1) + return SetTransmitState(EdictFlags.PVSCheck); + } + return SetTransmitState(EdictFlags.DontSend); + } +#endif + #if CLIENT_DLL public override void OnDataChanged(DataUpdateType updateType) { base.OnDataChanged(updateType); if (updateType == DataUpdateType.Created) ScriptedEntity.StartLua(); } + + public override void Spawn() { + SetThink(Think); + SetNextThink(gpGlobals.CurTime + 0.1); + SetNextClientThink(CLIENT_THINK_ALWAYS); + } + + public override void ClientThink() => ScriptedEntity.CallFunction((int)LUA_POOLEDSTRING.Think, false); + + public override void Think() { + if (!ScriptedEntity.CallFunction((int)LUA_POOLEDSTRING.Think, true)) + SetNextThink(gpGlobals.CurTime + 0.2); + } #endif } #endif diff --git a/Source.Common/MaterialSystem/MaterialReference.cs b/Source.Common/MaterialSystem/MaterialReference.cs index 4938d17d..c01fdf24 100644 --- a/Source.Common/MaterialSystem/MaterialReference.cs +++ b/Source.Common/MaterialSystem/MaterialReference.cs @@ -25,14 +25,14 @@ public void Init(ReadOnlySpan materialName, ReadOnlySpan textureGrou Init(mat); } - void Init(IMaterial material) { + public void Init(IMaterial material) { if (reference != material) { Shutdown(); reference = material; } } - private void Shutdown(bool deleteIfUnreferenced = false) { + public void Shutdown(bool deleteIfUnreferenced = false) { if (reference != null) reference = null; } diff --git a/Source.MaterialSystem/Material.cs b/Source.MaterialSystem/Material.cs index 0ec9caa9..1744401d 100644 --- a/Source.MaterialSystem/Material.cs +++ b/Source.MaterialSystem/Material.cs @@ -1165,7 +1165,17 @@ public void Uncache(bool preserveVars = false) { } private void CleanUpMaterialProxy() { + if (ProxyInfo.Count == 0) + return; + + IMaterialProxyFactory? materialProxyFactory = materials.GetMaterialProxyFactory(); + if (materialProxyFactory == null) + return; + + for (int i = ProxyInfo.Count - 1; i >= 0; i--) + materialProxyFactory.DeleteProxy(ProxyInfo[i]); + ProxyInfo.Clear(); } private void CleanUpShaderParams() { diff --git a/Source.StdShader.Gl46/g_Sky.cs b/Source.StdShader.Gl46/g_Sky.cs index a3101664..e6513e50 100644 --- a/Source.StdShader.Gl46/g_Sky.cs +++ b/Source.StdShader.Gl46/g_Sky.cs @@ -1,13 +1,13 @@ #if GMOD_DLL using Source.Common.MaterialSystem; +using Source.Common.ShaderAPI; using Source.Common.ShaderLib; namespace Source.StdShader.Gl46; -public class g_Sky : BaseVSShader +public class g_sky : BaseVSShader { - - public static string HelpString = "Help for g_Sky"; + public static string HelpString = "Help for g_sky"; public static ShaderFlags Flags = ShaderFlags.None; public static List ShaderParams = []; public static ShaderParam[] ShaderParamOverrides = new ShaderParam[(int)ShaderMaterialVars.Count]; @@ -50,33 +50,23 @@ public ShaderParam(string name, ShaderParamType type, ReadOnlySpan default public ReadOnlySpan GetHelp() => Info.Help; } - public static readonly ShaderParam DETAIL = new($"${nameof(DETAIL)}", ShaderParamType.Texture, "shadertest/detail", "detail texture"); - public static readonly ShaderParam DETAILSCALE = new($"${nameof(DETAILSCALE)}", ShaderParamType.Float, "4", "scale of the detail texture" ); - public static readonly ShaderParam ENVMAP = new($"${nameof(ENVMAP)}", ShaderParamType.Texture, "shadertest/shadertest_env", "envmap" ); - public static readonly ShaderParam ENVMAPFRAME = new($"${nameof(ENVMAPFRAME)}", ShaderParamType.Integer, "0", "" ); - public static readonly ShaderParam ENVMAPMASK = new($"${nameof(ENVMAPMASK)}", ShaderParamType.Texture, "shadertest/shadertest_envmask", "envmap mask" ); - public static readonly ShaderParam ENVMAPMASKFRAME = new($"${nameof(ENVMAPMASKFRAME)}", ShaderParamType.Integer, "0", "" ); - public static readonly ShaderParam ENVMAPMASKSCALE = new($"${nameof(ENVMAPMASKSCALE)}", ShaderParamType.Float, "1", "envmap mask scale" ); - public static readonly ShaderParam ENVMAPTINT = new($"${nameof(ENVMAPTINT)}", ShaderParamType.Color, "[1 1 1]", "envmap tint" ); - public static readonly ShaderParam ENVMAPOPTIONAL = new($"${nameof(ENVMAPOPTIONAL)}", ShaderParamType.Bool, "0", "Make the envmap only apply to dx9 and higher hardware" ); - public static readonly ShaderParam DETAILBLENDMODE = new($"${nameof(DETAILBLENDMODE)}", ShaderParamType.Integer, "0", "mode for combining detail texture with base. 0=normal, 1= additive, 2=alpha blend detail over base, 3=crossfade" ); - public static readonly ShaderParam ALPHATESTREFERENCE = new($"${nameof(ALPHATESTREFERENCE)}", ShaderParamType.Float, "0.7", "" ); - public static readonly ShaderParam OUTLINE = new($"${nameof(OUTLINE)}", ShaderParamType.Bool, "0", "Enable outline for distance coded textures."); - public static readonly ShaderParam OUTLINECOLOR = new($"${nameof(OUTLINECOLOR)}", ShaderParamType.Color, "[1 1 1]", "color of outline for distance coded images." ); - public static readonly ShaderParam OUTLINESTART0 = new($"${nameof(OUTLINESTART0)}", ShaderParamType.Float, "0.0", "outer start value for outline"); - public static readonly ShaderParam OUTLINESTART1 = new($"${nameof(OUTLINESTART1)}", ShaderParamType.Float, "0.0", "inner start value for outline"); - public static readonly ShaderParam OUTLINEEND0 = new($"${nameof(OUTLINEEND0)}", ShaderParamType.Float, "0.0", "inner end value for outline"); - public static readonly ShaderParam OUTLINEEND1 = new($"${nameof(OUTLINEEND1)}", ShaderParamType.Float, "0.0", "outer end value for outline"); - public static readonly ShaderParam SEPARATEDETAILUVS = new($"${nameof(SEPARATEDETAILUVS)}", ShaderParamType.Integer, "0", "" ); - + public static readonly ShaderParam TOPCOLOR = new($"${nameof(TOPCOLOR)}", ShaderParamType.Vec3, "[0 0 1]", ""); + public static readonly ShaderParam BOTTOMCOLOR = new($"${nameof(BOTTOMCOLOR)}", ShaderParamType.Vec3, "[0 1 1]", ""); + public static readonly ShaderParam FADEBIAS = new($"${nameof(FADEBIAS)}", ShaderParamType.Float, "1.0", ""); + public static readonly ShaderParam HDRSCALE = new($"${nameof(HDRSCALE)}", ShaderParamType.Float, "1.0", ""); + public static readonly ShaderParam SUNNORMAL = new($"${nameof(SUNNORMAL)}", ShaderParamType.Vec3, "[0 1 0.5]", ""); + public static readonly ShaderParam DUSKCOLOR = new($"${nameof(DUSKCOLOR)}", ShaderParamType.Vec3, "[1 0.4 0]", ""); + public static readonly ShaderParam DUSKSCALE = new($"${nameof(DUSKSCALE)}", ShaderParamType.Float, "1.0", ""); + public static readonly ShaderParam DUSKINTENSITY = new($"${nameof(DUSKINTENSITY)}", ShaderParamType.Float, "1.0", ""); + public static readonly ShaderParam SUNCOLOR = new($"${nameof(SUNCOLOR)}", ShaderParamType.Vec3, "[1 1 1]", ""); + public static readonly ShaderParam SUNSIZE = new($"${nameof(SUNSIZE)}", ShaderParamType.Float, "1", ""); + public static readonly ShaderParam STARTEXTURE = new($"${nameof(STARTEXTURE)}", ShaderParamType.Texture, "skybox/stars", ""); + public static readonly ShaderParam STARFADE = new($"${nameof(STARFADE)}", ShaderParamType.Float, "1", ""); + public static readonly ShaderParam STARSCALE = new($"${nameof(STARSCALE)}", ShaderParamType.Float, "1", ""); + public static readonly ShaderParam STARPOS = new($"${nameof(STARPOS)}", ShaderParamType.Float, "1", ""); + public static readonly ShaderParam STARLAYERS = new($"${nameof(STARLAYERS)}", ShaderParamType.Integer, "0", ""); - protected override void OnInitShaderParams(IMaterialVar[] vars, ReadOnlySpan materialName) { - InitParamsUnlitGeneric((int)ShaderMaterialVars.BaseTexture, DETAILSCALE, ENVMAPOPTIONAL, ENVMAP, ENVMAPTINT, ENVMAPMASKSCALE, DETAILBLENDMODE); - } - - public override string? GetFallbackShader(IMaterialVar[] vars) { - return null; - } + public override string? GetFallbackShader(IMaterialVar[] vars) => null; public override ShaderFlags GetFlags() => Flags; public override int GetNumParams() => base.GetNumParams() + ShaderParams.Count; public override ReadOnlySpan GetParamName(int paramIndex) { @@ -107,17 +97,72 @@ public override ReadOnlySpan GetParamDefault(int paramIndex) { else return ShaderParams[paramIndex - baseClassParamCount].GetDefaultValue(); } + protected override void OnInitShaderInstance(IMaterialVar[] vars, ReadOnlySpan materialName) { - InitUnlitGeneric((int)ShaderMaterialVars.BaseTexture, DETAIL, ENVMAP, ENVMAPMASK); + LoadTexture(STARTEXTURE); } + protected override void OnDrawElements(IMaterialVar[] vars, IShaderDynamicAPI shaderAPI, VertexCompressionType vertexCompression) { if (IsSnapshotting()) { - ShaderShadow.EnableDepthTest(false); + ShaderShadow.EnableDepthWrites(false); + ShaderShadow.VertexShaderVertexFormat(VertexFormat.Position, 1, null, 0); + ShaderShadow.EnableBlending(false); + ShaderShadow.BlendFunc(ShaderBlendFactor.One, ShaderBlendFactor.One); + if (!HardwareConfig.SupportsPixelShaders_2_b()) { + ShaderShadow.SetPixelShader("g_sky", 0); + ShaderShadow.SetVertexShader("g_sky", 0); + ShaderShadow.EnableTexture(Sampler.Sampler0, false); + } + else { + ShaderShadow.SetPixelShader("g_sky", vars[STARLAYERS].GetIntValue()); + ShaderShadow.SetVertexShader("g_sky", 0); + ShaderShadow.EnableTexture(Sampler.Sampler0, true); + ShaderShadow.EnableSRGBRead(Sampler.Sampler0, false); + } + ShaderShadow.EnableSRGBWrite(true); + ShaderShadow.EnableAlphaWrites(true); + } + else { + shaderAPI.SetVertexShaderIndex(0); + shaderAPI.SetPixelShaderIndex(0); + + Span v = [0, 0, 0, 0]; + shaderAPI.GetWorldSpaceCameraPosition(v); + shaderAPI.SetPixelShaderConstant(0, v, 1); + + vars[TOPCOLOR].GetVecValue(v); + shaderAPI.SetPixelShaderConstant(1, v, 1); + vars[BOTTOMCOLOR].GetVecValue(v); + shaderAPI.SetPixelShaderConstant(2, v, 1); + shaderAPI.SetPixelShaderConstant(3, [vars[FADEBIAS].GetFloatValue(), 0, 0, 0], 1); + + if (HardwareConfig.SupportsPixelShaders_2_0()) { + float hdrScale = vars[HDRSCALE].GetFloatValue(); + if (HardwareConfig.GetHDRType() == HDRType.None) + hdrScale = 1.0f; + shaderAPI.SetPixelShaderConstant(4, [hdrScale, 0, 0, 0], 1); + + vars[SUNNORMAL].GetVecValue(v); + shaderAPI.SetPixelShaderConstant(5, v, 1); + vars[DUSKCOLOR].GetVecValue(v); + shaderAPI.SetPixelShaderConstant(6, v, 1); + shaderAPI.SetPixelShaderConstant(7, [vars[DUSKSCALE].GetFloatValue(), 0, 0, 0], 1); + shaderAPI.SetPixelShaderConstant(8, [vars[DUSKINTENSITY].GetFloatValue(), 0, 0, 0], 1); + vars[SUNCOLOR].GetVecValue(v); + shaderAPI.SetPixelShaderConstant(9, v, 1); + shaderAPI.SetPixelShaderConstant(10, [vars[SUNSIZE].GetFloatValue(), 0, 0, 0], 1); + shaderAPI.SetPixelShaderConstant(11, [vars[STARFADE].GetFloatValue(), 0, 0, 0], 1); + } + + if (HardwareConfig.SupportsPixelShaders_2_b()) { + float starScale = vars[STARSCALE].GetFloatValue(); + if (starScale != 0.0f) + shaderAPI.SetPixelShaderConstant(12, [1.0f / starScale, 0, 0, 0], 1); + shaderAPI.SetPixelShaderConstant(13, [vars[STARPOS].GetFloatValue(), 0, 0, 0], 1); + BindTexture(Sampler.Sampler0, STARTEXTURE, -1); + } } - VertexShaderUnlitGenericPass((int)ShaderMaterialVars.BaseTexture, (int)ShaderMaterialVars.Frame, (int)ShaderMaterialVars.BaseTextureTransform, - DETAIL, DETAILSCALE, true, ENVMAP, ENVMAPFRAME, ENVMAPMASK, - ENVMAPMASKFRAME, ENVMAPMASKSCALE, ENVMAPTINT, ALPHATESTREFERENCE, - DETAILBLENDMODE, OUTLINE, OUTLINECOLOR, OUTLINESTART0, OUTLINEEND1, SEPARATEDETAILUVS, "unlitgeneric"); + Draw(); } } #endif