Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optix camera #1507

Merged
merged 5 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading