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
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 );
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.