2013-01-03 12:08:54 +00:00
|
|
|
/*
|
2013-08-18 14:16:15 +00:00
|
|
|
* Copyright 2011-2013 Blender Foundation
|
2013-01-03 12:08:54 +00:00
|
|
|
*
|
2013-08-18 14:16:15 +00:00
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
2013-01-03 12:08:54 +00:00
|
|
|
*
|
2013-08-18 14:16:15 +00:00
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
2013-01-03 12:08:54 +00:00
|
|
|
*
|
2013-08-18 14:16:15 +00:00
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License
|
2013-01-03 12:08:54 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
CCL_NAMESPACE_BEGIN
|
|
|
|
|
|
|
|
#ifdef __HAIR__
|
|
|
|
|
|
|
|
/* curve attributes */
|
|
|
|
|
|
|
|
__device float curve_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
|
|
|
|
{
|
2013-01-03 12:09:09 +00:00
|
|
|
if(elem == ATTR_ELEMENT_CURVE) {
|
2013-01-03 12:08:54 +00:00
|
|
|
#ifdef __RAY_DIFFERENTIALS__
|
|
|
|
if(dx) *dx = 0.0f;
|
|
|
|
if(dy) *dy = 0.0f;
|
|
|
|
#endif
|
|
|
|
|
2013-01-03 12:09:09 +00:00
|
|
|
return kernel_tex_fetch(__attributes_float, offset + sd->prim);
|
2013-01-03 12:08:54 +00:00
|
|
|
}
|
|
|
|
else if(elem == ATTR_ELEMENT_CURVE_KEY) {
|
2013-01-03 12:09:09 +00:00
|
|
|
float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
|
|
|
|
int k0 = __float_as_int(curvedata.x) + sd->segment;
|
|
|
|
int k1 = k0 + 1;
|
2013-01-03 12:08:54 +00:00
|
|
|
|
2013-01-03 12:09:09 +00:00
|
|
|
float f0 = kernel_tex_fetch(__attributes_float, offset + k0);
|
|
|
|
float f1 = kernel_tex_fetch(__attributes_float, offset + k1);
|
2013-01-03 12:08:54 +00:00
|
|
|
|
|
|
|
#ifdef __RAY_DIFFERENTIALS__
|
|
|
|
if(dx) *dx = sd->du.dx*(f1 - f0);
|
|
|
|
if(dy) *dy = 0.0f;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return (1.0f - sd->u)*f0 + sd->u*f1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
#ifdef __RAY_DIFFERENTIALS__
|
|
|
|
if(dx) *dx = 0.0f;
|
|
|
|
if(dy) *dy = 0.0f;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return 0.0f;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
__device float3 curve_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
|
|
|
|
{
|
2013-01-03 12:09:09 +00:00
|
|
|
if(elem == ATTR_ELEMENT_CURVE) {
|
2013-01-03 12:08:54 +00:00
|
|
|
/* idea: we can't derive any useful differentials here, but for tiled
|
|
|
|
* mipmap image caching it would be useful to avoid reading the highest
|
|
|
|
* detail level always. maybe a derivative based on the hair density
|
|
|
|
* could be computed somehow? */
|
|
|
|
#ifdef __RAY_DIFFERENTIALS__
|
|
|
|
if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
#endif
|
|
|
|
|
2013-01-03 12:09:09 +00:00
|
|
|
return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + sd->prim));
|
2013-01-03 12:08:54 +00:00
|
|
|
}
|
|
|
|
else if(elem == ATTR_ELEMENT_CURVE_KEY) {
|
2013-01-03 12:09:09 +00:00
|
|
|
float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
|
|
|
|
int k0 = __float_as_int(curvedata.x) + sd->segment;
|
|
|
|
int k1 = k0 + 1;
|
2013-01-03 12:08:54 +00:00
|
|
|
|
2013-01-03 12:09:09 +00:00
|
|
|
float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + k0));
|
|
|
|
float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + k1));
|
2013-01-03 12:08:54 +00:00
|
|
|
|
|
|
|
#ifdef __RAY_DIFFERENTIALS__
|
|
|
|
if(dx) *dx = sd->du.dx*(f1 - f0);
|
|
|
|
if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return (1.0f - sd->u)*f0 + sd->u*f1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
#ifdef __RAY_DIFFERENTIALS__
|
|
|
|
if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* hair info node functions */
|
|
|
|
|
|
|
|
__device float curve_thickness(KernelGlobals *kg, ShaderData *sd)
|
|
|
|
{
|
|
|
|
float r = 0.0f;
|
|
|
|
|
2013-06-02 14:52:29 +00:00
|
|
|
if(sd->segment != ~0) {
|
2013-01-03 12:09:09 +00:00
|
|
|
float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
|
|
|
|
int k0 = __float_as_int(curvedata.x) + sd->segment;
|
|
|
|
int k1 = k0 + 1;
|
2013-01-03 12:08:54 +00:00
|
|
|
|
2013-01-03 12:09:09 +00:00
|
|
|
float4 P1 = kernel_tex_fetch(__curve_keys, k0);
|
|
|
|
float4 P2 = kernel_tex_fetch(__curve_keys, k1);
|
|
|
|
r = (P2.w - P1.w) * sd->u + P1.w;
|
2013-01-03 12:08:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return r*2.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
__device float3 curve_tangent_normal(KernelGlobals *kg, ShaderData *sd)
|
|
|
|
{
|
|
|
|
float3 tgN = make_float3(0.0f,0.0f,0.0f);
|
|
|
|
|
2013-06-02 14:52:29 +00:00
|
|
|
if(sd->segment != ~0) {
|
2013-01-03 12:08:54 +00:00
|
|
|
|
2013-08-18 13:41:53 +00:00
|
|
|
tgN = -(-sd->I - sd->dPdu * (dot(sd->dPdu,-sd->I) / len_squared(sd->dPdu)));
|
2013-01-03 12:08:54 +00:00
|
|
|
tgN = normalize(tgN);
|
|
|
|
|
|
|
|
/* need to find suitable scaled gd for corrected normal */
|
|
|
|
#if 0
|
2013-08-18 13:41:53 +00:00
|
|
|
tgN = normalize(tgN - gd * sd->dPdu);
|
2013-01-03 12:08:54 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
return tgN;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
CCL_NAMESPACE_END
|
|
|
|
|