Author Topic: Tenkoku Fog and Water  (Read 139 times)

rostik1975

  • Newbie
  • *
  • Posts: 3
    • View Profile
Tenkoku Fog and Water
« on: May 11, 2019, 09:54:46 AM »
Hi,
Could you please tell me how I can edit Tenkoku Fog shader or script so the water is displayed behind the fog?
I use Lux Water that supports both Enviro and AzureSky fog, and I got the following answer from their support:
"Tenkoku should ship with a fog function for transparent shaders like particles, glas or billboards.
if so you would have to call that function at the end of the water shader (core file) - just where it calls the other fog functions right now."

So in LuxWater shader I can see
Code: [Select]
// Fog Mode
#include "Includes/LuxWater_Setup.cginc"

Then in cginc file I set
Code: [Select]
//  Azure Fog ---------------------------
// #define FOG_AZUR
// #include "Assets/Azure[Sky] Dynamic Skybox/Shaders/Transparent/AzureFogCore.cginc"
//  Tenkoku Fog ---------------------------
#define FOG_TENKOKU
#include "Assets/ --- *** "

*** - here I need to put the path to Tenkoku cginc Fog function.

Example - AzureSky uses the following function in AzureFogCore.cginc:
Code: [Select]
float4 ApplyAzureFog (float4 fragOutput, float3 worldPos)
{
#ifdef UNITY_PASS_FORWARDADD
float3 fogScatteringColor = 0;
#else
float3 fogScatteringColor = AzureComputeFogScattering(worldPos);
#endif

// Calcule Standard Fog.
float depth = distance(_WorldSpaceCameraPos, worldPos);
float fog = smoothstep(-_Azure_FogBlend, 1.25, depth / _Azure_FogDistance) * _Azure_FogDensity;
float heightFogDistance = smoothstep(-_Azure_HeightFogBlend, 1.25, depth / _Azure_HeightFogDistance);

// Calcule Height Fog.
float3 worldSpaceDirection = mul((float3x3)_Azure_UpMatrix, worldPos.xyz);
float heightFog = saturate((worldSpaceDirection.y - _Azure_HeightFogStart) / (_Azure_HeightFogEnd + _Azure_HeightFogStart));
heightFog = 1.0 - heightFog;
heightFog *= heightFog;
heightFog *= heightFogDistance;
float fogFactor = saturate(fog + heightFog * _Azure_HeightFogDensity);

// Apply Fog.
#if defined(_ALPHAPREMULTIPLY_ON)
fragOutput.a = lerp(fragOutput.a, 1.0, fogFactor);
#endif
fogScatteringColor = lerp(fragOutput.rgb, fogScatteringColor, fogFactor * lerp(fragOutput.a, 1.0, 2.0 - fogFactor));
return float4(fogScatteringColor, fragOutput.a);
}

it is called from LuxWaterCore.cginc:
Code: [Select]
#elif defined(FOG_AZUR)
            if (!backside){
                c = ApplyAzureFog( float4(c.rgb, 1), float4(i.grabUV.xy, surfaceEyeDepth, i.grabUV.w), worldPos);
            }

I can add the condition for Tenkoku Fog too, but I can't see such cginc files in your system.
Could you help me please?
Thank you.

Chingwa

  • Administrator
  • Hero Member
  • *****
  • Posts: 1640
    • View Profile
    • Tanuki Digital
Re: Tenkoku Fog and Water
« Reply #1 on: May 13, 2019, 09:25:08 AM »
Hi Rostik1975,
Thanks for the example code.  Currently Tenkoku does not have fog code access such as you're showing in these examples.  However there is probably a similar solution that can be obtained, let me dig around a bit and I'll get back to you.

rostik1975

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Tenkoku Fog and Water
« Reply #2 on: June 03, 2019, 03:36:18 PM »
Hi Chingwa,

Thank you for your reply,
Did you have a chance to look at the code? I am still trying to make Tenkoku compatible with LuxWater, but I am not good with shaders:(
Could you please advise me what part of the code is wrong?

Should I call TenkokuFogCore.cginc from LuxWaterCore.cginc with some parameters? Now I use
c = ComputeFog ();
but I get the following error: Shader error in 'Lux Water/WaterSurface': unrecognized identifier 'appdata_img' at SKY/SHADERS/TenkokuFogCore.cginc(60) (on d3d11)

Here is TenkokuFogCore.cginc that is based on Tenkoku_FX_Fog.shader:

Code: [Select]
uniform sampler2D _MainTex, _SkyTex;
uniform sampler2D_float _CameraDepthTexture;
sampler2D _CameraDepthNormalsTexture;

uniform float4 _HeightParams;

// x = start distance
uniform float4 _DistanceParams;

int4 _SceneFogMode;
float4 _SceneFogParams;

    float _Tenkoku_FogStart;
    float _Tenkoku_FogEnd;

uniform float4 _MainTex_TexelSize;

// for fast world space reconstruction
uniform float4x4 _FrustumCornersWS;
uniform float4 _CameraWS;

half4 _Tenkoku_FogColor;
float _fogSkybox;
float _fogHorizon;
float _FogStart;
float _FogDistance;
float _camDistance;

float _Tenkoku_AmbientGI;
float _Tenkoku_AtmosphereDensity;
float _Tenkoku_FogDensity;
float _tenkokufogFull;

    float4 Tenkoku_Vec_SunFwd;
    float4 Tenkoku_Vec_MoonFwd;
    float4 Tenkoku_Vec_LightningFwd;
   
    float4x4 _Tenkoku_CameraMV;
    samplerCUBE _Tenkoku_EnvironmentCube;
    samplerCUBE _Tenkoku_SkyCube;
    samplerCUBE _Tenkoku_SnowCube;
    sampler2D _Tenkoku_TexFX;
    sampler2D _Tenkoku_ParticleTex;
   
    float Tenkoku_LightningLightIntensity;
    float _Tenkoku_shaderDepth;
    float _Tenkoku_FadeDistance;



struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float2 uv_depth : TEXCOORD1;
float4 interpolatedRay : TEXCOORD2;
float4 screenPos: TEXCOORD3;
};

v2f vert (appdata_img v)
{
v2f o;
half index = v.vertex.z;
v.vertex.z = 0.1;
o.pos = UnityObjectToClipPos(v.vertex);
o.screenPos=ComputeScreenPos(o.pos);

o.uv = v.texcoord.xy;
o.uv_depth = v.texcoord.xy;

#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
o.uv.y = 1-o.uv.y;
#endif

//set frustrum indexes specifically
// this fixes fog/effect errors under webGL
if (0 == (int)index)
o.interpolatedRay = _FrustumCornersWS[0];
else if (1 == (int)index)
o.interpolatedRay = _FrustumCornersWS[1];
else if (2 == (int)index)
o.interpolatedRay = _FrustumCornersWS[2];
else
o.interpolatedRay = _FrustumCornersWS[3];

return o;
}


  // Distance-based fog
float ComputeDistance (float3 camDir, float zdepth)
{
float dist;
if (_SceneFogMode.y == 1)
dist = length(camDir);
else
dist = zdepth;// * _ProjectionParams.z;
return dist;
}


float ComputeHalfSpace (float3 wsDir)
{
float3 wpos = _CameraWS + wsDir;
float FH = _HeightParams.x;
float3 C = _CameraWS;
float3 V = wsDir;
float3 P = wpos;
float3 aV = _HeightParams.w * V;
float FdotC = _HeightParams.y;
float k = _HeightParams.z;
float FdotP = P.y-FH;
float FdotV = wsDir.y;
float c1 = k * (FdotP + FdotC);
float c2 = (1-2*k) * FdotP;
float g = min(c2, 0.0);
g = -length(aV) * (c1 - g * g / abs(FdotV+1.0e-5f));
return g;
}


    half4 ComputeFog ()
    {
// Reconstruct world space position & direction
// towards this screen pixel.
float rawDepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv_depth);
float dpth = Linear01Depth(rawDepth);
float4 wsDir = dpth * i.interpolatedRay;

//CALCULATE FOG
float diff = _Tenkoku_FogEnd - _Tenkoku_FogStart;
float invDiff = abs(diff) > 0.0001f ? 1.0 / diff : 0.0;
_SceneFogParams.z = -invDiff;
_SceneFogParams.w = _Tenkoku_FogEnd * invDiff;
half usedpth = _DistanceParams.z + ComputeDistance(wsDir, dpth) + ComputeHalfSpace (wsDir);
half fogFac = (saturate(max(0.0,usedpth) * _SceneFogParams.z + _SceneFogParams.w));

//Get Scene Color Info
half4 sceneColor = tex2D(_MainTex, i.uv);

//Recalculate fog with heat distortion
diff = _Tenkoku_FogEnd - _Tenkoku_FogStart;
invDiff = abs(diff) > 0.0001f ? 1.0 / diff : 0.0;
_SceneFogParams.z = -invDiff;
_SceneFogParams.w = _Tenkoku_FogEnd * invDiff;
usedpth = _DistanceParams.z + ComputeDistance(wsDir, dpth) + ComputeHalfSpace (wsDir);
fogFac = (saturate(max(0.0,usedpth) * _SceneFogParams.z + _SceneFogParams.w));

// Handle skybox fog
if (rawDepth == 1.0)
{
if (_fogSkybox == 1.0)
{
fogFac = 1.0;
}
if (_fogSkybox == 0.0)
{
fogFac = 0.0;
}
}

fogFac = saturate(fogFac+saturate(lerp(1.0,0.0,_Tenkoku_AtmosphereDensity*2.0)));

//Handle Horizon Fog
float diff2 = _tenkokufogFull - (10.0);
float invDiff2 = abs(diff2) > 0.0001f ? 1.0 / diff2 : 0.0;
half fogFac3 = saturate(max(0.0,usedpth) * -invDiff2 + (_tenkokufogFull * invDiff2));

if (_fogHorizon == 1.0)
{
fogFac *= saturate((wsDir.y/min(_tenkokufogFull,250.0)) + fogFac3);
}

//read texture mipmap based on depth
half4 skyColor = tex2Dlod(_SkyTex, float4(i.uv.x,i.uv.y,0,0));
half4 fCol = lerp(skyColor, sceneColor, fogFac);

if (rawDepth >= 1.0)
{
fCol = lerp(fCol, sceneColor, saturate(lerp(-0.1,1.0, ((dot(half3(0,1,0), i.interpolatedRay.xyz)*0.0005)))));
}

//tint fog
        half hVec = saturate(lerp(-4.0,3.0,saturate(dot(half3(0,1,0), normalize( i.interpolatedRay.xyz))+0.6)));

return fCol;
}

Thank you.

rostik1975

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Tenkoku Fog and Water
« Reply #3 on: June 18, 2019, 02:37:01 PM »
Hi Chingwa,

May I ask did you look on the code and the possibility of LuxWater <-> Tenkoku System integration? I was able to improve Tenkoku Sky performance (17fps to 80fps) in my project, by modifying TenkokuModule.cs, Calculations.cs and other scripts, and now it's OK except the only stopper -Tenkoku Fog / LuxWater interaction. I wrote the code earlier, and here is the screen.
Is it possible for you to share your knowledge with LuxWater owner, to resolve the issue? He's already integrated LuxWater with Azzuresky and Enviro, and I guess you will both benefit from this integration (and me as a satisfied customer too:).

Thank you.

Chingwa

  • Administrator
  • Hero Member
  • *****
  • Posts: 1640
    • View Profile
    • Tanuki Digital
Re: Tenkoku Fog and Water
« Reply #4 on: June 18, 2019, 09:01:08 PM »
I apologize for the delay.  I'll make this one of my priorities this week and see if I can get a code solution to you soon!