Files
Liubing\LB 3d8d4d18f3 first commit
先修复一下,错误的场景

删除不必要的钓场资产

修复into场景

update:更新meta文件,修复报错

update:修复资源

修复第一章节建造

修复建造第三章

update:删除多余内容

update:更新README.md

update:还原图标

update:更新README

update:更新配置
2026-04-28 02:17:22 +08:00

236 lines
8.4 KiB
HLSL

struct SceneData
{
float4 positionNDC; //Unnormalized
float2 screenPos; //Normalized and no refraction
float3 positionWS;
float3 color;
float refractionMask;
float viewDepth;
float verticalDepth;
};
// Project from eye space to world space
#define WorldPosFromDepth(NDCw, depth, viewDir) -(depth.eye * (viewDir/NDCw) - _WorldSpaceCameraPos)
//Linear depth difference between scene and current (transparent) geometry pixel
#define SurfaceDepth(depth, positionCS) depth.eye - LinearEyeDepth(positionCS.z, _ZBufferParams)
void PopulateSceneData(inout SceneData scene, in Varyings input, in WaterSurface water)
{
const float2 screenPos = input.positionNDC.xy / input.positionNDC.w;
scene.positionNDC = input.positionNDC;
scene.screenPos = screenPos;
//Default for disabled depth texture scene.viewDepth = 1;
scene.verticalDepth = 1;
#ifdef _REFRACTION
SceneDepth depth = SampleDepth(screenPos);
float3 positionWS = WorldPosFromDepth(input.positionNDC.w, depth, water.viewDelta);
float viewDepth = SurfaceDepth(depth, input.positionCS);
const float2 refractionOffset = input.normalWS.xz * 0.5 * _RefractionStrength;
SceneDepth depthRefract = SampleDepth(screenPos + refractionOffset);
float3 positionWSRefract = WorldPosFromDepth(input.positionNDC.w, depthRefract, water.viewDelta);
float viewDepthRefract = SurfaceDepth(depthRefract, input.positionCS);
float mask = saturate(viewDepth) * saturate(viewDepthRefract);
scene.positionWS = lerp(positionWS, positionWSRefract, mask);
scene.viewDepth = lerp(viewDepth, viewDepthRefract, mask);
//Distance to opaque geometry in normal direction
scene.verticalDepth = length((water.positionWS - scene.positionWS) * water.vertexNormal);
scene.color = SampleSceneColor(screenPos + refractionOffset * mask);
scene.refractionMask = mask;
#else
SceneDepth depth = SampleDepth(screenPos);
scene.positionWS = WorldPosFromDepth(input.positionNDC.w, depth, water.viewDelta);
scene.viewDepth = SurfaceDepth(depth, input.positionCS);
scene.verticalDepth = length((water.positionWS - scene.positionWS) * water.vertexNormal);
scene.color = SampleSceneColor(screenPos);
scene.refractionMask = 0;
#endif
}
float GetWaterDensity(SceneData scene, float heightScalar, float viewDepthScalar)
{
const float viewDepth = scene.viewDepth;
const float verticalDepth = scene.verticalDepth;
const float depthAttenuation = 1.0 - exp(-viewDepth * viewDepthScalar * 0.1);
const float heightAttenuation = saturate(verticalDepth * heightScalar);
return max(depthAttenuation, heightAttenuation);
}
float4 ForwardPassFragment(Varyings input) : SV_Target
{
WaterSurface water = (WaterSurface)0;
SceneData scene = (SceneData)0;
float3 normalWS = normalize(input.normalWS.xyz);
float3 WorldTangent = input.tangent.xyz;
float3 WorldBiTangent = input.bitangent.xyz;
//wPos.x in w-component
float3 positionWS = float3(input.normalWS.w, input.tangent.w, input.bitangent.w);
water.alpha = 1.0;
water.positionWS = positionWS;
water.viewDelta = _WorldSpaceCameraPos - positionWS;
float3 viewDir = normalize(water.viewDelta);
water.viewDir = viewDir;
water.vertexNormal = normalize(input.normalWS.xyz);
//Normal
water.tangentNormal = float3(0.5, 0.5, 1);
water.tangentWorldNormal = normalWS;
half VdotN = 1.0 - saturate(dot(viewDir, normalWS));
half4 shadowMask = 1.0;
float4 shadowCoords = float4(0, 0, 0, 0);
Light mainLight = GetMainLight(shadowCoords, water.positionWS, shadowMask);
PopulateSceneData(scene, input, water);
//return float4(scene.verticalDepth.xxx, 1);
//return float4(saturate(scene.viewDepth).xxx, 1);
//return float4(scene.color, 1);
water.fog = GetWaterDensity(scene, _DepthHorizontal, _DepthVertical);
//Albedo
float4 baseColor = lerp(_ShallowColor, _BaseColor, water.fog);
water.fog *= baseColor.a;
water.alpha = baseColor.a;
float fresnel = saturate(pow(VdotN, _HorizonDistance)) * _HorizonColor.a;
water.albedo = lerp(baseColor.rgb, _HorizonColor.rgb, fresnel);
water.edgeFade = saturate(scene.verticalDepth / (_EdgeFade * 0.01));
water.alpha *= water.edgeFade;
// Wave Mesure
#if _INTERSECTION || _WAVE_FOAM
float waveMesure = (positionWS.y - _WaveMesureMin) / (_WaveMesureMax - _WaveMesureMin);
float2 nUV = positionWS.xz * _IntersectionTiling;
float foamTexNoise = SAMPLE_TEXTURE2D(_IntersectionNoise, sampler_IntersectionNoise, nUV + TIME_VERTEX/_IntersectionTiling * _IntersectionSpeed).r;
float interSecGradient = 1-saturate(exp(scene.verticalDepth) / _IntersectionLength);
#endif
#ifdef _WAVE_FOAM
// remap wave from [_WaveFoamClipping,1] to [0,1]
//float waveFoamNoise = (waveMesure - _WaveFoamClipping) / (1 - _WaveFoamClipping) * foamTexNoise;
float waveFoamNoise = smoothstep(_WaveFoamClipping.x, _WaveFoamClipping.y, waveMesure * foamTexNoise);
//return float4(waveFoamNoise.xxx, 1);
#else
float waveFoamNoise = 0;
#endif
/* ========
// Intercection
=========== */
#ifdef _INTERSECTION
float intersecMesure = waveMesure * interSecGradient;
float dist = saturate(interSecGradient / _IntersectionFalloff);
float intersecNoise = saturate(foamTexNoise + intersecMesure) * dist + dist;
intersecNoise = smoothstep(_IntersectionClipping, 1, intersecNoise);
#else
float intersecNoise = 0;
#endif
#if _INTERSECTION || _WAVE_FOAM
float noise = saturate(intersecNoise + waveFoamNoise);
water.albedo.rgb = lerp(water.albedo.rgb, _IntersectionColor.rgb, noise);
water.alpha = saturate(water.alpha + interSecGradient);
#else
float noise = 0;
#endif
/* ========
// Causitcs
=========== */
#ifdef _CAUSTICS
float2 cuv = positionWS.xz * _CausticsTiling;
float coffset = TIME_VERTEX/_CausticsTiling * _CausticsSpeed;
float3 caustics1 = SAMPLE_TEXTURE2D(_CausticsTex, sampler_CausticsTex, cuv + coffset).rgb;
float3 caustics2 = SAMPLE_TEXTURE2D(_CausticsTex, sampler_CausticsTex, cuv*0.8 - coffset).rgb;
// Limit distance from cam and verticalDepth
float3 causticsDensity = saturate((1-length(water.viewDelta) / _CausticsClipping.x) * smoothstep(_CausticsClipping.y,1, scene.verticalDepth));
float3 caustics = min(caustics1, caustics2) * _CausticsBrightness * causticsDensity;
#endif
/* ========
// Reflection Prob
=========== */
half3 reflectionVector = reflect(-viewDir, normalWS);
water.reflections = GlossyEnvironmentReflection(reflectionVector, water.positionWS, _ReflectionBlur, 1 ,scene.screenPos.xy);
//Schlick's BRDF fresnel AIR_RI = 1.000293
float cosTheta = saturate(dot(normalWS, viewDir));
water.reflectionMask = pow(max(0.0, 1.000293 - cosTheta), _ReflectionFresnel) * _ReflectionStrength;
water.albedo = lerp(water.albedo, water.reflections.rgb, water.reflectionMask - noise);
// =================== Make ApplyLight simple =========================
// =====Translucency Begin========
float3 lightDir = mainLight.direction;
float3 lightColor = mainLight.color;
float3 emission = 0;
float3 specular = 0;
float scatteringMask = saturate(water.fog + water.edgeFade);
half incident = saturate(dot(lightDir, normalWS)) * _TranslucencyStrengthDirect;
const float lightIntensity = lightColor.r * 0.3 + lightColor.g * 0.59 + lightColor.b * 0.11;
half attenuation = incident * scatteringMask * lightIntensity;
#ifdef _CAUSTICS
emission += lerp(caustics * lightIntensity, _ShallowColor.rgb, attenuation) * mainLight.distanceAttenuation;
#else
emission = lerp(0, _ShallowColor.rgb, attenuation) * mainLight.distanceAttenuation;
#endif
// =====Translucency End========
#ifdef _LIGHT_COLOR
// LightingLambert Light applied here
half3 attenuatedLightColor = lightColor * (mainLight.distanceAttenuation * mainLight.shadowAttenuation);
half3 diffuseColor = LightingLambert(attenuatedLightColor, lightDir, normalWS) + _GlossyEnvironmentColor.rgb * _AmbientStrength;
float3 finalColor = (water.albedo * diffuseColor ) + emission + specular;
#else
float3 finalColor = (water.albedo ) + emission + specular;
#endif
finalColor = lerp(finalColor, _IntersectionColor.rgb, noise);
// =================== Make ApplyLight simple end =========================
finalColor = lerp(scene.color, finalColor, water.fog + noise);
//Apply fog
half fogCoord = InitializeInputDataFog(float4(positionWS,1), input.fogFactor);
finalColor = MixFog(finalColor, fogCoord);
return float4(finalColor, water.alpha);
}