Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/svm/svm_closure.h
| Show First 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | else | ||||
| ccl_fetch(sd, flag) |= bsdf_microfacet_ggx_setup(sc); | ccl_fetch(sd, flag) |= bsdf_microfacet_ggx_setup(sc); | ||||
| } | } | ||||
| } | } | ||||
| ccl_device_inline ShaderClosure *svm_node_closure_get_non_bsdf(ShaderData *sd, ClosureType type, float mix_weight) | ccl_device_inline ShaderClosure *svm_node_closure_get_non_bsdf(ShaderData *sd, ClosureType type, float mix_weight) | ||||
| { | { | ||||
| ShaderClosure *sc = ccl_fetch_array(sd, closure, ccl_fetch(sd, num_closure)); | ShaderClosure *sc = ccl_fetch_array(sd, closure, ccl_fetch(sd, num_closure)); | ||||
| if(ccl_fetch(sd, num_closure) < MAX_CLOSURE) { | if(ccl_fetch(sd, num_closure) < ccl_fetch(sd, max_closure)) { | ||||
| sc->weight *= mix_weight; | sc->weight *= mix_weight; | ||||
| sc->type = type; | sc->type = type; | ||||
| sc->data0 = 0.0f; | sc->data0 = 0.0f; | ||||
| sc->data1 = 0.0f; | sc->data1 = 0.0f; | ||||
| sc->data2 = 0.0f; | sc->data2 = 0.0f; | ||||
| #ifdef __OSL__ | #ifdef __OSL__ | ||||
| sc->prim = NULL; | sc->prim = NULL; | ||||
| #endif | #endif | ||||
| ccl_fetch(sd, num_closure)++; | ccl_fetch(sd, num_closure)++; | ||||
| return sc; | return sc; | ||||
| } | } | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| ccl_device_inline ShaderClosure *svm_node_closure_get_bsdf(ShaderData *sd, float mix_weight) | ccl_device_inline ShaderClosure *svm_node_closure_get_bsdf(ShaderData *sd, float mix_weight) | ||||
| { | { | ||||
| ShaderClosure *sc = ccl_fetch_array(sd, closure, ccl_fetch(sd, num_closure)); | ShaderClosure *sc = ccl_fetch_array(sd, closure, ccl_fetch(sd, num_closure)); | ||||
| float3 weight = sc->weight * mix_weight; | float3 weight = sc->weight * mix_weight; | ||||
| float sample_weight = fabsf(average(weight)); | float sample_weight = fabsf(average(weight)); | ||||
| if(sample_weight > CLOSURE_WEIGHT_CUTOFF && ccl_fetch(sd, num_closure) < MAX_CLOSURE) { | if(sample_weight > CLOSURE_WEIGHT_CUTOFF && ccl_fetch(sd, num_closure) < ccl_fetch(sd, max_closure)) { | ||||
| sc->weight = weight; | sc->weight = weight; | ||||
| sc->sample_weight = sample_weight; | sc->sample_weight = sample_weight; | ||||
| ccl_fetch(sd, num_closure)++; | ccl_fetch(sd, num_closure)++; | ||||
| #ifdef __OSL__ | #ifdef __OSL__ | ||||
| sc->prim = NULL; | sc->prim = NULL; | ||||
| #endif | #endif | ||||
| return sc; | return sc; | ||||
| } | } | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| ccl_device_inline ShaderClosure *svm_node_closure_get_absorption(ShaderData *sd, float mix_weight) | ccl_device_inline ShaderClosure *svm_node_closure_get_absorption(ShaderData *sd, float mix_weight) | ||||
| { | { | ||||
| ShaderClosure *sc = ccl_fetch_array(sd, closure, ccl_fetch(sd, num_closure)); | ShaderClosure *sc = ccl_fetch_array(sd, closure, ccl_fetch(sd, num_closure)); | ||||
| float3 weight = (make_float3(1.0f, 1.0f, 1.0f) - sc->weight) * mix_weight; | float3 weight = (make_float3(1.0f, 1.0f, 1.0f) - sc->weight) * mix_weight; | ||||
| float sample_weight = fabsf(average(weight)); | float sample_weight = fabsf(average(weight)); | ||||
| if(sample_weight > CLOSURE_WEIGHT_CUTOFF && ccl_fetch(sd, num_closure) < MAX_CLOSURE) { | if(sample_weight > CLOSURE_WEIGHT_CUTOFF && ccl_fetch(sd, num_closure) < ccl_fetch(sd, max_closure)) { | ||||
| sc->weight = weight; | sc->weight = weight; | ||||
| sc->sample_weight = sample_weight; | sc->sample_weight = sample_weight; | ||||
| ccl_fetch(sd, num_closure)++; | ccl_fetch(sd, num_closure)++; | ||||
| #ifdef __OSL__ | #ifdef __OSL__ | ||||
| sc->prim = NULL; | sc->prim = NULL; | ||||
| #endif | #endif | ||||
| return sc; | return sc; | ||||
| } | } | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int path_flag, int *offset) | ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int path_flag, int *offset) | ||||
| { | { | ||||
| uint type, param1_offset, param2_offset; | uint type, param1_offset, param2_offset; | ||||
| uint mix_weight_offset; | uint mix_weight_offset; | ||||
| decode_node_uchar4(node.y, &type, ¶m1_offset, ¶m2_offset, &mix_weight_offset); | decode_node_uchar4(node.y, &type, ¶m1_offset, ¶m2_offset, &mix_weight_offset); | ||||
| /* save closure space for shadow rays */ | |||||
| if(path_flag & (PATH_RAY_SHADOW|PATH_RAY_EMISSION)) { | |||||
| return; | |||||
| } | |||||
| float mix_weight = (stack_valid(mix_weight_offset)? stack_load_float(stack, mix_weight_offset): 1.0f); | float mix_weight = (stack_valid(mix_weight_offset)? stack_load_float(stack, mix_weight_offset): 1.0f); | ||||
| /* note we read this extra node before weight check, so offset is added */ | /* note we read this extra node before weight check, so offset is added */ | ||||
| uint4 data_node = read_node(kg, offset); | uint4 data_node = read_node(kg, offset); | ||||
| if(mix_weight == 0.0f) | if(mix_weight == 0.0f) | ||||
| return; | return; | ||||
| float3 N = stack_valid(data_node.x)? stack_load_float3(stack, data_node.x): ccl_fetch(sd, N); | float3 N = stack_valid(data_node.x)? stack_load_float3(stack, data_node.x): ccl_fetch(sd, N); | ||||
| float param1 = (stack_valid(param1_offset))? stack_load_float(stack, param1_offset): __uint_as_float(node.z); | float param1 = (stack_valid(param1_offset))? stack_load_float(stack, param1_offset): __uint_as_float(node.z); | ||||
| float param2 = (stack_valid(param2_offset))? stack_load_float(stack, param2_offset): __uint_as_float(node.w); | float param2 = (stack_valid(param2_offset))? stack_load_float(stack, param2_offset): __uint_as_float(node.w); | ||||
| int prev_flag = ccl_fetch(sd, flag); | |||||
| int prev_num_closure = ccl_fetch(sd, num_closure); | |||||
| switch(type) { | switch(type) { | ||||
| case CLOSURE_BSDF_DIFFUSE_ID: { | case CLOSURE_BSDF_DIFFUSE_ID: { | ||||
| ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); | ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); | ||||
| if(sc) { | if(sc) { | ||||
| sc->N = N; | sc->N = N; | ||||
| float roughness = param1; | float roughness = param1; | ||||
| Show All 20 Lines | case CLOSURE_BSDF_TRANSLUCENT_ID: { | ||||
| sc->data0 = 0.0f; | sc->data0 = 0.0f; | ||||
| sc->data1 = 0.0f; | sc->data1 = 0.0f; | ||||
| sc->data2 = 0.0f; | sc->data2 = 0.0f; | ||||
| sc->N = N; | sc->N = N; | ||||
| ccl_fetch(sd, flag) |= bsdf_translucent_setup(sc); | ccl_fetch(sd, flag) |= bsdf_translucent_setup(sc); | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| case CLOSURE_BSDF_TRANSPARENT_ID: { | |||||
| ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); | |||||
| if(sc) { | |||||
| sc->data0 = 0.0f; | |||||
| sc->data1 = 0.0f; | |||||
| sc->data2 = 0.0f; | |||||
| sc->N = N; | |||||
| ccl_fetch(sd, flag) |= bsdf_transparent_setup(sc); | |||||
| } | |||||
| break; | |||||
| } | |||||
| case CLOSURE_BSDF_REFLECTION_ID: | case CLOSURE_BSDF_REFLECTION_ID: | ||||
| case CLOSURE_BSDF_MICROFACET_GGX_ID: | case CLOSURE_BSDF_MICROFACET_GGX_ID: | ||||
| case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: | case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: | ||||
| case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: { | case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: { | ||||
| #ifdef __CAUSTICS_TRICKS__ | #ifdef __CAUSTICS_TRICKS__ | ||||
| if(!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE)) | if(!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE)) | ||||
| break; | break; | ||||
| #endif | #endif | ||||
| ▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | #endif | ||||
| case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: { | case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: { | ||||
| #ifdef __CAUSTICS_TRICKS__ | #ifdef __CAUSTICS_TRICKS__ | ||||
| if(!kernel_data.integrator.caustics_reflective && | if(!kernel_data.integrator.caustics_reflective && | ||||
| !kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) | !kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) | ||||
| { | { | ||||
| break; | break; | ||||
| } | } | ||||
| #endif | #endif | ||||
| int num_closure = ccl_fetch(sd, num_closure); | |||||
| /* index of refraction */ | /* index of refraction */ | ||||
| float eta = fmaxf(param2, 1e-5f); | float eta = fmaxf(param2, 1e-5f); | ||||
| eta = (ccl_fetch(sd, flag) & SD_BACKFACING)? 1.0f/eta: eta; | eta = (ccl_fetch(sd, flag) & SD_BACKFACING)? 1.0f/eta: eta; | ||||
| /* fresnel */ | /* fresnel */ | ||||
| float cosNO = dot(N, ccl_fetch(sd, I)); | float cosNO = dot(N, ccl_fetch(sd, I)); | ||||
| float fresnel = fresnel_dielectric_cos(cosNO, eta); | float fresnel = fresnel_dielectric_cos(cosNO, eta); | ||||
| float roughness = param1; | float roughness = param1; | ||||
| /* reflection */ | /* reflection */ | ||||
| ShaderClosure *sc = ccl_fetch_array(sd, closure, num_closure); | ShaderClosure *sc = ccl_fetch_array(sd, closure, prev_num_closure); | ||||
| float3 weight = sc->weight; | float3 weight = sc->weight; | ||||
| float sample_weight = sc->sample_weight; | float sample_weight = sc->sample_weight; | ||||
| sc = svm_node_closure_get_bsdf(sd, mix_weight*fresnel); | sc = svm_node_closure_get_bsdf(sd, mix_weight*fresnel); | ||||
| #ifdef __CAUSTICS_TRICKS__ | #ifdef __CAUSTICS_TRICKS__ | ||||
| if(kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) | if(kernel_data.integrator.caustics_reflective || (path_flag & PATH_RAY_DIFFUSE) == 0) | ||||
| #endif | #endif | ||||
| { | { | ||||
| if(sc) { | if(sc) { | ||||
| sc->N = N; | sc->N = N; | ||||
| svm_node_glass_setup(sd, sc, type, eta, roughness, false); | svm_node_glass_setup(sd, sc, type, eta, roughness, false); | ||||
| } | } | ||||
| } | } | ||||
| #ifdef __CAUSTICS_TRICKS__ | #ifdef __CAUSTICS_TRICKS__ | ||||
| if(!kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) | if(!kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) | ||||
| break; | break; | ||||
| #endif | #endif | ||||
| /* refraction */ | /* refraction */ | ||||
| if(num_closure + 1 < MAX_CLOSURE) { | if(prev_num_closure + 1 < ccl_fetch(sd, max_closure)) { | ||||
| sc = ccl_fetch_array(sd, closure, num_closure + 1); | sc = ccl_fetch_array(sd, closure, prev_num_closure + 1); | ||||
| sc->weight = weight; | sc->weight = weight; | ||||
| sc->sample_weight = sample_weight; | sc->sample_weight = sample_weight; | ||||
| sc = svm_node_closure_get_bsdf(sd, mix_weight*(1.0f - fresnel)); | sc = svm_node_closure_get_bsdf(sd, mix_weight*(1.0f - fresnel)); | ||||
| if(sc) { | if(sc) { | ||||
| sc->N = N; | sc->N = N; | ||||
| svm_node_glass_setup(sd, sc, type, eta, roughness, true); | svm_node_glass_setup(sd, sc, type, eta, roughness, true); | ||||
| ▲ Show 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: { | ||||
| sc->N = N; | sc->N = N; | ||||
| sc->data0 = 0.0f; | sc->data0 = 0.0f; | ||||
| sc->data1 = 0.0f; | sc->data1 = 0.0f; | ||||
| sc->data2 = 0.0f; | sc->data2 = 0.0f; | ||||
| ccl_fetch(sd, flag) |= bsdf_transparent_setup(sc); | ccl_fetch(sd, flag) |= bsdf_transparent_setup(sc); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| ShaderClosure *sc = ccl_fetch_array(sd, closure, ccl_fetch(sd, num_closure)); | ShaderClosure *sc = ccl_fetch_array(sd, closure, prev_num_closure); | ||||
| sc = svm_node_closure_get_bsdf(sd, mix_weight); | sc = svm_node_closure_get_bsdf(sd, mix_weight); | ||||
| if(sc) { | if(sc) { | ||||
| sc->N = N; | sc->N = N; | ||||
| sc->data0 = param1; | sc->data0 = param1; | ||||
| sc->data1 = param2; | sc->data1 = param2; | ||||
| sc->data2 = -stack_load_float(stack, data_node.z); | sc->data2 = -stack_load_float(stack, data_node.z); | ||||
| Show All 24 Lines | |||||
| # ifndef __SPLIT_KERNEL__ | # ifndef __SPLIT_KERNEL__ | ||||
| # define sc_next(sc) sc++ | # define sc_next(sc) sc++ | ||||
| # else | # else | ||||
| # define sc_next(sc) sc = ccl_fetch_array(sd, closure, ccl_fetch(sd, num_closure)) | # define sc_next(sc) sc = ccl_fetch_array(sd, closure, ccl_fetch(sd, num_closure)) | ||||
| # endif | # endif | ||||
| case CLOSURE_BSSRDF_CUBIC_ID: | case CLOSURE_BSSRDF_CUBIC_ID: | ||||
| case CLOSURE_BSSRDF_GAUSSIAN_ID: | case CLOSURE_BSSRDF_GAUSSIAN_ID: | ||||
| case CLOSURE_BSSRDF_BURLEY_ID: { | case CLOSURE_BSSRDF_BURLEY_ID: { | ||||
| ShaderClosure *sc = ccl_fetch_array(sd, closure, ccl_fetch(sd, num_closure)); | ShaderClosure *sc = ccl_fetch_array(sd, closure, prev_num_closure); | ||||
| float3 albedo = sc->weight; | float3 albedo = sc->weight; | ||||
| float3 weight = sc->weight * mix_weight; | float3 weight = sc->weight * mix_weight; | ||||
| float sample_weight = fabsf(average(weight)); | float sample_weight = fabsf(average(weight)); | ||||
| /* disable in case of diffuse ancestor, can't see it well then and | /* disable in case of diffuse ancestor, can't see it well then and | ||||
| * adds considerably noise due to probabilities of continuing path | * adds considerably noise due to probabilities of continuing path | ||||
| * getting lower and lower */ | * getting lower and lower */ | ||||
| if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR) | if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR) | ||||
| param1 = 0.0f; | param1 = 0.0f; | ||||
| if(sample_weight > CLOSURE_WEIGHT_CUTOFF && ccl_fetch(sd, num_closure)+2 < MAX_CLOSURE) { | if(sample_weight > CLOSURE_WEIGHT_CUTOFF && prev_num_closure+2 < ccl_fetch(sd, max_closure)) { | ||||
| /* radius * scale */ | /* radius * scale */ | ||||
| float3 radius = stack_load_float3(stack, data_node.z)*param1; | float3 radius = stack_load_float3(stack, data_node.z)*param1; | ||||
| /* sharpness */ | /* sharpness */ | ||||
| float sharpness = stack_load_float(stack, data_node.w); | float sharpness = stack_load_float(stack, data_node.w); | ||||
| /* texture color blur */ | /* texture color blur */ | ||||
| float texture_blur = param2; | float texture_blur = param2; | ||||
| /* create one closure per color channel */ | /* create one closure per color channel */ | ||||
| ▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | # endif | ||||
| break; | break; | ||||
| } | } | ||||
| # undef sc_next | # undef sc_next | ||||
| #endif | #endif | ||||
| default: | default: | ||||
| break; | break; | ||||
| } | } | ||||
| /* try merging if we didn't add any type of BSDF closure */ | |||||
| if(ccl_fetch(sd, flag) == prev_flag) { | |||||
| for(int i = prev_num_closure; i < ccl_fetch(sd, num_closure); i++) { | |||||
| shader_merge_last_closure_with_data(sd); | |||||
| } | |||||
| } | |||||
| } | } | ||||
| ccl_device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int path_flag) | ccl_device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int path_flag) | ||||
| { | { | ||||
| #ifdef __VOLUME__ | #ifdef __VOLUME__ | ||||
| uint type, param1_offset, param2_offset; | uint type, param1_offset, param2_offset; | ||||
| uint mix_weight_offset; | uint mix_weight_offset; | ||||
| decode_node_uchar4(node.y, &type, ¶m1_offset, ¶m2_offset, &mix_weight_offset); | decode_node_uchar4(node.y, &type, ¶m1_offset, ¶m2_offset, &mix_weight_offset); | ||||
| float mix_weight = (stack_valid(mix_weight_offset)? stack_load_float(stack, mix_weight_offset): 1.0f); | float mix_weight = (stack_valid(mix_weight_offset)? stack_load_float(stack, mix_weight_offset): 1.0f); | ||||
| if(mix_weight == 0.0f) | if(mix_weight == 0.0f) | ||||
| return; | return; | ||||
| float param1 = (stack_valid(param1_offset))? stack_load_float(stack, param1_offset): __uint_as_float(node.z); | float param1 = (stack_valid(param1_offset))? stack_load_float(stack, param1_offset): __uint_as_float(node.z); | ||||
| float param2 = (stack_valid(param2_offset))? stack_load_float(stack, param2_offset): __uint_as_float(node.w); | float param2 = (stack_valid(param2_offset))? stack_load_float(stack, param2_offset): __uint_as_float(node.w); | ||||
| float density = fmaxf(param1, 0.0f); | float density = fmaxf(param1, 0.0f); | ||||
| if(path_flag & PATH_RAY_EMISSION) { | |||||
| return; | |||||
| } | |||||
| else if(path_flag & PATH_RAY_SHADOW) { | |||||
| // save closures space for shadow rays | |||||
| type = CLOSURE_VOLUME_ABSORPTION_ID; | |||||
| } | |||||
| int prev_flag = ccl_fetch(sd, flag); | |||||
| switch(type) { | switch(type) { | ||||
| case CLOSURE_VOLUME_ABSORPTION_ID: { | case CLOSURE_VOLUME_ABSORPTION_ID: { | ||||
| ShaderClosure *sc = svm_node_closure_get_absorption(sd, mix_weight * density); | ShaderClosure *sc = svm_node_closure_get_absorption(sd, mix_weight * density); | ||||
| if(sc) { | if(sc) { | ||||
| sc->data0 = 0.0f; | |||||
| sc->data1 = 0.0f; | |||||
| sc->data2 = 0.0f; | |||||
| ccl_fetch(sd, flag) |= volume_absorption_setup(sc); | ccl_fetch(sd, flag) |= volume_absorption_setup(sc); | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID: { | case CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID: { | ||||
| ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight * density); | ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight * density); | ||||
| if(sc) { | if(sc) { | ||||
| sc->data0 = param2; /* g */ | sc->data0 = param2; /* g */ | ||||
| sc->data1 = 0.0f; | sc->data1 = 0.0f; | ||||
| sc->data2 = 0.0f; | sc->data2 = 0.0f; | ||||
| ccl_fetch(sd, flag) |= volume_henyey_greenstein_setup(sc); | ccl_fetch(sd, flag) |= volume_henyey_greenstein_setup(sc); | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| default: | default: | ||||
| break; | break; | ||||
| } | } | ||||
| /* try merging if we didn't add any type of volume closure */ | |||||
| if(ccl_fetch(sd, flag) == prev_flag) { | |||||
| shader_merge_last_closure_with_data(sd); | |||||
| } | |||||
| #endif | #endif | ||||
| } | } | ||||
| ccl_device void svm_node_closure_emission(ShaderData *sd, float *stack, uint4 node) | ccl_device void svm_node_closure_emission(ShaderData *sd, float *stack, uint4 node, int path_flag) | ||||
| { | { | ||||
| if(path_flag & PATH_RAY_SHADOW) { | |||||
| return; | |||||
| } | |||||
| uint mix_weight_offset = node.y; | uint mix_weight_offset = node.y; | ||||
| float mix_weight = 1.0f; | |||||
| if(stack_valid(mix_weight_offset)) { | if(stack_valid(mix_weight_offset)) { | ||||
| float mix_weight = stack_load_float(stack, mix_weight_offset); | float mix_weight = stack_load_float(stack, mix_weight_offset); | ||||
| if(mix_weight == 0.0f) | if(mix_weight == 0.0f) | ||||
| return; | return; | ||||
| } | |||||
| svm_node_closure_get_non_bsdf(sd, CLOSURE_EMISSION_ID, mix_weight); | svm_node_closure_get_non_bsdf(sd, CLOSURE_EMISSION_ID, mix_weight); | ||||
| } | |||||
| else | |||||
| svm_node_closure_get_non_bsdf(sd, CLOSURE_EMISSION_ID, 1.0f); | |||||
| if(ccl_fetch(sd, flag) & SD_EMISSION) { | |||||
| shader_merge_last_closure_without_data(sd); | |||||
| } | |||||
| else { | |||||
| ccl_fetch(sd, flag) |= SD_EMISSION; | ccl_fetch(sd, flag) |= SD_EMISSION; | ||||
| } | } | ||||
| } | |||||
| ccl_device void svm_node_closure_background(ShaderData *sd, float *stack, uint4 node) | ccl_device void svm_node_closure_background(ShaderData *sd, float *stack, uint4 node, int path_flag) | ||||
| { | { | ||||
| if(path_flag & PATH_RAY_SHADOW) { | |||||
| return; | |||||
| } | |||||
| uint mix_weight_offset = node.y; | uint mix_weight_offset = node.y; | ||||
| float mix_weight = 1.0f; | |||||
| if(stack_valid(mix_weight_offset)) { | if(stack_valid(mix_weight_offset)) { | ||||
| float mix_weight = stack_load_float(stack, mix_weight_offset); | mix_weight = stack_load_float(stack, mix_weight_offset); | ||||
| if(mix_weight == 0.0f) | if(mix_weight == 0.0f) | ||||
| return; | return; | ||||
| } | |||||
| svm_node_closure_get_non_bsdf(sd, CLOSURE_BACKGROUND_ID, mix_weight); | svm_node_closure_get_non_bsdf(sd, CLOSURE_BACKGROUND_ID, mix_weight); | ||||
| if(ccl_fetch(sd, flag) & SD_EMISSION) { | |||||
| /* save closure space by merging with existing closure */ | |||||
| shader_merge_last_closure_without_data(sd); | |||||
| } | |||||
| else { | |||||
| ccl_fetch(sd, flag) |= SD_EMISSION; | |||||
| } | |||||
| } | |||||
| ccl_device void svm_node_closure_transparent(ShaderData *sd, float *stack, uint4 node, int path_flag) | |||||
| { | |||||
| if(path_flag & PATH_RAY_EMISSION) { | |||||
| return; | |||||
| } | |||||
| uint mix_weight_offset = node.y; | |||||
| float mix_weight = 1.0f; | |||||
| if(stack_valid(mix_weight_offset)) { | |||||
| mix_weight = stack_load_float(stack, mix_weight_offset); | |||||
| if(mix_weight == 0.0f) | |||||
| return; | |||||
| } | |||||
| svm_node_closure_get_non_bsdf(sd, CLOSURE_BSDF_TRANSPARENT_ID, mix_weight); | |||||
| if(ccl_fetch(sd, flag) & SD_TRANSPARENT) { | |||||
| shader_merge_last_closure_without_data(sd); | |||||
| } | |||||
| else { | |||||
| ccl_fetch(sd, flag) |= SD_BSDF|SD_TRANSPARENT; | |||||
| } | } | ||||
| else | |||||
| svm_node_closure_get_non_bsdf(sd, CLOSURE_BACKGROUND_ID, 1.0f); | |||||
| } | } | ||||
| ccl_device void svm_node_closure_holdout(ShaderData *sd, float *stack, uint4 node) | ccl_device void svm_node_closure_holdout(ShaderData *sd, float *stack, uint4 node, int path_flag) | ||||
| { | { | ||||
| if(path_flag & (PATH_RAY_SHADOW|PATH_RAY_EMISSION)) { | |||||
| return; | |||||
| } | |||||
| uint mix_weight_offset = node.y; | uint mix_weight_offset = node.y; | ||||
| float mix_weight = 1.0f; | |||||
| if(stack_valid(mix_weight_offset)) { | if(stack_valid(mix_weight_offset)) { | ||||
| float mix_weight = stack_load_float(stack, mix_weight_offset); | float mix_weight = stack_load_float(stack, mix_weight_offset); | ||||
| if(mix_weight == 0.0f) | if(mix_weight == 0.0f) | ||||
| return; | return; | ||||
| } | |||||
| svm_node_closure_get_non_bsdf(sd, CLOSURE_HOLDOUT_ID, mix_weight); | svm_node_closure_get_non_bsdf(sd, CLOSURE_HOLDOUT_ID, mix_weight); | ||||
| } | |||||
| else | |||||
| svm_node_closure_get_non_bsdf(sd, CLOSURE_HOLDOUT_ID, 1.0f); | |||||
| if(ccl_fetch(sd, flag) & SD_HOLDOUT) { | |||||
| shader_merge_last_closure_without_data(sd); | |||||
| } | |||||
| else { | |||||
| ccl_fetch(sd, flag) |= SD_HOLDOUT; | ccl_fetch(sd, flag) |= SD_HOLDOUT; | ||||
| } | } | ||||
| } | |||||
| ccl_device void svm_node_closure_ambient_occlusion(ShaderData *sd, float *stack, uint4 node) | ccl_device void svm_node_closure_ambient_occlusion(ShaderData *sd, float *stack, uint4 node, int path_flag) | ||||
| { | { | ||||
| if(path_flag & (PATH_RAY_SHADOW|PATH_RAY_EMISSION)) { | |||||
| return; | |||||
| } | |||||
| uint mix_weight_offset = node.y; | uint mix_weight_offset = node.y; | ||||
| float mix_weight = 1.0f; | |||||
| if(stack_valid(mix_weight_offset)) { | if(stack_valid(mix_weight_offset)) { | ||||
| float mix_weight = stack_load_float(stack, mix_weight_offset); | float mix_weight = stack_load_float(stack, mix_weight_offset); | ||||
| if(mix_weight == 0.0f) | if(mix_weight == 0.0f) | ||||
| return; | return; | ||||
| } | |||||
| svm_node_closure_get_non_bsdf(sd, CLOSURE_AMBIENT_OCCLUSION_ID, mix_weight); | svm_node_closure_get_non_bsdf(sd, CLOSURE_AMBIENT_OCCLUSION_ID, mix_weight); | ||||
| } | |||||
| else | |||||
| svm_node_closure_get_non_bsdf(sd, CLOSURE_AMBIENT_OCCLUSION_ID, 1.0f); | |||||
| if(ccl_fetch(sd, flag) & SD_AO) { | |||||
| shader_merge_last_closure_without_data(sd); | |||||
| } | |||||
| else { | |||||
| ccl_fetch(sd, flag) |= SD_AO; | ccl_fetch(sd, flag) |= SD_AO; | ||||
| } | } | ||||
| } | |||||
| /* Closure Nodes */ | /* Closure Nodes */ | ||||
| ccl_device_inline void svm_node_closure_store_weight(ShaderData *sd, float3 weight) | ccl_device_inline void svm_node_closure_store_weight(ShaderData *sd, float3 weight) | ||||
| { | { | ||||
| if(ccl_fetch(sd, num_closure) < MAX_CLOSURE) { | if(ccl_fetch(sd, num_closure) < ccl_fetch(sd, max_closure)) { | ||||
| ShaderClosure *sc = ccl_fetch_array(sd, closure, ccl_fetch(sd, num_closure)); | ShaderClosure *sc = ccl_fetch_array(sd, closure, ccl_fetch(sd, num_closure)); | ||||
| sc->weight = weight; | sc->weight = weight; | ||||
| } | } | ||||
| } | } | ||||
| ccl_device void svm_node_closure_set_weight(ShaderData *sd, uint r, uint g, uint b) | ccl_device void svm_node_closure_set_weight(ShaderData *sd, uint r, uint g, uint b) | ||||
| { | { | ||||
| float3 weight = make_float3(__uint_as_float(r), __uint_as_float(g), __uint_as_float(b)); | float3 weight = make_float3(__uint_as_float(r), __uint_as_float(g), __uint_as_float(b)); | ||||
| ▲ Show 20 Lines • Show All 50 Lines • Show Last 20 Lines | |||||