@@ -44,8 +44,8 @@ class MaterialCompilerTest final : public application_templates::MonoDeviceAppli
4444
4545 auto logger = m_logger.get ();
4646
47- // dummy monochrome image
48- smart_refctd_ptr<ICPUImageView> monochromeImageView;
47+ // dummy image views
48+ smart_refctd_ptr<ICPUImageView> monochromeImageView, rgbImageView ;
4949 {
5050 constexpr auto format = EF_R16_SFLOAT;
5151 auto image = ICPUImage::create ({
@@ -58,6 +58,18 @@ class MaterialCompilerTest final : public application_templates::MonoDeviceAppli
5858 });
5959 monochromeImageView = ICPUImageView::create ({.image =std::move (image),.viewType =ICPUImageView::ET_2D,.format =format});
6060 }
61+ {
62+ constexpr auto format = EF_R8G8B8A8_SRGB;
63+ auto image = ICPUImage::create ({
64+ .type = IImage::E_TYPE::ET_2D,
65+ .samples = IImage::E_SAMPLE_COUNT_FLAGS::ESCF_1_BIT,
66+ .format = format,
67+ .extent = {1024 ,1024 ,1 },
68+ .mipLevels = 11 ,
69+ .arrayLayers = 72 // fur teh lulz
70+ });
71+ rgbImageView = ICPUImageView::create ({.image =std::move (image),.viewType =ICPUImageView::ET_2D_ARRAY,.format =format});
72+ }
6173
6274// TODO: use std::source_info
6375#define ASSERT_VALUE (WHAT,VALUE,MSG ) if (WHAT!=VALUE) return logFail(" %s:%d test doesn't match expected value. %s" ,__FILE__,__LINE__,MSG)
@@ -159,9 +171,143 @@ class MaterialCompilerTest final : public application_templates::MonoDeviceAppli
159171 }
160172 }
161173
162- // emitter without IES profile
174+ // emitter without IES profile
175+ {
176+ const auto layerH = forest->_new <CFrontendIR::CLayer>();
177+ auto * layer = forest->deref (layerH);
178+ layer->debugInfo = forest->_new <CNodePool::CDebugInfo>(" Twosided Constant Emitter" );
179+ {
180+ const auto mulH = forest->_new <CFrontendIR::CMul>();
181+ auto * mul = forest->deref (mulH);
182+ {
183+ const auto emitterH = forest->_new <CFrontendIR::CEmitter>();
184+ // no profile, unit emission
185+ mul->lhs = emitterH;
186+ }
187+ // we multiply the unit emitter by the value we actually want
188+ {
189+ spectral_var_t ::SCreationParams<3 > params = {};
190+ params.getSemantics () = spectral_var_t ::Semantics::Fixed3_SRGB;
191+ params.knots .params [0 ].scale = 3 .f ;
192+ params.knots .params [1 ].scale = 7 .f ;
193+ params.knots .params [2 ].scale = 15 .f ;
194+ mul->rhs = forest->_new <spectral_var_t >(std::move (params));
195+ }
196+ layer->brdfTop = mulH;
197+ layer->brdfBottom = mulH;
198+ }
199+ ASSERT_VALUE (forest->addMaterial (layerH,logger),true ," Add Material" );
200+ }
201+
202+ // emitter with IES profile
203+ {
204+ const auto layerH = forest->_new <CFrontendIR::CLayer>();
205+ auto * layer = forest->deref (layerH);
206+ layer->debugInfo = forest->_new <CNodePool::CDebugInfo>(" IES Profile Emitter" );
207+ {
208+ const auto mulH = forest->_new <CFrontendIR::CMul>();
209+ auto * mul = forest->deref (mulH);
210+ {
211+ const auto emitterH = forest->_new <CFrontendIR::CEmitter>();
212+ auto * emitter = forest->deref (emitterH);
213+ // you should use this to normalize the profile to unit emission over the hemisphere
214+ // so the light gets picked "fairly"
215+ emitter->profile .scale = 0 .01f ;
216+ emitter->profile .viewChannel = 0 ;
217+ emitter->profile .view = monochromeImageView;
218+ // these are defaults but going to set them
219+ emitter->profile .sampler .TextureWrapU = ISampler::E_TEXTURE_CLAMP::ETC_REPEAT;
220+ emitter->profile .sampler .TextureWrapV = ISampler::E_TEXTURE_CLAMP::ETC_REPEAT;
221+ // TODO: set transform after merging the OBB PR
222+ // emitter->profileTransform = ;
223+ mul->lhs = emitterH;
224+ }
225+ // we multiply the unit emitter by the emission color value we actually want
226+ {
227+ spectral_var_t ::SCreationParams<3 > params = {};
228+ params.getSemantics () = spectral_var_t ::Semantics::Fixed3_SRGB;
229+ params.knots .params [0 ].scale = 60 .f ;
230+ params.knots .params [1 ].scale = 90 .f ;
231+ params.knots .params [2 ].scale = 45 .f ;
232+ mul->rhs = forest->_new <spectral_var_t >(std::move (params));
233+ }
234+ layer->brdfTop = mulH;
235+ }
236+ ASSERT_VALUE (forest->addMaterial (layerH,logger),true ," Add Material" );
237+ }
238+
239+ // onesided emitter with spatially varying emission from the backside
240+ {
241+ const auto layerH = forest->_new <CFrontendIR::CLayer>();
242+ auto * layer = forest->deref (layerH);
243+ layer->debugInfo = forest->_new <CNodePool::CDebugInfo>(" Spatially Varying Emitter" );
244+ {
245+ const auto mulH = forest->_new <CFrontendIR::CMul>();
246+ auto * mul = forest->deref (mulH);
247+ {
248+ const auto emitterH = forest->_new <CFrontendIR::CEmitter>();
249+ // no profile, unit emission
250+ mul->lhs = emitterH;
251+ }
252+ // we multiply the unit emitter by the value we actually want
253+ {
254+ spectral_var_t ::SCreationParams<3 > params = {};
255+ params.getSemantics () = spectral_var_t ::Semantics::Fixed3_SRGB;
256+ for (auto c=0 ; c<3 ; c++)
257+ {
258+ params.knots .params [c].scale = 4 .9f ;
259+ params.knots .params [c].viewChannel = c;
260+ params.knots .params [c].view = rgbImageView;
261+ params.knots .params [c].sampler .TextureWrapU = ISampler::E_TEXTURE_CLAMP::ETC_CLAMP_TO_BORDER;
262+ params.knots .params [c].sampler .TextureWrapV = ISampler::E_TEXTURE_CLAMP::ETC_CLAMP_TO_BORDER;
263+ params.knots .params [c].sampler .BorderColor = ISampler::E_TEXTURE_BORDER_COLOR::ETBC_FLOAT_OPAQUE_BLACK;
264+ }
265+ mul->rhs = forest->_new <spectral_var_t >(std::move (params));
266+ }
267+ layer->brdfBottom = mulH;
268+ }
269+ ASSERT_VALUE (forest->addMaterial (layerH,logger),true ," Add Material" );
270+ }
163271
164- // emitter with IES profile
272+ // spatially varying emission but with a profile (think classroom projector)
273+ {
274+ const auto layerH = forest->_new <CFrontendIR::CLayer>();
275+ auto * layer = forest->deref (layerH);
276+ layer->debugInfo = forest->_new <CNodePool::CDebugInfo>(" Spatially Varying Emitter with IES profile e.g. Digital Projector" );
277+ {
278+ const auto mulH = forest->_new <CFrontendIR::CMul>();
279+ auto * mul = forest->deref (mulH);
280+ {
281+ const auto emitterH = forest->_new <CFrontendIR::CEmitter>();
282+ auto * emitter = forest->deref (emitterH);
283+ emitter->profile .scale = 67 .f ;
284+ emitter->profile .viewChannel = 0 ;
285+ emitter->profile .view = monochromeImageView;
286+ // lets try some other samplers
287+ emitter->profile .sampler .TextureWrapU = ISampler::E_TEXTURE_CLAMP::ETC_CLAMP_TO_EDGE;
288+ emitter->profile .sampler .TextureWrapV = ISampler::E_TEXTURE_CLAMP::ETC_CLAMP_TO_EDGE;
289+ // try with default transform
290+ mul->lhs = emitterH;
291+ }
292+ // we multiply the unit emitter by the value we actually want
293+ {
294+ spectral_var_t ::SCreationParams<3 > params = {};
295+ params.getSemantics () = spectral_var_t ::Semantics::Fixed3_SRGB;
296+ for (auto c=0 ; c<3 ; c++)
297+ {
298+ params.knots .params [c].scale = 900 .f ; // super bright cause its probably small
299+ params.knots .params [c].viewChannel = c;
300+ params.knots .params [c].view = rgbImageView;
301+ params.knots .params [c].sampler .TextureWrapU = ISampler::E_TEXTURE_CLAMP::ETC_CLAMP_TO_BORDER;
302+ params.knots .params [c].sampler .TextureWrapV = ISampler::E_TEXTURE_CLAMP::ETC_CLAMP_TO_BORDER;
303+ params.knots .params [c].sampler .BorderColor = ISampler::E_TEXTURE_BORDER_COLOR::ETBC_FLOAT_OPAQUE_BLACK;
304+ }
305+ mul->rhs = forest->_new <spectral_var_t >(std::move (params));
306+ }
307+ layer->brdfTop = mulH;
308+ }
309+ ASSERT_VALUE (forest->addMaterial (layerH,logger),true ," Add Material" );
310+ }
165311
166312 // anisotropic cook torrance GGX with Conductor Fresnel
167313 {
0 commit comments