Search Unity

[RELEASED] DirectX 11 Grass Shader

Discussion in 'Assets and Asset Store' started by Nonakesh, Aug 17, 2015.

  1. Abnormalia_

    Abnormalia_

    Joined:
    Jul 23, 2013
    Posts:
    128
    Works really well for our game in VR:
     
    Last edited: Dec 26, 2016
  2. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,358
    Cool, I hope to make a forest scene for our MP Shooter, might be possible then, We use baked lighting (mixed mode directional light) and forward renderer however, might create problems with this shader? Need to look into that too

    edit: We use Tims guns too :D



    edit: The magazine interaction point is not rigged in above clip
     
  3. Abnormalia_

    Abnormalia_

    Joined:
    Jul 23, 2013
    Posts:
    128
    Well done! For our game this is way too realistic but personally I love it! Weill keep on eye.

    As for level its really huge and we used many levels of optimizations there. No bake lights. Forward render. some unity very hardcore optimizations and custom shaders + our own solutions. Run well on Ultra setting on 1070. Will do more optimizations by release. Most resources go to water renderer. With DX11 grass you can find really good balance between visuals and performance.
     
    Nonakesh and AndersMalmgren like this.
  4. Nonakesh

    Nonakesh

    Joined:
    Aug 27, 2011
    Posts:
    576
    The grass should not be set as static, for animated objects that wouldn't make much sense anyways. Then it should not interfere with the lightmapper at all. The shader works in both deferred and forward rendering mode. (To be precise, right now it only supports forward rendering, but Unity's deferred renderer can handle forward rendered objects)
     
  5. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,358
    Cool, and I guess it works with the mixed mode directional light without problem? It casts shadows on the grass?
     
  6. Nonakesh

    Nonakesh

    Joined:
    Aug 27, 2011
    Posts:
    576
    Yes, the grass supports recieving and casting shadows, but keep in mind that casting shadows can increase the performance cost significantly. (Receiving shouldn't increase the cost by too much)
     
  7. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,358
    I guess most important is that it receives shadow from characters and static environment. Thanks for fast responses
     
  8. Nonakesh

    Nonakesh

    Joined:
    Aug 27, 2011
    Posts:
    576
    Hey, again sorry about the delay, I've finally had the time to look at the problem.
    It actually really easy to fix, the problem is that the resolution of the displacement camera is too low, which causes the small jittering artifacts. To fix it, select the displacement camera, double click the render texture variable. Now you should see the RenderTexture settings, just increase the resolution to a power of two, like 1024x1024.
    After saving the scene there can be a problem where all of the grass is flattened down, just reload the scene and this will be fixed.
     
  9. JaredMerritt

    JaredMerritt

    Joined:
    Oct 8, 2012
    Posts:
    53
    Can you use PBR textures on grass? I have some bespoke PBR ready mapped grass, but I'd like to know if this asset supports them. Also, what does this asset have in terms of performance improvements (batching etc)?
     
  10. Nonakesh

    Nonakesh

    Joined:
    Aug 27, 2011
    Posts:
    576
    The grass only supports a single color texture, but you can set specularity and roughness for each grass type. There is no normal map support, it honestly wouldn't make much sense with how it is rendered right now, I'm using quite a few strange lighting calculations that would make it difficult. (This might be added in a future patch)
    What textures do you need? Specularity and roughness textures could be added relatively easily, but they would increase performance consumption.

    There is honestly not much need for batching or something like that, well it also wouldn't really be possible to use it with the shader. The shader has one draw call (+ the draw calls per light of course), everything happens on the GPU anyways. Are you planning something specific so you'd require anything like that?
     
  11. facundogalella

    facundogalella

    Joined:
    Mar 5, 2016
    Posts:
    59
    Looks amazing!

    Sorry if you answered this question before, but I can use this grass in my terrain objects? I mean, I'm creating my terrains outside of Unity in other softwares and importing this in a fbx file. I can use this grass in this objects?

    I don't want use the terrain of Unity, because not useful for my project.
     
  12. Nonakesh

    Nonakesh

    Joined:
    Aug 27, 2011
    Posts:
    576
    Yes, in my experience it works even better than Unity's terrain. The only thing you have to consider is that the polygon density of the terrain should be the same everywhere on the terrain, ideally a perfect grid. If you don't do this, the grass will have different densities on different parts of the terrain.
     
    facundogalella likes this.
  13. Genq

    Genq

    Joined:
    Feb 22, 2016
    Posts:
    6
    Hi I bought your shader about two weeks ago and have been trying very hard (and failing) to set a min burn distance so that the grass can only be burned to a set height from a displacement trail render and cannot figure it out any advice is helpful.
     
  14. Nonakesh

    Nonakesh

    Joined:
    Aug 27, 2011
    Posts:
    576
    Am I understanding this correctly: You want the grass to burn down, but leave small grass stumps at the bottom, so the grass doesn't disappear completely?
     
  15. Genq

    Genq

    Joined:
    Feb 22, 2016
    Posts:
    6
    Yes exactly.
     
  16. Nonakesh

    Nonakesh

    Joined:
    Aug 27, 2011
    Posts:
    576
    I haven't tested this, but I will probably add this as a feature in a future patch.

    Open the file GrassGeom.cginc go to Line 354 and add this:
    Code (Shader):
    1. burnFactor = max(burnFactor, 0.1);
    You can replace the number with any value you want.
     
  17. Tallath

    Tallath

    Joined:
    Jan 11, 2013
    Posts:
    1
    Apologize in advanced if this is a dumb question, but would this shader allow for say, a lawn mower, to cut a path through the grass and have all the blades nice and tidy in a certain area?
     
  18. Nonakesh

    Nonakesh

    Joined:
    Aug 27, 2011
    Posts:
    576
    Yeah, it does! You could for example use the burn feature, but set the burn color to white (no change), so only the grass length is changed. Combine that with a particle effect and you're done.
     
  19. Genq

    Genq

    Joined:
    Feb 22, 2016
    Posts:
    6
    Thanks for that but I already was able to get these results when I redrive over the grass it burns it again.
     

    Attached Files:

  20. Nonakesh

    Nonakesh

    Joined:
    Aug 27, 2011
    Posts:
    576
    Looks like you guys are trying to do the same thing here! I actually posted another answer for you, but here it is again:

    I haven't tested this, but I will probably add this as a feature in a future patch.

    Open the file GrassGeom.cginc go to Line 354 and add this:
    Code (Shader):
    1. burnFactor = max(burnFactor, 0.1);
    You can replace the number with any value you want.
     
  21. Genq

    Genq

    Joined:
    Feb 22, 2016
    Posts:
    6

    No what I am saying and showed in attachment is that it doesn't work quite as its supposed to when you redrive over the grass it burns it again which you can already accomplish with the burn strength variable and by making the burn texture less red.
     
  22. Nonakesh

    Nonakesh

    Joined:
    Aug 27, 2011
    Posts:
    576
    Oh right, if you've done the change in the code, you have to set the burn strength higher. The code I posted only sets a minimum burn rate, above that it still works as usual. So either set the number in the code to something higher, like 0.25, or increase the burn rate of the trail renderer. I hope that works, as I said I still wasn't able to test this myself.
     
    Tallath likes this.
  23. Genq

    Genq

    Joined:
    Feb 22, 2016
    Posts:
    6
    Awesome worked correctly exactly what I needed.
     

    Attached Files:

    Tallath and Nonakesh like this.
  24. VisualPath

    VisualPath

    Joined:
    Oct 20, 2016
    Posts:
    2
    Hello, one quick question.
    By using this grass, will my game require DirectX 11 for my players to be able to play it / see the grass? Noob question :)
     
  25. Nonakesh

    Nonakesh

    Joined:
    Aug 27, 2011
    Posts:
    576
    Yes, the shader requires DirectX 11 features. In theory it should also work perfectly with OpenGL, but there are some bugs in the shader compiler that prevent that. (Well, it kind of runs in OpenGL core, but it's really buggy)

    In other words, right now it only works on these platforms (more may be supported in the future):
    • Windows with DirectX 11
    • Playstation 4
    • XBox One
     
  26. bpears

    bpears

    Joined:
    Aug 23, 2012
    Posts:
    249
    Docs say that this is known bug for improve view above option, but I still get it with disabled but not as much. Tested with softness all the way down, still happens. I also tried the resize bounds script. EDIT: not intersecting issue, just renders parts white sometimes like theres a backface coming through or something?

    asdf.JPG

    Would it be possible to get it so that the grass rotates as the camera goes up? I did this in a billboard shader using Unity_Matrix_T_MV so it would always rotate at the root, no matter camera view, it would follow it.
     
    Last edited: Jan 30, 2017
  27. bpears

    bpears

    Joined:
    Aug 23, 2012
    Posts:
    249
    Also, for the trail renderer, how do we make it so it doesn't render the normal map texture and just creates the displacement trail? And how do we use like a decal ?

    Really loving this asset btw, great work. I came back to it from a while back and it seems more intuitive now.
     
  28. bpears

    bpears

    Joined:
    Aug 23, 2012
    Posts:
    249
    Solved (maybe not the best way) the white/cull/cutout issue by doing this in GrassDefinitionsAndFunctions:


    Code (CSharp):
    1. inline float3 getCameraPos()
    2. {
    3.     #ifdef UNITY_PASS_SHADOWCASTER
    4.         return mul(inverse(UNITY_MATRIX_V), float4(0, 0, 0, 1)).xyz;
    5.     #else
    6.         //return _WorldSpaceCameraPos.xyz;
    7.         return mul(inverse(UNITY_MATRIX_V), float4(0, 0, 0, 1)).xyz;
    8.     #endif
    9. }
    So, _WorldSpaceCameraPos.xyz; must not be working in a good way. Hope this helps!

    And I'm using Deffered rendering if that matters.
     
  29. Nonakesh

    Nonakesh

    Joined:
    Aug 27, 2011
    Posts:
    576
    I've never actually seen that bug! When exactly does it happen? Also what Unity version are you on?

    Thanks, I've been trying to make it more intuitive, but I'll probably have to make a few advanced tutorials for the grass displacement system. It's really powerful, but a bit unintuitive in my opinion (still better than the original displacement).

    All the displacement objects should be on a single layer, that layer shouldn't have anything but displacement objects on it (like the trail renderer). The displacement camera should only render this layer, while all other cameras shouldn't render it. You can even make the layer invisible in the editor, there's a layer selection menu at the top right of the editor.

    Thanks for sharing your fix! The problem is that "inverse" is a really costly operation, so the shader may run slower now. Can you share a few more screenshots for the original problem? I can look at it myself next week!
     
  30. MaxWitsch

    MaxWitsch

    Joined:
    Jul 6, 2015
    Posts:
    114
    Hi, really nice work!!!!
    I Love the easy setup of the Shader and the ability to use it with the terrain.
    Nevertheless i faced a problem.
    And i wonder if anyone could fix it, give me a guide or a workaround.
    Problema.PNG
    As you can see i copied the terrain for the shader but as soon as the basemap color of the terrain blends in the Grass shader turns the terrain to a dark thing.

    I'm assuming it's probably because the shader has no basemap Pass.

    I would increase the distance for the basemap but if i do the whole thing gets crazy Expensive in performance.
    Any Ideas?

    Thanks in advance :)
     
  31. bpears

    bpears

    Joined:
    Aug 23, 2012
    Posts:
    249
    Using Unity 5.6.0b1 Pro. Linear lighting in deferred. I have cast shadows off. But still receiving shadows. This grass is a lifesaver.
     
  32. Nonakesh

    Nonakesh

    Joined:
    Aug 27, 2011
    Posts:
    576
    The shader doesn't have a basemap pass, to be honest I'm not even sure if it would be possible. I've kind of given up on making it work natively with Unity terrain, after a few sad attempts. I'll probably look into it again, but no promises, the system is a bit hard to work with in my opinion.

    Until then you could try a few workarounds: Instead of duplicating the terrain in the scene, duplicate it in the assets and put it at the same position as the other terrain. Now you can increase the basemap distance for the grass alone, while leaving the other terrain how it is. I've also heard that having duplicate terrain assets, instead of both linking to the same, can improve the performance in general (probably because Unity terrain is buggy or something like that).

    You could also try moving the grass downwards, until the basemap of the original terrain is above the grass terrain. I'm not really a fan of this one, but its a workaround. At least it doesn't add any performance cost.

    Too bad Unity terrain doesn't support just not rendering the basemap. I really hope they make a better system soon.
     
  33. Axis-Games

    Axis-Games

    Joined:
    Feb 12, 2014
    Posts:
    29
    Hey! Quick question. We are developing a football game, and we're looking at using a grass asset like this for our field grass. I couldn't tell from the description of the asset if or how we would be able to white add lines to the field grass. Is that something that could be done?

    I wasn't sure if it was possible to paint/put the grass over our existing field texture or if we could paint certain sections of your grass asset different colors.

    Thanks in advanced!

    We're currently just using a texture on a flat plane for our grass, similar to this:
     
  34. Nonakesh

    Nonakesh

    Joined:
    Aug 27, 2011
    Posts:
    576
    Yes, it's possible to use a color texture with the grass shader. You just put it in, like with a regular floor shader.
    But just as a warning, my shader might not be what you are looking for, if you are doing a football game. When you want very short grass, you will need extremely high density for it to look good, so it will only be possible on the highest gen PCs right now. Of course it would work well for areas outside the playfield.
     
  35. Axis-Games

    Axis-Games

    Joined:
    Feb 12, 2014
    Posts:
    29
    Sounds good - thanks for the reply!
     
  36. Shinao

    Shinao

    Joined:
    Mar 7, 2014
    Posts:
    36
    Hey! Your asset looks good, I tried the demo but it seems there is some problem with the scene 4 :

    Though the other ones looks good :


    W10, last version of Firefox (51.01). Kinda bummed me out...
     
  37. bpears

    bpears

    Joined:
    Aug 23, 2012
    Posts:
    249
    I noticed with the directional light the billboard grass changes shade unnaturally. Like, the grass is most bright with the directional light at a skewed angle, and it is most dark with light directly down(doesnt make sense), and light directly up(makes sense). Is there something I can change for a quick fix? I am wanting it to shade about the same as regular objects.
     
  38. bpears

    bpears

    Joined:
    Aug 23, 2012
    Posts:
    249
    Changed this, and it now works good. Idk if I'm wasting performance on diffuseTerm still though?

    //half3 color = diffColor * (gi.diffuse + light.color * diffuseTerm)
    half3 color = diffColor * (gi.diffuse + light.color)
     
  39. Nonakesh

    Nonakesh

    Joined:
    Aug 27, 2011
    Posts:
    576
    Yeah, sorry about that, the demo scene is a bit out dated anyways. For example it still uses the old grass displacement (moving through grass) system, which had lots of problems.
    I'll have to update it some time...

    Actually, as unintuitive it seems, that is actually the correct behaviour for the grass right now. The grass polygons are almost perpendicular to the floor, so when the light is too, they will be shaded less. By the way, when the grass has shadow casting and receiving it shouldn't be brighter when the directional light is almost parallel to the ground. (But shadows are expensive, so your solution is probably better)
    Of course the right calculation isn't always the nicest looking one... You actually created a unlit mode (without shading dependent on the angle) that's still affected by the light color. That's a nice way of doing things if it works for you! If "diffuseTerm" isn't used anywhere, the compiler probably doesn't calculate it, so this should be fine.

    I will look into more/better lighting modes in the future. Maybe I'll use you quick fix, I think it would work really well for cell-shaded / stylized games.
     
  40. khos

    khos

    Joined:
    May 10, 2016
    Posts:
    1,487
    Hi Nonakesh,
    Could I ask a question, with your asset, is there a way to not paint grass in only a certain area of the mesh/plane? Unity terrain you can paint the grass only where you want, can you do the same with your wonderful grass? I want to be able to control that Programmatically/via script..
     
  41. Nonakesh

    Nonakesh

    Joined:
    Aug 27, 2011
    Posts:
    576
    Yes, there is! You could either use the grass painter, to paint the grass like you would with Unity's terrain, or you can change the Density Texture directly via script. Just create a texture where each channel represents the density of one grass type, so red is channel 1, gressn is channel 2, etc. Then set the texture on the material and everything should work as expected.
     
  42. khos

    khos

    Joined:
    May 10, 2016
    Posts:
    1,487
    Wow, ok cool, I am certainly interested in the option "change the Density Texture directly via script.", but I have no idea where to start, I tried looking at the manual but there do not seem to be any API samples that I can find, I'd like to be able to mouse click and have a small area of grass removed for a certain radius.. Any clues or tips on how I could approach this would be much appreciated.
     
  43. Nonakesh

    Nonakesh

    Joined:
    Aug 27, 2011
    Posts:
    576
    If you want to do that in the editor, just select your grass object, click "Open Grass Painter" in its material settings, follow the on screen instructions to create a new texture and paint away. It should be pretty self explanatory how the painter works, but if you have any questions, just ask them here.

    If you want to do that in the game, it's going to be a lot harder. You will have to recreate my grass painter in game code. You could try to adapt my code for that, but you'll probably have to change quite a few things where I'm using editor functions.
     
  44. khos

    khos

    Joined:
    May 10, 2016
    Posts:
    1,487
    I'll give it a go , where do I find your painter code so I can take a look? I'll post my efforts here then..
     
  45. Nonakesh

    Nonakesh

    Joined:
    Aug 27, 2011
    Posts:
    576
    The painter code is in the file "Editor/GrassPainter.cs" in the shader folder. But some important parts of the script might be in "GrassManipulationUtility.cs".
    I think large parts of the actual texture manipulation will be the same for game code, but you won't need the code for saving textures any more, as well as all the editor gui of course.
     
  46. Dolzen

    Dolzen

    Joined:
    Mar 26, 2014
    Posts:
    90
    Hello Nonakesh, can you help me with this?

    My scene is a planet, so light can come from all sides depending on the directional light rotation. And that is my problem, when light source is comming from the side of the grass, it looks with the correct brightness but if the light source is comming directly from above, the grass is darker as you can see in the image;



    Lighting mode is Inverted Specular PBR.

    Is there a way to fix the grass brightness when the light source is comming from above? I wan the brightness to be the same as if the light were comming from the side without changing lighting mode because I want the grass to receive shadows.

    Thanks!
     
    Last edited: Mar 5, 2017
  47. Dolzen

    Dolzen

    Joined:
    Mar 26, 2014
    Posts:
    90
    nevermind, I achived what I wanted by playing with GrassFrag.cginc
     
  48. JonDadley

    JonDadley

    Joined:
    Sep 2, 2013
    Posts:
    139
    Hey,

    Unity 5.6 finally allows HDR in Forward rendering. However this is causing some issues with DX11 Grass. When using the Inverted Specular PBR shader + HDR + Bloom + Linear in Forward Rendering I get bright blotchy 'sparkles' from the grass when I move the camera around. If I simply switch the camera to Deferred, the issue disappears. Similarly turning off HDR in Forward also makes the issue stop. Also, switching to the Standard shader variant the issue disappears.

    I'm guessing there's something about the Inverted Specular PBR shader that doesn't get along with HDR + Bloom + Linear in Forward Rendering.

    Any chance of a fix? I'd love to be able to combine all these awesome things to get my games look right.

    Cheers!
     
  49. khos

    khos

    Joined:
    May 10, 2016
    Posts:
    1,487
    I've tried looking at your code, I cannot yet see any function for removing grass in certain areas, strange, probably me just not looking well enough. I'll keep on looking/searching. Any tips would be awesome :)
     
  50. Nonakesh

    Nonakesh

    Joined:
    Aug 27, 2011
    Posts:
    576
    Nice you were able to fix this yourself! I'm planning to add other lighting modes, but I don't now yet when I'll have the time for it.

    I'll look into it! Again, I'm a bit busy right now, so I don't know when I'll be able to fix it.

    The important parts are here: The function "OnSceneGUI()", here's where the mouse click is checked and a ray is cast to see where you want to change the grass. The function ApplyBrush(), accesses each pixel and calls ApplyBrushToPixel(), here the script selects if grass is removed or added, also which channel is changed.
    If you remove everything editor only for those scripts (for example OnSceneGUI could be changed to a Update function) you should be able to use it in-game without problems.
    I'd be happy to help you out, if you have any more questions.
     
    JonDadley likes this.