diff options
Diffstat (limited to 'intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h')
-rw-r--r-- | intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h | 168 |
1 files changed, 92 insertions, 76 deletions
diff --git a/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h index 80fd9ba2b37..8122bcc1424 100644 --- a/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h +++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h @@ -36,126 +36,142 @@ CCL_NAMESPACE_BEGIN typedef ccl_addr_space struct VelvetBsdf { - SHADER_CLOSURE_BASE; + SHADER_CLOSURE_BASE; - float sigma; - float invsigma2; + float sigma; + float invsigma2; } VelvetBsdf; ccl_device int bsdf_ashikhmin_velvet_setup(VelvetBsdf *bsdf) { - float sigma = fmaxf(bsdf->sigma, 0.01f); - bsdf->invsigma2 = 1.0f/(sigma * sigma); + float sigma = fmaxf(bsdf->sigma, 0.01f); + bsdf->invsigma2 = 1.0f / (sigma * sigma); - bsdf->type = CLOSURE_BSDF_ASHIKHMIN_VELVET_ID; + bsdf->type = CLOSURE_BSDF_ASHIKHMIN_VELVET_ID; - return SD_BSDF|SD_BSDF_HAS_EVAL; + return SD_BSDF | SD_BSDF_HAS_EVAL; } ccl_device bool bsdf_ashikhmin_velvet_merge(const ShaderClosure *a, const ShaderClosure *b) { - const VelvetBsdf *bsdf_a = (const VelvetBsdf*)a; - const VelvetBsdf *bsdf_b = (const VelvetBsdf*)b; + const VelvetBsdf *bsdf_a = (const VelvetBsdf *)a; + const VelvetBsdf *bsdf_b = (const VelvetBsdf *)b; - return (isequal_float3(bsdf_a->N, bsdf_b->N)) && - (bsdf_a->sigma == bsdf_b->sigma); + return (isequal_float3(bsdf_a->N, bsdf_b->N)) && (bsdf_a->sigma == bsdf_b->sigma); } -ccl_device float3 bsdf_ashikhmin_velvet_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +ccl_device float3 bsdf_ashikhmin_velvet_eval_reflect(const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + float *pdf) { - const VelvetBsdf *bsdf = (const VelvetBsdf*)sc; - float m_invsigma2 = bsdf->invsigma2; - float3 N = bsdf->N; + const VelvetBsdf *bsdf = (const VelvetBsdf *)sc; + float m_invsigma2 = bsdf->invsigma2; + float3 N = bsdf->N; - float cosNO = dot(N, I); - float cosNI = dot(N, omega_in); - if(cosNO > 0 && cosNI > 0) { - float3 H = normalize(omega_in + I); + float cosNO = dot(N, I); + float cosNI = dot(N, omega_in); + if (cosNO > 0 && cosNI > 0) { + float3 H = normalize(omega_in + I); - float cosNH = dot(N, H); - float cosHO = fabsf(dot(I, H)); + float cosNH = dot(N, H); + float cosHO = fabsf(dot(I, H)); - if(!(fabsf(cosNH) < 1.0f-1e-5f && cosHO > 1e-5f)) - return make_float3(0.0f, 0.0f, 0.0f); + if (!(fabsf(cosNH) < 1.0f - 1e-5f && cosHO > 1e-5f)) + return make_float3(0.0f, 0.0f, 0.0f); - float cosNHdivHO = cosNH / cosHO; - cosNHdivHO = fmaxf(cosNHdivHO, 1e-5f); + float cosNHdivHO = cosNH / cosHO; + cosNHdivHO = fmaxf(cosNHdivHO, 1e-5f); - float fac1 = 2 * fabsf(cosNHdivHO * cosNO); - float fac2 = 2 * fabsf(cosNHdivHO * cosNI); + float fac1 = 2 * fabsf(cosNHdivHO * cosNO); + float fac2 = 2 * fabsf(cosNHdivHO * cosNI); - float sinNH2 = 1 - cosNH * cosNH; - float sinNH4 = sinNH2 * sinNH2; - float cotangent2 = (cosNH * cosNH) / sinNH2; + float sinNH2 = 1 - cosNH * cosNH; + float sinNH4 = sinNH2 * sinNH2; + float cotangent2 = (cosNH * cosNH) / sinNH2; - float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * M_1_PI_F / sinNH4; - float G = min(1.0f, min(fac1, fac2)); // TODO: derive G from D analytically + float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * M_1_PI_F / sinNH4; + float G = min(1.0f, min(fac1, fac2)); // TODO: derive G from D analytically - float out = 0.25f * (D * G) / cosNO; + float out = 0.25f * (D * G) / cosNO; - *pdf = 0.5f * M_1_PI_F; - return make_float3(out, out, out); - } + *pdf = 0.5f * M_1_PI_F; + return make_float3(out, out, out); + } - return make_float3(0.0f, 0.0f, 0.0f); + return make_float3(0.0f, 0.0f, 0.0f); } -ccl_device float3 bsdf_ashikhmin_velvet_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +ccl_device float3 bsdf_ashikhmin_velvet_eval_transmit(const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + float *pdf) { - return make_float3(0.0f, 0.0f, 0.0f); + return make_float3(0.0f, 0.0f, 0.0f); } -ccl_device int bsdf_ashikhmin_velvet_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) +ccl_device int bsdf_ashikhmin_velvet_sample(const ShaderClosure *sc, + float3 Ng, + float3 I, + float3 dIdx, + float3 dIdy, + float randu, + float randv, + float3 *eval, + float3 *omega_in, + float3 *domega_in_dx, + float3 *domega_in_dy, + float *pdf) { - const VelvetBsdf *bsdf = (const VelvetBsdf*)sc; - float m_invsigma2 = bsdf->invsigma2; - float3 N = bsdf->N; + const VelvetBsdf *bsdf = (const VelvetBsdf *)sc; + float m_invsigma2 = bsdf->invsigma2; + float3 N = bsdf->N; - // we are viewing the surface from above - send a ray out with uniform - // distribution over the hemisphere - sample_uniform_hemisphere(N, randu, randv, omega_in, pdf); + // we are viewing the surface from above - send a ray out with uniform + // distribution over the hemisphere + sample_uniform_hemisphere(N, randu, randv, omega_in, pdf); - if(dot(Ng, *omega_in) > 0) { - float3 H = normalize(*omega_in + I); + if (dot(Ng, *omega_in) > 0) { + float3 H = normalize(*omega_in + I); - float cosNI = dot(N, *omega_in); - float cosNO = dot(N, I); - float cosNH = dot(N, H); - float cosHO = fabsf(dot(I, H)); + float cosNI = dot(N, *omega_in); + float cosNO = dot(N, I); + float cosNH = dot(N, H); + float cosHO = fabsf(dot(I, H)); - if(fabsf(cosNO) > 1e-5f && fabsf(cosNH) < 1.0f-1e-5f && cosHO > 1e-5f) { - float cosNHdivHO = cosNH / cosHO; - cosNHdivHO = fmaxf(cosNHdivHO, 1e-5f); + if (fabsf(cosNO) > 1e-5f && fabsf(cosNH) < 1.0f - 1e-5f && cosHO > 1e-5f) { + float cosNHdivHO = cosNH / cosHO; + cosNHdivHO = fmaxf(cosNHdivHO, 1e-5f); - float fac1 = 2 * fabsf(cosNHdivHO * cosNO); - float fac2 = 2 * fabsf(cosNHdivHO * cosNI); + float fac1 = 2 * fabsf(cosNHdivHO * cosNO); + float fac2 = 2 * fabsf(cosNHdivHO * cosNI); - float sinNH2 = 1 - cosNH * cosNH; - float sinNH4 = sinNH2 * sinNH2; - float cotangent2 = (cosNH * cosNH) / sinNH2; + float sinNH2 = 1 - cosNH * cosNH; + float sinNH4 = sinNH2 * sinNH2; + float cotangent2 = (cosNH * cosNH) / sinNH2; - float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * M_1_PI_F / sinNH4; - float G = min(1.0f, min(fac1, fac2)); // TODO: derive G from D analytically + float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * M_1_PI_F / sinNH4; + float G = min(1.0f, min(fac1, fac2)); // TODO: derive G from D analytically - float power = 0.25f * (D * G) / cosNO; + float power = 0.25f * (D * G) / cosNO; - *eval = make_float3(power, power, power); + *eval = make_float3(power, power, power); #ifdef __RAY_DIFFERENTIALS__ - // TODO: find a better approximation for the retroreflective bounce - *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx; - *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy; + // TODO: find a better approximation for the retroreflective bounce + *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx; + *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy; #endif - } - else - *pdf = 0.0f; - } - else - *pdf = 0.0f; - - return LABEL_REFLECT|LABEL_DIFFUSE; + } + else + *pdf = 0.0f; + } + else + *pdf = 0.0f; + + return LABEL_REFLECT | LABEL_DIFFUSE; } CCL_NAMESPACE_END -#endif /* __BSDF_ASHIKHMIN_VELVET_H__ */ +#endif /* __BSDF_ASHIKHMIN_VELVET_H__ */ |