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
3
Question by sean · Feb 17, 2012 at 08:07 PM · shadercgmatrixglslinverse

shader inverse(float4x4) function

Is there a way to successfully use the standard CG inverse(float4x4) / GLSL inverse(mat4) function in a Unity shader? When used in my surface shader, compilation chokes saying GLSL can't find a valid overload:

 GLSL vertex shader: ERROR: 0:356: 'inverse' : no matching overloaded function

When I

 #pragma exclude_renderers gles

it compiles, but as soon as I actually patch the code into anything that gets executed (in this case by putting the '#pragma vertex:vert' into the surface shader to run my custom vertex pre-shader), it breaks again and reports inverse is an undefined variable

 Program 'vert_surf', undefined variable "inverse"

And before you ask, yes, I really do need to take an inverse here, and no, I can't guarantee offhand that the matrix will be simple enough to use any of the short-of-really-doing-the-proper-inverse hacks. The only alternative might be if I could couple my own complete vertex shader with a standard surface-shader rather than performing creative pre-vertex-shader-proper math, but I have seen no examples of that being viable.

Cg inverse() def: http://http.developer.nvidia.com/Cg/inverse.html

GLSL inverse() def: http://www.opengl.org/sdk/docs/manglsl/

Comment
Add comment · Show 4
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 Owen-Reynolds · Feb 22, 2012 at 04:12 PM 0
Share

You can't just precompute it and pass it in as a, ummm, uniform? You really have a different matrix for each vertex?

avatar image sean · Feb 22, 2012 at 04:20 PM 0
Share

Decent point- for each vertex, no, but for each frame, yes. And the base matrix (long story short- it's the $$anonymous$$VP, but precisely what I'm doing is under NDA) is already in there, so crunching its inverse out in script every frame just to pass it to the shader which has access to the original matrix and should be able to take an inverse seems like equally much overkill to writing an inverse function in the shader.

avatar image Owen-Reynolds · Feb 23, 2012 at 01:45 AM 0
Share

I just looked -- about 300 math ops (multiplies and adds.) Not too bad, but not great. And Unity doesn't provide that one. I'd give it a try and see how fast it runs. Can you usually use a short-cut, toss in an "if $$anonymous$$VP hasn't changed..."

avatar image sean · Feb 23, 2012 at 03:16 PM 0
Share

$$anonymous$$VP changes every frame, unfortunately. Crazy custom effect going on here. I've implemented my own inverse in two ways so far- if I'm doing less in the surface shader (e.g. basic diffuse/specular lighting), I can fit a fewer-lines/more-arithmetic-ops raw computation. I hit the cap on operations per shader on my card if I do that on e.g. a bumped-specular shader, though, in which case I have to build 16 3x3 submatrices and make a lot of deter$$anonymous$$ant() calls for the adjugate method proper.

2 Replies

· Add your reply
  • Sort: 
avatar image
7

Answer by DBN · Feb 16, 2014 at 09:12 PM

In case anyone else finds this question like I did, here's the function I ended up writing:

 float4x4 inverse(float4x4 input)
 {
     #define minor(a,b,c) determinant(float3x3(input.a, input.b, input.c))
     //determinant(float3x3(input._22_23_23, input._32_33_34, input._42_43_44))
     
     float4x4 cofactors = float4x4(
          minor(_22_23_24, _32_33_34, _42_43_44), 
         -minor(_21_23_24, _31_33_34, _41_43_44),
          minor(_21_22_24, _31_32_34, _41_42_44),
         -minor(_21_22_23, _31_32_33, _41_42_43),
         
         -minor(_12_13_14, _32_33_34, _42_43_44),
          minor(_11_13_14, _31_33_34, _41_43_44),
         -minor(_11_12_14, _31_32_34, _41_42_44),
          minor(_11_12_13, _31_32_33, _41_42_43),
         
          minor(_12_13_14, _22_23_24, _42_43_44),
         -minor(_11_13_14, _21_23_24, _41_43_44),
          minor(_11_12_14, _21_22_24, _41_42_44),
         -minor(_11_12_13, _21_22_23, _41_42_43),
         
         -minor(_12_13_14, _22_23_24, _32_33_34),
          minor(_11_13_14, _21_23_24, _31_33_34),
         -minor(_11_12_14, _21_22_24, _31_32_34),
          minor(_11_12_13, _21_22_23, _31_32_33)
     );
     #undef minor
     return transpose(cofactors) / determinant(input);
 }

Not too confident on the math or the speed but it worked for my needs. This code is released under the WTFPL license.

Comment
Add comment · Show 1 · 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 Aily · Apr 04, 2015 at 05:02 AM 0
Share

Thank you so much! This works ideal.

avatar image
0

Answer by sean · Feb 22, 2012 at 03:54 PM

As a stop-gap, determinant() seems to be usable, so it's possible to write a tedious but fairly straightforward adjugate-method inverse function. This can chew up GPU resources/instructions, though, so a way to get at the inverse() ops directly would still be welcome.

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

7 People are following this question.

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

Related Questions

Shardelab/CG shaders not working on iOS 1 Answer

How to force the compilation of a shader in Unity? 5 Answers

Cg Language incompatibility Desktop VS GLSL Android 0 Answers

How to prevent shader optimizations? 1 Answer

Grabpass refraction masking 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