// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld' #ifndef FOG_VOLUME_FRAGMENT_INCLUDED #define FOG_VOLUME_FRAGMENT_INCLUDED #define HALF_MAX 65504.0 // Clamp HDR value within a safe range inline half SafeHDR(half c) { return min(c, HALF_MAX); } inline half2 SafeHDR(half2 c) { return min(c, HALF_MAX); } inline half3 SafeHDR(half3 c) { return min(c, HALF_MAX); } inline half4 SafeHDR(half4 c) { return min(c, HALF_MAX); } float4 frag(v2f i) : SV_Target { float3 ViewDir = normalize(i.LocalPos - i.LocalEyePos); float tmin = 0.0, tmax = 0.0; bool hit = IntersectBox(i.LocalEyePos, ViewDir, _BoxMin.xyz, _BoxMax.xyz, tmin, tmax); if (!hit) discard; //likely to resolve to a free modifier if (tmin < 0) tmin = 0; float4 ScreenUVs = UNITY_PROJ_COORD(i.ScreenUVs); float2 screenUV = ScreenUVs.xy / ScreenUVs.w; float Depth = 0; #if _FOG_LOWRES_RENDERER && !ExternalDepth //low res #ifdef FOG_VOLUME_STEREO_ON //left eye if (unity_CameraProjection[0][2] < 0)//lo estaba haciendo con unity_StereoEyeIndex, pero por algún motivo, no se entera { Depth = tex2D(RT_Depth, screenUV); } //right eye else //if (unity_CameraProjection[0][2] > 0) { Depth = tex2Dlod(RT_DepthR, float4(screenUV, 0, 0)); } #else Depth = tex2Dlod(RT_Depth, float4(screenUV, 0, 0)); #endif Depth = 1.0 / Depth; //#else //#ifdef ExternalDepth // //injected from water asset // float Depth = tex2D(_CustomCameraDepthTexture, screenUV).r; // Depth = 1.0 / Depth; // //#else //full res or Scene view // float Depth = tex2D(_CameraDepthTexture, screenUV).r; // Depth = LinearEyeDepth(Depth); //#endif #endif #ifdef ExternalDepth //injected from water asset Depth = tex2D(_CustomCameraDepthTexture, screenUV).r; Depth = 1.0 / Depth; #else #if !_FOG_LOWRES_RENDERER //full res or Scene view Depth = tex2D(_CameraDepthTexture, screenUV).r; Depth = LinearEyeDepth(Depth); #endif #endif //probando //Depth = tex2D(_CameraDepthTexture, screenUV).r; //Depth = LinearEyeDepth(Depth); //return float4( Depth.xxx, 1); Depth = length(Depth / normalize(i.ViewPos).z); float thickness = min(max(tmin, tmax), Depth) - min(min(tmin, tmax), Depth); float Fog = thickness / _Visibility; Fog = 1.0 - exp(-Fog); //return Fog; float4 Final = 0; float3 Normalized_CameraWorldDir = normalize(i.Wpos - _WorldSpaceCameraPos); float3 CameraLocalDir = (i.LocalPos - i.LocalEyePos); half InscatteringDistanceClamp = saturate(Depth / InscatteringTransitionWideness - InscatteringStartDistance); // half InscatteringDistanceClamp = saturate((InscatteringTransitionWideness -Depth) / (InscatteringTransitionWideness- InscatteringStartDistance)); half4 PointLightAccum = 0; float4 PointLightsFinal = 0; #if _FOG_VOLUME_NOISE || _FOG_GRADIENT half jitter = 1; #ifdef JITTER jitter = remap_tri(nrand(ScreenUVs + frac(_Time.x))); jitter = lerp(1, jitter, _jitter); #endif float4 Noise = 1; float3 ShadowColor = 0; float3 rayStart = i.LocalEyePos + ViewDir * tmin; float3 rayStop = i.LocalEyePos + ViewDir * tmax; float3 rayDir = rayStop - rayStart; float RayLength = length(rayDir); Speed *= _Time.x; float4 FinalNoise = 0; float4 Gradient = 1; half Contact = 1; half3 AmbientColor = 1; half DistanceFade = 0; half SphereDistance = 0; half DetailCascade0 = 0; half DetailCascade1 = 0; half DetailCascade2 = 0; half3 Phase = 0; /*half*/ PrimitiveAccum = 1; float3 normal = float3(0, 0, 1); half LambertTerm = 1; float3 LightTerms = 0; half SelfShadows = 1; float OpacityTerms = 0; half4 debugOutput = 1; float DirectLightingShadowStepSize = (1.0 / (float)DirectLightingShadowSteps)*_DirectionalLightingDistance; float3 LightVector = _LightLocalDirection; //LightVector.xz = LightVector.zx; //LightVector.z = -LightVector.z; //LightVector *= DirectLightingShadowStepSize; float DirectionalLightingAccum = 1; float3 DirectionalLighting = 1; half3 AmbientTerm = 1; half Lambert = 1; half absorption = 1; half LightShafts = 1; half4 VolumeFog = 0; half LighsShaftsLightVectorConstrain = VolumeSize.y / VolumeSize.x; float3 LightShaftsDir = L; LightShaftsDir.xz = LighsShaftsLightVectorConstrain * LightShaftsDir.zx; float4 debugIterations = float4(0,0,0,1); float t = 0, dt = _RayStep; float3 r0 = rayStart; float3 rd = normalize(rayDir); #ifdef SAMPLING_METHOD_ViewAligned float PlaneNdotRay = dot(rd, i.SliceNormal); dt = _RayStep / abs(PlaneNdotRay); t = dt - fmod(dot(r0, i.SliceNormal), _RayStep) / PlaneNdotRay; #endif #ifdef JITTER t *= jitter; dt *= jitter; #endif half VolumeRayDistanceTraveled = 0; for (int s = 1; s < STEP_COUNT && RayLength>0; s += 1, t += dt, RayLength -= dt) { dt *= 1 + s * s * s * _OptimizationFactor;//live fast and die young float3 pos = r0 + rd * t; VolumeSpaceCoords = pos; // added casting for ps4 VolumeSpaceCoordsWorldSpace = mul((float3x3)unity_ObjectToWorld, (float3)VolumeSpaceCoords) + _VolumePosition; float3 NoiseCoordinates = VolumeSpaceCoords * (_3DNoiseScale * Stretch.rgb); //DistanceFade = distance(VolumeSpaceCoords, i.LocalEyePos); DistanceFade = distance(VolumeSpaceCoordsWorldSpace, _WorldSpaceCameraPos);//3.2.1 DetailCascade0 = 1 - saturate(DistanceFade / DetailDistance); DetailCascade1 = 1 - saturate(DistanceFade / DirectLightingDistance); #if SHADER_API_GLCORE || SHADER_API_D3D11 || SHADER_API_METAL #if ATTEN_METHOD_1 || ATTEN_METHOD_2 || ATTEN_METHOD_3 DetailCascade2 = 1 - saturate(DistanceFade * PointLightingDistance2Camera); #endif #endif DistanceFade = saturate(DistanceFade / FadeDistance); DistanceFade = 1 - DistanceFade; if (DistanceFade < .001) break; //#ifdef _COLLISION if (Collisions != 0) { Contact = saturate((Depth - distance(VolumeSpaceCoords, i.LocalEyePos))*_SceneIntersectionSoftness); if (Contact < .01) break; //#endif } #ifdef DF PrimitiveAccum = 0; half3 p = 0; //Additive primitives for (int k = 0; k < _PrimitiveCount; k++) { if (_PrimitiveActionType(k) <= 1.0f) { p = mul(_PrimitivesTransform[k], VolumeSpaceCoords - _PrimitivePosition[k]); PrimitiveAccum = max(PrimitiveAccum, 1 - (PrimitiveShape(_PrimitiveShapeType(k), p, _PrimitiveScale[k] * .5) + Constrain)); } } //Subtractive primitives for (int n = 0; n < _PrimitiveCount; n++) { if (_PrimitiveActionType(k) > 1.0f) { p = mul(_PrimitivesTransform[n], VolumeSpaceCoords - _PrimitivePosition[n]); PrimitiveAccum = min(PrimitiveAccum, (PrimitiveShape(_PrimitiveShapeType(n), p, _PrimitiveScale[n] * .5) + Constrain)); } } //Final adjustments PrimitiveAccum = ContrastF(PrimitiveAccum * _PrimitiveEdgeSoftener, 1); #endif #if defined(_FOG_GRADIENT) half2 GradientCoords = VolumeSpaceCoords.xy / (_BoxMax.xy - _BoxMin.xy) - .5f; GradientCoords.y *= 0.95;//correct bottom. must check in the future what's wrong with the uv at the edges GradientCoords.y -= 0.04;//3.1.1 //if(PrimitiveAccum>.99) if (gain>0) Gradient = tex2Dlod(_Gradient, half4(GradientCoords, 0, 0)); #endif VerticalGrad = (VolumeSpaceCoords.y / (_BoxMax.y - _BoxMin.y) + 0.5); #ifdef VOLUME_FOG if (OpacityTerms <1) VolumeRayDistanceTraveled++; float VolumeDepth01 = (float)VolumeRayDistanceTraveled / STEP_COUNT; float DistanceCamera2VolumeWalls = length(CameraLocalDir); float DistanceCamera2Center = distance(_WorldSpaceCameraPos, _VolumePosition); float DistanceCamera2VolumePoints = distance(_WorldSpaceCameraPos, VolumeSpaceCoordsWorldSpace); float VolumeDepth = min(max(tmin, tmax), DistanceCamera2VolumePoints) - min(min(tmin, tmax), DistanceCamera2VolumePoints); float VolumeDensity = DistanceCamera2VolumePoints - DistanceCamera2VolumeWalls; VolumeFog = saturate(1 - exp(-VolumeDepth / _Visibility * 5)); //VolumeFog= saturate(1 - exp(-VolumeRayDistanceTraveled / _Visibility)); VolumeFog.a *= Contact/**Gradient.a*/;// aquí hay que decidir si el gradiente se lo come o no #endif NoiseAtten = gain; NoiseAtten *= DistanceFade; NoiseAtten *= Contact; #ifdef HEIGHT_GRAD heightGradient = half2(HeightGradient(VerticalGrad, GradMin, GradMax), /*3.1.10: Adding secondary gradient*/HeightGradient(VerticalGrad, GradMin2, GradMax2)); NoiseAtten *= heightGradient.x*heightGradient.y; #endif #if SPHERICAL_FADE SphereDistance = 1 - saturate(length(VolumeSpaceCoords) / SphericalFadeDistance); NoiseAtten *= SphereDistance; #endif //TEXTURE SAMPLERS////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #if _FOG_VOLUME_NOISE || _FOG_GRADIENT #if Twirl_X || Twirl_Y || Twirl_Z float3 rotationDegree = length(NoiseCoordinates) * _Vortex + _Rotation + _RotationSpeed * _Time.x; NoiseCoordinates = rotate(NoiseCoordinates , rotationDegree); #endif half4 VerticalCoords = float4(VolumeSpaceCoords.zx / (_BoxMax.zx - _BoxMin.zx) - .5f, 0, 0); #ifdef COVERAGE half CoverageTile = 1; half4 CoverageCoords = CoverageTile * float4(VolumeSpaceCoords.xz / (_BoxMax.xz - _BoxMin.xz) - .5f, 0, 0); half4 CoverageRGB = tex2Dlod(CoverageTex, CoverageCoords); #ifdef HEIGHT_GRAD //CoverageRGB.r *=heightGradient.y * (1+heightGradient.x * heightGradient.x); CoverageRGB.r *= heightGradient.y; #endif half CumulonimbusTop = HeightGradient(VerticalGrad, 1.0, .5); half Cresta = HeightGradient(VerticalGrad, 0.7, 1)*CumulonimbusTop; Cresta *= 10 * CoverageRGB.r; NoiseAtten *= CoverageRGB.r; NoiseAtten += CoverageRGB.r * 4 * CumulonimbusTop + Cresta; #endif if (Contact > 0 && NoiseAtten > 0 && PrimitiveAccum > _PrimitiveCutout) { #if _FOG_VOLUME_NOISE && !_FOG_GRADIENT Noise = noise(NoiseCoordinates, DetailCascade0); #endif #if !_FOG_VOLUME_NOISE && _FOG_GRADIENT Gradient.a *= gain; Noise = Gradient; #endif #if _FOG_VOLUME_NOISE && _FOG_GRADIENT Noise = noise(NoiseCoordinates, DetailCascade0) * Gradient; #endif if (Noise.a>0) Noise *= DistanceFade; } else { Noise = 0; Gradient.a = 0; } half absorptionFactor = lerp(1, 200, Absorption); #ifdef ABSORPTION half d = Noise.a;//si se multiplica aquí añade cotraste //half absorptionFactor = lerp(1, 20, Absorption); half Beers = exp(-d* absorptionFactor)* absorptionFactor;//la última multiplicación da contraste half Powder = 1 - exp(-d * 2); absorption = lerp(1, saturate(Beers*Powder), Absorption); #ifdef HEIGHT_GRAD half HeightGradientAtten = 1 - heightGradient.x; HeightGradientAtten = 1.0 - exp(-HeightGradientAtten); absorption *= lerp(1,HeightGradientAtten, HeightAbsorption); #endif // AmbientTerm = absorption;3.2 #else //AmbientTerm = 1;3.2 #endif #if _LAMBERT_SHADING if (LightShafts > 0.1)//si estamos en sombra, pos no hagas ná { //Lambert lighting if (Noise.a > 0 && NoiseAtten > 0 && DetailCascade1 > 0) { normal = calcNormal(NoiseCoordinates, DetailCascade0); //normal = normalize(VolumeSpaceCoordsWorldSpace- _VolumePosition);//sphere normals LambertTerm = max(0, dot(normal, normalize(-L))); //kind of half lambert LambertTerm = LambertTerm*0.5 + LambertianBias; LambertTerm *= LambertTerm; Lambert = lerp(1, LambertTerm, Noise.a*DirectLightingAmount*ContrastF(DetailCascade1 * 3, 2)); Lambert = max(0.0, Lambert); } } #endif AmbientColor = _AmbientColor.rgb; #ifndef SHADOW_PASS AmbientTerm.rgb = _AmbientColor.rgb; #endif half3 ProxyAmbient = 1; UNITY_BRANCH if (PROBES == 1) { //#ifdef PROBES ProxyAmbient = ShadeSHPerPixel(i.worldNormal, 0, VolumeSpaceCoordsWorldSpace); AmbientTerm.rgb *= ProxyAmbient/* * _AmbientColor.rgb*/; AmbientColor *= ProxyAmbient; } //#endif AmbientTerm *= absorption;//3.2 #endif #if _SHADE if (Noise.a > 0) SelfShadows = Shadow(NoiseCoordinates, i, DetailCascade0, LightVector* ShadowShift, NoiseAtten); #endif //3.1.10 HeightAtten = HeightGradient(VerticalGrad, _AmbientHeightAbsorptionMin, _AmbientHeightAbsorptionMax); HeightAtten = saturate(1.0 - exp(-HeightAtten)); if (_AmbientHeightAbsorptionMin == -1 && _AmbientHeightAbsorptionMax == -1)//just to avoid adding one more shader variant HeightAtten = 1; //AmbientTerm *= HeightAtten;3.2 ambient shouldn't be affected by this SelfShadows *= HeightAtten; // #if DIRECTIONAL_LIGHTING float DirectionalLightingSample = 0; //TODO if (LightShafts > 0.1) if (NoiseAtten>0 && Noise.a>0) { float3 DirectionalLightingSamplingPosition = NoiseCoordinates; for (int s = 0; s < DirectLightingShadowSteps; s++) { DirectionalLightingSamplingPosition += LightVector*DirectLightingShadowStepSize; DirectionalLightingSample = noise(DirectionalLightingSamplingPosition, DetailCascade0).r; DirectionalLightingAccum += DirectionalLightingSample/* / DirectLightingShadowSteps*/; } DirectionalLighting = DirectionalLightingAccum; } DirectionalLighting *= Noise.a; #endif #if defined (_INSCATTERING) #if ABSORPTION //lets diffuse LambertTerm according to density/absorption //remap absorption greyscale to -1 1 range to affect anisotropy according to media density //////// multiply ranges of [0, 1] half t = (1 - Noise.a) * (InscatteringShape*0.5 + 0.5); //get back to [-1, 1] t = t * 2 - 1; InscatteringShape = lerp(InscatteringShape, (t), Absorption); // #if ABSORPTION && VOLUME_FOG // InscatteringShape = lerp(InscatteringShape*absorption, InscatteringShape, Noise.a); // #endif #endif half HG = Henyey(Normalized_CameraWorldDir, L, InscatteringShape); HG *= InscatteringDistanceClamp * Contact; Phase = _InscatteringColor.rgb * _InscatteringIntensity * HG * Gradient.xyz * _LightColor.rgb;//3.2; Phase *= absorption; #endif #ifdef HALO half LdotV = saturate(dot(L, Normalized_CameraWorldDir)); LdotV = pow(LdotV, _HaloRadius); LdotV = 1 - exp(-LdotV); LdotV = ContrastF(LdotV, _HaloWidth);//franja LdotV = saturate(LdotV); LdotV -= .5; //#ifdef ABSORPTION // half HaloDensityTerm = absorption; //#else half HaloDensityTerm = Noise.a; //#endif half mip = saturate(Noise.a * 12) * _HaloAbsorption * (1 - HaloDensityTerm); half4 Halo = 0; if (LdotV >0) { Halo = tex2Dlod(_LightHaloTexture, float4(0, LdotV, 0, mip)); Halo.g = tex2Dlod(_LightHaloTexture, float4(0, LdotV * 1.1, 0, mip)/**_HaloOpticalDispersion*/).r; Halo.b = tex2Dlod(_LightHaloTexture, float4(0, LdotV * 1.2, 0, mip)/**_HaloOpticalDispersion*/).r; Halo.rgb *= _HaloIntensity; Halo.rgb *= Halo.a; Halo.rgb *= HaloDensityTerm * (1.0 - HaloDensityTerm); Halo.rgb *= 1 - mip / 12; Halo.rgb *= LdotV; } else Halo = 0; #endif OpacityTerms = Noise.a*Contact; #if DIRECTIONAL_LIGHTING //Shadow Color DirectionalLighting /= LightExtinctionColor.rgb; DirectionalLighting = DirectionalLighting* DirectLightingShadowDensity; DirectionalLighting = exp(-DirectionalLighting); Phase *= DirectionalLighting; #endif //half3 LightTerms = exp(-DirectionalLighting) * OpacityTerms; half3 LightTerms = OpacityTerms * AmbientTerm.rgb * DirectionalLighting;//3.2 //#ifdef VOLUMETRIC_SHADOWS UNITY_BRANCH if (VOLUMETRIC_SHADOWS == 1) { // added casting for ps4 half2 shadowUVs = (mul((float3x3)_ShadowCameraProjection, (float3)(VolumeSpaceCoordsWorldSpace - _ShadowCameraPosition)).xy + _ShadowCameraSize) / (_ShadowCameraSize*2.0f); #ifdef CONVOLVE_VOLUMETRIC_SHADOWS #define _GeneralShadowOffset 0.003f float pointDepth = length(_ShadowCameraPosition - VolumeSpaceCoordsWorldSpace); // half4 shadows; shadows.x = step(pointDepth, tex2Dlod(_ShadowTexture, float4(shadowUVs + float2(-_GeneralShadowOffset, -_GeneralShadowOffset), 0, 0)).r); shadows.y = step(pointDepth, tex2Dlod(_ShadowTexture, float4(shadowUVs + float2(_GeneralShadowOffset, _GeneralShadowOffset), 0, 0)).r); shadows.z = step(pointDepth, tex2Dlod(_ShadowTexture, float4(shadowUVs + float2(-_GeneralShadowOffset, _GeneralShadowOffset), 0, 0)).r); shadows.w = step(pointDepth, tex2Dlod(_ShadowTexture, float4(shadowUVs + float2(_GeneralShadowOffset, -_GeneralShadowOffset), 0, 0)).r); VolumeShadow = max(dot(shadows, 0.25f), 0.0f); #else VolumeShadow = FrameShadow(shadowUVs, VolumeSpaceCoordsWorldSpace); #endif //3.2 #if defined (_INSCATTERING) Phase *= VolumeShadow; #endif #ifdef HALO Halo.rgb *= VolumeShadow; #endif //3.2 //LightTerms *= lerp(_AmbientColor.rgb, 1, VolumeShadow);//previous 3.2 //LightTerms *= lerp(AmbientTerm.rgb, 1, VolumeShadow);//3.2 test } //#endif //Phase *= LightTerms;//atten with shadowing//3.2 comment Phase *= OpacityTerms;//3.2 //LightTerms *= lerp(_AmbientColor.rgb, 1, absorption);//previous 3.2 //LightTerms *= lerp(AmbientTerm.rgb, 1, absorption);//3.2 test #ifdef VOLUME_SHADOWS half4 LightMapCoords = VerticalCoords; LightMapCoords.xy = LightMapCoords.yx; #ifndef LIGHT_ATTACHED LightMapCoords.xy += LightShaftsDir.zx*(1 - VerticalGrad); #endif LightMapCoords.x = clamp(LightMapCoords.x, -1, 0); LightMapCoords.y = clamp(LightMapCoords.y, -1, 0); LightShafts = tex2Dlod(LightshaftTex, LightMapCoords).r; LightShafts = LightShafts*lerp(50,1,_Cutoff); LightShafts = 1 - saturate(LightShafts); //LightShafts *= _LightColor.rgb;3.2 #if defined (_INSCATTERING) Phase *= LightShafts; #endif #ifdef HALO Halo.rgb *= LightShafts; // changed to rgb for ps4 #endif #endif #ifdef VOLUME_SHADOWS LightTerms *= LightShafts; #endif LightTerms *= Lambert; #ifdef _SHADE float3 SelfShadowsColor = lerp(_SelfShadowColor.rgb * AmbientTerm.rgb, 1.0, SelfShadows);//3.2 replaced ambient color with AmbientTerm LightTerms *= SelfShadowsColor; Phase *= SelfShadowsColor; #endif //3.1.10 LightTerms *= HeightAtten; Phase *= HeightAtten; // #ifdef VOLUME_FOG half3 VolumetricFogVolor = _FogColor.rgb; //#ifdef AMBIENT_AFFECTS_FOG_COLOR if (AMBIENT_AFFECTS_FOG_COLOR) VolumetricFogVolor *= AmbientColor; //#endif #ifdef VOLUME_SHADOWS LightTerms = lerp(LightTerms, VolumetricFogVolor * Gradient.rgb * (LightShafts + _AmbientColor.a), VolumeFog.a); #else LightTerms = lerp(LightTerms, VolumetricFogVolor * Gradient.rgb, VolumeFog.a); #endif #if defined (_VOLUME_FOG_INSCATTERING) half VolumeFogInscatteringDistanceClamp = saturate((VolumeRayDistanceTraveled - VolumeFogInscatteringStartDistance) / VolumeFogInscatteringTransitionWideness); half3 VolumeFogPhase = Henyey(Normalized_CameraWorldDir, L, VolumeFogInscatteringAnisotropy); VolumeFogPhase *= Contact; VolumeFogPhase *= VolumeFogInscatteringDistanceClamp; VolumeFogPhase *= VolumeFogInscatteringColor.rgb * VolumeFogInscatteringIntensity * Gradient.xyz; VolumeFogPhase *= saturate(1 - Noise.a * VolumeFogInscatteringIntensity/*pushin' proportionaly to intensity*/); half3 FogInscatter = 0; UNITY_BRANCH if (FOG_TINTS_INSCATTER == 1) FogInscatter = VolumeFog.a *VolumetricFogVolor * VolumeFogPhase * _LightColor.rgb; //3.2 else FogInscatter = VolumeFog.a *VolumetricFogVolor * VolumeFogPhase * _LightColor.rgb + VolumeFog.a * VolumeFogPhase * _LightColor.rgb; #ifdef VOLUME_SHADOWS FogInscatter *= LightShafts; #endif UNITY_BRANCH if (VOLUMETRIC_SHADOWS == 1) FogInscatter *= VolumeShadow; LightTerms += FogInscatter; #endif OpacityTerms = min(OpacityTerms + VolumeFog.a, 1); #endif #if defined(_FOG_GRADIENT) LightTerms *= Gradient.rgb; #endif //#ifdef PROBES //LightTerms *= ProxyAmbient*5;//maybe not //#endif LightTerms += Phase; //Multiply by LambertTerm and color before additive stuff LightTerms *= _Color.rgb; LightTerms *= _LightExposure;//new in 3.1.1 LightTerms += AmbientTerm*Noise.a;//multiplicando para no afectar a la niebla #if SHADER_API_GLCORE || SHADER_API_D3D11 || SHADER_API_METAL #if ATTEN_METHOD_1 || ATTEN_METHOD_2 || ATTEN_METHOD_3 if (DetailCascade2>0) { for (int k = 0; k < _LightsCount; k++) { half PointLightRange = 1 - (length(_LightPositions[k].xyz - VolumeSpaceCoords) * PointLightingDistance);//range clamp if (PointLightRange > .99) { if (_LightData[k].z >= 0.0) { PointLightAccum += (Noise.a + VolumeFog.a)*SpotLight( _LightPositions[k].xyz, VolumeSpaceCoords, _LightRange(k), _LightColors[k], _LightIntensity(k), _LightRotations[k], _LightSpotAngle(k), _LightColors[k].w, i) * Contact; } else { PointLightAccum += (Noise.a + VolumeFog.a)*PointLight( _LightPositions[k].xyz, VolumeSpaceCoords, _LightRange(k), _LightColors[k], _LightIntensity(k), //1, i) * Contact; } } } half atten = saturate(PointLightAccum.a); if (atten > 0) { PointLightsFinal = PointLightAccum; } } #endif #endif #ifdef HALO //LightTerms += Halo.rgb; //3.1.10 LightTerms *= (1 + Halo.rgb); #endif #ifdef DEBUG if (_DebugMode == DEBUG_ITERATIONS) { debugOutput.rgb = tex2Dlod(_PerformanceLUT, float4(0, (float)s / STEP_COUNT, 0, 0)).rgb; } if (_DebugMode == DEBUG_INSCATTERING) { LightTerms = Phase; } if (_DebugMode == DEBUG_VOLUMETRIC_SHADOWS) { LightTerms = LightShafts * .05; } #if VOLUME_FOG && _VOLUME_FOG_INSCATTERING if (_DebugMode == DEBUG_VOLUME_FOG_INSCATTER_CLAMP) { LightTerms = OpacityTerms * VolumeFogInscatteringDistanceClamp; } if (_DebugMode == DEBUG_VOLUME_FOG_PHASE) { LightTerms = OpacityTerms * FogInscatter; } #endif #endif OpacityTerms *= _PushAlpha; //FinalNoise.a = saturate(FinalNoise.a); FinalNoise = FinalNoise + float4(LightTerms, OpacityTerms) * (1.0 - FinalNoise.a); if (FinalNoise.a > .999)break;//KILL'EM ALL if its already opaque, don't do anything else } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////LOOP END #ifdef DEBUG if (_DebugMode == DEBUG_INSCATTERING || _DebugMode == DEBUG_VOLUMETRIC_SHADOWS || _DebugMode == DEBUG_VOLUME_FOG_INSCATTER_CLAMP || _DebugMode == DEBUG_VOLUME_FOG_PHASE) { debugOutput = FinalNoise; } return debugOutput; #endif //return FinalNoise; //return float4(Contact, Contact, Contact,1); //return float4(NoiseAtten, NoiseAtten, NoiseAtten, 1); ; //FinalNoise.rgb *= _Color.rgb; _Color = FinalNoise; _InscatteringColor *= FinalNoise; #endif #if _INSCATTERING && !_FOG_VOLUME_NOISE && !_FOG_GRADIENT float Inscattering = Henyey(Normalized_CameraWorldDir, L, InscatteringShape); //_InscatteringIntensity *= .05; Inscattering *= InscatteringDistanceClamp; Final = float4(_Color.rgb + _InscatteringColor.rgb * _InscatteringIntensity * Inscattering, _Color.a); #else Final = _Color; #endif #if ATTEN_METHOD_1 || ATTEN_METHOD_2 || ATTEN_METHOD_3 Final.rgb += PointLightsFinal.rgb; #endif #ifdef ColorAdjust Final.rgb = lerp(Final.rgb, pow(max((Final.rgb + Offset), 0), 1 / Gamma), Final.a); #if _TONEMAP Final.rgb = ToneMap(Final.rgb, Exposure); #endif #endif #if !_FOG_VOLUME_NOISE && !_FOG_GRADIENT Final.a *= (Fog * _Color.a); #endif if (IsGammaSpace()) Final.rgb = pow(Final.rgb, 1 / 2.2); Final.a = saturate(Final.a); Final.rgb = SafeHDR(Final.rgb); #ifdef Enviro_Integration float4 EnviroFog = TransparentFog(Final, i.Wpos, screenUV, Depth); EnviroFog.a = EnviroFog.a * Final.a; Final = EnviroFog; #endif //Debug the build problem #if DF && defined(DEBUG_PRIMITIVES) //Final.rgb = _PrimitiveCount/1.5; //Final.a = 0; Final.rgb = float3(0,.5, .5); #endif return Final; } #endif