骑马与砍杀中文站论坛

 找回密码
 注册(Register!)

QQ登录

只需一步,快速开始

搜索
购买CDKEY 小黑盒加速器
查看: 9149|回复: 22

[功能与代码] 【shaders】使用postFX.fx提升战团画质(战团重置版的核心)

[复制链接]

35

主题

468

回帖

251

积分

见习骑士

Rank: 3

UID
3257703
第纳尔
2062
精华
0
互助
16
荣誉
2
贡献
10
魅力
118
注册时间
2021-8-1

骑砍中文站APP会员勋章

鲜花(80) 鸡蛋(0)
发表于 2023-2-1 19:44:50 | 显示全部楼层 |阅读模式
本帖最后由 fengguoyehao 于 2023-2-1 20:22 编辑

如果大家体验过战团重置版,肯定会对战团重置版提升画质的方法感到好奇。今天我们就来聊一聊提升战团重置版画质的核心:postFX.fx

在阅读本文之前,如果你不了解战团的shaders,可以阅读这个帖子,里面的介绍写得很清晰:【shaders技术研究】关于骑砍中的着色器的编辑方法 - MOD制作资料区 - 骑马与砍杀中文站论坛 - Powered by Discuz! (mountblade.com.cn)(其实我不太懂高级着色器语言,以下内容是我花了半年时间自学的。如果有会高级着色器语言的大神看到这篇文章,欢迎补充内容!顺便请帮忙看看Reshade的光追效果有没有可能移植到战团的postFX.fx里,万分感谢!)

让我们进入正题:

postFX.fx控制着战团的HDR、自动调光和动态模糊效果。战团重置版的postFX.fx包含SSAO效果和后期调色效果。其中,SSAO效果勾选“动态模糊”启用,后期调色效果可以通过打开HDR启用。
以下为postFX.fx代码,可以使用Sublime Text来编写。

SSAO(环境光遮蔽):
关于SSAO效果,在外网论坛上有代码(Pure Depth SSAO (theorangeduck.com))。这个代码不够完整,不过Tama将这份代码改了改,成功地写入了postFX.fx(OSP - Shaders - Tama's Shaders (Dynamic Parallax Occlusion & Parallax & SSAO) | TaleWorlds Forums),完整代码如下:
  1. sampler postFX_sampler5 : register(s5);// depth

  2. float3 randomNormal(float2 tex)
  3. {
  4.       float noiseX = (frac(sin(dot(tex, float2(15.8989f, 76.132f)*1.0f))*46336.23745f));
  5.       float noiseY = (frac(sin(dot(tex, float2(11.9899f, 62.223f)*2.0f))*34748.34744f));
  6.       float noiseZ = (frac(sin(dot(tex, float2(13.3238f, 63.122f)*3.0f))*59998.47362f));
  7.       return normalize(float3(noiseX, noiseY, noiseZ));
  8. }

  9. float3 normal_from_depth(float depth, float2 texcoords) {
  10.   
  11.   const float2 offset1 = float2(0.0,0.001);
  12.   const float2 offset2 = float2(0.001,0.0);
  13.   
  14.   float depth1 = tex2D(postFX_sampler5, texcoords + offset1).r;
  15.   float depth2 = tex2D(postFX_sampler5, texcoords + offset2).r;
  16.   
  17.   float3 p1 = float3(offset1, depth1 - depth);
  18.   float3 p2 = float3(offset2, depth2 - depth);
  19.   
  20.   float3 normal = cross(p1, p2);
  21.   normal.z = -normal.z;
  22.   
  23.   return normalize(normal);
  24. }

  25.         const float total_strength = 1.5f;
  26.         const float base = 0.6f;
  27.   
  28.         const float area = 0.0075;
  29.         const float falloff = 0.00001;
  30.   
  31.         const float radius = 0.0002;
  32.   
  33.         const int samples = 16;
  34.         float3 sample_sphere[samples] = {
  35.                 float3( 0.5381, 0.1856,-0.4319), float3( 0.1379, 0.2486, 0.4430),
  36.                 float3( 0.3371, 0.5679,-0.0057), float3(-0.6999,-0.0451,-0.0019),
  37.                 float3( 0.0689,-0.1598,-0.8547), float3( 0.0560, 0.0069,-0.1843),
  38.                 float3(-0.0146, 0.1402, 0.0762), float3( 0.0100,-0.1924,-0.0344),
  39.                 float3(-0.3577,-0.5301,-0.4358), float3(-0.3169, 0.1063, 0.0158),
  40.                 float3( 0.0103,-0.5869, 0.0046), float3(-0.0897,-0.4940, 0.3287),
  41.                 float3( 0.7119,-0.0154,-0.0918), float3(-0.0533, 0.0596,-0.5411),
  42.                 float3( 0.0352,-0.0631, 0.5460), float3(-0.4776, 0.2847,-0.0271)
  43.         };
  44.   

  45.         float3 random = normalize( randomNormal( inTex * 4.0) );
  46.   
  47.         float depth = tex2D(postFX_sampler5, inTex).r;

  48.         float3 position = float3(inTex, depth);
  49.         float3 normal = normal_from_depth(depth, inTex);
  50.   
  51.         float radius_depth = radius/depth;
  52.         float occlusion = 0.0;
  53.         for(int i=0; i < samples; i++) {
  54.   
  55.                 float3 ray = radius_depth * reflect(sample_sphere[i], random);
  56.                 float3 hemi_ray = position + sign(dot(ray,normal)) * ray;
  57.    
  58.                 float occ_depth = tex2D(postFX_sampler5, saturate(hemi_ray.xy)).r;
  59.                 float difference = depth - occ_depth;
  60.    
  61.                 occlusion += step(falloff, difference) * (1.0-smoothstep(falloff, area, difference));
  62.         }
  63.   
  64.         float ao = 1.0 - total_strength * occlusion * (1.0 / samples);
  65.                
  66.         float ssao = saturate(ao + base);
  67.         
  68.         return float4(color, ssao); //WEIRD!

  69.         color.rgb *= tex2D(postFX_sampler1, texCoord).a; //Enhanced
复制代码

后期调色功能(HDR):
思路是移植Reshade和sweetfx(其实两个是一个东西)里面的fx文件语言到postFX.fx里,也就是大家熟知的“滤镜”效果。
Reshade是一个开源的二次渲染软件,但用于战团时有很多问题,比如说ui渲染不同步,无法获取深度信息...最重要的是,它和ENB一样十分吃配置。将Reshade的语言移植到postFX.fx里面可以最大程度上进行帧数优化。
后期调色功能得以实现,要感谢@杜撰。以下的Filimcpass,DPX,Vibrance,Technicolor2,Tint(Sepia),LiftGammaGain都是@杜撰最早移植的。可以说,@杜撰为战团的画质带来了一场革命!
下面,我来展示一些移植成功的语言。

移植fx代码:
  1. //FilmicPass {{{2
  2. float3 LumCoeff = float3(0.212656, 0.715158, 0.072186);
  3.         color.rgb = FilmicPass(color.rgb,
  4.                 0.7, 0.30, 1.0,
  5.                 0.5, 0.0, -0.1,
  6.                 1.0, 1.0, 1.5,
  7.                 1,
  8.                 1.0,
  9.                 1.50,
  10.                 0.900, 1.300, 1.20,
  11.                 LumCoeff);
复制代码
  1. //Tonemap {{{2
  2. float3 Tonemap(float3 color, float Gamma, float Exposure, float Saturation, float Bleach, float Defog, float3 FogColor)
  3. {
  4.         float3 colorr = color;
  5.         colorr = saturate(colorr - Defog * FogColor * 2.55); // Defog
  6.         colorr *= pow(2.0f, Exposure); // Exposure
  7.         colorr = pow(colorr, Gamma); // Gamma

  8.         const float3 coefLuma = float3(0.2126, 0.7152, 0.0722);
  9.         float lum = dot(coefLuma, colorr);
  10.         
  11.         float L = saturate(10.0 * (lum - 0.45));
  12.         float3 A2 = Bleach * colorr;

  13.         float3 result1 = 2.0f * colorr * lum;
  14.         float3 result2 = 1.0f - 2.0f * (1.0f - lum) * (1.0f - colorr);
  15.         
  16.         float3 newColor = lerp(result1, result2, L);
  17.         float3 mixRGB = A2 * newColor;
  18.         colorr += ((1.0f - A2) * mixRGB);
  19.         
  20.         float3 middlegray = dot(colorr, (1.0 / 3.0));
  21.         float3 diffcolor = colorr - middlegray;
  22.         colorr = (colorr + diffcolor * Saturation) / (1 + (diffcolor * Saturation)); // Saturation
  23.         
  24.         return colorr;
  25. }
复制代码
  1. //Sepia {{{2
  2. float3 Sepia(float3 col, float I, float3 RGB)
  3. {
  4.         return lerp(col, col * RGB * 2.55, I);
  5. }
复制代码
  1. //LiftGammaGain {{{2
  2. float3 LiftGammaGain(float3 color, float3 RGB_Lift, float3 RGB_Gamma, float3 RGB_Gain)
  3. {
  4.         color = color * (1.5 - 0.5 * RGB_Lift) + 0.5 * RGB_Lift - 0.5;
  5.         color = saturate(color); // Is not strictly necessary, but does not cost performance

  6.         // -- Gain --
  7.         color *= RGB_Gain;

  8.         // -- Gamma --
  9.         color = pow(color, 1.0 / RGB_Gamma);

  10.         return saturate(color);
  11. }
复制代码
  1. //Technicolor {{{2
  2. //
  3. float3 Technicolor(float3 color, float Power, float3 RGBNegativeAmount, float Strength)
  4. {
  5.         const float3 cyanfilter = float3(0.0, 1.30, 1.0);
  6.         const float3 magentafilter = float3(1.0, 0.0, 1.05);
  7.         const float3 yellowfilter = float3(1.6, 1.6, 0.05);
  8.         const float2 redorangefilter = float2(1.05, 0.620); // RG_
  9.         const float2 greenfilter = float2(0.30, 1.0);       // RG_
  10.         const float2 magentafilter2 = magentafilter.rb;     // R_B

  11.         float3 tcol = color;
  12.         
  13.         float2 negative_mul_r = tcol.rg * (1.0 / (RGBNegativeAmount.r * Power));
  14.         float2 negative_mul_g = tcol.rg * (1.0 / (RGBNegativeAmount.g * Power));
  15.         float2 negative_mul_b = tcol.rb * (1.0 / (RGBNegativeAmount.b * Power));
  16.         float3 output_r = dot(redorangefilter, negative_mul_r).xxx + cyanfilter;
  17.         float3 output_g = dot(greenfilter, negative_mul_g).xxx + magentafilter;
  18.         float3 output_b = dot(magentafilter2, negative_mul_b).xxx + yellowfilter;

  19.         return lerp(tcol, output_r * output_g * output_b, Strength);
  20. }
复制代码
  1. //Technicolor2 {{{2
  2. //
  3. float3 Technicolor2(float3 color, float3 colorStrength, float Brightness, float Saturation, float Strength)
  4. {
  5.     float3 colorr = color;
  6.         float3 temp = 1.0 - colorr;
  7.         float3 target = temp.grg;
  8.         float3 target2 = temp.bbr;
  9.         float3 temp2 = colorr * target;
  10.         temp2 *= target2;

  11.         temp = temp2 * colorStrength;
  12.         temp2 *= Brightness;

  13.         target = temp.grg;
  14.         target2 = temp.bbr;

  15.         temp = colorr - target;
  16.         temp += temp2;
  17.         temp2 = temp - target2;

  18.         colorr = lerp(colorr, temp2, Strength);
  19.         colorr = lerp(dot(colorr, 0.333), colorr, Saturation);

  20.         return colorr;
  21. }
复制代码
  1. //DPX {{{2
  2. //
  3. static const float3x3 RGB = float3x3(
  4.          2.6714711726599600, -1.2672360578624100, -0.4109956021722270,
  5.         -1.0251070293466400,  1.9840911624108900,  0.0439502493584124,
  6.          0.0610009456429445, -0.2236707508128630,  1.1590210416706100
  7. );
  8. static const float3x3 XYZ = float3x3(
  9.          0.5003033835433160,  0.3380975732227390,  0.1645897795458570,
  10.          0.2579688942747580,  0.6761952591447060,  0.0658358459823868,
  11.          0.0234517888692628,  0.1126992737203000,  0.8668396731242010
  12. );

  13. float3 DPX(float3 color, float3 RGB_Curve, float3 RGB_C, float Contrast, float Saturation, float Colorfulness, float Strength)
  14. {
  15.         float3 input = color;

  16.         float3 B = input;
  17.         B = B * (1.0 - Contrast) + (0.5 * Contrast);
  18.         float3 Btemp = (1.0 / (1.0 + exp(RGB_Curve / 2.0)));
  19.         B = ((1.0 / (1.0 + exp(-RGB_Curve * (B - RGB_C)))) / (-2.0 * Btemp + 1.0)) + (-Btemp / (-2.0 * Btemp + 1.0));

  20.         float value = max(max(B.r, B.g), B.b);
  21.         float3 colorr = B / value;
  22.         colorr = pow(abs(colorr), 1.0 / Colorfulness);

  23.         float3 c0 = colorr * value;
  24.         c0 = mul(XYZ, c0);
  25.         float luma = dot(c0, float3(0.30, 0.59, 0.11));
  26.         c0 = (1.0 - Saturation) * luma + Saturation * c0;
  27.         c0 = mul(RGB, c0);

  28.         return lerp(input, c0, Strength);
  29. }
复制代码
  1. //Vibrance {{{2
  2. float3 Vibrance(float3 color, float I, float3 RGB)
  3. {
  4.         const float3 coefLuma = float3(0.212656, 0.715158, 0.072186);
  5.         float luma = dot(coefLuma, color);
  6.         float max_color = max(color.r, max(color.g, color.b)); // Find the strongest color
  7.         float min_color = min(color.r, min(color.g, color.b)); // Find the weakest color
  8.         float color_saturation = max_color - min_color; // The difference between the two is the saturation

  9.         float3 coeffVibrance = float3(RGB * I);
  10.         color = lerp(luma, color, 1.0 + (coeffVibrance * (1.0 - (sign(coeffVibrance) * color_saturation))));

  11.     return color;
  12. }
复制代码

输出代码:
  1. //Technicolor {{{2
  2. color.rgb = Technicolor(color.rgb, 0.1, float3(0.4,0.3,0.6), 1.0);
复制代码
  1. //Sepia {{{2
  2. color.rgb = Sepia(color.rgb, 0.3, float3(0.6,0.47,0.5));
复制代码
  1. //Technicolor2 {{{2
  2. color.rgb = Technicolor2(color.rgb, float3(0.4,0.3,0.6), 1.0, 0.9, 0.5);
复制代码
  1. //FilmicPass {{{2
  2. float3 LumCoeff = float3(0.212656, 0.715158, 0.072186);
  3.         color.rgb = FilmicPass(color.rgb,
  4.                 0.7, 0.30, 1.0,
  5.                 0.5, 0.0, -0.1,
  6.                 1.0, 1.0, 1.5,
  7.                 1,
  8.                 1.0,
  9.                 1.50,
  10.                 0.900, 1.300, 1.20,
  11.                 LumCoeff);
复制代码
  1. //Vibrance {{{2
  2.         color.rgb = Vibrance(color.rgb, 0.3, float3(0.6,0.6,1.0));
复制代码
  1. //Lift Gamma Gain {{{2
  2.         color.rgb = LiftGammaGain(color.rgb,
  3.                 float3(1.00,1.00,1.00),
  4.                 float3(1.00,1.00,1.00),
  5.                 float3(1.00,1.00,1.00));
复制代码
  1. //DPX {{{2
  2. color.rgb = DPX(color.rgb, float3(15,15,15), float3(0.33,0.33,0.33), 0.20, 3.0, 1.4, 0.20);
复制代码
  1. //Tonemap {{{2
  2. color.rgb = Tonemap(color.rgb, 1.0, 0.0, 0.0, 0.0, 1.0, float3(0.0,0.0,0.0));
复制代码

写入方法(以写入Vibrance功能和DPX功能为例,其余的以此类推):
1)找到这一段代码:
  1. /////////////////////////////////////////////////////////////////////////////////////

  2. float4 FinalScenePassPS(uniform const bool use_dof, uniform const int use_hdr, uniform const bool use_auto_exp, float2 texCoord: TEXCOORD0) : COLOR {
  3.                
  4.         // Sample the scene
  5.         float4 scene = tex2D(postFX_sampler0, texCoord);
  6.         scene.rgb  = pow(scene.rgb, output_gamma);
复制代码

在“//////////////////////////////////////////////////////////”下面一行添加// Func {{{1
就像这样:
  1. /////////////////////////////////////////////////////////////////////////////////////
  2. // Func {{{1
复制代码
再重起一行,添加Vibrance和DPX的fx代码,就像这样。在代码的最底下添加// Final {{{1(表示结束):
  1. /////////////////////////////////////////////////////////////////////////////////////
  2. // Func {{{1

  3. //Vibrance {{{2
  4. float3 Vibrance(float3 color, float I, float3 RGB)
  5. {
  6.         const float3 coefLuma = float3(0.212656, 0.715158, 0.072186);
  7.         float luma = dot(coefLuma, color);
  8.         float max_color = max(color.r, max(color.g, color.b)); // Find the strongest color
  9.         float min_color = min(color.r, min(color.g, color.b)); // Find the weakest color
  10.         float color_saturation = max_color - min_color; // The difference between the two is the saturation

  11.         float3 coeffVibrance = float3(RGB * I);
  12.         color = lerp(luma, color, 1.0 + (coeffVibrance * (1.0 - (sign(coeffVibrance) * color_saturation))));

  13.     return color;
  14. }

  15. //DPX {{{2
  16. //
  17. static const float3x3 RGB = float3x3(
  18.          2.6714711726599600, -1.2672360578624100, -0.4109956021722270,
  19.         -1.0251070293466400,  1.9840911624108900,  0.0439502493584124,
  20.          0.0610009456429445, -0.2236707508128630,  1.1590210416706100
  21. );
  22. static const float3x3 XYZ = float3x3(
  23.          0.5003033835433160,  0.3380975732227390,  0.1645897795458570,
  24.          0.2579688942747580,  0.6761952591447060,  0.0658358459823868,
  25.          0.0234517888692628,  0.1126992737203000,  0.8668396731242010
  26. );

  27. float3 DPX(float3 color, float3 RGB_Curve, float3 RGB_C, float Contrast, float Saturation, float Colorfulness, float Strength)
  28. {
  29.         float3 input = color;

  30.         float3 B = input;
  31.         B = B * (1.0 - Contrast) + (0.5 * Contrast);
  32.         float3 Btemp = (1.0 / (1.0 + exp(RGB_Curve / 2.0)));
  33.         B = ((1.0 / (1.0 + exp(-RGB_Curve * (B - RGB_C)))) / (-2.0 * Btemp + 1.0)) + (-Btemp / (-2.0 * Btemp + 1.0));

  34.         float value = max(max(B.r, B.g), B.b);
  35.         float3 colorr = B / value;
  36.         colorr = pow(abs(colorr), 1.0 / Colorfulness);

  37.         float3 c0 = colorr * value;
  38.         c0 = mul(XYZ, c0);
  39.         float luma = dot(c0, float3(0.30, 0.59, 0.11));
  40.         c0 = (1.0 - Saturation) * luma + Saturation * c0;
  41.         c0 = mul(RGB, c0);

  42.         return lerp(input, c0, Strength);
  43. }
  44. // Final {{{1
复制代码
2)找到这段代码:
  1. //--float2 luminanceAvgMax = tex2D(postFX_sampler2, float2(0.5f, 0.5f)).rg;
  2. //--return tex2D(postFX_sampler2, texCoord).y * 100;
复制代码


另起一行添加输出代码:
  1. //--float2 luminanceAvgMax = tex2D(postFX_sampler2, float2(0.5f, 0.5f)).rg;
  2. //--return tex2D(postFX_sampler2, texCoord).y * 100;

  3. //Vibrance {{{2
  4. color.rgb = Vibrance(color.rgb, 0.3, float3(0.6,0.6,1.0));

  5. //DPX {{{2
  6. color.rgb = DPX(color.rgb, float3(15,15,15), float3(0.33,0.33,0.33), 0.58, 1.6, 1.5, 0.20);
复制代码

3)保存文件
分析部分:
1)关于调整数据:
以DPX为例,它的移植代码里面有这一行:
  1. float3 DPX(float3 color, float3 RGB_Curve, float3 RGB_C, float Contrast, float Saturation, float Colorfulness, float Strength)
复制代码
输出代码里面有这一行:
  1. color.rgb = DPX(color.rgb, float3(15,15,15), float3(0.33,0.33,0.33), 0.58, 1.6, 1.5, 0.20);
复制代码
看到这,你会发现float是一一对应的关系:
float3 RGB_Curve对应float3(15,15,15);float3 RGB_C对应float3(0.33,0.33,0.33);float Contrast对应0.58;float Saturation对应1.6;float Colorfulness对应1.5;float Strength对应0.20
2)实时调色
移植代码里面的功能和Reshade里面是一致的。
可以先下载一个Reshade,在Reshade里面把数据调好,再写入postFX.fx


总结:
postFX.fx可以实现的功能还有很多,比如说DOF。目前,我成功移植的Reshade语言仅限于调色功能。也许未来的某一天会有人找到移植MXAO,Lightroomdof,RTGI等高级功能的方法。
愿战团再战十年!





评分

参与人数 2荣誉 +1 第纳尔 +35 互助 +1 魅力 +25 收起 理由
Aomine Daiki + 20 + 20 文章不错,继续努力!
幼稚园殺手 + 1 + 15 + 1 + 5 您的帖子很有价值!

查看全部评分

35

主题

468

回帖

251

积分

见习骑士

Rank: 3

UID
3257703
第纳尔
2062
精华
0
互助
16
荣誉
2
贡献
10
魅力
118
注册时间
2021-8-1

骑砍中文站APP会员勋章

鲜花(80) 鸡蛋(0)
 楼主| 发表于 2023-2-2 14:32:07 | 显示全部楼层
补充一点,如果出现ps_2_0报错,把postFX.fx里面的所有ps_2_0改为PS_2_X

51

主题

287

回帖

101

积分

见习骑士

Rank: 3

UID
2880114
第纳尔
1576
精华
0
互助
0
荣誉
0
贡献
0
魅力
3
注册时间
2017-9-30
QQ
鲜花(12) 鸡蛋(0)
发表于 2023-2-2 17:52:07 | 显示全部楼层
shaders可以修改大地图光影变化吗?

35

主题

468

回帖

251

积分

见习骑士

Rank: 3

UID
3257703
第纳尔
2062
精华
0
互助
16
荣誉
2
贡献
10
魅力
118
注册时间
2021-8-1

骑砍中文站APP会员勋章

鲜花(80) 鸡蛋(0)
 楼主| 发表于 2023-2-2 19:12:39 | 显示全部楼层
djman 发表于 2023-2-2 17:52
shaders可以修改大地图光影变化吗?

请问你是指大地图的亮度吗?天空盒子和postFX.fx都可以影响大地图的亮度。

51

主题

287

回帖

101

积分

见习骑士

Rank: 3

UID
2880114
第纳尔
1576
精华
0
互助
0
荣誉
0
贡献
0
魅力
3
注册时间
2017-9-30
QQ
鲜花(12) 鸡蛋(0)
发表于 2023-2-2 19:29:33 | 显示全部楼层
fengguoyehao 发表于 2023-2-2 19:12
请问你是指大地图的亮度吗?天空盒子和postFX.fx都可以影响大地图的亮度。

就是大地图上模拟太阳光照变化,就像骑砍2,战团大地图编辑器里也可以调节太阳的位置,光影也会变化。而战团游戏大地图里影子是固定的没有变化,而且也只有昼夜变化,没有中午下午的光影变化

35

主题

468

回帖

251

积分

见习骑士

Rank: 3

UID
3257703
第纳尔
2062
精华
0
互助
16
荣誉
2
贡献
10
魅力
118
注册时间
2021-8-1

骑砍中文站APP会员勋章

鲜花(80) 鸡蛋(0)
 楼主| 发表于 2023-2-2 19:38:20 | 显示全部楼层
djman 发表于 2023-2-2 19:29
就是大地图上模拟太阳光照变化,就像骑砍2,战团大地图编辑器里也可以调节太阳的位置,光影也会变化。而 ...

我知道有一个天空盒可以实现你说的功能:https://forums.taleworlds.com/in ... 42181/#post-8161786

51

主题

287

回帖

101

积分

见习骑士

Rank: 3

UID
2880114
第纳尔
1576
精华
0
互助
0
荣誉
0
贡献
0
魅力
3
注册时间
2017-9-30
QQ
鲜花(12) 鸡蛋(0)
发表于 2023-2-2 19:43:55 | 显示全部楼层
fengguoyehao 发表于 2023-2-2 19:38
我知道有一个天空盒可以实现你说的功能:https://forums.taleworlds.com/index.php?threads/skyboxes-lig ...

还有战团设置里的伽马值调的最高还是有些暗,能提高伽马值的上限吗

35

主题

468

回帖

251

积分

见习骑士

Rank: 3

UID
3257703
第纳尔
2062
精华
0
互助
16
荣誉
2
贡献
10
魅力
118
注册时间
2021-8-1

骑砍中文站APP会员勋章

鲜花(80) 鸡蛋(0)
 楼主| 发表于 2023-2-2 19:51:06 | 显示全部楼层
djman 发表于 2023-2-2 19:43
还有战团设置里的伽马值调的最高还是有些暗,能提高伽马值的上限吗

可以,就用postFX.fx调,但必须打开HDR才能生效

35

主题

468

回帖

251

积分

见习骑士

Rank: 3

UID
3257703
第纳尔
2062
精华
0
互助
16
荣誉
2
贡献
10
魅力
118
注册时间
2021-8-1

骑砍中文站APP会员勋章

鲜花(80) 鸡蛋(0)
 楼主| 发表于 2023-2-2 19:52:29 | 显示全部楼层
本帖最后由 fengguoyehao 于 2023-2-2 19:55 编辑
djman 发表于 2023-2-2 19:43
还有战团设置里的伽马值调的最高还是有些暗,能提高伽马值的上限吗

我不会调伽马值的上限,不过我会用postFX.fx调节HDR模式下的亮度

23

主题

331

回帖

266

积分

见习骑士

Rank: 3

UID
3189500
第纳尔
2549
精华
0
互助
24
荣誉
4
贡献
10
魅力
235
注册时间
2020-6-13
鲜花(66) 鸡蛋(0)
发表于 2023-2-17 21:35:24 | 显示全部楼层
这是我诱导chatgpt编写的添加模拟光追的代码,由于我还不太懂相关代码,请楼主看看是否经优化后可行,不妨分享出来
“首先,需要在shader文件中定义一些变量和函数来实现模拟光线追踪的效果。以下是一个简单的示例:”
  1. // 定义场景中的相机
  2. float4x4 view_matrix; // 相机观察矩阵
  3. float4x4 projection_matrix; // 相机投影矩阵

  4. // 定义光线追踪的变量
  5. float3 ray_origin; // 光线起点
  6. float3 ray_direction; // 光线方向
  7. float3 ray_color; // 光线颜色

  8. // 定义光线追踪的函数
  9. float3 TraceRay(float3 ray_origin, float3 ray_direction, int depth)
  10. {
  11.     // 计算光线与场景中物体的交点
  12.     float t = 10000.0; // 初始最大距离
  13.     float3 hit_point = ray_origin;
  14.     float3 hit_normal = 0;
  15.     for (int i = 0; i < num_objects; i++) {
  16.         float t_obj = Intersect(ray_origin, ray_direction, objects[i]);
  17.         if (t_obj > 0 && t_obj < t) {
  18.             t = t_obj;
  19.             hit_point = ray_origin + ray_direction * t;
  20.             hit_normal = CalculateNormal(hit_point, objects[i]);
  21.         }
  22.     }

  23.     // 计算光线的颜色
  24.     if (t < 10000.0) { // 有交点
  25.         // 添加光照效果
  26.         float3 diffuse_color = 0;
  27.         for (int i = 0; i < num_lights; i++) {
  28.             float3 light_direction = Normalize(lights[i].position - hit_point);
  29.             float ndotl = dot(hit_normal, light_direction);
  30.             if (ndotl > 0) {
  31.                 float3 shadow_ray_direction = light_direction;
  32.                 float shadow_t = Intersect(hit_point, shadow_ray_direction, objects);
  33.                 if (shadow_t > 0 && shadow_t < Length(lights[i].position - hit_point)) {
  34.                     ndotl = 0; // 有阴影
  35.                 }
  36.             }
  37.             diffuse_color += lights[i].color * ndotl;
  38.         }
  39.         float3 ambient_color = ambient_intensity * ambient_color;
  40.         ray_color = diffuse_color + ambient_color;
  41.     } else { // 没有交点
  42.         ray_color = background_color;
  43.     }

  44.     // 添加反射效果
  45.     if (depth > 0 && reflection_intensity > 0) {
  46.         float3 reflected_direction = Normalize(ray_direction - 2 * dot(ray_direction, hit_normal) * hit_normal);
  47.         float3 reflected_color = TraceRay(hit_point, reflected_direction, depth - 1);
  48.         ray_color = Lerp(ray_color, reflected_color, reflection_intensity);
  49.     }

  50.     return ray_color;
  51. }
复制代码
“接下来就是在像素着色器函数中调用这个光线追踪函数,获取每个像素的颜色值。下面是一个简单的示例:”
  1. float4 PS(VertexShaderOutput input) : SV_Target
  2. {
  3.     float3 rayDirection = normalize(input.worldPosition - cameraPosition); // 计算光线方向
  4.     float3 color = TraceRay(input.worldPosition, rayDirection, 0); // 调用光线追踪函数获取颜色值
  5.     return float4(color, 1.0f); // 返回颜色值
  6. }
复制代码



B站个人空间:https://b23.tv/rZhCYpH

23

主题

331

回帖

266

积分

见习骑士

Rank: 3

UID
3189500
第纳尔
2549
精华
0
互助
24
荣誉
4
贡献
10
魅力
235
注册时间
2020-6-13
鲜花(66) 鸡蛋(0)
发表于 2023-2-22 14:12:20 | 显示全部楼层
楼主有进展吗??
B站个人空间:https://b23.tv/rZhCYpH

30

主题

200

回帖

169

积分

见习骑士

Rank: 3

UID
2462463
第纳尔
1472
精华
0
互助
20
荣誉
0
贡献
0
魅力
50
注册时间
2015-3-3
鲜花(43) 鸡蛋(0)
发表于 2023-2-23 23:53:49 | 显示全部楼层
代码是看不懂了,但是学会了把“postFX.fx”复制到其他mod,相当于打了enb,不错不错

35

主题

468

回帖

251

积分

见习骑士

Rank: 3

UID
3257703
第纳尔
2062
精华
0
互助
16
荣誉
2
贡献
10
魅力
118
注册时间
2021-8-1

骑砍中文站APP会员勋章

鲜花(80) 鸡蛋(0)
 楼主| 发表于 2023-4-7 20:25:05 | 显示全部楼层
apk43 发表于 2023-2-17 21:35
这是我诱导chatgpt编写的添加模拟光追的代码,由于我还不太懂相关代码,请楼主看看是否经优化后可行,不妨 ...

这个代码太不完整了,我的能力有限,目前没有办法写入骑砍postFX.fx

23

主题

331

回帖

266

积分

见习骑士

Rank: 3

UID
3189500
第纳尔
2549
精华
0
互助
24
荣誉
4
贡献
10
魅力
235
注册时间
2020-6-13
鲜花(66) 鸡蛋(0)
发表于 2023-4-7 21:12:01 | 显示全部楼层
fengguoyehao 发表于 2023-4-7 20:25
这个代码太不完整了,我的能力有限,目前没有办法写入骑砍postFX.fx

postFX.txt (31.57 KB, 下载次数: 108) 由于帖子限制,我改了后缀。
可以看看我根据Reshade插件Glamarye_Fast_Effects和_Sebastian_写的ssao代码改的,你下载看看效果如何。不知道为啥在WSE2无效,所以我的mod还是用的reshade

鲜花鸡蛋

fengguoyehao  在2023-4-7 22:49  送朵鲜花  并说:太强了!
fengguoyehao  在2023-4-7 22:47  送朵鲜花  并说:我非常同意你的观点,送朵鲜花鼓励一下
fengguoyehao  在2023-4-7 22:46  送朵鲜花  并说:我非常同意你的观点,送朵鲜花鼓励一下
B站个人空间:https://b23.tv/rZhCYpH

35

主题

468

回帖

251

积分

见习骑士

Rank: 3

UID
3257703
第纳尔
2062
精华
0
互助
16
荣誉
2
贡献
10
魅力
118
注册时间
2021-8-1

骑砍中文站APP会员勋章

鲜花(80) 鸡蛋(0)
 楼主| 发表于 2023-4-7 22:44:32 | 显示全部楼层
apk43 发表于 2023-4-7 21:12
由于帖子限制,我改了后缀。
可以看看我根据Reshade插件Glamarye_Fast_Effects和_Sebastian_写的ssao代 ...

太强了!请问你是怎么把这个需要获取深度信息的fx成功移植进骑砍的postFX.fx的?我到现在只会移植一些如Tonemap、DPX的纯调色功能

35

主题

468

回帖

251

积分

见习骑士

Rank: 3

UID
3257703
第纳尔
2062
精华
0
互助
16
荣誉
2
贡献
10
魅力
118
注册时间
2021-8-1

骑砍中文站APP会员勋章

鲜花(80) 鸡蛋(0)
 楼主| 发表于 2023-4-7 22:45:11 | 显示全部楼层
本帖最后由 fengguoyehao 于 2023-4-7 22:46 编辑
apk43 发表于 2023-4-7 21:12
由于帖子限制,我改了后缀。
可以看看我根据Reshade插件Glamarye_Fast_Effects和_Sebastian_写的ssao代 ...

mb36.jpg mb35.jpg

甚至把原本postFX.fx高光位置过曝的问题解决了!

35

主题

468

回帖

251

积分

见习骑士

Rank: 3

UID
3257703
第纳尔
2062
精华
0
互助
16
荣誉
2
贡献
10
魅力
118
注册时间
2021-8-1

骑砍中文站APP会员勋章

鲜花(80) 鸡蛋(0)
 楼主| 发表于 2023-4-7 22:52:03 | 显示全部楼层
apk43 发表于 2023-4-7 21:12
由于帖子限制,我改了后缀。
可以看看我根据Reshade插件Glamarye_Fast_Effects和_Sebastian_写的ssao代 ...

发现了一个无关紧要的小问题,火光会变白,应该是数据调节问题: mb37.jpg

35

主题

468

回帖

251

积分

见习骑士

Rank: 3

UID
3257703
第纳尔
2062
精华
0
互助
16
荣誉
2
贡献
10
魅力
118
注册时间
2021-8-1

骑砍中文站APP会员勋章

鲜花(80) 鸡蛋(0)
 楼主| 发表于 2023-4-7 23:11:18 | 显示全部楼层
apk43 发表于 2023-4-7 21:12
由于帖子限制,我改了后缀。
可以看看我根据Reshade插件Glamarye_Fast_Effects和_Sebastian_写的ssao代 ...

屏幕空间光线追踪全局光照:https://bbs.mountblade.com.cn/thread-2043687-1-1.html
去年我与这个帖子的作者聊过几句。作者说这个画面是通过Marty Mcfly's rt shader和MagicHDR(还有DPX),结合了天空盒子调节出来的。Marty Mcfly's rt shader应该是最好的“伪”光追了。这是包含了所有Marty Mcfly's rt shader版本的文件,麻烦一下,可以帮忙看一看有可能移植到postFX.fx里面吗? RTGI.zip (3.31 MB, 下载次数: 89)


23

主题

331

回帖

266

积分

见习骑士

Rank: 3

UID
3189500
第纳尔
2549
精华
0
互助
24
荣誉
4
贡献
10
魅力
235
注册时间
2020-6-13
鲜花(66) 鸡蛋(0)
发表于 2023-4-7 23:25:20 | 显示全部楼层
fengguoyehao 发表于 2023-4-7 22:44
太强了!请问你是怎么把这个需要获取深度信息的fx成功移植进骑砍的postFX.fx的?我到现在只会移植一些如T ...

获取深度的代码是官网论坛上的,但是移植Reshader的Fake GI的时候用的sampler我是一个个试的,不知道行不行。但是SSAO是肯定行的
B站个人空间:https://b23.tv/rZhCYpH

23

主题

331

回帖

266

积分

见习骑士

Rank: 3

UID
3189500
第纳尔
2549
精华
0
互助
24
荣誉
4
贡献
10
魅力
235
注册时间
2020-6-13
鲜花(66) 鸡蛋(0)
发表于 2023-4-7 23:27:36 | 显示全部楼层
fengguoyehao 发表于 2023-4-7 23:11
屏幕空间光线追踪全局光照:https://bbs.mountblade.com.cn/thread-2043687-1-1.html
去年我与这个帖子 ...

我用过RTGI,虽然效果很好,但是性能骤降。移植估计够呛,太过复杂
B站个人空间:https://b23.tv/rZhCYpH

35

主题

468

回帖

251

积分

见习骑士

Rank: 3

UID
3257703
第纳尔
2062
精华
0
互助
16
荣誉
2
贡献
10
魅力
118
注册时间
2021-8-1

骑砍中文站APP会员勋章

鲜花(80) 鸡蛋(0)
 楼主| 发表于 2023-4-7 23:33:05 | 显示全部楼层
本帖最后由 fengguoyehao 于 2023-4-7 23:38 编辑
apk43 发表于 2023-4-7 23:27
我用过RTGI,虽然效果很好,但是性能骤降。移植估计够呛,太过复杂

我有一个远景模糊的fx,一直想移植,但却一直没有成功,我一直无法获取深度信息。请问可以帮我看一下吗?麻烦了! LightDoF.zip (2.69 KB, 下载次数: 83)

23

主题

331

回帖

266

积分

见习骑士

Rank: 3

UID
3189500
第纳尔
2549
精华
0
互助
24
荣誉
4
贡献
10
魅力
235
注册时间
2020-6-13
鲜花(66) 鸡蛋(0)
发表于 2023-4-7 23:50:38 | 显示全部楼层
fengguoyehao 发表于 2023-4-7 23:33
我有一个远景模糊的fx,一直想移植,但却一直没有成功,我一直无法获取深度信息。请问可以帮我看一下 ...

稍微改良了一下景深效果 - MOD制作资料区 - 骑马与砍杀中文站论坛 - Powered by Discuz! (mountblade.com.cn)
要不你看看这个?
B站个人空间:https://b23.tv/rZhCYpH

3

主题

136

回帖

42

积分

扈从

Rank: 2Rank: 2

UID
3054596
第纳尔
694
精华
0
互助
0
荣誉
0
贡献
0
魅力
0
注册时间
2019-1-19

骑砍中文站APP会员勋章

鲜花(2) 鸡蛋(0)
发表于 2024-2-9 21:58:38 | 显示全部楼层
都下不了你给的链接有什么用?
您需要登录后才可以回帖 登录 | 注册(Register!)

本版积分规则

Archiver|手机版|小黑屋|骑马与砍杀中文站

GMT+8, 2024-4-25 23:54 , Processed in 0.152821 second(s), 28 queries , Gzip On, MemCached On.

Powered by Discuz! X3.4 Licensed

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表