Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by sean · Sep 09, 2011 at 09:56 PM · renderviewfrustrumselective

Asymmetric view frusta / selective region rendering

There's another question on this, but it seems to be locked down so I can't investigate/confirm. Does anyone have a good technique for telling the render pipeline to only bother with a certain subset of a viewport? Not changing the viewport rect, or changing the field of view, but literally saying "make like you're going to render this whole region, but really, I'm only going to use these pixels of it, so don't bother with the rest"? E.g., due to view frustum geometry, if you're rendering say, a 60-degree FoV to a 100x100 rectangle, there's a difference between the image you get if you take the rightmost 25 columns of that render vs setting up a new camera that's 15 degrees wide and pointing it 22.5 degrees right to render a 25x100 image. I want to get the former. I guess an equivalent technical question is how to make an asymmetric view frustum equivalent to a particular off-center wedge of a standard view frustum. Without having my CG theory fresh enough in my head to know offhand how to construct the right replacement view matrix manually, I'm wondering if anyone here has tried similar effects or has any pointers.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by sean · Sep 12, 2011 at 07:48 PM

http://unity3d.com/support/documentation/ScriptReference/Camera-projectionMatrix.html has, surprise surprise, an example of kinda-close-to-pretty-much the effect I was going for. Building my own off-axis frustum of a part of the screen does not appear to line up precisely with the stock matrix of a fullscreen camera, but I can build two cameras with custom disjoint adjacent off-axis frusta and have them align seamlessly. Just take the provided off-axis projection matrix builder (included here in case the unity docs ever change)

// Set an off-center projection, where perspective's vanishing // point is not necessarily in the center of the screen. // // left/right/top/bottom define near plane size, i.e. // how offset are corners of camera's near plane. // Tweak the values and you can see camera's frustum change.

@script ExecuteInEditMode

var left : float = -0.2; var right : float = 0.2; var top : float = 0.2; var bottom : float = -0.2;

function LateUpdate () { var cam : Camera = camera; var m : Matrix4x4 = PerspectiveOffCenter( left, right, bottom, top, cam.nearClipPlane, cam.farClipPlane ); cam.projectionMatrix = m; }

static function PerspectiveOffCenter( left : float, right : float, bottom : float, top : float, near : float, far : float ) : Matrix4x4 { var x : float = (2.0 near) / (right - left); var y : float = (2.0 near) / (top - bottom); var a : float = (right + left) / (right - left); var b : float = (top + bottom) / (top - bottom); var c : float = -(far + near) / (far - near); var d : float = -(2.0 far near) / (far - near); var e : float = -1.0;

var m : Matrix4x4; m[0,0] = x; m[0,1] = 0; m[0,2] = a; m[0,3] = 0; m[1,0] = 0; m[1,1] = y; m[1,2] = b; m[1,3] = 0; m[2,0] = 0; m[2,1] = 0; m[2,2] = c; m[2,3] = d; m[3,0] = 0; m[3,1] = 0; m[3,2] = e; m[3,3] = 0; return m; }

and patch in your own code to grab the camera's default near/far/aspect/FoV and do up the trig for where to place the top/bottom/left/right.

Edit: actually, this works ~perfectly~ when I remember that aspect ratio multiplies the linear viewport measurement rather than the angular field of view facepalm

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by sean · Sep 12, 2011 at 02:48 PM

If I promote this answer later, that'll mean it's working for me, but for now it's just a lead- http://forums.create.msdn.com/forums/p/7821/41594.aspx is answering the same question, and I'm pretty sure I understand the math the thread concludes with:

asymmetricFrustumMatrix = perspectiveProjectionMatrix *dot* fustrumAlteredMatrix

where fustrumAlteredMatrix = |1 0 A 0| |0 1 B 0| |0 0 1 0| |0 0 0 1|

A = xRight + xleft / -2znear (= ((xRight+xLeft)/2)/(-zNear) = frustumCenterXAtZNear/-zNear) B = yTop + yBottom / -2znear (= ((yTop+yBottom)/2)/(-zNear) = frustumCenterYAtZNear/-zNear)

Basically saying that on the x and y axes, take the existing perspective coordinate and set it to itself+f(z) where f(z) is just the per-unit-z distance off-center of the desired skew axis at the nearplane (draw it out on paper as triangles; it makes sense). Iirc, you can retrieve the camera's projection matrix in Unity and set it manually, so it should be possible to let Unity do the projection and then put the matrix, skew it, and drop it back in.

Edit: This theory does hold some water. It's a little finnicky to get the numbers right, but it should be good for some distortion effects. It does not, however, do precisely what I want.

Edit 2: Upon further tweaking, the skew approach also works perfectly, it's just a little mind-bendy to work out how much to skew by for horizontal vs vertical offset regions.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

2 People are following this question.

avatar image avatar image

Related Questions

Particles only rendering in Sceneview from an angle and never in game 1 Answer

How can I know if a gameObject is 'seen' by a particular camera? 11 Answers

If I script something to render, can it be frustrum culled? 2 Answers

Screen position out of view frustum error? 2 Answers

How to draw an outline of a camera view along a path ? 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges