diff --git a/zenovis/xinxinoptix/PTKernel.cu b/zenovis/xinxinoptix/PTKernel.cu index d91d950d45..e6dcd8a9b3 100644 --- a/zenovis/xinxinoptix/PTKernel.cu +++ b/zenovis/xinxinoptix/PTKernel.cu @@ -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( idx.x + params.windowCrop_min.x ) + subpixel_jitter.x ) / static_cast( w ), - ( static_cast( idx.y + params.windowCrop_min.y ) + subpixel_jitter.y ) / static_cast( 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( idx.x + params.windowCrop_min.x ) + subpixel_jitter.x ) / static_cast( w ), + ( static_cast( idx.y + params.windowCrop_min.y ) + subpixel_jitter.y ) / static_cast( 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; @@ -386,4 +425,4 @@ extern "C" __global__ void __miss__occlusion() extern "C" __global__ void __closesthit__occlusion() { setPayloadOcclusion( true ); -} \ No newline at end of file +} diff --git a/zenovis/xinxinoptix/optixPathTracer.cpp b/zenovis/xinxinoptix/optixPathTracer.cpp index f1443be031..a93fe90f88 100644 --- a/zenovis/xinxinoptix/optixPathTracer.cpp +++ b/zenovis/xinxinoptix/optixPathTracer.cpp @@ -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) { diff --git a/zenovis/xinxinoptix/optixPathTracer.h b/zenovis/xinxinoptix/optixPathTracer.h index cfb4208cd0..72cae6f77c 100644 --- a/zenovis/xinxinoptix/optixPathTracer.h +++ b/zenovis/xinxinoptix/optixPathTracer.h @@ -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 @@ -227,8 +235,6 @@ struct MissData { float4 bg_color; }; - - struct HitGroupData { //float4* vertices; diff --git a/zenovis/xinxinoptix/xinxinoptixapi.h b/zenovis/xinxinoptix/xinxinoptixapi.h index 098576471e..d743d17a2c 100644 --- a/zenovis/xinxinoptix/xinxinoptixapi.h +++ b/zenovis/xinxinoptix/xinxinoptixapi.h @@ -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> const &vtab,int const *matids, std::vector 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);