Cycles: window texture coordinates now work with orthographic cameras, this
was an old issue since the first version.
This commit is contained in:
@@ -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
|
||||
|
||||
|
@@ -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 */
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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 );
|
||||
|
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user