@@ -39,10 +39,18 @@ struct SOrenNayar
3939 };
4040 using creation_type = SCreationParams;
4141
42+ struct SQuery
43+ {
44+ scalar_type getVdotL () NBL_CONST_MEMBER_FUNC { return VdotL; }
45+ scalar_type VdotL;
46+ };
47+
4248 static this_t create (scalar_type A)
4349 {
4450 this_t retval;
4551 retval.A = A;
52+ retval.A2 = A * 0.5 ;
53+ retval.AB = vector2_type (1.0 , 0.0 ) + vector2_type (-0.5 , 0.45 ) * vector2_type (retval.A2, retval.A2) / vector2_type (retval.A2 + 0.33 , retval.A2 + 0.09 );
4654 return retval;
4755 }
4856 static this_t create (NBL_CONST_REF_ARG (creation_type) params)
@@ -52,58 +60,66 @@ struct SOrenNayar
5260
5361 scalar_type __rec_pi_factored_out_wo_clamps (scalar_type VdotL, scalar_type maxNdotL, scalar_type maxNdotV)
5462 {
55- scalar_type A2 = A * 0.5 ;
56- vector2_type AB = vector2_type (1.0 , 0.0 ) + vector2_type (-0.5 , 0.45 ) * vector2_type (A2, A2) / vector2_type (A2 + 0.33 , A2 + 0.09 );
5763 scalar_type C = 1.0 / max <scalar_type>(maxNdotL, maxNdotV);
58-
5964 scalar_type cos_phi_sin_theta = max <scalar_type>(VdotL - maxNdotL * maxNdotV, 0.0 );
6065 return (AB.x + AB.y * cos_phi_sin_theta * C);
6166 }
67+ template<typename Query>
68+ spectral_type __eval (NBL_CONST_REF_ARG (Query) query, NBL_CONST_REF_ARG (sample_type) _sample, NBL_CONST_REF_ARG (isotropic_interaction_type) interaction)
69+ {
70+ scalar_type NdotL = _sample.getNdotL (_clamp);
71+ return hlsl::promote<spectral_type>(NdotL * numbers::inv_pi<scalar_type> * __rec_pi_factored_out_wo_clamps (query.getVdotL (), NdotL, interaction.getNdotV (_clamp)));
72+ }
6273
6374 spectral_type eval (NBL_CONST_REF_ARG (sample_type) _sample, NBL_CONST_REF_ARG (isotropic_interaction_type) interaction)
6475 {
65- scalar_type NdotL = _sample.getNdotL (_clamp);
66- return hlsl::promote<spectral_type>(NdotL * numbers::inv_pi<scalar_type> * __rec_pi_factored_out_wo_clamps (hlsl::dot (interaction.getV ().getDirection (), _sample.getL ().getDirection ()), NdotL, interaction.getNdotV (_clamp)));
76+ SQuery query;
77+ query.VdotL = hlsl::dot (interaction.getV ().getDirection (), _sample.getL ().getDirection ());
78+ return __eval<SQuery>(query, _sample, interaction);
6779 }
6880 spectral_type eval (NBL_CONST_REF_ARG (sample_type) _sample, NBL_CONST_REF_ARG (anisotropic_interaction_type) interaction)
6981 {
7082 return eval (_sample, interaction.isotropic);
7183 }
7284
73- sample_type generate_wo_clamps (NBL_CONST_REF_ARG (anisotropic_interaction_type) interaction, const vector2_type u)
85+ sample_type generate (NBL_CONST_REF_ARG (anisotropic_interaction_type) interaction, const vector2_type u)
7486 {
7587 ray_dir_info_type L;
7688 L.direction = sampling::ProjectedHemisphere<scalar_type>::generate (u);
7789 return sample_type::createFromTangentSpace (L, interaction.getFromTangentSpace ());
7890 }
7991
80- sample_type generate (NBL_CONST_REF_ARG (anisotropic_interaction_type) interaction, const vector2_type u)
81- {
82- return generate_wo_clamps (interaction, u);
83- }
84-
8592 sample_type generate (NBL_CONST_REF_ARG (isotropic_interaction_type) interaction, const vector2_type u)
8693 {
87- return generate_wo_clamps (anisotropic_interaction_type::create (interaction), u);
94+ return generate (anisotropic_interaction_type::create (interaction), u);
8895 }
8996
9097 scalar_type pdf (NBL_CONST_REF_ARG (sample_type) _sample)
9198 {
9299 return sampling::ProjectedHemisphere<scalar_type>::pdf (_sample.getNdotL (_clamp));
93100 }
94101
95- quotient_pdf_type quotient_and_pdf (NBL_CONST_REF_ARG (sample_type) _sample, NBL_CONST_REF_ARG (isotropic_interaction_type) interaction)
102+ template<typename Query>
103+ quotient_pdf_type __quotient_and_pdf (NBL_CONST_REF_ARG (Query) query, NBL_CONST_REF_ARG (sample_type) _sample, NBL_CONST_REF_ARG (isotropic_interaction_type) interaction)
96104 {
97105 scalar_type _pdf = pdf (_sample);
98- scalar_type q = __rec_pi_factored_out_wo_clamps (hlsl:: dot (interaction. getV (). getDirection (), _sample. getL (). getDirection () ), _sample.getNdotL (_clamp), interaction.getNdotV (_clamp));
106+ scalar_type q = __rec_pi_factored_out_wo_clamps (query. getVdotL ( ), _sample.getNdotL (_clamp), interaction.getNdotV (_clamp));
99107 return quotient_pdf_type::create (q, _pdf);
100108 }
109+ quotient_pdf_type quotient_and_pdf (NBL_CONST_REF_ARG (sample_type) _sample, NBL_CONST_REF_ARG (isotropic_interaction_type) interaction)
110+ {
111+ SQuery query;
112+ query.VdotL = hlsl::dot (interaction.getV ().getDirection (), _sample.getL ().getDirection ());
113+ return __quotient_and_pdf<SQuery>(query, _sample, interaction);
114+ }
101115 quotient_pdf_type quotient_and_pdf (NBL_CONST_REF_ARG (sample_type) _sample, NBL_CONST_REF_ARG (anisotropic_interaction_type) interaction)
102116 {
103117 return quotient_and_pdf (_sample, interaction.isotropic);
104118 }
105119
106120 scalar_type A;
121+ scalar_type A2;
122+ vector2_type AB;
107123};
108124
109125}
0 commit comments