Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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
1
Question by Ben Humphreys · May 02, 2013 at 09:47 AM · shaderscreenfragment

Getting a pixel's screen-space coordinate in a fragment shader

I'm trying to write a shader that works using screen-space pixels. Namely, something akin to a horizontal fade out across each object.

Is there a way to access the pixel's screen-space coordinate from within a fragment shader?

This documentation page's Detail Texture in Screen Space is pretty much what I want, but it uses Unity Surface Shaders, and I can't access clip() from there, and I need it for my shader.

Any ideas?

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

1 Reply

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

Answer by CHPedersen · May 02, 2013 at 09:57 AM

You're in luck! This is thankfully simple. :)

After a vertex has been multiplied by the modelviewprojection matrix (globally accessible in shaders as "UNITY_MATRIX_MVP"), its coordinates are in clip space. Clip space's coordinates range from (-1,-1,-1) to (1,1,1) in OpenGL, where the z coordinate is the depth value that gets written to the depth buffer. The range of z is 0 and 1 in Direct3D, but you don't have to care about this discrepancy, because for pixel positions, you're only interested in the x and y coordinates.

The center of clip space is the center of the screen, i.e. x = -1 is the left side of the screen and x = 1 is the right, with y = -1 the bottom and y = 1 the top. So all you have to do is save the clip space vertex coordinate using one of the texture channels in your vertex shader, then access the same texture channel in the fragment shader's input parameters. Then the rasterizer will have interpolated the pixel's clip space coordinate for you.

Using that, you can convert the pixel clip space coordinate to screen space using the screen resolution. This other question has the code samples and the conversion formula, saving me the trouble of writing it here:

http://answers.unity3d.com/questions/39803/how-to-get-an-objects-position-in-screen-space-in.html

Comment
Add comment · Show 4 · 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 whydoidoit · May 02, 2013 at 09:58 AM 1
Share

A much more complete answer ;)

avatar image Ben Humphreys · May 02, 2013 at 10:22 AM 0
Share

Thanks for the answer!

All the tutorials I've seen so far gloss over what the $$anonymous$$VP multiplication was Actually doing in terms of numbers.

I read the linked formula, and I've tried to understand what it means by writing it out: http://pastie.org/7752194

However the left-right black-white gradient only stretches the centre of the screen, not all the way across. Could you tell me why? Shouldn't the X value range between 0 and 1 across the whole screen?

avatar image CHPedersen · May 02, 2013 at 11:06 AM 3
Share

Okay... Here's some background on the $$anonymous$$VP matrix. I decided to write it out in the hope it would clear up what the other sites you've visited glossed over.

The $$anonymous$$VP matrix is a concatenated series of transforms between multiple coordinate systems. First, there's the model matrix, which sends a point from the object coordinate system ('local' coordinates in Unity scripts) to the world coordinate system. After that, there is the viewing matrix (made up by the camera's position and rotation) which sends points from the world coordinate system to the camera's coordinate system. Finally, the points are subjected to a projection transform that simulates the real-world phenomenon that objects appear smaller with distance. This last transform (which is not affine if the projection matrix is perspective) turns the camera's frustum into a cube, and it is this final coordinate system which is called "clip space". The projection matrix is the only difference between a perspective camera and an orthogonal camera. An orthogonal camera has another projection matrix whose projection is affine - it preserves parallel lines. After this, dividing all (4D) point coordinates with their fourth, homogeneous coordinate, w, is called 'perspective division' and is what makes all vector components lie within -1 to 1, hence the name 'normalized device coordinates'.

Rather than perfor$$anonymous$$g each step separately on each vertex in succession, it's more efficient to concatenate (multiply together to one) the three matrices and send the result as a single matrix to the graphics card. This concatenated matrix is thus the $$anonymous$$odel-View-Projection ($$anonymous$$VP) matrix. Our shaders then perform all 3 transforms in one go using that.

x ranges from -1 to 1 in normalized divice coordinates, but gets converted to the range 0 - screen_width by doing 0.5*(x+1)*screen_width (same for y, with height).

avatar image CHPedersen · May 02, 2013 at 11:08 AM 1
Share

By the way, I learned about these transforms by reading NVidia's book "The Cg Tutorial". It's available online, and these transforms are explained in greater detail in chapter 4:

http://http.developer.nvidia.com/CgTutorial/cg_tutorial_chapter04.html

It's a short chapter and well worth the read.

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

15 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Writing from fragment shader into 3D render texture 1 Answer

Shader that renders fragment behind 0 Answers

Need help with this Shader; camera Solid color is being rendered on skybox. 0 Answers

Transparent grid shader issue 1 Answer

How to mask gameObject by gameObject 4 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