Blender V2.61 - r43446
|
00001 /* 00002 * Copyright 2011, Blender Foundation. 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 /* 00020 * ShaderData, used in four steps: 00021 * 00022 * Setup from incoming ray, sampled position and background. 00023 * Execute for surface, volume or displacement. 00024 * Evaluate one or more closures. 00025 * Release. 00026 * 00027 */ 00028 00029 00030 #ifdef __OSL__ 00031 00032 #include "osl_shader.h" 00033 00034 #else 00035 00036 #include "svm/bsdf.h" 00037 #include "svm/emissive.h" 00038 #include "svm/volume.h" 00039 #include "svm/svm_bsdf.h" 00040 #include "svm/svm.h" 00041 00042 #endif 00043 00044 CCL_NAMESPACE_BEGIN 00045 00046 /* ShaderData setup from incoming ray */ 00047 00048 __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd, 00049 const Intersection *isect, const Ray *ray) 00050 { 00051 /* fetch triangle data */ 00052 int prim = kernel_tex_fetch(__prim_index, isect->prim); 00053 float4 Ns = kernel_tex_fetch(__tri_normal, prim); 00054 float3 Ng = make_float3(Ns.x, Ns.y, Ns.z); 00055 int shader = __float_as_int(Ns.w); 00056 00057 /* vectors */ 00058 sd->P = bvh_triangle_refine(kg, isect, ray); 00059 sd->Ng = Ng; 00060 sd->N = Ng; 00061 sd->I = -ray->D; 00062 sd->shader = shader; 00063 00064 /* triangle */ 00065 #ifdef __INSTANCING__ 00066 sd->object = isect->object; 00067 #endif 00068 sd->prim = prim; 00069 #ifdef __UV__ 00070 sd->u = isect->u; 00071 sd->v = isect->v; 00072 #endif 00073 00074 /* smooth normal */ 00075 if(sd->shader & SHADER_SMOOTH_NORMAL) 00076 sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v); 00077 00078 sd->flag = kernel_tex_fetch(__shader_flag, sd->shader & SHADER_MASK); 00079 00080 #ifdef __DPDU__ 00081 /* dPdu/dPdv */ 00082 triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim); 00083 #endif 00084 00085 #ifdef __INSTANCING__ 00086 if(sd->object != ~0) { 00087 /* instance transform */ 00088 object_normal_transform(kg, sd->object, &sd->N); 00089 object_normal_transform(kg, sd->object, &sd->Ng); 00090 #ifdef __DPDU__ 00091 object_dir_transform(kg, sd->object, &sd->dPdu); 00092 object_dir_transform(kg, sd->object, &sd->dPdv); 00093 #endif 00094 } 00095 else { 00096 /* non-instanced object index */ 00097 sd->object = kernel_tex_fetch(__prim_object, isect->prim); 00098 } 00099 #endif 00100 00101 /* backfacing test */ 00102 bool backfacing = (dot(sd->Ng, sd->I) < 0.0f); 00103 00104 if(backfacing) { 00105 sd->flag |= SD_BACKFACING; 00106 sd->Ng = -sd->Ng; 00107 sd->N = -sd->N; 00108 #ifdef __DPDU__ 00109 sd->dPdu = -sd->dPdu; 00110 sd->dPdv = -sd->dPdv; 00111 #endif 00112 } 00113 00114 #ifdef __RAY_DIFFERENTIALS__ 00115 /* differentials */ 00116 differential_transfer(&sd->dP, ray->dP, ray->D, ray->dD, sd->Ng, isect->t); 00117 differential_incoming(&sd->dI, ray->dD); 00118 differential_dudv(&sd->du, &sd->dv, sd->dPdu, sd->dPdv, sd->dP, sd->Ng); 00119 #endif 00120 } 00121 00122 /* ShaderData setup from position sampled on mesh */ 00123 00124 __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd, 00125 const float3 P, const float3 Ng, const float3 I, 00126 int shader, int object, int prim, float u, float v) 00127 { 00128 /* vectors */ 00129 sd->P = P; 00130 sd->N = Ng; 00131 sd->Ng = Ng; 00132 sd->I = I; 00133 sd->shader = shader; 00134 00135 /* primitive */ 00136 #ifdef __INSTANCING__ 00137 sd->object = object; 00138 #endif 00139 sd->prim = prim; 00140 #ifdef __UV__ 00141 sd->u = u; 00142 sd->v = v; 00143 #endif 00144 00145 /* detect instancing, for non-instanced the object index is -object-1 */ 00146 #ifdef __INSTANCING__ 00147 bool instanced = false; 00148 00149 if(sd->prim != ~0) { 00150 if(sd->object >= 0) 00151 instanced = true; 00152 else 00153 #endif 00154 sd->object = -sd->object-1; 00155 #ifdef __INSTANCING__ 00156 } 00157 #endif 00158 00159 /* smooth normal */ 00160 if(sd->shader & SHADER_SMOOTH_NORMAL) { 00161 sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v); 00162 00163 #ifdef __INSTANCING__ 00164 if(instanced) 00165 object_normal_transform(kg, sd->object, &sd->N); 00166 #endif 00167 } 00168 00169 sd->flag = kernel_tex_fetch(__shader_flag, sd->shader & SHADER_MASK); 00170 00171 #ifdef __DPDU__ 00172 /* dPdu/dPdv */ 00173 if(sd->prim == ~0) { 00174 sd->dPdu = make_float3(0.0f, 0.0f, 0.0f); 00175 sd->dPdv = make_float3(0.0f, 0.0f, 0.0f); 00176 } 00177 else { 00178 triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim); 00179 00180 #ifdef __INSTANCING__ 00181 if(instanced) { 00182 object_dir_transform(kg, sd->object, &sd->dPdu); 00183 object_dir_transform(kg, sd->object, &sd->dPdv); 00184 } 00185 #endif 00186 } 00187 #endif 00188 00189 /* backfacing test */ 00190 if(sd->prim != ~0) { 00191 bool backfacing = (dot(sd->Ng, sd->I) < 0.0f); 00192 00193 if(backfacing) { 00194 sd->flag |= SD_BACKFACING; 00195 sd->Ng = -sd->Ng; 00196 sd->N = -sd->N; 00197 #ifdef __DPDU__ 00198 sd->dPdu = -sd->dPdu; 00199 sd->dPdv = -sd->dPdv; 00200 #endif 00201 } 00202 } 00203 00204 #ifdef __RAY_DIFFERENTIALS__ 00205 /* no ray differentials here yet */ 00206 sd->dP.dx = make_float3(0.0f, 0.0f, 0.0f); 00207 sd->dP.dy = make_float3(0.0f, 0.0f, 0.0f); 00208 sd->dI.dx = make_float3(0.0f, 0.0f, 0.0f); 00209 sd->dI.dy = make_float3(0.0f, 0.0f, 0.0f); 00210 sd->du.dx = 0.0f; 00211 sd->du.dy = 0.0f; 00212 sd->dv.dx = 0.0f; 00213 sd->dv.dy = 0.0f; 00214 #endif 00215 } 00216 00217 /* ShaderData setup for displacement */ 00218 00219 __device void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd, 00220 int object, int prim, float u, float v) 00221 { 00222 float3 P, Ng, I = make_float3(0.0f, 0.0f, 0.0f); 00223 int shader; 00224 00225 P = triangle_point_MT(kg, prim, u, v); 00226 Ng = triangle_normal_MT(kg, prim, &shader); 00227 00228 /* force smooth shading for displacement */ 00229 shader |= SHADER_SMOOTH_NORMAL; 00230 00231 /* watch out: no instance transform currently */ 00232 00233 shader_setup_from_sample(kg, sd, P, Ng, I, shader, object, prim, u, v); 00234 } 00235 00236 /* ShaderData setup from ray into background */ 00237 00238 __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData *sd, const Ray *ray) 00239 { 00240 /* vectors */ 00241 sd->P = ray->D; 00242 sd->N = -sd->P; 00243 sd->Ng = -sd->P; 00244 sd->I = -sd->P; 00245 sd->shader = kernel_data.background.shader; 00246 sd->flag = kernel_tex_fetch(__shader_flag, sd->shader & SHADER_MASK); 00247 00248 #ifdef __INSTANCING__ 00249 sd->object = ~0; 00250 #endif 00251 sd->prim = ~0; 00252 #ifdef __UV__ 00253 sd->u = 0.0f; 00254 sd->v = 0.0f; 00255 #endif 00256 00257 #ifdef __DPDU__ 00258 /* dPdu/dPdv */ 00259 sd->dPdu = make_float3(0.0f, 0.0f, 0.0f); 00260 sd->dPdv = make_float3(0.0f, 0.0f, 0.0f); 00261 #endif 00262 00263 #ifdef __RAY_DIFFERENTIALS__ 00264 /* differentials */ 00265 sd->dP = ray->dD; 00266 differential_incoming(&sd->dI, sd->dP); 00267 sd->du.dx = 0.0f; 00268 sd->du.dy = 0.0f; 00269 sd->dv.dx = 0.0f; 00270 sd->dv.dy = 0.0f; 00271 #endif 00272 } 00273 00274 /* BSDF */ 00275 00276 #ifdef __MULTI_CLOSURE__ 00277 00278 __device_inline float3 _shader_bsdf_multi_eval(const ShaderData *sd, const float3 omega_in, float *pdf, 00279 int skip_bsdf, float3 sum_eval, float sum_pdf, float sum_sample_weight) 00280 { 00281 for(int i = 0; i< sd->num_closure; i++) { 00282 if(i == skip_bsdf) 00283 continue; 00284 00285 const ShaderClosure *sc = &sd->closure[i]; 00286 00287 if(CLOSURE_IS_BSDF(sc->type)) { 00288 float bsdf_pdf = 0.0f; 00289 #ifdef __OSL__ 00290 float3 eval = OSLShader::bsdf_eval(sd, sc, omega_in, bsdf_pdf); 00291 #else 00292 float3 eval = svm_bsdf_eval(sd, sc, omega_in, &bsdf_pdf); 00293 #endif 00294 00295 if(bsdf_pdf != 0.0f) { 00296 sum_eval += eval*sc->weight; 00297 sum_pdf += bsdf_pdf*sc->sample_weight; 00298 } 00299 00300 sum_sample_weight += sc->sample_weight; 00301 } 00302 } 00303 00304 *pdf = sum_pdf/sum_sample_weight; 00305 return sum_eval; 00306 } 00307 00308 #endif 00309 00310 __device float3 shader_bsdf_eval(KernelGlobals *kg, const ShaderData *sd, 00311 const float3 omega_in, float *pdf) 00312 { 00313 #ifdef __MULTI_CLOSURE__ 00314 return _shader_bsdf_multi_eval(sd, omega_in, pdf, -1, make_float3(0.0f, 0.0f, 0.0f), 0.0f, 0.0f); 00315 #else 00316 const ShaderClosure *sc = &sd->closure; 00317 *pdf = 0.0f; 00318 return svm_bsdf_eval(sd, sc, omega_in, pdf)*sc->weight; 00319 #endif 00320 } 00321 00322 __device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd, 00323 float randu, float randv, float3 *eval, 00324 float3 *omega_in, differential3 *domega_in, float *pdf) 00325 { 00326 #ifdef __MULTI_CLOSURE__ 00327 int sampled = 0; 00328 00329 if(sd->num_closure > 1) { 00330 /* pick a BSDF closure based on sample weights */ 00331 float sum = 0.0f; 00332 00333 for(sampled = 0; sampled < sd->num_closure; sampled++) { 00334 const ShaderClosure *sc = &sd->closure[sampled]; 00335 00336 if(CLOSURE_IS_BSDF(sc->type)) 00337 sum += sc->sample_weight; 00338 } 00339 00340 float r = sd->randb_closure*sum; 00341 sum = 0.0f; 00342 00343 for(sampled = 0; sampled < sd->num_closure; sampled++) { 00344 const ShaderClosure *sc = &sd->closure[sampled]; 00345 00346 if(CLOSURE_IS_BSDF(sc->type)) { 00347 sum += sd->closure[sampled].sample_weight; 00348 00349 if(r <= sum) 00350 break; 00351 } 00352 } 00353 00354 if(sampled == sd->num_closure) { 00355 *pdf = 0.0f; 00356 return LABEL_NONE; 00357 } 00358 } 00359 00360 const ShaderClosure *sc = &sd->closure[sampled]; 00361 int label; 00362 00363 *pdf = 0.0f; 00364 #ifdef __OSL__ 00365 label = OSLShader::bsdf_sample(sd, sc, randu, randv, *eval, *omega_in, *domega_in, *pdf); 00366 #else 00367 label = svm_bsdf_sample(sd, sc, randu, randv, eval, omega_in, domega_in, pdf); 00368 #endif 00369 00370 *eval *= sc->weight; 00371 00372 if(sd->num_closure > 1 && *pdf != 0.0f) { 00373 float sweight = sc->sample_weight; 00374 *eval = _shader_bsdf_multi_eval(sd, *omega_in, pdf, sampled, *eval, *pdf*sweight, sweight); 00375 } 00376 00377 return label; 00378 #else 00379 /* sample the single closure that we picked */ 00380 *pdf = 0.0f; 00381 int label = svm_bsdf_sample(sd, &sd->closure, randu, randv, eval, omega_in, domega_in, pdf); 00382 *eval *= sd->closure.weight; 00383 return label; 00384 #endif 00385 } 00386 00387 __device void shader_bsdf_blur(KernelGlobals *kg, ShaderData *sd, float roughness) 00388 { 00389 #ifndef __OSL__ 00390 #ifdef __MULTI_CLOSURE__ 00391 for(int i = 0; i< sd->num_closure; i++) { 00392 ShaderClosure *sc = &sd->closure[i]; 00393 00394 if(CLOSURE_IS_BSDF(sc->type)) 00395 svm_bsdf_blur(sc, roughness); 00396 } 00397 #else 00398 svm_bsdf_blur(&sd->closure, roughness); 00399 #endif 00400 #endif 00401 } 00402 00403 __device float3 shader_bsdf_transparency(KernelGlobals *kg, ShaderData *sd) 00404 { 00405 #ifdef __MULTI_CLOSURE__ 00406 float3 eval = make_float3(0.0f, 0.0f, 0.0f); 00407 00408 for(int i = 0; i< sd->num_closure; i++) { 00409 ShaderClosure *sc = &sd->closure[i]; 00410 00411 if(sc->type == CLOSURE_BSDF_TRANSPARENT_ID) // todo: make this work for osl 00412 eval += sc->weight; 00413 } 00414 00415 return eval; 00416 #else 00417 if(sd->closure.type == CLOSURE_BSDF_TRANSPARENT_ID) 00418 return sd->closure.weight; 00419 else 00420 return make_float3(0.0f, 0.0f, 0.0f); 00421 #endif 00422 } 00423 00424 00425 /* Emission */ 00426 00427 __device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd) 00428 { 00429 float3 eval; 00430 #ifdef __MULTI_CLOSURE__ 00431 eval = make_float3(0.0f, 0.0f, 0.0f); 00432 00433 for(int i = 0; i < sd->num_closure; i++) { 00434 ShaderClosure *sc = &sd->closure[i]; 00435 00436 if(CLOSURE_IS_EMISSION(sc->type)) { 00437 #ifdef __OSL__ 00438 eval += OSLShader::emissive_eval(sd)*sc->weight; 00439 #else 00440 eval += svm_emissive_eval(sd, sc)*sc->weight; 00441 #endif 00442 } 00443 } 00444 #else 00445 eval = svm_emissive_eval(sd, &sd->closure)*sd->closure.weight; 00446 #endif 00447 00448 return eval; 00449 } 00450 00451 /* Holdout */ 00452 00453 __device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd) 00454 { 00455 #ifdef __MULTI_CLOSURE__ 00456 float3 weight = make_float3(0.0f, 0.0f, 0.0f); 00457 00458 for(int i = 0; i < sd->num_closure; i++) { 00459 ShaderClosure *sc = &sd->closure[i]; 00460 00461 if(CLOSURE_IS_HOLDOUT(sc->type)) 00462 weight += sc->weight; 00463 } 00464 00465 return weight; 00466 #else 00467 if(sd->closure.type == CLOSURE_HOLDOUT_ID) 00468 return make_float3(1.0f, 1.0f, 1.0f); 00469 00470 return make_float3(0.0f, 0.0f, 0.0f); 00471 #endif 00472 } 00473 00474 /* Surface Evaluation */ 00475 00476 __device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd, 00477 float randb, int path_flag) 00478 { 00479 #ifdef __OSL__ 00480 OSLShader::eval_surface(kg, sd, randb, path_flag); 00481 #else 00482 00483 #ifdef __SVM__ 00484 svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, randb, path_flag); 00485 #else 00486 bsdf_diffuse_setup(sd, &sd->closure); 00487 sd->closure.weight = make_float3(0.8f, 0.8f, 0.8f); 00488 #endif 00489 00490 #endif 00491 } 00492 00493 /* Background Evaluation */ 00494 00495 __device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag) 00496 { 00497 #ifdef __OSL__ 00498 return OSLShader::eval_background(kg, sd, path_flag); 00499 #else 00500 00501 #ifdef __SVM__ 00502 svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, 0.0f, path_flag); 00503 00504 #ifdef __MULTI_CLOSURE__ 00505 float3 eval = make_float3(0.0f, 0.0f, 0.0f); 00506 00507 for(int i = 0; i< sd->num_closure; i++) { 00508 const ShaderClosure *sc = &sd->closure[i]; 00509 00510 if(CLOSURE_IS_BACKGROUND(sc->type)) 00511 eval += sc->weight; 00512 } 00513 00514 return eval; 00515 #else 00516 if(sd->closure.type == CLOSURE_BACKGROUND_ID) 00517 return sd->closure.weight; 00518 else 00519 return make_float3(0.0f, 0.0f, 0.0f); 00520 #endif 00521 00522 #else 00523 return make_float3(0.8f, 0.8f, 0.8f); 00524 #endif 00525 00526 #endif 00527 } 00528 00529 /* Volume */ 00530 00531 __device float3 shader_volume_eval_phase(KernelGlobals *kg, ShaderData *sd, 00532 float3 omega_in, float3 omega_out) 00533 { 00534 #ifdef __MULTI_CLOSURE__ 00535 float3 eval = make_float3(0.0f, 0.0f, 0.0f); 00536 00537 for(int i = 0; i< sd->num_closure; i++) { 00538 const ShaderClosure *sc = &sd->closure[i]; 00539 00540 if(CLOSURE_IS_VOLUME(sc->type)) { 00541 #ifdef __OSL__ 00542 eval += OSLShader::volume_eval_phase(sd, omega_in, omega_out); 00543 #else 00544 eval += volume_eval_phase(sd, sc, omega_in, omega_out); 00545 #endif 00546 } 00547 } 00548 00549 return eval; 00550 #else 00551 return volume_eval_phase(sd, &sd->closure, omega_in, omega_out); 00552 #endif 00553 } 00554 00555 /* Volume Evaluation */ 00556 00557 __device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd, 00558 float randb, int path_flag) 00559 { 00560 #ifdef __SVM__ 00561 #ifdef __OSL__ 00562 OSLShader::eval_volume(kg, sd, randb, path_flag); 00563 #else 00564 svm_eval_nodes(kg, sd, SHADER_TYPE_VOLUME, randb, path_flag); 00565 #endif 00566 #endif 00567 } 00568 00569 /* Displacement Evaluation */ 00570 00571 __device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd) 00572 { 00573 /* this will modify sd->P */ 00574 #ifdef __SVM__ 00575 #ifdef __OSL__ 00576 OSLShader::eval_displacement(kg, sd); 00577 #else 00578 svm_eval_nodes(kg, sd, SHADER_TYPE_DISPLACEMENT, 0.0f, 0); 00579 #endif 00580 #endif 00581 } 00582 00583 /* Transparent Shadows */ 00584 00585 #ifdef __TRANSPARENT_SHADOWS__ 00586 __device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect) 00587 { 00588 int prim = kernel_tex_fetch(__prim_index, isect->prim); 00589 float4 Ns = kernel_tex_fetch(__tri_normal, prim); 00590 int shader = __float_as_int(Ns.w); 00591 int flag = kernel_tex_fetch(__shader_flag, shader & SHADER_MASK); 00592 00593 return (flag & SD_HAS_SURFACE_TRANSPARENT) != 0; 00594 } 00595 #endif 00596 00597 /* Free ShaderData */ 00598 00599 __device void shader_release(KernelGlobals *kg, ShaderData *sd) 00600 { 00601 #ifdef __OSL__ 00602 OSLShader::release(kg, sd); 00603 #endif 00604 } 00605 00606 CCL_NAMESPACE_END 00607