1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
//! # Nodal Scene Interface Helpers For 3Delight //! Shortcuts for instancing common nodes. use nsi; use nsi::toolbelt::generate_or_use_handle; /// Creates a typical environment node. /// /// A latitutde-lungitude environment map will be aligned as-shot /// with the horizon along the X-Z plane at infinity. /// /// If `handle` is [`None`] a random handle is generated. /// /// # Arguments /// * `angle` – In degrees; specicfies how much to rotate the /// environment around the Y (up) axis. /// /// * `visible` – If the environment is visible to the camera. /// /// Returns `handle` and the handle of the created `shader`. /// /// Note that the `shader` node is empty. It is up to the user /// to set the resp. attributes on the node or hook up an OSL /// network below it. pub fn environment( ctx: &nsi::Context, handle: Option<&str>, angle: Option<f64>, visible: Option<bool>, ) -> (String, String) { // Create a rotation transform – this is the handle we return. let rotation = ctx.rotation( None, angle.unwrap_or(0.0), &[0.0, 1.0, 0.0], ); let environment = generate_or_use_handle(handle, Some("environment")); // Set up an environment light. ctx.append( &rotation, None, &ctx.node(Some(environment.as_str()), nsi::NodeType::Environment, &[]), ); let shader = ctx.node(None, nsi::NodeType::Shader, &[]); ctx.append( &environment, Some("geometryattributes"), ctx.append( &ctx.node(None, nsi::NodeType::Attributes, &[nsi::integer!( "visibility.camera", visible.unwrap_or(true) as _ )] ), Some("surfaceshader"), shader.as_str() ).0, ); (rotation, shader) } /// Creates a textured environment light. /// /// If `handle` is [`None`] a random handle is generated. /// /// # Arguments /// * `texture – A latitude-longitude texture map in one of these /// formats: /// * TIFF /// * JPEG /// * Radiance /// * OpenEXR /// * GIF /// * IFF /// * SGI /// * PIC /// * Photoshop PSD /// * TGA /// /// * `angle` – In degrees; specicfies how much to rotate the /// environment around the Y (up) axis. /// /// * `exposure` – Scales the intensity in /// [stops or EV values](https://en.wikipedia.org/wiki/Exposure_value). /// /// * `visible` – If the environment is visible to the camera. /// /// Returns `handle` and the handle of the created `shader`. /// /// Note that the `shader` node is empty. It is up to the user /// to set the resp. attributes on the node or hook up an OSL /// network below it. pub fn environment_texture<'a, 'b>( ctx: &nsi::Context<'a>, handle: Option<&str>, texture: &str, angle: Option<f64>, exposure: Option<f32>, visible: Option<bool>, args: &nsi::ArgSlice<'b, 'a>, ) -> (String, String) { let (rotation, shader) = environment(ctx, handle, angle, visible); // Environment light attributes. ctx.set_attribute( shader.as_str(), &[ nsi::string!("shaderfilename", "${DELIGHT}/osl/environmentLight"), nsi::float!("intensity", 2.0f32.powf(exposure.unwrap_or(0.0))), nsi::string!("image", texture), ], ); if !args.is_empty() { ctx.set_attribute(shader.as_str(), args); } (rotation, shader) } /// **Convenience method; not part of the official ɴsɪ API.** /// /// Creates a phiscally plausible, procedural sky environment /// light. /// /// If `handle` is [`None`] a random handle is generated. /// /// # Arguments /// * `angle` – In degrees; specicfies how much to rotate the /// environment around the Y (up) axis. /// /// * `exposure` – Scales the intensity in /// [stops or EV values](https://en.wikipedia.org/wiki/Exposure_value). /// /// * `visible` – If the environment is visible to the camera. /// /// Returns `handle` and the handle of the created `shader`. /// /// Note that this instances a `dlSky` shader. Using the returned /// `shader` handle you can set more attributes on this node. pub fn environment_sky<'a, 'b>( ctx: &nsi::Context<'a>, handle: Option<&str>, angle: Option<f64>, exposure: Option<f32>, visible: Option<bool>, args: &nsi::ArgSlice<'b, 'a>, ) -> (String, String) { let (rotation, shader) = environment(ctx, handle, angle, visible); // Environment light attributes. ctx.set_attribute( shader.as_str(), &[ nsi::string!("shaderfilename", "${DELIGHT}/osl/dlSky"), nsi::float!("intensity", 2.0f32.powf(exposure.unwrap_or(0.0))), ], ); if !args.is_empty() { ctx.set_attribute(shader.as_str(), args); } (rotation, shader) }