diff options
Diffstat (limited to 'intern/cycles/kernel/closure/bsdf_disney_specular.h')
-rw-r--r-- | intern/cycles/kernel/closure/bsdf_disney_specular.h | 79 |
1 files changed, 43 insertions, 36 deletions
diff --git a/intern/cycles/kernel/closure/bsdf_disney_specular.h b/intern/cycles/kernel/closure/bsdf_disney_specular.h index cbcfc4106c5..7e8139fd040 100644 --- a/intern/cycles/kernel/closure/bsdf_disney_specular.h +++ b/intern/cycles/kernel/closure/bsdf_disney_specular.h @@ -35,40 +35,47 @@ CCL_NAMESPACE_BEGIN +typedef ccl_addr_space struct DisneySpecularBsdf { + SHADER_CLOSURE_BASE; -ccl_device int bsdf_disney_specular_setup(ShaderClosure *sc) + float specular, specularTint, roughness, metallic, anisotropic, alpha_x, alpha_y, rough_g; + float3 N, T; + float3 baseColor, cspec0; +} DisneySpecularBsdf; + +ccl_device int bsdf_disney_specular_setup(DisneySpecularBsdf *bsdf) { - float m_cdlum = 0.3f * sc->color0.x + 0.6f * sc->color0.y + 0.1f * sc->color0.z; // luminance approx. + float m_cdlum = 0.3f * bsdf->baseColor.x + 0.6f * bsdf->baseColor.y + 0.1f * bsdf->baseColor.z; // luminance approx. - float3 m_ctint = m_cdlum > 0.0f ? sc->color0/*baseColor*/ / m_cdlum : make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat + float3 m_ctint = m_cdlum > 0.0f ? bsdf->baseColor / m_cdlum : make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat - float3 tmp_col = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - sc->data2/*specularTint*/) + m_ctint * sc->data2/*specularTint*/; // lerp(make_float3(1.0f, 1.0f, 1.0f), m_ctint, sc->data2/*specularTint*/); - sc->custom_color0/*cspec0*/ = (sc->data1/*specular*/ * 0.08f * tmp_col) * (1.0f - sc->data0/*metallic*/) + sc->color0/*baseColor*/ * sc->data0/*metallic*/; // lerp(sc->data1/*specular*/ * 0.08f * tmp_col, sc->color0/*baseColor*/, sc->data0/*metallic*/); + float3 tmp_col = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - bsdf->specularTint) + m_ctint * bsdf->specularTint; // lerp(make_float3(1.0f, 1.0f, 1.0f), m_ctint, sc->data2/*specularTint*/); + bsdf->cspec0 = (bsdf->specular * 0.08f * tmp_col) * (1.0f - bsdf->metallic) + bsdf->baseColor * bsdf->metallic; // lerp(sc->data1/*specular*/ * 0.08f * tmp_col, sc->color0/*baseColor*/, sc->data0/*metallic*/); - float aspect = safe_sqrtf(1.0f - sc->data4/*anisotropic*/ * 0.9f); - float r2 = sqr(sc->data3/*roughness*/); + float aspect = safe_sqrtf(1.0f - bsdf->anisotropic * 0.9f); + float r2 = sqr(bsdf->roughness); /* ax */ - sc->custom1 = fmaxf(0.001f, r2 / aspect); + bsdf->alpha_x = fmaxf(0.001f, r2 / aspect); /* ay */ - sc->custom2 = fmaxf(0.001f, r2 * aspect); + bsdf->alpha_y = fmaxf(0.001f, r2 * aspect); /* rough_g */ - sc->custom3 = sqr(sc->data3/*roughness*/ * 0.5f + 0.5f); + bsdf->rough_g = sqr(bsdf->roughness * 0.5f + 0.5f); - sc->type = CLOSURE_BSDF_DISNEY_SPECULAR_ID; + bsdf->type = CLOSURE_BSDF_DISNEY_SPECULAR_ID; return SD_BSDF|SD_BSDF_HAS_EVAL; } ccl_device float3 bsdf_disney_specular_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { - float alpha_x = sc->custom1; - float alpha_y = sc->custom2; - float3 N = sc->N; + const DisneySpecularBsdf *bsdf = (const DisneySpecularBsdf *)sc; + + float3 N = bsdf->N; - if (fmaxf(alpha_x, alpha_y) <= 1e-4f) + if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f) return make_float3(0.0f, 0.0f, 0.0f); float cosNO = dot(N, I); @@ -77,10 +84,10 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const ShaderClosure *sc, con if (cosNI > 0 && cosNO > 0) { /* get half vector */ float3 m = normalize(omega_in + I); - float alpha2 = alpha_x * alpha_y; + float alpha2 = bsdf->alpha_x * bsdf->alpha_y; float D, G1o, G1i; - if (alpha_x == alpha_y) { + if (bsdf->alpha_x == bsdf->alpha_y) { /* isotropic * eq. 20: (F*G*D)/(4*in*on) * eq. 33: first we calculate D(m) */ @@ -97,12 +104,12 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const ShaderClosure *sc, con else { /* anisotropic */ float3 X, Y, Z = N; - make_orthonormals_tangent(Z, sc->T, &X, &Y); + make_orthonormals_tangent(Z, bsdf->T, &X, &Y); // distribution float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m)); - float slope_x = -local_m.x/(local_m.z*alpha_x); - float slope_y = -local_m.y/(local_m.z*alpha_y); + float slope_x = -local_m.x/(local_m.z*bsdf->alpha_x); + float slope_y = -local_m.y/(local_m.z*bsdf->alpha_y); float slope_len = 1 + slope_x*slope_x + slope_y*slope_y; float cosThetaM = local_m.z; @@ -116,7 +123,7 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const ShaderClosure *sc, con float cosPhiO = dot(I, X); float sinPhiO = dot(I, Y); - float alphaO2 = (cosPhiO*cosPhiO)*(alpha_x*alpha_x) + (sinPhiO*sinPhiO)*(alpha_y*alpha_y); + float alphaO2 = (cosPhiO*cosPhiO)*(bsdf->alpha_x*bsdf->alpha_x) + (sinPhiO*sinPhiO)*(bsdf->alpha_y*bsdf->alpha_y); alphaO2 /= cosPhiO*cosPhiO + sinPhiO*sinPhiO; G1o = 2 / (1 + safe_sqrtf(1 + alphaO2 * tanThetaO2)); @@ -125,7 +132,7 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const ShaderClosure *sc, con float cosPhiI = dot(omega_in, X); float sinPhiI = dot(omega_in, Y); - float alphaI2 = (cosPhiI*cosPhiI)*(alpha_x*alpha_x) + (sinPhiI*sinPhiI)*(alpha_y*alpha_y); + float alphaI2 = (cosPhiI*cosPhiI)*(bsdf->alpha_x*bsdf->alpha_x) + (sinPhiI*sinPhiI)*(bsdf->alpha_y*bsdf->alpha_y); alphaI2 /= cosPhiI*cosPhiI + sinPhiI*sinPhiI; G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2)); @@ -137,7 +144,7 @@ ccl_device float3 bsdf_disney_specular_eval_reflect(const ShaderClosure *sc, con float common = D * 0.25f / cosNO; float FH = schlick_fresnel(dot(omega_in, m)); - float3 F = sc->custom_color0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH; // lerp(sc->custom_color0, make_float3(1.0f, 1.0f, 1.0f), FH); + float3 F = bsdf->cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH; // lerp(sc->custom_color0, make_float3(1.0f, 1.0f, 1.0f), FH); float3 out = F * G * common; @@ -166,18 +173,18 @@ ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { - float alpha_x = sc->custom1; - float alpha_y = sc->custom2; - float3 N = sc->N; + const DisneySpecularBsdf *bsdf = (const DisneySpecularBsdf *)sc; + + float3 N = bsdf->N; float cosNO = dot(N, I); if(cosNO > 0) { float3 X, Y, Z = N; - if(alpha_x == alpha_y) + if (bsdf->alpha_x == bsdf->alpha_y) make_orthonormals(Z, &X, &Y); else - make_orthonormals_tangent(Z, sc->T, &X, &Y); + make_orthonormals_tangent(Z, bsdf->T, &X, &Y); /* importance sampling with distribution of visible normals. vectors are * transformed to local space before and after */ @@ -186,7 +193,7 @@ ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc, float3 m; float G1o; - local_m = importance_sample_microfacet_stretched(local_I, alpha_x, alpha_y, + local_m = importance_sample_microfacet_stretched(local_I, bsdf->alpha_x, bsdf->alpha_y, randu, randv, false, &G1o); m = X*local_m.x + Y*local_m.y + Z*local_m.z; @@ -200,7 +207,7 @@ ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc, *omega_in = 2 * cosMO * m - I; if(dot(Ng, *omega_in) > 0) { - if(fmaxf(alpha_x, alpha_y) <= 1e-4f) { + if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f) { /* some high number for MIS */ *pdf = 1e6f; *eval = make_float3(1e6f, 1e6f, 1e6f); @@ -208,10 +215,10 @@ ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc, else { /* microfacet normal is visible to this ray */ /* eq. 33 */ - float alpha2 = alpha_x * alpha_y; + float alpha2 = bsdf->alpha_x * bsdf->alpha_y; float D, G1i; - if(alpha_x == alpha_y) { + if (bsdf->alpha_x == bsdf->alpha_y) { float cosThetaM2 = cosThetaM * cosThetaM; float cosThetaM4 = cosThetaM2 * cosThetaM2; float tanThetaM2 = 1/(cosThetaM2) - 1; @@ -225,8 +232,8 @@ ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc, } else { /* anisotropic distribution */ - float slope_x = -local_m.x/(local_m.z*alpha_x); - float slope_y = -local_m.y/(local_m.z*alpha_y); + float slope_x = -local_m.x / (local_m.z*bsdf->alpha_x); + float slope_y = -local_m.y / (local_m.z*bsdf->alpha_y); float slope_len = 1 + slope_x*slope_x + slope_y*slope_y; float cosThetaM = local_m.z; @@ -242,7 +249,7 @@ ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc, float cosPhiI = dot(*omega_in, X); float sinPhiI = dot(*omega_in, Y); - float alphaI2 = (cosPhiI*cosPhiI)*(alpha_x*alpha_x) + (sinPhiI*sinPhiI)*(alpha_y*alpha_y); + float alphaI2 = (cosPhiI*cosPhiI)*(bsdf->alpha_x*bsdf->alpha_x) + (sinPhiI*sinPhiI)*(bsdf->alpha_y*bsdf->alpha_y); alphaI2 /= cosPhiI*cosPhiI + sinPhiI*sinPhiI; G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2)); @@ -253,7 +260,7 @@ ccl_device int bsdf_disney_specular_sample(const ShaderClosure *sc, *pdf = common; float FH = schlick_fresnel(dot(*omega_in, m)); - float3 F = sc->custom_color0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH; // lerp(sc->custom_color0, make_float3(1.0f, 1.0f, 1.0f), FH); + float3 F = bsdf->cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH; // lerp(sc->custom_color0, make_float3(1.0f, 1.0f, 1.0f), FH); *eval = G1i * common * F; } |