Skip to content

Commit

Permalink
Merge pull request #1507 from zenustech/OptixCamera
Browse files Browse the repository at this point in the history
Optix camera
  • Loading branch information
zhouhang95 authored Nov 9, 2023
2 parents 9cc99c7 + f111169 commit ea58e24
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 95 deletions.
177 changes: 108 additions & 69 deletions zenovis/xinxinoptix/PTKernel.cu
Original file line number Diff line number Diff line change
Expand Up @@ -65,75 +65,114 @@ vec3 ACESFitted(vec3 color, float gamma)
extern "C" __global__ void __raygen__rg()
{

const int w = params.windowSpace.x;
const int h = params.windowSpace.y;
//const float3 eye = params.eye;
const uint3 idxx = optixGetLaunchIndex();
uint3 idx;
idx.x = idxx.x + params.tile_i * params.tile_w;
idx.y = idxx.y + params.tile_j * params.tile_h;
if(idx.x>w || idx.y>h)
const int w = params.windowSpace.x;
const int h = params.windowSpace.y;
//const float3 eye = params.eye;
const uint3 idxx = optixGetLaunchIndex();
uint3 idx;
idx.x = idxx.x + params.tile_i * params.tile_w;
idx.y = idxx.y + params.tile_j * params.tile_h;
if(idx.x>w || idx.y>h)
return;
const unsigned int image_index = idx.y * w + idx.x;
const int subframe_index = params.subframe_index;
const CameraInfo cam = params.cam;

int seedy = idx.y/4, seedx = idx.x/8;
int sid = (idx.y%4) * 8 + idx.x%8;
unsigned int seed = tea<4>( idx.y * w + idx.x, subframe_index);
// auto tmp = idx.y * w + idx.x + subframe_index * w * h;
// unsigned int seed = pcg_hash(tmp);

unsigned int eventseed = seed; //tea<4>( idx.y * w + idx.x, subframe_index+1);
float focalPlaneDistance = cam.focalPlaneDistance>0.01f? cam.focalPlaneDistance : 0.01f;
float aperture = clamp(cam.aperture,0.0f,100.0f);
aperture/=10;

float3 result = make_float3( 0.0f );
float3 result_d = make_float3( 0.0f );
float3 result_s = make_float3( 0.0f );
float3 result_t = make_float3( 0.0f );
float3 result_b = make_float3( 0.0f );
int i = params.samples_per_launch;

float3 tmp_albedo{};
float3 tmp_normal{};
unsigned int sobolseed = subframe_index;
do
{
// The center of each pixel is at fraction (0.5,0.5)
float2 subpixel_jitter = sobolRnd(sobolseed);

float2 d = 2.0f * make_float2(
( static_cast<float>( idx.x + params.windowCrop_min.x ) + subpixel_jitter.x ) / static_cast<float>( w ),
( static_cast<float>( idx.y + params.windowCrop_min.y ) + subpixel_jitter.y ) / static_cast<float>( h )
) - 1.0f;

float2 r01 = sobolRnd(sobolseed);

float r0 = r01.x * 2.0f * M_PIf;
float r1 = r01.y * aperture * aperture;
r1 = sqrtf(r1);

float3 eye_shake = r1 * ( cosf(r0)* normalize(cam.right) + sinf(r0)* normalize(cam.up)); // Camera local space
float3 ray_origin = cam.eye + eye_shake;
float3 ray_direction = focalPlaneDistance / length(cam.front) * (cam.right * d.x + cam.up * d.y + cam.front) - eye_shake; // Camera local space
ray_direction = normalize(ray_direction);

RadiancePRD prd;
prd.emission = make_float3(0.f);
prd.radiance = make_float3(0.f);
prd.attenuation = make_float3(1.f);
prd.attenuation2 = make_float3(1.f);
prd.prob = 1.0f;
prd.prob2 = 1.0f;
prd.countEmitted = true;
prd.done = false;
prd.seed = seed;
prd.eventseed = eventseed;
prd.flags = 0;
prd.maxDistance = 1e16f;
prd.medium = DisneyBSDF::PhaseFunctions::vacuum;

const unsigned int image_index = idx.y * w + idx.x;
const int subframe_index = params.subframe_index;
const CameraInfo cam = params.cam;

int seedy = idx.y/4, seedx = idx.x/8;
int sid = (idx.y%4) * 8 + idx.x%8;
unsigned int seed = tea<4>( idx.y * w + idx.x, subframe_index);
unsigned int eventseed = tea<4>( idx.y * w + idx.x, subframe_index + 1);
float focalPlaneDistance = cam.focal_distance>0.01f? cam.focal_distance: 0.01f;
float aperture = clamp(cam.aperture,0.0f,100.0f);

float3 result = make_float3( 0.0f );
float3 result_d = make_float3( 0.0f );
float3 result_s = make_float3( 0.0f );
float3 result_t = make_float3( 0.0f );
float3 result_b = make_float3( 0.0f );
int i = params.samples_per_launch;

float3 tmp_albedo{};
float3 tmp_normal{};
unsigned int sobolseed = subframe_index;
do{
// The center of each pixel is at fraction (0.5,0.5)
float2 subpixel_jitter = sobolRnd(sobolseed);

float2 d = 2.0f * make_float2(
( static_cast<float>( idx.x + params.windowCrop_min.x ) + subpixel_jitter.x ) / static_cast<float>( w ),
( static_cast<float>( idx.y + params.windowCrop_min.y ) + subpixel_jitter.y ) / static_cast<float>( h )
) - 1.0f;

float2 r01 = sobolRnd(sobolseed);

float r0 = r01.x * 2.0f * M_PIf;
float r1 = sqrtf(r01.y) * aperture;

float sin_yaw = sinf(cam.yaw);
float cos_yaw = cosf(cam.yaw);
float sin_pitch = sinf(cam.pitch);
float cos_pitch = cosf(cam.pitch);

mat3 tile_transform = mat3(
cos_yaw, -sin_yaw * cos_pitch, sin_pitch*sin_yaw,
sin_yaw, cos_yaw * cos_pitch, - cos_yaw * sin_pitch,
0.0f, sin_pitch, cos_pitch
);

mat3 camera_transform = mat3(
cam.right.x, cam.up.x, cam.front.x,
cam.right.y, cam.up.y, cam.front.y,
cam.right.z, cam.up.z, cam.front.z
);

// Under camer local space, cam.eye as origin, cam.right as X axis, cam.up as Y axis, cam.front as Z axis.
float3 eye_shake = r1 * (cosf(r0) * make_float3(1.0f,0.0f,0.0f) + sinf(r0) * make_float3(0.0f,1.0f,0.0f)); // r1 * ( cos(r0) , sin(r0) , 0 );
float3 focal_plane_center = make_float3(cam.vertical_shift*cam.height, cam.horizontal_shift*cam.width, cam.focal_length);
float3 old_direction = focal_plane_center + make_float3(cam.width * d.x, cam.height*d.y, 0.0f);
float3 tile_normal = make_float3(sin_pitch*sin_yaw, - cos_yaw * sin_pitch, cos_pitch);

float D = - dot(tile_normal , focal_plane_center);//surcface equaltion is Ax+By+Cz+D = 0

/*to sphere coordinate
x = r * sin(theta) * cos(phi) = r * C1;
y = r * sin(theta) * sin(phi) = r * C2;
z = r * cos(phi) = r* C3;
*/
float old_r = length(old_direction);
float3 C_vector = old_direction/old_r;
float new_r = -D / dot(tile_normal,C_vector);
/*
Ax+By+Cz+D = A*C1*r + B*C2*r + C*C3*r + D = ((A,B,C) dot (C1,C2,C3)) * r + D =0
old_direction/old_r = (C1,C2,C3)
*/
float3 terminal_point = new_r * C_vector;
terminal_point = terminal_point * (cam.focal_distance/cam.focal_length);//focal_length control

//transform to world space
terminal_point = camera_transform * terminal_point;
eye_shake = camera_transform * eye_shake;

float3 ray_origin = cam.eye + eye_shake;
float3 ray_direction = terminal_point - eye_shake;
ray_direction = normalize(ray_direction);

RadiancePRD prd;
prd.emission = make_float3(0.f);
prd.radiance = make_float3(0.f);
prd.attenuation = make_float3(1.f);
prd.attenuation2 = make_float3(1.f);
prd.prob = 1.0f;
prd.prob2 = 1.0f;
prd.countEmitted = true;
prd.done = false;
prd.seed = seed;
prd.eventseed = eventseed;
prd.flags = 0;
prd.maxDistance = 1e16f;
prd.medium = DisneyBSDF::PhaseFunctions::vacuum;


prd.origin = ray_origin;
prd.direction = ray_direction;
Expand Down Expand Up @@ -386,4 +425,4 @@ extern "C" __global__ void __miss__occlusion()
extern "C" __global__ void __closesthit__occlusion()
{
setPayloadOcclusion( true );
}
}
73 changes: 56 additions & 17 deletions zenovis/xinxinoptix/optixPathTracer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3364,32 +3364,71 @@ void set_window_size(int nx, int ny) {
}

void set_perspective(float const *U, float const *V, float const *W, float const *E, float aspect, float fov, float fpd, float aperture) {
set_perspective_by_fov(U,V,W,E,aspect,fov,0.0f,0.024f,fpd,aperture,0.0f,0.0f,0.0f,0.0f);
}
void set_perspective_by_fov(float const *U, float const *V, float const *W, float const *E, float aspect, float fov, int fov_type, float L, float focal_distance, float aperture, float pitch, float yaw, float h_shift, float v_shift) {
auto &cam = state.params.cam;
//float c_aspect = fw/fh;
//float u_aspect = aspect;
//float r_fh = fh * 0.001;
//float r_fw = fw * 0.001;
//zeno::log_info("Camera film w {} film h {} aspect {} {}", fw, fh, u_aspect, c_aspect);
cam.eye = make_float3(E[0], E[1], E[2]);
cam.right = normalize(make_float3(U[0], U[1], U[2]));
cam.up = normalize(make_float3(V[0], V[1], V[2]));
cam.front = normalize(make_float3(W[0], W[1], W[2]));

float half_radfov = fov * float(M_PI) / 360.0f;
float half_tanfov = std::tan(half_radfov);
cam.focal_length = L / 2.0f / half_tanfov;
if(aperture < 0.01f){
cam.aperture = 0.0f;
}else{
cam.aperture = cam.focal_length / aperture;
}


// L = L/cam.focal_length;
// cam.focal_length = 1.0f;

switch (fov_type){
case 0:
cam.height = L;
break;
case 1:
cam.height = L / aspect;
break;
case 2:
cam.height = sqrtf(L * L / (1.0f + aspect *aspect));
break;
}
cam.width = cam.height * aspect;

cam.pitch = pitch;
cam.yaw = yaw;
cam.horizontal_shift = h_shift;
cam.vertical_shift = v_shift;
cam.focal_distance = focal_distance;
camera_changed = true;
}
void set_perspective_by_focal_length(float const *U, float const *V, float const *W, float const *E, float aspect, float focal_length, float w, float h, float focal_distance, float aperture, float pitch, float yaw, float h_shift, float v_shift) {
auto &cam = state.params.cam;
cam.eye = make_float3(E[0], E[1], E[2]);
cam.right = normalize(make_float3(U[0], U[1], U[2]));
cam.up = normalize(make_float3(V[0], V[1], V[2]));
cam.front = normalize(make_float3(W[0], W[1], W[2]));

float radfov = fov * float(M_PI) / 180;
float tanfov = std::tan(radfov / 2.0f);
cam.front /= tanfov;
cam.right *= aspect;
cam.focal_length = focal_length;

if(aperture < 0.01f){
cam.aperture = 0.0f;
}else{
cam.aperture = cam.focal_length / aperture;
}

cam.width = w;
cam.height = h;
cam.pitch = pitch;
cam.yaw = yaw;
cam.horizontal_shift = h_shift;
cam.vertical_shift = v_shift;
cam.focal_distance = focal_distance;
camera_changed = true;
//cam.aspect = aspect;
//cam.fov = fov;
//camera.setZxxViewMatrix(U, V, W);
//camera.setAspectRatio(aspect);
//camera.setFovY(fov * aspect * (float)M_PI / 180.0f);

cam.focalPlaneDistance = fpd;
cam.aperture = aperture;
}

static void write_pfm(std::string& path, int w, int h, const float *rgb) {
Expand Down
22 changes: 14 additions & 8 deletions zenovis/xinxinoptix/optixPathTracer.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,20 @@ struct GenericLight

struct CameraInfo
{
float3 eye;
float3 right, up, front;
//float aspect;
//float fov;
float focalPlaneDistance;
float aperture;
//all distance in meters;
float3 eye; //lens center position
float3 right; //lens right direction
float3 front; //lens front direction, so call optical axis
float3 up; //lens up direction
float horizontal_shift;
float vertical_shift;
float pitch;
float yaw;
float focal_length; //lens focal length
float aperture; //diameter of aperture
float focal_distance; //distance from focal plane center to lens plane
float width; //sensor physical width
float height; //sensor physical height
};

struct Params
Expand Down Expand Up @@ -227,8 +235,6 @@ struct MissData
{
float4 bg_color;
};


struct HitGroupData
{
//float4* vertices;
Expand Down
3 changes: 2 additions & 1 deletion zenovis/xinxinoptix/xinxinoptixapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ void optixupdateend();

void set_window_size(int nx, int ny);
void set_perspective(float const *U, float const *V, float const *W, float const *E, float aspect, float fov, float fpd, float aperture);

void set_perspective_by_fov(float const *U, float const *V, float const *W, float const *E, float aspect, float fov, int fov_type, float L, float focal_distance, float aperture, float pitch, float yaw, float h_shift, float v_shift);
void set_perspective_by_focal_length(float const *U, float const *V, float const *W, float const *E, float aspect, float focal_length, float w, float h, float focal_distance, float aperture, float pitch, float yaw, float h_shift, float v_shift);
void load_object(std::string const &key, std::string const &mtlid, const std::string& instID, float const *verts, size_t numverts, int const *tris, size_t numtris, std::map<std::string, std::pair<float const *, size_t>> const &vtab,int const *matids, std::vector<std::string> const &matNameList);
void unload_object(std::string const &key);
void load_inst(const std::string &key, const std::string &instID, const std::string &onbType, std::size_t numInsts, const float *pos, const float *nrm, const float *uv, const float *clr, const float *tang);
Expand Down

0 comments on commit ea58e24

Please sign in to comment.