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 OswaldHurlem · Oct 07, 2018 at 12:35 AM · shaderlightinggraphicsshaderlabsurface

How do I incorporate per-vertex lighting data into a surface shader?

Context

I am working on a game for modern PCs but which has stylized graphics somewhat reminiscent of older 3D games. One goal for my team is to perform rendering which computes lighting on a per-vertex basis, but which leverages Unity's Global Illumination, baked lights, etc. I want to write this as a surface shader, and as a starting point, I've written one which exposes most of the opportunities for customization. There's custom per-vertex data, a custom lighting model, and a custom function to return the final color of a shaded surface.

https://hastebin.com/cakodidinu.cs

One way to accomplish my visual goal might be to compute the UnityGI value on a per-vertex basis, pass that into the Lighting Model, and use these per-vertex GI values in lieu of the per-pixel values provided. This would create a very artifact-heavy look which varies depending on how detailed the geometry is. That's something that would be good for this game.

 struct custom_per_vert_data {
     // Other fields like UVs
     UnityGI vertexInterpolatedGI;
 };

 struct custom_surface_output { /* Albedo, Normal, etc */ };

 void CustomVert(inout custom_input_data v, out custom_per_vert_data o)
 {
     // Assign other fields
     o.vertexInterpolatedGI = GET_GI_AT_VERTEX(v);
 }

 void CustomSurface(custom_per_vert_data v, inout custom_surface_output o)
 {
     o = GET_SURFACE_PROPERTIES(/* UVs and such from v */);
 }

 half4 LightingCustomModel(custom_surface_output s, custom_per_vert_data v, float3 viewDir, UnityGI gi)
 {
     // Ignore gi param as it is not per-vertex
     return PerformSomewhatStandardLighting(s, viewDir, v.vertexInterpolatedGI);
 }

However, this doesn't work because the function signature for custom lighting models cannot have the custom_per_vert_data parameter. I'll have to use a less elegant solution instead.


Question

What is the best way to incorporate per-vertex lighting data into a surface shader? Something as close to the above "ideal" solution would be nice. I have identified two options, though there may be others.


The first solution is to transport the per-vertex lighting data to the lighting model function via fields in the custom_surface_output struct.

 struct small_light_properties { /* Color, maybe one other field */ }

 struct custom_per_vert_data {
     // Other fields like UVs
     small_light_properties vertexLight;
 };

 struct surface_properties { /*Albedo, Normal, Etc*/ }

 struct custom_surface_output
 {
     surface_properties surfaceProperties;
     UnityGI vertexLight;
 };

 void CustomVert(inout custom_input_data v, out custom_per_vert_data o)
 {
     // Assign other fields like UVs
     o.vertexLight = GET_GI_AT_VERTEX(v);
 }
 
 void CustomSurface(custom_per_vert_data v, inout custom_surface_output o)
 {
     o.surfaceProperties = GET_SURFACE_PROPERTIES(/* UVs and such from v */);
     o.vertexLight = v.vertexLight;
 }

 half4 LightingCustomModel(custom_surface_output s, float3 viewDir, UnityGI gi)
 {
     // gi paramter is per-pixel and is ignored
     return PerformLessStandardLighting(s.surfaceProperties, viewDir, s.vertexLight);
 }

This isn't great because it makes custom_surface_output -- a struct which is ostensibly just for surface-related data -- also carry lighting-related data. I'm not sure what the consequences of this would be. Additionally, the number of interpolators allowed in custom_surface_output is limited by Shader Model 3.0 -- this means I can't have all the GI-related data in it.


Another solution is the compute the lighting in the CustomColor function, which executes last. The lighting model then only serves to pass forward the view direction.

 struct small_light_properties { /* Color, maybe one other field */ }

 struct custom_per_vert_data {
     // Other fields like UVs
     small_light_properties vertexLight;
 };

 struct surface_properties { /*Albedo, Normal, Etc*/ }

 struct custom_surface_output
 {
     surface_properties surfaceProperties;
 };

 void CustomVert(inout custom_input_data v, out custom_per_vert_data o)
 {
     // Assign other fields like UVs
     o.vertexLight = GET_LIGHT_AT_VERT(v);
 }

 void CustomSurface(custom_per_vert_data v, inout custom_surface_output o)
 {
     o.surfaceProperties = GET_SURFACE_PROPERTIES(/* UVs and such from v */);
 }

 half4 LightingCustomModel(custom_surface_output s, float3 viewDir, UnityGI gi)
 {
     return viewDir;
 }

 void CustomColor(custom_per_vert_data v, custom_surface_output o, inout fixed4 colorFromLightingModel)
 {
     half4 viewDir = colorFromLightingModel;
     color = PerformLessStandardLighting(s.surface_properties, viewDir, v.vertexLight);
 }


The downsides to this is that it makes it so that the lighting model is totally phony... again I'm not sure what the ramifications of this are.


Anyway, I'm interested to hear which of these solutions is better, and if there's another one I haven't thought of.

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

0 Replies

· Add your reply
  • Sort: 

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

181 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 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 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 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 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 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 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 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 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 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 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 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 avatar image

Related Questions

Implementing Custom Vertex Lighting Shader 1 Answer

How to access another sprite's texture from a 2D shader 0 Answers

How to lighten/darken a greyscale shader 0 Answers

Would learning some GLSL help with Unity Shading? 1 Answer

Transparent objects and shadow 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