mirror of
https://github.com/jessicanataliagta/PSPRecomp
synced 2026-09-26 16:49:34 -04:00
clouds almost done
clouds almost done
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
Enabled=true
|
||||
DownscaleDiv=2
|
||||
Layers=2
|
||||
ShadowSteps=4
|
||||
ShadowSteps=8
|
||||
Opacity=1.0
|
||||
Speed=0.0
|
||||
Brightness=1.0
|
||||
@@ -38,6 +38,6 @@ FogColorB=0.78
|
||||
FogStart=4500.0
|
||||
|
||||
; ProperShaders temporal resolve controls.
|
||||
TemporalBlend=0.85
|
||||
TemporalBlend=0.50
|
||||
TemporalDenoise=1.0
|
||||
TemporalClamp=1.0
|
||||
|
||||
@@ -158,9 +158,13 @@ float DetailB(float lump,float3 pos,float3 density,float3 scale,float4 dp,float3
|
||||
dens+=density.y*noise3d((pD+d/3)*scale.y);dens+=dens*density.z*noise3d((pD+d*8)*scale.z);return dens;}
|
||||
float GetDensity(float df,float height,float low,float high,float2 vb,float2 sol){return clampMap(df,low,high,0,clampMap(height,vb.y,vb.x,sol.y,sol.x));}
|
||||
float ShadowMarching(float dens,float3 p,CloudProfile a,float3 threshold,float3 sunDir){
|
||||
if(dens<=0.025)return dens*a.shadow.x;float stepLen=a.shadow.x*2.0;
|
||||
float limit=2.0/a.shadow.w/stepLen,d=0;float4 st=float4(sunDir*stepLen,stepLen);
|
||||
uint shadowSteps=(g_Settings>>8)&15u;
|
||||
if(dens<=0.025)return dens*a.shadow.x;
|
||||
// ProperShaders used four large samples for the DX9/SM3 instruction budget.
|
||||
// DX12 can split the same physical shadow-march reach into up to eight
|
||||
// samples, removing the dark density contours without changing its extent.
|
||||
float stepLen=a.shadow.x*(8.0/max((float)shadowSteps,1.0));
|
||||
float limit=2.0/a.shadow.w/stepLen,d=0;float4 st=float4(sunDir*stepLen,stepLen);
|
||||
[loop]for(uint i=0;i<8;i++){if(i>=shadowSteps||d>=limit||p.z>=a.volumeBox.x||p.z<=a.volumeBox.y)break;
|
||||
p+=st.xyz;float4 cs=CloudShape(p.z,a.shape,threshold);float d1=Chunk(p,a.densityChunk,a.scaleChunk,a.cloudShift,a.offsetA,a.offsetB,cs.x);
|
||||
float d2=DetailA(p,a.densityDetail,a.scaleDetail,a.offsetC,DistortionVec(d1,a.distortion))*a.shadow.y;
|
||||
@@ -188,6 +192,34 @@ float4 CloudAtRay(CloudProfile a,CloudBaseColor b,float3 dir,float3 cam,float3 l
|
||||
distance=distance*fx.z+d.y*(1-fx.z);return float4(C,fx.z);}}
|
||||
return float4(0,0,0,1);}
|
||||
|
||||
float4 CloudAtRayHighLite(CloudBaseColor b,float3 dir,float3 cam,float3 light,float3 lightDir,float time,inout float distance){
|
||||
const float top=3600.0,bottom=3500.0;float4 d=float4(0,0,0,75);
|
||||
float3 p=PosOnPlane(cam,dir,clamp(cam.z,bottom+.001,top-.001),d.x);d.y=d.x;
|
||||
if(d.x>=0&&distance>d.x){
|
||||
float coverage=g_CloudCoverage.z;float3 range=float3(1+coverage*.3,.2,.35);
|
||||
float grow=noise3d(float3(3800,bottom,time/2000))*.45+.65;
|
||||
range.x*=grow*(1-coverage)+coverage;range.x=1/range.x;
|
||||
const float2 volumeBox=float2(top,bottom),solidness=float2(.25,0),densityChunk=float2(.4,.3);
|
||||
const float3 scaleChunk=float3(.00016,.0008,1.5),densityDetail=float3(.2,.1,.6),scaleDetail=float3(.004,.006667,.02);
|
||||
const float4 distortion=float4(2.5,15000,0,0);
|
||||
float3 oA=float3(1.3,-1.8,0)*-time,oB=float3(1.6,.8,0)*-time;
|
||||
float3 oC=float3(2.5,.2,.5)*-time,oD=float3(3,.1,-.1)*-time;
|
||||
float3 fx=float3(0,0,1);float last=0,pdf=0;
|
||||
[loop]for(int i=0;i<32;i++){
|
||||
if(fx.z<=0||p.z>top||p.z<bottom||d.x-d.w>=distance||d.x>=60000)break;
|
||||
float3 cs=CloudShape(p.z,float4(3800,3520,3450,0),range).xyz;
|
||||
float d1=Chunk(p,densityChunk,scaleChunk,0,oA,oB,cs.x);
|
||||
float d2=DetailB(d1,p,densityDetail,scaleDetail,distortion,oC,oD,cs.x);float df=d1*d2+d1;
|
||||
if(df>cs.z){float dens=GetDensity(df,p.z,cs.z,cs.y,volumeBox,solidness);float cd=(dens+last)*2.5;last=dens;
|
||||
if(d.x>=distance)cd*=d.z/d.w;if(cd>0)d.y=d.y*(1-fx.z)+fx.z*d.x;
|
||||
fx.y+=cd;fx.z=(exp(-fx.y)-.2)/.8;d.z=distance-d.x;if(fx.y<2.3)fx.x+=cd*exp(-fx.y);}
|
||||
d.w=clampMap(2*df-pdf,cs.z*.85,0,5,75);d.w*=clampMap(d.x,0,2000000,1,500);
|
||||
d.w+=noise2d(p+g_Time)*5;pdf=df;p+=dir*d.w;d.x+=d.w;}
|
||||
if(fx.z<1){fx=saturate(fx);float3 cbright=light*(.5/LightingDecay);
|
||||
float3 C=cbright*fx.x*MiePhase(dot(lightDir,dir))+(b.BaseColor*g_vCloudBaseColor)*(1-fx.z);
|
||||
distance=distance*fx.z+d.y*(1-fx.z);return float4(C,fx.z);}}
|
||||
return float4(0,0,0,1);}
|
||||
|
||||
CloudProfile BuildProfile0(float time,float coverage){CloudProfile p=(CloudProfile)0;
|
||||
p.march=float4(5,80,8,64);p.cutoff=float2(0,.2);p.volumeBox=float2(900,500);p.shape=float4(900,650,0,0);p.brightness=.5;
|
||||
p.range=float3(.9+coverage*.16,.1,.2+coverage*.4);p.solidness=float2(5,0)*coverage;p.densityChunk=float2(.3,.5);
|
||||
@@ -216,7 +248,7 @@ float4 RenderClouds(float3 dir,float3 cam){float time=gameTime();CloudBaseColor
|
||||
float3 lightDir=normalize(vSunLightDir);float3 light=LightSource(lightDir,fDayProgression,g_vSunColor,lightDir);float distance=100000;
|
||||
float4 result=CloudAtRay(BuildProfile0(time,g_CloudCoverage.x),base,dir,cam,light,lightDir,time,distance);
|
||||
uint layers=g_Settings&3u;if(layers>=3u&&result.w>.01){float4 mid=CloudAtRay(BuildProfile1(time,g_CloudCoverage.y),base,dir,cam,light,lightDir,time,distance);result.rgb+=mid.rgb*result.w;result.w*=mid.w;}
|
||||
if(layers>=2u&&result.w>.01){float4 high=CloudAtRay(BuildProfile2(time,g_CloudCoverage.z),base,dir,cam,light,lightDir,time,distance);result.rgb+=high.rgb*result.w;result.w*=high.w;}
|
||||
if(layers>=2u&&result.w>.01){float4 high=CloudAtRayHighLite(base,dir,cam,light,lightDir,time,distance);result.rgb+=high.rgb*result.w;result.w*=high.w;}
|
||||
return result;}
|
||||
float3 WorldRay(float2 uv){float2 ndc=float2(uv.x*2-1,1-uv.y*2);return normalize(CloudRayForward+CloudRayRight*ndc.x+CloudRayUp*ndc.y);}
|
||||
|
||||
|
||||
@@ -2176,11 +2176,10 @@ CloudShaderConstants cloud_present_constants(const Dx12GeState &s) noexcept {
|
||||
out.ray_forward_opacity[axis] = static_cast<float>(center_world[axis]);
|
||||
out.camera_settings[axis] = camera->camera_position[axis];
|
||||
}
|
||||
// ProperShaders supplies g_Time in milliseconds. The stochastic march
|
||||
// offset deliberately changes every frame so temporal accumulation can
|
||||
// average it away; seconds made adjacent samples nearly identical and left
|
||||
// the high-frequency grain fixed on screen.
|
||||
out.ray_right_time[3] = static_cast<float>(s.frame_epoch) * (1000.0f / 60.0f);
|
||||
// ProperShaders converts CTimer's milliseconds to seconds before setting
|
||||
// g_Time. Keep the same unit: both the stochastic march and the animated
|
||||
// density field use this value directly.
|
||||
out.ray_right_time[3] = static_cast<float>(s.frame_epoch) * (1.0f / 60.0f);
|
||||
out.ray_up_seed[3] = config.random_seed;
|
||||
out.ray_forward_opacity[3] = config.opacity;
|
||||
const std::uint32_t settings = std::clamp<std::uint32_t>(config.layers, 1u, 3u) |
|
||||
|
||||
@@ -182,7 +182,7 @@ struct VolumetricCloudsConfiguration {
|
||||
bool enabled{false};
|
||||
std::uint32_t downscale_div{2u};
|
||||
std::uint32_t layers{2u};
|
||||
std::uint32_t shadow_steps{4u};
|
||||
std::uint32_t shadow_steps{8u};
|
||||
float coverage_low{0.35f};
|
||||
float coverage_mid{0.25f};
|
||||
float coverage_high{0.18f};
|
||||
@@ -206,7 +206,7 @@ struct VolumetricCloudsConfiguration {
|
||||
float fog_color_b{0.78f};
|
||||
float fog_start{4500.0f};
|
||||
float day_progression{0.88f};
|
||||
float temporal_blend{0.85f};
|
||||
float temporal_blend{0.50f};
|
||||
float temporal_denoise{1.0f};
|
||||
float temporal_clamp{1.0f};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user