three_d/renderer/material/
normal_material.rs1use crate::core::*;
2use crate::renderer::*;
3
4#[derive(Clone)]
10pub struct NormalMaterial {
11 pub normal_scale: f32,
13 pub normal_texture: Option<Texture2DRef>,
15 pub render_states: RenderStates,
17}
18
19impl NormalMaterial {
20 pub fn new(context: &Context, cpu_material: &CpuMaterial) -> Self {
22 let normal_texture = cpu_material
23 .normal_texture
24 .as_ref()
25 .map(|cpu_texture| Texture2DRef::from_cpu_texture(context, cpu_texture));
26 Self {
27 normal_scale: cpu_material.normal_scale,
28 normal_texture,
29 render_states: RenderStates::default(),
30 }
31 }
32
33 pub fn from_physical_material(physical_material: &PhysicalMaterial) -> Self {
35 Self {
36 normal_scale: physical_material.normal_scale,
37 normal_texture: physical_material.normal_texture.clone(),
38 render_states: RenderStates {
39 write_mask: WriteMask::default(),
40 blend: Blend::Disabled,
41 ..physical_material.render_states
42 },
43 }
44 }
45}
46
47impl FromCpuMaterial for NormalMaterial {
48 fn from_cpu_material(context: &Context, cpu_material: &CpuMaterial) -> Self {
49 Self::new(context, cpu_material)
50 }
51}
52
53impl Material for NormalMaterial {
54 fn id(&self) -> EffectMaterialId {
55 EffectMaterialId::NormalMaterial(self.normal_texture.is_some())
56 }
57
58 fn fragment_shader_source(&self, _lights: &[&dyn Light]) -> String {
59 let mut source = String::new();
60 if self.normal_texture.is_some() {
61 source.push_str("#define USE_TEXTURE\nin vec2 uvs;\nin vec3 tang;\nin vec3 bitang;\n");
62 }
63 source.push_str(include_str!("shaders/normal_material.frag"));
64 source
65 }
66
67 fn use_uniforms(&self, program: &Program, _viewer: &dyn Viewer, _lights: &[&dyn Light]) {
68 if let Some(ref tex) = self.normal_texture {
69 program.use_uniform("normalScale", self.normal_scale);
70 program.use_uniform("textureTransformation", tex.transformation);
71 program.use_texture("normalTexture", tex);
72 }
73 }
74 fn render_states(&self) -> RenderStates {
75 self.render_states
76 }
77 fn material_type(&self) -> MaterialType {
78 MaterialType::Opaque
79 }
80}
81
82impl Default for NormalMaterial {
83 fn default() -> Self {
84 Self {
85 normal_texture: None,
86 normal_scale: 1.0,
87 render_states: RenderStates::default(),
88 }
89 }
90}