11//! A simple 3D scene with a spinning cube with a normal map and depth map to demonstrate parallax mapping. 
22//! Press left mouse button to cycle through different views. 
33
4+ use  std:: fmt; 
5+ 
46use  bevy:: { prelude:: * ,  render:: render_resource:: TextureFormat ,  window:: close_on_esc} ; 
57
68fn  main ( )  { 
@@ -48,6 +50,34 @@ impl Default for TargetLayers {
4850        TargetLayers ( 5.0 ) 
4951    } 
5052} 
53+ struct  CurrentMethod ( ParallaxMappingMethod ) ; 
54+ impl  Default  for  CurrentMethod  { 
55+     fn  default ( )  -> Self  { 
56+         CurrentMethod ( ParallaxMappingMethod :: Relief  {  max_steps :  4  } ) 
57+     } 
58+ } 
59+ impl  fmt:: Display  for  CurrentMethod  { 
60+     fn  fmt ( & self ,  f :  & mut  fmt:: Formatter )  -> fmt:: Result  { 
61+         match  self . 0  { 
62+             ParallaxMappingMethod :: Occlusion  => write ! ( f,  "Parallax Occlusion Mapping" ) , 
63+             ParallaxMappingMethod :: Relief  {  max_steps }  => { 
64+                 write ! ( f,  "Relief Mapping with {max_steps} steps" ) 
65+             } 
66+         } 
67+     } 
68+ } 
69+ impl  CurrentMethod  { 
70+     fn  next_method ( & mut  self )  { 
71+         use  ParallaxMappingMethod :: * ; 
72+         self . 0  = match  self . 0  { 
73+             Occlusion  => Relief  {  max_steps :  2  } , 
74+             Relief  {  max_steps }  if  max_steps < 3  => Relief  {  max_steps :  4  } , 
75+             Relief  {  max_steps }  if  max_steps < 5  => Relief  {  max_steps :  8  } , 
76+             Relief  {  .. }  => Occlusion , 
77+         } 
78+     } 
79+ } 
80+ 
5181fn  update_parallax_depth_scale ( 
5282    input :  Res < Input < KeyCode > > , 
5383    mut  materials :  ResMut < Assets < StandardMaterial > > , 
@@ -57,7 +87,7 @@ fn update_parallax_depth_scale(
5787)  { 
5888    if  input. just_pressed ( KeyCode :: Key1 )  { 
5989        target_depth. 0  -= DEPTH_UPDATE_STEP ; 
60-         target_depth. 0  = target_depth. 0 . max ( - MAX_DEPTH ) ; 
90+         target_depth. 0  = target_depth. 0 . max ( 0.0 ) ; 
6191        * depth_update = true ; 
6292    } 
6393    if  input. just_pressed ( KeyCode :: Key2 )  { 
@@ -84,25 +114,18 @@ fn switch_method(
84114    input :  Res < Input < KeyCode > > , 
85115    mut  materials :  ResMut < Assets < StandardMaterial > > , 
86116    mut  text :  Query < & mut  Text > , 
87-     mut  current :  Local < ParallaxMappingMethod > , 
117+     mut  current :  Local < CurrentMethod > , 
88118)  { 
89119    if  input. just_pressed ( KeyCode :: Space )  { 
90-         * current = match  * current { 
91-             ParallaxMappingMethod :: Relief  {  .. }  => ParallaxMappingMethod :: Occlusion , 
92-             ParallaxMappingMethod :: Occlusion  => ParallaxMappingMethod :: Relief  {  max_steps :  5  } , 
93-         } 
120+         current. next_method ( ) ; 
94121    }  else  { 
95122        return ; 
96123    } 
97-     let  method_name = match  * current { 
98-         ParallaxMappingMethod :: Relief  {  .. }  => "Relief Mapping" , 
99-         ParallaxMappingMethod :: Occlusion  => "Parallax Occlusion Mapping" , 
100-     } ; 
101124    let  mut  text = text. single_mut ( ) ; 
102-     text. sections [ 2 ] . value  = format ! ( "Method: {method_name }\n " ) ; 
125+     text. sections [ 2 ] . value  = format ! ( "Method: {}\n " ,   * current ) ; 
103126
104127    for  ( _,  mat)  in  materials. iter_mut ( )  { 
105-         mat. parallax_mapping_method  = * current; 
128+         mat. parallax_mapping_method  = current. 0 ; 
106129    } 
107130} 
108131
@@ -133,7 +156,7 @@ fn spin(time: Res<Time>, mut query: Query<(&mut Transform, &Spin)>) {
133156    for  ( mut  transform,  spin)  in  query. iter_mut ( )  { 
134157        transform. rotate_local_y ( spin. speed  *  time. delta_seconds ( ) ) ; 
135158        transform. rotate_local_x ( spin. speed  *  time. delta_seconds ( ) ) ; 
136-         transform. rotate_local_z ( spin. speed  *  time. delta_seconds ( ) ) ; 
159+         transform. rotate_local_z ( - spin. speed  *  time. delta_seconds ( ) ) ; 
137160    } 
138161} 
139162
@@ -183,7 +206,7 @@ fn setup(
183206    asset_server :  Res < AssetServer > , 
184207)  { 
185208    // The normal map. Note that to generate it in the GIMP image editor, you should 
186-     // open the bump  map, and do Filters → Generic → Normal Map 
209+     // open the depth  map, and do Filters → Generic → Normal Map 
187210    // You should enable the "flip X" checkbox. 
188211    let  normal_handle = asset_server. load ( "textures/parallax_example/cube_normal.jpg" ) ; 
189212    normal. 0  = Some ( normal_handle) ; 
@@ -249,6 +272,7 @@ fn setup(
249272
250273    let  parallax_depth_scale = TargetDepth :: default ( ) . 0 ; 
251274    let  max_parallax_layer_count = TargetLayers :: default ( ) . 0 . exp2 ( ) ; 
275+     let  parallax_mapping_method = CurrentMethod :: default ( ) ; 
252276    let  parallax_material = materials. add ( StandardMaterial  { 
253277        perceptual_roughness :  0.4 , 
254278        base_color_texture :  Some ( asset_server. load ( "textures/parallax_example/cube_color.jpg" ) ) , 
@@ -257,7 +281,7 @@ fn setup(
257281        // white the lowest. 
258282        depth_map :  Some ( asset_server. load ( "textures/parallax_example/cube_depth.jpg" ) ) , 
259283        parallax_depth_scale, 
260-         parallax_mapping_method :  ParallaxMappingMethod :: DEFAULT_RELIEF_MAPPING , 
284+         parallax_mapping_method :  parallax_mapping_method . 0 , 
261285        max_parallax_layer_count, 
262286        ..default ( ) 
263287    } ) ; 
@@ -306,7 +330,7 @@ fn setup(
306330                format!( "Layers: {max_parallax_layer_count:.0}\n " ) , 
307331                style. clone( ) , 
308332            ) , 
309-             TextSection :: new( "Method: Relief Mapping \n ",  style. clone( ) ) , 
333+             TextSection :: new( format! ( "{parallax_mapping_method} \n ") ,  style. clone( ) ) , 
310334            TextSection :: new( "\n \n " ,  style. clone( ) ) , 
311335            TextSection :: new( "Controls\n " ,  style. clone( ) ) , 
312336            TextSection :: new( "---------------\n " ,  style. clone( ) ) , 
0 commit comments