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

aperturesize, resolution, viewplane, shuttertime fixes #33

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
28 changes: 15 additions & 13 deletions src/GafferCycles/IECoreCyclesPreview/CameraAlgo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
#include "GafferCycles/IECoreCyclesPreview/ObjectAlgo.h"
#include "GafferCycles/IECoreCyclesPreview/SocketAlgo.h"

#include "Gaffer/Context.h"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that you are needing to get the current frame somehow on line 129, we don't want a dependency on Gaffer in the IECoreCycles code as it might one day appear in Cortex. What we can do here is use modf() to extract the fractional part of the shutter (good find I didn't know it included the frame in it).


#include "IECoreScene/Camera.h"

#include "IECore/SimpleTypedData.h"
Expand Down Expand Up @@ -66,7 +68,7 @@ ccl::Camera *convertCommon( const IECoreScene::Camera *camera, const std::string
ccam->fov = M_PI_2;
if( camera->getFStop() > 0.0f )
{
ccam->aperturesize = camera->getFocalLength() * camera->getFocalLengthWorldScale() / camera->getFStop();
ccam->aperturesize = 0.5f * camera->getFocalLength() * camera->getFocalLengthWorldScale() / camera->getFStop();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could've sworn the camera code in Cycles was in diameter not radius, maybe it changed after I implemented this and I didn't notice? But, if it's matching to GafferArnold then I guess I was wrong/it changed! :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, seems a bit unintuitive but it matches visually with Arnold and based on the below it seems the same is done on the Blender camera conversion:

https://github.com/boberfly/cycles/blob/89cb9a6f74b28e6f797e38304ffafdbb9b395030/src/blender/blender_camera.cpp#L219

ccam->focaldistance = camera->getFocusDistance();
}
}
Expand All @@ -87,7 +89,7 @@ ccl::Camera *convertCommon( const IECoreScene::Camera *camera, const std::string

// Screen window/resolution TODO: full_ might be something to do with cropping?
const Imath::Box2f &frustum = camera->frustum();
const Imath::V2i &resolution = camera->getResolution();
const Imath::V2i &resolution = camera->renderResolution();
const float pixelAspectRatio = camera->getPixelAspectRatio();
ccam->width = resolution[0];
ccam->height = resolution[1];
Expand All @@ -104,6 +106,11 @@ ccl::Camera *convertCommon( const IECoreScene::Camera *camera, const std::string
ccam->nearclip = clippingPlanes.x;
ccam->farclip = clippingPlanes.y;

// Invert the viewplane in Y so Gaffer's aperture offsets and overscan are applied in the correct direction
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we simplify this to the lines above?

	// Invert the viewplane in Y so Gaffer's aperture offsets and overscan are applied in the correct direction
	ccam->viewplane.bottom = -frustum.max.y;
	ccam->viewplane.top = -frustum.min.y;

And will we need to change the crop window to match?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I started with something like that, but I've also been playing with getting overscan working and would need to apply the same flip to the overscan values when modifying the viewplane so figured it'd be cleaner to just flip it all in one place at the end. Happy to take the simpler path and revisit it if/when I put up a PR for overscan.

The crop window doesn't need to be flipped as it applies to the image, rather than the camera viewplane.

swap( ccam->viewplane.bottom, ccam->viewplane.top );
ccam->viewplane.bottom *= -1.0f;
ccam->viewplane.top *= -1.0f;

// Crop window
if ( camera->hasCropWindow() )
{
Expand All @@ -115,27 +122,22 @@ ccl::Camera *convertCommon( const IECoreScene::Camera *camera, const std::string
ccam->border.clamp();
}

// Shutter TODO: Need to see if this is correct or not, cycles also has a shutter curve...
// Shutter TODO: Cycles also has a shutter curve...
const Imath::V2f &shutter = camera->getShutter();
if ((shutter.x > 0.0) && (shutter.y > 0.0))
ccam->shuttertime = shutter.y - shutter.x;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking we might need to add an abs here eg. abs( shutter.y - shutter.x ); if we render with a negative frame.


const Imath::V2f relativeShutter = shutter - Imath::V2f( Gaffer::Context::current()->getFrame() );
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const Imath::V2f relativeShutter = Imath::V2f( modf( shutter.x, nullptr ), modf( shutter.y, nullptr ) );
I'll test here and see.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright had a bit more of a think to this the next day, modf won't cut it. I'm testing now by bringing this code into Renderer.cpp and hashing the frame number with the camera hash there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tried out your camerafixes2 branch with the above changes, renders look good to me.

I guess a simpler way of approaching this would be to calculate the relative shutter time with something like const Imath::V2f relativeShutter = shutter - Imath::V2f( round(shutter.x + shuttertime / 2.0f) );

if ((relativeShutter.x >= 0.0) && (relativeShutter.y > 0.0))
{
ccam->motion_position = ccl::Camera::MOTION_POSITION_START;
ccam->shuttertime = shutter.x + shutter.y;
}
else if ((shutter.x < 0.0) && (shutter.y > 0.0))
{
ccam->motion_position = ccl::Camera::MOTION_POSITION_CENTER;
ccam->shuttertime = abs(shutter.x) + shutter.y;
}
else if ((shutter.x < 0.0) && (shutter.y <= 0.0))
else if ((relativeShutter.x < 0.0) && (relativeShutter.y <= 0.0))
{
ccam->motion_position = ccl::Camera::MOTION_POSITION_END;
ccam->shuttertime = abs(shutter.x) + abs(shutter.y);
}
else
{
ccam->motion_position = ccl::Camera::MOTION_POSITION_CENTER;
ccam->shuttertime = 1.0;
}

return ccam;
Expand Down