1
1
//! A simple 3D scene with a spinning cube with a normal map and depth map to demonstrate parallax mapping.
2
2
//! Press left mouse button to cycle through different views.
3
3
4
+ use std:: fmt;
5
+
4
6
use bevy:: { prelude:: * , render:: render_resource:: TextureFormat , window:: close_on_esc} ;
5
7
6
8
fn main ( ) {
@@ -48,6 +50,34 @@ impl Default for TargetLayers {
48
50
TargetLayers ( 5.0 )
49
51
}
50
52
}
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
+
51
81
fn update_parallax_depth_scale (
52
82
input : Res < Input < KeyCode > > ,
53
83
mut materials : ResMut < Assets < StandardMaterial > > ,
@@ -57,7 +87,7 @@ fn update_parallax_depth_scale(
57
87
) {
58
88
if input. just_pressed ( KeyCode :: Key1 ) {
59
89
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 ) ;
61
91
* depth_update = true ;
62
92
}
63
93
if input. just_pressed ( KeyCode :: Key2 ) {
@@ -84,25 +114,18 @@ fn switch_method(
84
114
input : Res < Input < KeyCode > > ,
85
115
mut materials : ResMut < Assets < StandardMaterial > > ,
86
116
mut text : Query < & mut Text > ,
87
- mut current : Local < ParallaxMappingMethod > ,
117
+ mut current : Local < CurrentMethod > ,
88
118
) {
89
119
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 ( ) ;
94
121
} else {
95
122
return ;
96
123
}
97
- let method_name = match * current {
98
- ParallaxMappingMethod :: Relief { .. } => "Relief Mapping" ,
99
- ParallaxMappingMethod :: Occlusion => "Parallax Occlusion Mapping" ,
100
- } ;
101
124
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 ) ;
103
126
104
127
for ( _, mat) in materials. iter_mut ( ) {
105
- mat. parallax_mapping_method = * current;
128
+ mat. parallax_mapping_method = current. 0 ;
106
129
}
107
130
}
108
131
@@ -133,7 +156,7 @@ fn spin(time: Res<Time>, mut query: Query<(&mut Transform, &Spin)>) {
133
156
for ( mut transform, spin) in query. iter_mut ( ) {
134
157
transform. rotate_local_y ( spin. speed * time. delta_seconds ( ) ) ;
135
158
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 ( ) ) ;
137
160
}
138
161
}
139
162
@@ -183,7 +206,7 @@ fn setup(
183
206
asset_server : Res < AssetServer > ,
184
207
) {
185
208
// 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
187
210
// You should enable the "flip X" checkbox.
188
211
let normal_handle = asset_server. load ( "textures/parallax_example/cube_normal.jpg" ) ;
189
212
normal. 0 = Some ( normal_handle) ;
@@ -249,6 +272,7 @@ fn setup(
249
272
250
273
let parallax_depth_scale = TargetDepth :: default ( ) . 0 ;
251
274
let max_parallax_layer_count = TargetLayers :: default ( ) . 0 . exp2 ( ) ;
275
+ let parallax_mapping_method = CurrentMethod :: default ( ) ;
252
276
let parallax_material = materials. add ( StandardMaterial {
253
277
perceptual_roughness : 0.4 ,
254
278
base_color_texture : Some ( asset_server. load ( "textures/parallax_example/cube_color.jpg" ) ) ,
@@ -257,7 +281,7 @@ fn setup(
257
281
// white the lowest.
258
282
depth_map : Some ( asset_server. load ( "textures/parallax_example/cube_depth.jpg" ) ) ,
259
283
parallax_depth_scale,
260
- parallax_mapping_method : ParallaxMappingMethod :: DEFAULT_RELIEF_MAPPING ,
284
+ parallax_mapping_method : parallax_mapping_method . 0 ,
261
285
max_parallax_layer_count,
262
286
..default ( )
263
287
} ) ;
@@ -306,7 +330,7 @@ fn setup(
306
330
format!( "Layers: {max_parallax_layer_count:.0}\n " ) ,
307
331
style. clone( ) ,
308
332
) ,
309
- TextSection :: new( "Method: Relief Mapping \n ", style. clone( ) ) ,
333
+ TextSection :: new( format! ( "{parallax_mapping_method} \n ") , style. clone( ) ) ,
310
334
TextSection :: new( "\n \n " , style. clone( ) ) ,
311
335
TextSection :: new( "Controls\n " , style. clone( ) ) ,
312
336
TextSection :: new( "---------------\n " , style. clone( ) ) ,
0 commit comments