Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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 theFrenchDutch · Feb 08, 2015 at 02:30 AM · shadowsgrassgeometry shader

Receiving shadows on grass (geometry shader)

Hello !

We are making a custom terrain engine using Unity for a school project, and have started using geometry shaders to display trees and grass as flat billboards.

After some research we found out how to make Unity cast shadows on a custom shader without a surface shader (since we have a vertex / geometry / fragment shader setup for both trees and grass), thanks to this post : link text This post was also really helpful to get the shadow caster to work with a geometry shader : link text

So what we have is a normal pass to render the tree or grass billboard, and then a second pass (ShadowCaster pass) that does the same thing but with V2F_SHADOW_CASTER; in our structs and SHADOW_CASTER_FRAGMENT(input) in the fragment shader instead of returning a color. This works : it makes the trees cast a shadow that the ground can receive.

However what we can't figure out is how to get a Shadow Collector pass to work with our geometry shaders, and after a LOT of research it seems that no one has ever tried this or posted about it. What we'd like to do is have the grass receive shadows from trees and the terrain (to have great-looking woods !)

Simply adding a third pass exactly like what the code in the link does doesn't work, and we can't get a third pass to work doing the same thing as the normal pass (with geometry shader and everything) combined with the V2F_SHADOW_COLLECTOR; in structs and TRANSFER_SHADOW_COLLECTOR() in the shader programs.

This is the shadow collector pass we are trying to get to work :

     // Pass to render grass as a shadow collector
             Pass {
                 Name "ShadowCollector"
                 Tags { "Queue" = "Geometry" "RenderType"= "Overlay" "LightMode" = "ShadowCollector"}
                 Fog {Mode Off}
                 LOD 200
     
                 ZWrite On ZTest LEqual Cull Off
          
                 Offset 1, 1
      
                 CGPROGRAM
                 #pragma target 5.0
                 #pragma vertex COLLECTOR_VS_Main
                 #pragma fragment COLLECTOR_FS_Main
                 #pragma geometry COLLECTOR_GS_Main
                 #pragma multi_compile_shadowcollector
                 #pragma fragmentoption ARB_precision_hint_fastest
                 #define SHADOW_COLLECTOR_PASS
                 #include "UnityCG.cginc"
     
                 // **************************************************************
                 // Vars                                                            *
                 // **************************************************************
     
                 float _SizeH;
                 float _SizeL;
                 float growUp;
                 float4x4 _VP;
                 sampler2D  _SpriteTex1;
                 uniform float maxDist;
                 uniform float3 camPos;    
                 uniform float4 _LightColor0;
     
     
                 // **************************************************************
                 // Data structures                                                *
                 // **************************************************************    
                            
                 struct COLLECTOR_GS_INPUT
                 {
                     V2F_SHADOW_COLLECTOR;
                     ...other stuff related to size and rotation of the grass
                     
                 };
                 
                 struct COLLECTOR_FS_INPUT
                 {
                     V2F_SHADOW_COLLECTOR;
                     float2  tex1    : TEXCOORD9;
                 };
     
     
                 // **************************************************************
                 // Shader Programs                                                *
                 // **************************************************************
      
                 // Vertex Shader ------------------------------------------------
                 COLLECTOR_GS_INPUT COLLECTOR_VS_Main(appdata_base v)
                 {
                     COLLECTOR_GS_INPUT output = (COLLECTOR_GS_INPUT)0;
                     TRANSFER_SHADOW_COLLECTOR(output)
                     ...other stuff
                     return output;
                 }
     
                 // Geometry Shader -----------------------------------------------------
                 [maxvertexcount(4)]
                 void COLLECTOR_GS_Main(point COLLECTOR_GS_INPUT p[1], inout TriangleStream<COLLECTOR_FS_INPUT> triStream)
                 {
 
 stuff to create the four vertices of the quad for the billboard :
                     float3 up = float3(0, 1, 0);
                     float3 rot = float3(p[0].rotX, 0, p[0].rotY);
                     rot = normalize(rot);
                     float3 right = cross(up, rot);
     
                     _SizeH = p[0].size;
                     _SizeL = p[0].size;
                     float halfSy = 0.5f * _SizeH;
                     float halfSx = 0.5f * _SizeL;
     
     
                     float4 v[4];
     
                     p[0].pos.y -= growUp;
                     v[0] = float4(p[0].pos + halfSx * right, 1.0f);
                     v[1] = float4(p[0].pos + halfSx * right + _SizeH * up, 1.0f);
                     v[2] = float4(p[0].pos - halfSx * right, 1.0f);
                     v[3] = float4(p[0].pos - halfSx * right + _SizeH * up, 1.0f);
     
     
                    
                     float4x4 vp = mul(UNITY_MATRIX_MVP, _World2Object);
 
 ...the interesting bit :
                     COLLECTOR_FS_INPUT pIn;
                     UNITY_INITIALIZE_OUTPUT(COLLECTOR_FS_INPUT, pIn);
                     TRANSFER_SHADOW_COLLECTOR(pIn)
     
                     pIn.pos = mul(vp, v[0]);
                     pIn.tex1 = float2(1.0f, 0.0f);                
                     triStream.Append(pIn);
     
                     pIn.pos =  mul(vp, v[1]);
                     pIn.tex1 = float2(1.0f, 1.0f);
                     triStream.Append(pIn);
     
                     pIn.pos =  mul(vp, v[2]);
                     pIn.tex1 = float2(0.0f, 0.0f);
                     triStream.Append(pIn);
     
                     pIn.pos =  mul(vp, v[3]);
                     pIn.tex1 = float2(0.0f, 1.0f);
                     triStream.Append(pIn);
     
                 }
     
      
                 // Fragment Shader -----------------------------------------------
                 fixed4 COLLECTOR_FS_Main(COLLECTOR_FS_INPUT input) : COLOR
                 {
     
                     SHADOW_COLLECTOR_FRAGMENT(input)
                     
                 }
     
                 ENDCG
             }

With this, we don't get any immediate error when launching the scene but when grass starts to appear (it seems that weirdly the shader only compiles at runtime) we get this error on the TRANSFER_SHADOW_COLLECTOR(pIn) (at line 117 in the code sample) in the geometry shader :

 Shader error in 'Grass/GrassRendering ': invalid subscript 'vertex' 'mul': no matching 2 parameter intrinsic function; Possible intrinsic functions are: mul(float|half|double|min10float|min16float|int|uint|min12int|min16int|min16uint, float|half|double|min10float|min16float|int|uint|min12int|min16int|min16uint) mul(float|half|double|min10float|min16float|int|uint|min12int|min16int|min16uint, floatK|halfK|doubleK|min10floatK|min16floatK|intK|uintK|min12intK|min16intK|min16uintK) mul(float|half|double|min10float|min16float|int|uint|min12int|min16int|min16uint, floatLxK|halfLxK|doubleLxK|min10floatLxK|min16floatLxK|intLxK|uintLxK|min12intLxK|min16intLxK|min16uintLxK) mul(floatM|halfM|doubleM|min10floatM|min16floatM|intM|uintM|min12intM|min16intM|min16uintM, float|half|double|min10float|min16float|int|uint|min12int|min16int|min16uint) mul(floatM|halfM|doubleM|min10floatM|min16floatM|intM|uintM|min12intM|min16intM|min16uintM, floatM|halfM|doubleM|min10floatM|min16floatM|intM|uintM|min12intM|min16intM|min16uintM)


Being still quite new to shaders, we can't understand what the error means and what can be done about it... Also these are Unity functions that don't seem to be documented anywhere, did we miss it maybe ?

So our question is, how would one do to receive shadows on geometry shaded billboards ? And if this is the correct way to do it, can someone help us understandind why it doesn't work ?

Thanks a lot guys, I know this is a long post and I'd very grateful towards anyone trying to help :)

Comment
Add comment · Show 1
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 nikomikulicic · May 14, 2015 at 08:48 PM 0
Share

It has been 7 years now. Have you had any progress with this? :D I'm quite interested in how did you do any of the stuff you mentioned. I'm building something like a terrain engine for my college project and now I'm successfully creating grass as billboards in geometry shader. However, I have no idea how to make it cast or receive shadows.

If you have any update on this, I would be very thankful if you could share.

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by sshinderman · Dec 23, 2015 at 04:27 PM

ack! the backspace key just deleted my answer. the gist of it is that a chain of macros (in AutoLight.cginc) eventually look for something like v.vertex -- so make sure the appdata_base v is the incoming parameter (or somehow there's a variable v with a member .vertex). The macro should be designed so that can be passed in -- it's pretty brittle.

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 CorvusGameLab · Apr 10 at 01:35 PM

Hi, i made a grass shader with lots of features like player interaction or placing the grass only on a certain height. If you are interested you can download it here: https://www.youtube.com/watch?v=st-EjyeObEM

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

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Terrain Being Buggy 0 Answers

Grass in Geometry/Compute Shader 2 Answers

Using shadow texture to recieve shadows (on grass) 1 Answer

I need swaying, self-shadowing, ultra-realistic grass 0 Answers

Grass can not receive shadows from pointlight? 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