mc光影吧 关注:8,603贴子:130,418
  • 15回复贴,共1

[教程] 移植Chocapic13 v6的镜头光晕到Complementary

只看楼主收藏回复

先放效果图



IP属地:山东1楼2025-02-23 09:12回复
    成功还原的功能:
    光晕本体
    太阳越靠近屏幕中心光晕强度越弱
    雨天强度减弱
    complementary原版自带的滑块控制光晕强度
    改进/重置的功能:
    光晕强度随地形遮挡程度加深而减弱(由累加改为随机采样)
    光晕强度暗区增益大,亮区增益小(修复了chocapic13原版的失真)
    未实现/有bug的功能:
    模式只支持“仅太阳”不支持“日月”
    太阳离开屏幕边缘光晕直接消失,没有淡入淡出


    IP属地:山东2楼2025-02-23 09:26
    回复
      第一步,找到complementary目录内shaders\lib\misc的lensFlare.glsl,用文本编辑器打开它(推荐vscode和notepad++等)


      IP属地:山东3楼2025-02-23 09:29
      回复
        第二步,同样的打开chocapic13 v6的shaders文件夹内composite2.fsh


        IP属地:山东4楼2025-02-23 09:32
        收起回复
          interesting


          IP属地:山东来自Android客户端5楼2025-02-23 09:35
          回复
            第三步(删!)
            依次按照这个顺序把lensFlare.glsl中的内容全删掉:1-39行、12-32行、27-50行、30-31行、36-39行
            全部完成后应该看起来是这个样子


            IP属地:山东6楼2025-02-23 09:47
            回复
              第四步
              把6-9行的内容换成以下内容:(composite2.vsh第182-185行)
              vec4 tpos = vec4(sunPosition,1.0)*gbufferProjection; tpos = vec4(tpos.xyz/tpos.w,1.0); vec2 pos1 = tpos.xy/tpos.z; vec2 lightPos = pos1*0.5+0.5;
              然后在最前面加入以下内容:
              uniform vec3 sunPosition;
              float sunVisibility = pow(clamp(SdotU+0.15,0.0,0.15)/0.15,4.0);


              IP属地:山东7楼2025-02-23 09:51
              回复
                第五步(移植光晕本体)
                在第19行下面复制粘贴composite2.fsh的第524-1763行(应该是以左大括号开始,右大括号结束)
                然后查找替换所有texcoord为texCoord、所有lightColor为color
                然后把vec2 ntc2 = texCoord后面的*2.0-1.0删掉


                IP属地:山东8楼2025-02-23 09:58
                回复
                  第六步(制作太阳遮罩)
                  把30-36行的内容替换成
                  //随机采样检测地形遮挡float visibility = 0.0;
                  for(int i = 0; i < 16; i++) {
                  float random1 = fract(sin(float(i)*12.9898) * 43758.5453); float random2 = fract(sin(float(i)*78.233) * 43758.5453); vec2 offset = vec2( (random1 * 2.0 - 1.0) * 0.04, (random2 * 2.0 - 1.0) * 0.04 );
                  vec2 sampleCoord = lightPos + offset; float sceneDepth = texture(depthtex1, sampleCoord).r;
                  visibility += step(1.0, sceneDepth);}
                  visibility /= 16;
                  //检测屏幕边缘bool inBounds = all(greaterThan(lightPos, vec2(-0.12))) && all(lessThan(lightPos, vec2(1.12)));
                  //最终遮罩计算float sunmask = visibility * float(inBounds && isEyeInWater <= 0.1 && blindness == 0.0);


                  IP属地:山东9楼2025-02-23 10:01
                  回复
                    第七步(制作雨天衰减)
                    把第56行的sunmask *= (1.0 - rainStrength);删掉,把1281-1289行的内容拿上来,把前两个flareFactor改成sunmask


                    IP属地:山东10楼2025-02-23 10:08
                    回复
                      第八步(修复太阳越靠近屏幕中心颜色越暗的bug以及制作反转响应曲线)
                      找到下面的Darken colors if the sun is visible这部分
                      把vec3 lenslc这句提到3个color.rgb前面,然后把3个color改成lenslc
                      在vec3 lenslc前面加上以下内容:
                      //物理亮度计算(CIE标准)const vec3 luminanceWeights = vec3(0.2126, 0.7152, 0.0722);float perceivedLuminance = dot(color, luminanceWeights);
                      //反转响应曲线(暗区增益大,亮区增益小)float inverseResponse = 1.0 - smoothstep(0.1, 0.9, perceivedLuminance); inverseResponse = pow(inverseResponse, 0.5) * 2.0; //伽马校正
                      然后把中间的*length(color)改成*inverseResponse


                      IP属地:山东11楼2025-02-23 10:15
                      收起回复
                        剩下的根据个人需要自行调整参数、删改光晕即可,以下是我的个人方案抛砖引玉(改太阳中心那几个过于晃眼的)
                        flare_strip1_scale改成vec2(0.5*flarescale, 20.0*flarescale),color.r改成0.14,g改成0.13,并且删掉后面的*flaremult(让它强度始终恒定不会因为太阳靠近屏幕中心而衰减)
                        flare_strip3_fill改成2.0,pow改成0.25,color.r和g分别改成0.3和0.7
                        改前vs改后





                        IP属地:山东12楼2025-02-23 10:32
                        回复
                          另外我这还整了一套模仿chocapic13 v6风格的调色,不知道有没有人感兴趣







                          IP属地:山东13楼2025-02-23 10:42
                          回复
                            实现太阳进入/离开屏幕边缘的淡入淡出:
                            在 //检测屏幕边缘 部分把bool inBounds删了,改成这个:
                            float edgeMaskx = 1.0 - clamp(distance(lightPos.x, 0.5f)*9.0f - 4.5f, 0.0f, 1.0f);float edgeMasky = 1.0 - clamp(distance(lightPos.y, 0.5f)*9.0f - 4.5f, 0.0f, 1.0f);
                            float edgeMask = edgeMaskx * edgeMasky;
                            然后在下面 //最终遮罩计算 sunmask乘上edgeMask ,float(...); 里面的inBounds删了


                            IP属地:山东14楼2025-02-28 07:53
                            回复