diff --git a/src/c/D3d/Renderer.cpp b/src/c/D3d/Renderer.cpp
index 6acb5f95cb7f0f1cc7fa8259e1704effac8d31b4..6d7045b8b65a256303904f2af27cddfa8af679c8 100644
--- a/src/c/D3d/Renderer.cpp
+++ b/src/c/D3d/Renderer.cpp
@@ -104,8 +104,14 @@ HRESULT Renderer::init(std::string rootDir, Vec<int> viewportSizeIn)
 {
 	dllRoot = rootDir;
 
-	for ( int i=0; i < TargetChains::NumTC; ++i )
-		viewportSize[i] = viewportSizeIn;
+	// Default scaling is 100% except
+	for (int i = 0; i < TargetChains::NumTC; ++i)
+		dpiScale[i] = 100;
+	// Main backbuffer scale is 150% to improve render speed
+	dpiScale[TargetChains::Screen] = 150;
+
+	for (int i = 0; i < TargetChains::NumTC; ++i)
+		setViewportSize(viewportSizeIn, (TargetChains)i);
 
 	HRESULT hr = initDevice();
 	if (FAILED(hr))
@@ -200,7 +206,7 @@ void Renderer::releaseDevice()
 
 HRESULT Renderer::initRenderTargets()
 {
-	Vec<int> size = viewportSize[TargetChains::Screen];
+	Vec<int> size = getViewportSize(TargetChains::Screen);
 	renderChains[TargetChains::Screen][RenderTargetTypes::DefaultRT] = std::make_shared<SwapChainTarget>(this, gWindowHandle, size.x, size.y);
 	renderChains[TargetChains::Capture][RenderTargetTypes::DefaultRT] = std::make_shared<ReadbackRenderTarget>(this, size.x, size.y);
 
@@ -884,9 +890,9 @@ void Renderer::startRender(TargetChains chain)
 		resetViewPort(chain);
 
 	// Set up the camera projections
-	gCameraText->setViewportSize(viewportSize[chain]);
-	gCameraWidget->setViewportSize(viewportSize[chain]);
-	gCameraDefaultMesh->setViewportSize(viewportSize[chain]);
+	gCameraText->setViewportSize(getViewportSize(chain));
+	gCameraWidget->setViewportSize(getViewportSize(chain));
+	gCameraDefaultMesh->setViewportSize(getViewportSize(chain));
 
 	attachTargets(chain, RenderTargetTypes::DefaultRT, DepthTargetTypes::DefaultDT);
 
@@ -1106,7 +1112,8 @@ void Renderer::renderLabel(TargetChains chain, const Camera* camera, const Graph
 	DirectX::XMFLOAT3 centerOfmass(centerOfmassVec.x,centerOfmassVec.y,centerOfmassVec.z);
 	DirectX::XMVECTOR com = DirectX::XMLoadFloat3(&centerOfmass);
 
-	const Vec<int>& size = viewportSize[chain];
+	const Vec<int>& size = getViewportSize(chain);
+	//const Vec<int>& size = viewportSize[chain];
 
 	v2D = DirectX::XMVector3Project(com,0.0f,0.0f,(float)size.x,(float)size.y,0.0f,1.0f,
 		camera->getProjectionTransform(),camera->getViewTransform(),node->getLocalToWorld());
@@ -1127,7 +1134,8 @@ void Renderer::renderScaleValue(TargetChains chain, const Camera* camera)
 	if ( !volInfo )
 		return;
 
-	Vec<int>& viewSize = viewportSize[chain];
+	const Vec<int>& viewSize = getViewportSize(chain);
+	//const Vec<int>& viewSize = viewportSize[chain];
 
 	float sz = camera->getVolUnitsPerPix();
 
@@ -1195,7 +1203,9 @@ void Renderer::renderFrameNum(TargetChains chain)
 	char buff[36];
 	sprintf(buff, "Frame:%d", currentFrame+1);
 
-	Vec<int>& viewSize = viewportSize[chain];
+	const Vec<int>& viewSize = getViewportSize(chain);
+	//const Vec<int>& viewSize = viewportSize[chain];
+
 	Vec<int> screenPos(viewSize.x-120, 10, 0);
 	textRenderer->drawString(buff, screenPos);
 }
@@ -1600,15 +1610,26 @@ int Renderer::getPolygon(Vec<float> pnt, Vec<float> direction)
 	return node->getIndex();
 }
 
-void Renderer::resizeViewPort(Vec<int> sizeIn, TargetChains selectChain)
+void Renderer::setViewportSize(Vec<int> sizeIn, TargetChains selectChain)
 {
 	viewportSize[selectChain] = sizeIn;
+	scaledViewSize[selectChain] = (sizeIn * 100) / dpiScale[selectChain];
+}
+
+const Vec<int>& Renderer::getViewportSize(TargetChains selectChain) const
+{
+	return scaledViewSize[selectChain];
+}
+
+void Renderer::resizeViewPort(Vec<int> sizeIn, TargetChains selectChain)
+{
+	setViewportSize(sizeIn, selectChain);
 
 	for ( int i=0; i < RenderTargetTypes::NumRT; ++i )
-		renderChains[selectChain][i]->resizeTarget(viewportSize[selectChain].x, viewportSize[selectChain].y);
+		renderChains[selectChain][i]->resizeTarget(getViewportSize(selectChain).x, getViewportSize(selectChain).y);
 
 	for ( int i=0; i < DepthTargetTypes::NumDT; ++i )
-		depthChains[selectChain][i]->resizeDepth(viewportSize[selectChain].x, viewportSize[selectChain].y);
+		depthChains[selectChain][i]->resizeDepth(getViewportSize(selectChain).x, getViewportSize(selectChain).y);
 
 	resetViewPort(selectChain);
 }
@@ -1622,8 +1643,8 @@ void Renderer::flushContext()
 HRESULT Renderer::resetViewPort(TargetChains selectChain)
 {
 	D3D11_VIEWPORT vp;
-	vp.Width = (float)viewportSize[selectChain].x;
-	vp.Height = (float)viewportSize[selectChain].y;
+	vp.Width = (float)getViewportSize(selectChain).x;
+	vp.Height = (float)getViewportSize(selectChain).y;
 	vp.MinDepth = 0.0f;
 	vp.MaxDepth = 1.0f;
 	vp.TopLeftX = 0;
@@ -1703,6 +1724,13 @@ void Renderer::setWorldRotation(DirectX::XMMATRIX rotation)
 	rootScene->updateRotation(rotation);
 }
 
+void Renderer::setDpiScale(int scale, TargetChains selectChain)
+{
+	dpiScale[selectChain] = scale;
+
+	resizeViewPort(viewportSize[selectChain], selectChain);
+}
+
 
 unsigned char* Renderer::captureWindow(Vec<size_t>& dims)
 {
diff --git a/src/c/D3d/Renderer.h b/src/c/D3d/Renderer.h
index 36fbcb3b4efc51f35f95718a2faf8f8306ba7005..7564e01fdae5c03c0e4a0f8e8d9dcf1a0e4667f6 100644
--- a/src/c/D3d/Renderer.h
+++ b/src/c/D3d/Renderer.h
@@ -111,7 +111,7 @@ public:
 //////////////////////////////////////////////////////////////////////////
 	HRESULT init(std::string rootDir, Vec<int> viewportSizeIn);
 
-//Setters	
+//Setters
 	void setRendering(bool rendering){isRendering = rendering;}
 	void setCurrentFrame(int frame);
 	void incrementFrame();
@@ -141,6 +141,7 @@ public:
 	void setWorldRotation(DirectX::XMMATRIX rotation);
 	void resetRootWorldTransform();
 	
+	void setDpiScale(int scale, TargetChains selectChain);
 	void setClipChunkPercent(float ccp);
 	void setNumPlanes(int numPlanes); //TODO this could be changed to be smarter about where to peel from
 	void setLabels(bool on){labelsOn=on;}
@@ -276,13 +277,20 @@ private:
 
 	const SwapChainTarget* getSwapChain() const;
 
+	// Used internally by resizeViewport and init to set dpiScaled size of viewport
+	void setViewportSize(Vec<int> sizeIn, TargetChains selectChain);
+	const Vec<int>& getViewportSize(TargetChains selectChain) const;
+
 
 	//Member variables 
 	bool isDirty;
 	bool isRendering;
 
 	TargetChains lastChain;
+	// Percentage of resolution reduction relative to pixel size of window (e.g. 200% => 1920x1080 / 2.0 = 960x540)
+	int dpiScale[TargetChains::NumTC];
 	Vec<int> viewportSize[TargetChains::NumTC];
+	Vec<int> scaledViewSize[TargetChains::NumTC];
 
 	Vec<float> backgroundColor;
 
diff --git a/src/c/Messages/ViewMessages.cpp b/src/c/Messages/ViewMessages.cpp
index 45ea65c4de904a6c792ba327906293b9fb52e047..136fa713e8172847396499bc010a3b62c7770ef1 100644
--- a/src/c/Messages/ViewMessages.cpp
+++ b/src/c/Messages/ViewMessages.cpp
@@ -18,6 +18,18 @@ bool MessageSetWindowSize::process()
 }
 
 
+bool MessageSetDpiScale::process()
+{
+	if ( !gRenderer )
+		return false;
+
+	gRenderer->setDpiScale(scale, TargetChains::Screen);
+	gRenderer->forceUpdate();
+
+	return true;
+}
+
+
 
 bool MessageResetView::process()
 {
diff --git a/src/c/Messages/ViewMessages.h b/src/c/Messages/ViewMessages.h
index a9223a0710a3787fc70630f919bbe2bb9f3b6082..f5c2b381dedb44a6594df3a5390bbf07b7c7afd5 100644
--- a/src/c/Messages/ViewMessages.h
+++ b/src/c/Messages/ViewMessages.h
@@ -20,6 +20,19 @@ private:
 	int height;
 };
 
+class MessageSetDpiScale : public Message
+{
+public:
+
+	MessageSetDpiScale(int scale) : scale(scale) {}
+
+protected:
+	virtual bool process();
+
+private:
+	int scale;
+};
+
 
 class MessageResetView: public Message
 {
diff --git a/src/c/Mex/CommandList.h b/src/c/Mex/CommandList.h
index fc24419e7feabbf8933922c6132af4739fe15f79..7fda97d889de6be9b2939999ac0a5f432cdfc2d2 100644
--- a/src/c/Mex/CommandList.h
+++ b/src/c/Mex/CommandList.h
@@ -60,6 +60,7 @@ DEF_MEX_COMMAND(SetBackgroundColor)
 DEF_MEX_COMMAND(SetBorderColor)
 DEF_MEX_COMMAND(SetCapturePath)
 DEF_MEX_COMMAND(SetCaptureSize)
+DEF_MEX_COMMAND(SetDpiScale)
 DEF_MEX_COMMAND(SetFrame)
 DEF_MEX_COMMAND(SetFrontClip)
 DEF_MEX_COMMAND(SetViewOrigin)
diff --git a/src/c/Mex/MexSetDpiScale.cpp b/src/c/Mex/MexSetDpiScale.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3e0792e92696c124301fc8939fce91e74ad945a0
--- /dev/null
+++ b/src/c/Mex/MexSetDpiScale.cpp
@@ -0,0 +1,30 @@
+#include "MexCommand.h"
+#include "Global/Globals.h"
+
+#include "Messages/ViewMessages.h"
+
+void MexSetDpiScale::execute(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) const
+{
+	int dpiScale = (int)mxGetScalar(prhs[0]);
+	gMsgQueueToDirectX.pushMessage(new MessageSetDpiScale(dpiScale));
+}
+
+std::string MexSetDpiScale::check(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) const
+{
+	if (nrhs != 1)
+		return "Invalid number of arguments";
+
+	return "";
+}
+
+void MexSetDpiScale::usage(std::vector<std::string>& outArgs, std::vector<std::string>& inArgs) const
+{
+	inArgs.push_back("scalePct");
+}
+
+void MexSetDpiScale::help(std::vector<std::string>& helpLines) const
+{
+	helpLines.push_back("This sets the amount to enlarge each window pixel (larger scale percentages improve render speed but can blur the rendering).");
+
+	helpLines.push_back("\tScalePct - The percentage to 'enlarge' each pixel in the window (default 150%).");
+}
diff --git a/src/c/d3dViewer.vcxproj b/src/c/d3dViewer.vcxproj
index be47c419eeed8252dfacea4323237c559b204c0b..7effa212e04a2a3e1d995dee8d0b6925c75f3d0b 100644
--- a/src/c/d3dViewer.vcxproj
+++ b/src/c/d3dViewer.vcxproj
@@ -112,6 +112,7 @@ copy "$(OutDir)$(ProjectName).dll" "$(ProjectDir)Mex.mexw64"</Command>
     <ClCompile Include="Mex\MexMoveCamera.cpp" />
     <ClCompile Include="Mex\MexSetBorderColor.cpp" />
     <ClCompile Include="Mex\MexSetCaptureSize.cpp" />
+    <ClCompile Include="Mex\MexSetDpiScale.cpp" />
     <ClCompile Include="Mex\MexSetFrontClip.cpp" />
     <ClCompile Include="Mex\MexSetWorldRotation.cpp" />
     <ClCompile Include="Mex\MexShowFrameNumber.cpp" />
diff --git a/src/c/d3dViewer.vcxproj.filters b/src/c/d3dViewer.vcxproj.filters
index b58df763deaf97e4dd60995cd1c8e4ef717c84e9..df3dcf88bc2e63d26b9e81226b06aaced1f78ade 100644
--- a/src/c/d3dViewer.vcxproj.filters
+++ b/src/c/d3dViewer.vcxproj.filters
@@ -163,6 +163,9 @@
     <ClCompile Include="Mex\MexSetCaptureSize.cpp">
       <Filter>Mex\Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Mex\MexSetDpiScale.cpp">
+      <Filter>Mex\Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Mex\MexCommand.h">