diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2013-06-08 14:51:33 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2013-06-08 14:51:33 +0400 |
commit | c53b20b683cbc6c198f2ec1e78e1b8a16e83d2b3 (patch) | |
tree | 2e3ba6f31128fe5f33917a81e7e7cce08dcc9fe3 /intern/cycles/kernel | |
parent | c423e3ed8f2b92eddd37709648e185bce67f32c7 (diff) |
Cycles: window texture coordinates now work with orthographic cameras, this
was an old issue since the first version.
Diffstat (limited to 'intern/cycles/kernel')
-rw-r--r-- | intern/cycles/kernel/kernel_camera.h | 31 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_shader.h | 10 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_types.h | 4 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/osl_services.cpp | 29 | ||||
-rw-r--r-- | intern/cycles/kernel/shaders/node_texture_coordinate.osl | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm.h | 6 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_tex_coord.h | 58 |
7 files changed, 91 insertions, 49 deletions
diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h index a23586a53a4..4b9ef8893f7 100644 --- a/intern/cycles/kernel/kernel_camera.h +++ b/intern/cycles/kernel/kernel_camera.h @@ -245,6 +245,12 @@ __device void camera_sample(KernelGlobals *kg, int x, int y, float filter_u, flo /* Utilities */ +__device_inline float3 camera_position(KernelGlobals *kg) +{ + Transform cameratoworld = kernel_data.cam.cameratoworld; + return make_float3(cameratoworld.x.w, cameratoworld.y.w, cameratoworld.z.w); +} + __device_inline float camera_distance(KernelGlobals *kg, float3 P) { Transform cameratoworld = kernel_data.cam.cameratoworld; @@ -258,5 +264,30 @@ __device_inline float camera_distance(KernelGlobals *kg, float3 P) return len(P - camP); } +__device_inline float3 camera_world_to_ndc(KernelGlobals *kg, ShaderData *sd, float3 P) +{ + if(kernel_data.cam.type != CAMERA_PANORAMA) { + /* perspective / ortho */ + if(sd->object == ~0 && kernel_data.cam.type == CAMERA_PERSPECTIVE) + P += camera_position(kg); + + Transform tfm = kernel_data.cam.worldtondc; + return transform_perspective(&tfm, P); + } + else { + /* panorama */ + Transform tfm = kernel_data.cam.worldtocamera; + + if(sd->object != ~0) + P = normalize(transform_point(&tfm, P)); + else + P = normalize(transform_direction(&tfm, P)); + + float2 uv = direction_to_panorama(kg, P); + + return make_float3(uv.x, uv.y, 0.0f); + } +} + CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index 908c5a91768..347c066962a 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -402,9 +402,9 @@ __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData { /* vectors */ sd->P = ray->D; - sd->N = -sd->P; - sd->Ng = -sd->P; - sd->I = -sd->P; + sd->N = -ray->D; + sd->Ng = -ray->D; + sd->I = -ray->D; sd->shader = kernel_data.background.shader; sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2); #ifdef __OBJECT_MOTION__ @@ -437,6 +437,10 @@ __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData sd->du = differential_zero(); sd->dv = differential_zero(); #endif + + /* for NDC coordinates */ + sd->ray_P = ray->P; + sd->ray_dP = ray->dP; } /* BSDF */ diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 11cdad6bb44..771c79ba637 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -572,6 +572,10 @@ typedef struct ShaderData { ShaderClosure closure; #endif + /* ray start position, only set for backgrounds */ + float3 ray_P; + differential3 ray_dP; + #ifdef __OSL__ struct KernelGlobals *osl_globals; #endif diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index f2311e14c3a..fd3f349286b 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -43,6 +43,7 @@ #include "kernel_primitive.h" #include "kernel_projection.h" #include "kernel_accumulate.h" +#include "kernel_camera.h" #include "kernel_shader.h" CCL_NAMESPACE_BEGIN @@ -653,12 +654,36 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD bool OSLRenderServices::get_background_attribute(KernelGlobals *kg, ShaderData *sd, ustring name, TypeDesc type, bool derivatives, void *val) { - /* Ray Length */ if (name == u_path_ray_length) { + /* Ray Length */ float f = sd->ray_length; return set_attribute_float(f, type, derivatives, val); } - + else if (name == u_ndc) { + /* NDC coordinates with special exception for otho */ + OSLThreadData *tdata = kg->osl_tdata; + OSL::ShaderGlobals *globals = &tdata->globals; + float3 ndc[3]; + + if((globals->raytype & PATH_RAY_CAMERA) && sd->object == ~0 && kernel_data.cam.type == CAMERA_ORTHOGRAPHIC) { + ndc[0] = camera_world_to_ndc(kg, sd, sd->ray_P); + + if(derivatives) { + ndc[1] = camera_world_to_ndc(kg, sd, sd->ray_P + sd->ray_dP.dx) - ndc[0]; + ndc[2] = camera_world_to_ndc(kg, sd, sd->ray_P + sd->ray_dP.dy) - ndc[0]; + } + } + else { + ndc[0] = camera_world_to_ndc(kg, sd, sd->P); + + if(derivatives) { + ndc[1] = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dx) - ndc[0]; + ndc[2] = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dy) - ndc[0]; + } + } + + return set_attribute_float3(ndc, type, derivatives, val); + } else return false; } diff --git a/intern/cycles/kernel/shaders/node_texture_coordinate.osl b/intern/cycles/kernel/shaders/node_texture_coordinate.osl index 37460bcfc98..9da582da5dc 100644 --- a/intern/cycles/kernel/shaders/node_texture_coordinate.osl +++ b/intern/cycles/kernel/shaders/node_texture_coordinate.osl @@ -38,7 +38,7 @@ shader node_texture_coordinate( Object = P; point Pcam = transform("camera", "world", point(0, 0, 0)); Camera = transform("camera", P + Pcam); - Window = transform("NDC", P + Pcam); + getattribute("NDC", Window); Normal = NormalIn; Reflection = I; } diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h index 16b684e79a0..cfb930d92e8 100644 --- a/intern/cycles/kernel/svm/svm.h +++ b/intern/cycles/kernel/svm/svm.h @@ -385,14 +385,14 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT svm_node_min_max(kg, sd, stack, node.y, node.z, &offset); break; case NODE_TEX_COORD: - svm_node_tex_coord(kg, sd, stack, node.y, node.z); + svm_node_tex_coord(kg, sd, path_flag, stack, node.y, node.z); break; #ifdef __EXTRA_NODES__ case NODE_TEX_COORD_BUMP_DX: - svm_node_tex_coord_bump_dx(kg, sd, stack, node.y, node.z); + svm_node_tex_coord_bump_dx(kg, sd, path_flag, stack, node.y, node.z); break; case NODE_TEX_COORD_BUMP_DY: - svm_node_tex_coord_bump_dy(kg, sd, stack, node.y, node.z); + svm_node_tex_coord_bump_dy(kg, sd, path_flag, stack, node.y, node.z); break; case NODE_CLOSURE_SET_NORMAL: svm_node_set_normal(kg, sd, stack, node.y, node.z ); diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h index 98f99a91bc6..e76b50d6fac 100644 --- a/intern/cycles/kernel/svm/svm_tex_coord.h +++ b/intern/cycles/kernel/svm/svm_tex_coord.h @@ -20,38 +20,7 @@ CCL_NAMESPACE_BEGIN /* Texture Coordinate Node */ -__device_inline float3 svm_background_position(KernelGlobals *kg, float3 P) -{ - Transform cameratoworld = kernel_data.cam.cameratoworld; - float3 camP = make_float3(cameratoworld.x.w, cameratoworld.y.w, cameratoworld.z.w); - - return camP + P; -} - -__device_inline float3 svm_world_to_ndc(KernelGlobals *kg, ShaderData *sd, float3 P) -{ - if(kernel_data.cam.type != CAMERA_PANORAMA) { - if(sd->object == ~0) - P = svm_background_position(kg, P); - - Transform tfm = kernel_data.cam.worldtondc; - return transform_perspective(&tfm, P); - } - else { - Transform tfm = kernel_data.cam.worldtocamera; - - if(sd->object != ~0) - P = normalize(transform_point(&tfm, P)); - else - P = normalize(transform_direction(&tfm, P)); - - float2 uv = direction_to_panorama(kg, P); - - return make_float3(uv.x, uv.y, 0.0f); - } -} - -__device void svm_node_tex_coord(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) +__device void svm_node_tex_coord(KernelGlobals *kg, ShaderData *sd, int path_flag, float *stack, uint type, uint out_offset) { float3 data; @@ -80,11 +49,14 @@ __device void svm_node_tex_coord(KernelGlobals *kg, ShaderData *sd, float *stack if(sd->object != ~0) data = transform_point(&tfm, sd->P); else - data = transform_point(&tfm, svm_background_position(kg, sd->P)); + data = transform_point(&tfm, sd->P + camera_position(kg)); break; } case NODE_TEXCO_WINDOW: { - data = svm_world_to_ndc(kg, sd, sd->P); + if((path_flag & PATH_RAY_CAMERA) && sd->object == ~0 && kernel_data.cam.type == CAMERA_ORTHOGRAPHIC) + data = camera_world_to_ndc(kg, sd, sd->ray_P); + else + data = camera_world_to_ndc(kg, sd, sd->P); data.z = 0.0f; break; } @@ -108,7 +80,7 @@ __device void svm_node_tex_coord(KernelGlobals *kg, ShaderData *sd, float *stack stack_store_float3(stack, out_offset, data); } -__device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) +__device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, ShaderData *sd, int path_flag, float *stack, uint type, uint out_offset) { #ifdef __RAY_DIFFERENTIALS__ float3 data; @@ -138,11 +110,14 @@ __device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, ShaderData *sd, floa if(sd->object != ~0) data = transform_point(&tfm, sd->P + sd->dP.dx); else - data = transform_point(&tfm, svm_background_position(kg, sd->P + sd->dP.dx)); + data = transform_point(&tfm, sd->P + sd->dP.dx + camera_position(kg)); break; } case NODE_TEXCO_WINDOW: { - data = svm_world_to_ndc(kg, sd, sd->P + sd->dP.dx); + if((path_flag & PATH_RAY_CAMERA) && sd->object == ~0 && kernel_data.cam.type == CAMERA_ORTHOGRAPHIC) + data = camera_world_to_ndc(kg, sd, sd->ray_P + sd->ray_dP.dx); + else + data = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dx); data.z = 0.0f; break; } @@ -169,7 +144,7 @@ __device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, ShaderData *sd, floa #endif } -__device void svm_node_tex_coord_bump_dy(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) +__device void svm_node_tex_coord_bump_dy(KernelGlobals *kg, ShaderData *sd, int path_flag, float *stack, uint type, uint out_offset) { #ifdef __RAY_DIFFERENTIALS__ float3 data; @@ -199,11 +174,14 @@ __device void svm_node_tex_coord_bump_dy(KernelGlobals *kg, ShaderData *sd, floa if(sd->object != ~0) data = transform_point(&tfm, sd->P + sd->dP.dy); else - data = transform_point(&tfm, svm_background_position(kg, sd->P + sd->dP.dy)); + data = transform_point(&tfm, sd->P + sd->dP.dy + camera_position(kg)); break; } case NODE_TEXCO_WINDOW: { - data = svm_world_to_ndc(kg, sd, sd->P + sd->dP.dy); + if((path_flag & PATH_RAY_CAMERA) && sd->object == ~0 && kernel_data.cam.type == CAMERA_ORTHOGRAPHIC) + data = camera_world_to_ndc(kg, sd, sd->ray_P + sd->ray_dP.dy); + else + data = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dy); data.z = 0.0f; break; } |