Jump to content

  • Log In with Google      Sign In   
  • Create Account

Horizon:zero Dawn Cloud System

  • You cannot reply to this topic
2 replies to this topic

#1 ChenA   Members   -  Reputation: 153

Like
0Likes
Like

Posted Yesterday, 12:39 PM

recently  i read the gpu pro 7 article <<Real-Time Volumetric Cloudscapes>>, i want to implement a volumetric cloud system myself.

 

i create the 3d noise texture accord to the article.

and write the shader, test it. but i found it's hard to model the cloud.

i use the sample cloud density code from the article, and a weather texture from the video which embed in the siggraph 2015 ppt.

and the result is not good.

 

the article didn't mention the mapping method which mapping the weather texture to the sky dome.

i use a plane projection, just use the position.xy to calculate the weather texture uv.

but the uv is mostly distribute in the horizon direction, distortion is very obvious.

 

so how to mapping the weather texture to the sky dome?

 

and how to generate the weather?

i found the left bottom weather texture in the video maybe is not the original weather texture, it's just used to show some info.

 

has someone do the same thing?

any suggestion will be so appreciate.

thanks.


Edited by ChenA, Yesterday, 12:52 PM.

hehe.

#2 Ryokeen   Members   -  Reputation: 561

Like
1Likes
Like

Posted Yesterday, 03:30 PM

i kind of coded clouds similar to theirs(well based on their noise texture ideas), so the mapping is done by raymarching through the 3d noise texture and doing the density, coverage,refinement and lighting on each of the raymarch sample.

You can start raymarching by intersecting a lower cloud "plane" with the eye-vector at a pixel, then you march in steps and do your calculations.

Later on you can do an intersection with a sphere around your map so you get a nice curvature at the horizon.

So reading up on raymarching and volume rendering is a good idea.

 

About how one could generate the weather texture, that's something i need ideas for aswell. You could precompute/prepaint some weather textures for a single cloud.

Then based on the weather you want, pack some of the premade textures in a fbo, add some magic and use that in the final raymarch shader.

 

The cloud shape depends a lot on the baked 3D noise texture and how you combine it later on. I mean you have 4 channels with different octaves and only need a float density value. For me it was a lot of experimenting.



#3 ChenA   Members   -  Reputation: 153

Like
0Likes
Like

Posted Yesterday, 08:43 PM

i kind of coded clouds similar to theirs(well based on their noise texture ideas), so the mapping is done by raymarching through the 3d noise texture and doing the density, coverage,refinement and lighting on each of the raymarch sample.

You can start raymarching by intersecting a lower cloud "plane" with the eye-vector at a pixel, then you march in steps and do your calculations.

Later on you can do an intersection with a sphere around your map so you get a nice curvature at the horizon.

So reading up on raymarching and volume rendering is a good idea.

 

About how one could generate the weather texture, that's something i need ideas for aswell. You could precompute/prepaint some weather textures for a single cloud.

Then based on the weather you want, pack some of the premade textures in a fbo, add some magic and use that in the final raymarch shader.

 

The cloud shape depends a lot on the baked 3D noise texture and how you combine it later on. I mean you have 4 channels with different octaves and only need a float density value. For me it was a lot of experimenting.

 

thanks for your reply.

 

i already implement the raymarch and volume rendering.

problem is how to get the cloud density, i think need to use the weather texture to get cloud base shape and empty sky regions.

so every raymarch step, we need a weather data to calculate the cloud density, so we need use position to calculate a uv to sample the weather texture.

my problem is that : how to calculate the weather texture uv?how to mapping the weather texture to sky dome?

 

 

 

for me the key point is the noise texture, weather texture, the mapping method, and the compose algorithm.

i already generated the noise texture .

below is the gpu pro 7 compose algorithm:

// Fractional value for sample position in the cloud layer .
float GetHeightFractionForPoint ( float3 inPosition , float2 inCloudMinMax )
{
    // Get global fractional position in cloud zone .
    float height_fraction = (inPosition.z − inCloudMinMax.x ) / ( inCloudMinMax.y − inCloudMinMax.x ) ;
    return saturate ( height_fraction ) ;
}

// Utility function that maps a value from one range to another .
float Remap ( float original_value , float original_min , float original_max , float new_min , float new_max )
{
    return new_min + ( ( ( original_value − original_min) / ( original_max − original_min ) ) ∗ ( new_max − new_min ) );
}

float SampleCloudDensity ( float3 p , float3 weather_data )
{
    // Read the low−frequency Perlin−Worley and Worley noises.
    float4 low_frequency_noises = tex3Dlod ( Cloud3DNoiseTextureA , Cloud3DNoiseSamplerA , float4 ( p , mip_level) ).rgba;

    // Build an FBM out of the low frequency Worley noises
    // that can be used to add detail to the low−frequency
    // Perlin−Worley noise.
    float low_freq_FBM = ( low_frequency_noises.g ∗ 0.625 )
    + ( low_frequency_noises.b ∗ 0.25 )
    + ( low_frequency_noises.a ∗ 0.125 );

    // define the base cloud shape by dilating it with the
    // low−frequency FBM made of Worley noise.
    float base_cloud = Remap ( low_frequency_noises.r , −( 1.0 − low_freq_FBM ) , 1 .0 , 0 .0 , 1 .0 );

    // Get the density−height gradient using the density height
    // function explained in Section 4.3.2.
    float density_height_gradient = GetDensityHeightGradientForPoint ( p , weather_data );
    
    // Apply the height function to the base cloud shape.
    base_cloud ∗= density_height_gradient ;

    // Cloud coverage is stored in weather data’s red channel.
    float cloud_coverage = weather_data.r;
    
    // Use remap to apply the cloud coverage attribute.
    float base_cloud_with_coverage = Remap ( base_cloud , cloud_coverage, 1. 0 , 0. 0 , 1.0);

    // Multiply the result by the cloud coverage attribute so
    // that smaller clouds are lighter and more aesthetically
    // pleasing.
    base_cloud_with_coverage ∗= cloud_coverage;


    // Add some turbulence to bottoms of clouds.
    p.xy += curl_noise.xy ∗ ( 1 . 0 − height_fraction );

    // Sample high−frequency noises.
    float3 high_frequency_noises = tex3Dlod ( Cloud3DNoiseTextureB , Cloud3DNoiseSamplerB , float4 ( p ∗ 0.1 , mip_level) ).rgb;

    // Build−high frequency Worley noise FBM.
    float high_freq_FBM = ( high_frequency_noises.r ∗ 0.625 )
    + ( high_frequency_noises.g ∗ 0.25 )
    + ( high_frequency_noises.b ∗ 0.125 );

    // Get the height fraction for use with blending noise types
    // over height.
    float height_fraction = GetHeightFractionForPoint ( p , inCloudMinMax );

    // Transition from wispy shapes to billowy shapes over height.
    float high_freq_noise_modifier = mix ( high_freq_FBM ,
    1 .0 − high_freq_FBM , saturate ( height_fraction ∗ 10.0 ) );

    // Erode the base cloud shape with the distorted
    // high−frequency Worley noises.
    float final_cloud = Remap ( base_cloud_with_coverage ,
    high_freq_noise_modifier ∗ 0.2 , 1.0 , 0.0 , 1.0 );


    return final_cloud;
}

so the last problem is the mapping method, and how to create the weather texture.

especially the coverage, the cloud type is easy to create.


Edited by ChenA, Yesterday, 09:12 PM.

hehe.





PARTNERS