@@ -45,27 +45,29 @@ pub struct Shader {
45
45
impl Shader {
46
46
pub fn from_wgsl ( source : impl Into < Cow < ' static , str > > ) -> Shader {
47
47
let source = source. into ( ) ;
48
+ let shader_imports = SHADER_IMPORT_PROCESSOR . get_imports_from_str ( & source) ;
48
49
Shader {
49
- imports : SHADER_IMPORT_PROCESSOR . get_imports_from_str ( & source) ,
50
+ imports : shader_imports. imports ,
51
+ import_path : shader_imports. import_path ,
50
52
source : Source :: Wgsl ( source) ,
51
- import_path : None ,
52
53
}
53
54
}
54
55
55
56
pub fn from_glsl ( source : impl Into < Cow < ' static , str > > , stage : naga:: ShaderStage ) -> Shader {
56
57
let source = source. into ( ) ;
58
+ let shader_imports = SHADER_IMPORT_PROCESSOR . get_imports_from_str ( & source) ;
57
59
Shader {
58
- imports : SHADER_IMPORT_PROCESSOR . get_imports_from_str ( & source) ,
60
+ imports : shader_imports. imports ,
61
+ import_path : shader_imports. import_path ,
59
62
source : Source :: Glsl ( source, stage) ,
60
- import_path : None ,
61
63
}
62
64
}
63
65
64
66
pub fn from_spirv ( source : impl Into < Cow < ' static , [ u8 ] > > ) -> Shader {
65
67
Shader {
66
68
imports : Vec :: new ( ) ,
67
- source : Source :: SpirV ( source. into ( ) ) ,
68
69
import_path : None ,
70
+ source : Source :: SpirV ( source. into ( ) ) ,
69
71
}
70
72
}
71
73
@@ -238,12 +240,16 @@ impl AssetLoader for ShaderLoader {
238
240
_ => panic ! ( "unhandled extension: {}" , ext) ,
239
241
} ;
240
242
241
- shader. import_path = Some ( ShaderImport :: AssetPath (
242
- load_context. path ( ) . to_string_lossy ( ) . to_string ( ) ,
243
- ) ) ;
244
- let imports = SHADER_IMPORT_PROCESSOR . get_imports ( & shader) ;
243
+ let shader_imports = SHADER_IMPORT_PROCESSOR . get_imports ( & shader) ;
244
+ if shader_imports. import_path . is_some ( ) {
245
+ shader. import_path = shader_imports. import_path ;
246
+ } else {
247
+ shader. import_path = Some ( ShaderImport :: AssetPath (
248
+ load_context. path ( ) . to_string_lossy ( ) . to_string ( ) ,
249
+ ) ) ;
250
+ }
245
251
let mut asset = LoadedAsset :: new ( shader) ;
246
- for import in imports {
252
+ for import in shader_imports . imports {
247
253
if let ShaderImport :: AssetPath ( asset_path) = import {
248
254
let path = PathBuf :: from_str ( & asset_path) ?;
249
255
asset. add_dependency ( path. into ( ) ) ;
@@ -281,6 +287,7 @@ pub enum ProcessShaderError {
281
287
pub struct ShaderImportProcessor {
282
288
import_asset_path_regex : Regex ,
283
289
import_custom_path_regex : Regex ,
290
+ define_import_path_regex : Regex ,
284
291
}
285
292
286
293
#[ derive( Debug , PartialEq , Eq , Clone , Hash ) ]
@@ -292,34 +299,48 @@ pub enum ShaderImport {
292
299
impl Default for ShaderImportProcessor {
293
300
fn default ( ) -> Self {
294
301
Self {
295
- import_asset_path_regex : Regex :: new ( r#"^\s*#\s*import\s*"(.+)""# ) . unwrap ( ) ,
296
- import_custom_path_regex : Regex :: new ( r"^\s*#\s*import\s*(.+)" ) . unwrap ( ) ,
302
+ import_asset_path_regex : Regex :: new ( r#"^\s*#\s*import\s+"(.+)""# ) . unwrap ( ) ,
303
+ import_custom_path_regex : Regex :: new ( r"^\s*#\s*import\s+(.+)" ) . unwrap ( ) ,
304
+ define_import_path_regex : Regex :: new ( r"^\s*#\s*define_import_path\s+(.+)" ) . unwrap ( ) ,
297
305
}
298
306
}
299
307
}
300
308
309
+ #[ derive( Default ) ]
310
+ pub struct ShaderImports {
311
+ imports : Vec < ShaderImport > ,
312
+ import_path : Option < ShaderImport > ,
313
+ }
314
+
301
315
impl ShaderImportProcessor {
302
- pub fn get_imports ( & self , shader : & Shader ) -> Vec < ShaderImport > {
316
+ pub fn get_imports ( & self , shader : & Shader ) -> ShaderImports {
303
317
match & shader. source {
304
318
Source :: Wgsl ( source) => self . get_imports_from_str ( source) ,
305
319
Source :: Glsl ( source, _stage) => self . get_imports_from_str ( source) ,
306
- Source :: SpirV ( _source) => Vec :: new ( ) ,
320
+ Source :: SpirV ( _source) => ShaderImports :: default ( ) ,
307
321
}
308
322
}
309
323
310
- pub fn get_imports_from_str ( & self , shader : & str ) -> Vec < ShaderImport > {
311
- let mut imports = Vec :: new ( ) ;
324
+ pub fn get_imports_from_str ( & self , shader : & str ) -> ShaderImports {
325
+ let mut shader_imports = ShaderImports :: default ( ) ;
312
326
for line in shader. lines ( ) {
313
327
if let Some ( cap) = self . import_asset_path_regex . captures ( line) {
314
328
let import = cap. get ( 1 ) . unwrap ( ) ;
315
- imports. push ( ShaderImport :: AssetPath ( import. as_str ( ) . to_string ( ) ) ) ;
329
+ shader_imports
330
+ . imports
331
+ . push ( ShaderImport :: AssetPath ( import. as_str ( ) . to_string ( ) ) ) ;
316
332
} else if let Some ( cap) = self . import_custom_path_regex . captures ( line) {
317
333
let import = cap. get ( 1 ) . unwrap ( ) ;
318
- imports. push ( ShaderImport :: Custom ( import. as_str ( ) . to_string ( ) ) ) ;
334
+ shader_imports
335
+ . imports
336
+ . push ( ShaderImport :: Custom ( import. as_str ( ) . to_string ( ) ) ) ;
337
+ } else if let Some ( cap) = self . define_import_path_regex . captures ( line) {
338
+ let path = cap. get ( 1 ) . unwrap ( ) ;
339
+ shader_imports. import_path = Some ( ShaderImport :: Custom ( path. as_str ( ) . to_string ( ) ) ) ;
319
340
}
320
341
}
321
342
322
- imports
343
+ shader_imports
323
344
}
324
345
}
325
346
@@ -413,6 +434,11 @@ impl ShaderProcessor {
413
434
shader_defs,
414
435
& mut final_string,
415
436
) ?;
437
+ } else if SHADER_IMPORT_PROCESSOR
438
+ . define_import_path_regex
439
+ . is_match ( line)
440
+ {
441
+ // ignore import path lines
416
442
} else if * scopes. last ( ) . unwrap ( ) {
417
443
final_string. push_str ( line) ;
418
444
final_string. push ( '\n' ) ;
0 commit comments