This GitHub project provides C# scripts and shaders that make Projector component work with Lightweight/Universal Render Pipeline.
Branches
branch name | verified RP version |
---|---|
master | Lightweigt RP 6.9.0 |
master-universalrp | Universal RP 7.1.7 |
Install
If you use git, clone (or submodule add) the repository into the Assets folder in your Unity Project. If you don’t use git, you can download zip file and extract it into the Assets folder.
Lightweight RP: https://github.com/nyahoon-games/ProjectorForLWRP/tree/master
Universal RP : https://github.com/nyahoon-games/ProjectorForLWRP/tree/master-universalrp
Download Zip : For Universal RP, For Lightweight RP
Setup
First of all, you need to add ProjectorRendererFeature into your Lightweight Render Pipeline. If you created your project from LWRP template (or already configured LWRP properly), a LightweightRenderPipelineAsset had been assigned to Scriptable Render Pipeline Settings in Graphics Settings.
Double click the asset to select it in Inspector View.
If you are using the default forward renderer, change Renderer Type to Custom, then click the small button of Data field, and select ForwardRendererWithProjectorPass (Universal RP doesn’t have Renderer Type field. Just replace the default renderer with ForwardRendererWithProjectorPass).
If you are already using your custom forward renderer, please add ProjectorRendererFeature into your forward renderer data.
How to use
Add a Projector For LWRP component to your Projector object, if you already have one. If you want to create a new Projector object, just add a Projector For LWRP component to an empty GameObject, then Projector component will also be added.
Once Projector For LWRP component is added, Projector component will be hidden from Inspector View. The properties of Projector component are shown in Projector For LWRP component, and you can setup those properties as usual. One thing that is different from usual settings is that you cannot use the projector shaders in Standard Assets. Please use one of the shaders in this project, or create a custom shader if needed (see below for more details). The shaders in Fast Shadow Receiver and Dynamic Shadow Projector are also available.
In addition to setting up Projector properties, you might need to setup the properties of Projector For LWRP component.
Properties of Projector For LWRP component
Rendering Layer Mask | Only the renderers whose renderingLayerMask property contains any layers in this property can receive projection. |
Render Queue Lower/Upper Bound | Only the renderers of which the render queue values of their materials are within this range can receive projection. |
Terrain Render Flags | This property specifies what parts of the terrains in Terrains To Be Filtered With Render Flags can receive the projection. |
Terrains To Be Filtered With Render Flags | A list of terrains to which Terrain Render Flags are applied. This property is useful for the terrains which are associated with Fast Shadow Receiver. Instead of using Ignore Layers , you can add the terrains to this list to ignore only terrain surface but not details and trees. |
Shader Tag List | An array of LightMode tag values. Only the renderers whose material has a shader that contains a pass whose LightMode tag value is identical to one of the values in the array can receive projection. If a shader pass doesn’t have LightMode tag, its LightMode tag value is considered as SRPDefaultUnlit . Default value is an empty array which means LightweightForward (or UniversalForward ) and SRPDefaultUnlit are used for this property. If the array is not empty, default tags are overwritten. To add a value, please increase Size first. |
Render Pass Event | An event in which projector render pass is inserted. Please be aware that the render queue value of the projector’s material is ignored. |
Per Object Data | Kinds of per object data (other than transform matrix) that are required by the projector’s material. |
Use Stencil Test | Stencil Test requires additional rendering passes, but it can reduce the cost of the projector rendering pass. If the cost of projector rendering pass can be reduced more than the cost of the additional stencil passes, you can get performance gain. Just try and see if it is effective or not. Stencil Test might not be effective at all on some GPU. You don’t need stencil test, if the projector is used with Fast Shadow Receiver. |
Clear stencil after draw | If this option is checked, a stencil clear pass will be inserted after the projector rendering pass so that the subsequent projectors are rendered correctly. If not checked, another stencil bit will be allocated for the subsequent projector rendering and the stencil buffer will be cleared afted all the stencil bits are consumed. By default, all the 8 stencil bits are reserved for projector rendering. If you need to keep some stencil bits for other rendering, please modify Stencil Mask property in Projector Renderer Feature . |
Prevent overwriting | If this option is checked, stencil test will never improve the performance. Instead, it prevents drawing the projection more than once on the same pixel, which could happen if there are transparent objects in the projector frustum. |
Create a custom projector shader
If you need a custom projector shader, please include “Assets/ProjectorForLWRP/Shaders/P4LWRP.cginc” and use fsrTransformVertex
function to transform vertex and projection uv. The shader must be compiled with FSR_PROJECTOR_FOR_LWRP
keyword.
To make the shader SRP Batcher compatible, please use HLSLPROGRAM
instead of CGPROGRAM
.
Sample Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
Shader "Custom/Projector/Shadow" { Properties { [NoScaleOffset] _ShadowTex ("Cookie", 2D) = "gray" {} [NoScaleOffset] _FalloffTex ("FallOff", 2D) = "white" {} _Offset ("Offset", Range (-1, -10)) = -1.0 } SubShader { Tags {"Queue"="Transparent-1"} Pass { ZWrite Off Fog { Color (1, 1, 1) } ColorMask RGB Blend DstColor Zero Offset -1, [_Offset] HLSLPROGRAM #pragma vertex vert #pragma fragment frag #pragma shader_feature_local FSR_PROJECTOR_FOR_LWRP #pragma multi_compile_local _ FSR_RECEIVER #pragma multi_compile_fog #include "Assets/ProjectorForLWRP/Shaders/P4LWRP.cginc" P4LWRP_V2F_PROJECTOR vert(float4 vertex : POSITION) { P4LWRP_V2F_PROJECTOR o; fsrTransformVertex(vertex, o.pos, o.uvShadow); UNITY_TRANSFER_FOG(o, o.pos); return o; } fixed4 frag(P4LWRP_V2F_PROJECTOR i) : SV_Target { fixed4 col; fixed falloff = tex2D(_FalloffTex, i.uvShadow.zz).a; col.rgb = tex2Dproj(_ShadowTex, UNITY_PROJ_COORD(i.uvShadow)).rgb; col.a = 1.0f; col.rgb = lerp(fixed3(1,1,1), col.rgb, falloff); UNITY_APPLY_FOG_COLOR(i.fogCoord, col, fixed4(1,1,1,1)); return col; } ENDHLSL } } } |
You guys are lifesavers! This helped so much! Just a side note for anyone else who may come across the problem we did, leaving “Draw Instanced” on a Terrain will prevent a projector from showing up on that Terrain. At least for 2019.1f.
Thank you for sharing your experience! If you want to keep “Draw Instanced” on, try our another asset Fast Shadow Receiver which can receive a projector shadow on behalf of the terrain.
Where is the option to add ProjectorRendererFeature in Unity 2018?
It seems like Projector For LWRP is not available in Unity 2018. The latest version of LWRP available in Unity 2018 is 4.10 preview which doesn’t have ScriptableRendererFeature class.
Hi,
Anyone that can confirm that it works LWRP 5.16.1 as well? It seems that I can not make it work properly with 5.16.1.
I tried LWRP 5.16.1 and I didn’t see problems. What kind of issues did you find?
Thank you so much for this!
Just tried it on Unity 2019.3.0f1 with the latest LWRP and seems to work perfectly!
Just leaving a few comments here because I had never used projectors before and had some trouble setting up the texture. The way I got it to work was by importing the texture as a Default texture (not cookie, with cookie it didn’t show at all) and changing the wrap mode from Repeat to Clamp. As I said, it may be the way it always worked with projectors, but might help someone who hadn’t used them before.
Thanks again!
Works great in the editor together with the dynamic shadow projected for URP but in the build I get the following errors.
Releasing render texture that is set as Camera.targetTexture!
UnityEditor.BuildPlayerWindow:BuildPlayerAndRun()
Error building Player: Releasing render texture that is set as Camera.targetTexture!
Would appreciate some help in resolving these thank you.
Thank you for the bug report. I tried on both Windows and Mac, but I couldn’t see the error. Which platform are you making a build for?
A suspicious code I can think of is the line 590 in DynamicShadowProjector/Scripts/ShadowTextureRenderer.cs (OnDestroy function).
DestroyImmediate(m_shadowTexture);
Please try to remove this line and see if you still get the error.
There was an issue that will show “Releasing render texture that is set as Camera.targetTexture!” error message if there is a prefab object of a ShadowTextureRenderer. I fixed this issue in version 1.1.1 of DynamicShadowProjector which will be available soon on Asset Store. I am not sure if this is your case though, please try this new version.
I’m having an issue using this in my scene where it only render from a certain angle and from the other side it disappears.
I fixed view clipping issue. Please try the latest version.
I’m having a weird issue:
The current Lightweight Render Pipeline Asset does not have Forward Renderer Data! Please set a Forward Renderer Data which contains ProjectorRendererFeature to the current render pipeline asset.
UnityEngine.Debug:LogError(Object, Object)
ProjectorForLWRP.ProjectorRendererFeature:AddProjector(ProjectorForLWRP, Camera) (at Assets/ProjectorForLWRP-master/Scripts/ProjectorRendererFeature.cs:34)
ProjectorForLWRP.ProjectorForLWRP:OnBeginFrameRendering(ScriptableRenderContext, Camera[]) (at Assets/ProjectorForLWRP-master/Scripts/ProjectorForLWRP.cs:310)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)
I have made sure to follow the setup but this keeps appearing.
What I did was I selected my Lightweight Render Pipeline Asset and swapped out the default Forward Renderer to the one you provided.
Hi,
Thank you for trying Projector For LWRP. Please make sure that your Lightweight Render Pipeline Asset is selected in the Graphics settings.
Hi I have issue when build to android, I used URP unity 2019.3.11f1, on editor good work but when build have messages like this:
– No ProjectorRendererFeature instances are created!
– NullReferenceException: Object reference not set to an instance of an object
Editor.log
No ProjectorRendererFeature instances are created!
(Filename: ./Runtime/Export/Debug/Debug.bindings.h Line: 35)
NullReferenceException: Object reference not set to an instance of an object
(Filename: Assets/ProjectorForLWRP-master-universalrp/Scripts/ProjectorRendererFeature.cs Line: 108)
Hi, thank you for the bug report. I fixed this issue. Please pull the fixes from Github.
I tried this out in Unity2019.2.14f1 LWPR and in Unity2019.3.14f1 LWPR but it worked unfortunately only in the older version. I might need a bit of patience for an update I guess or maybe I made something wrong? I wanted to use the projector as a simple shadow that gets smaller when a character gets further away from the ground. So I would just set up such a projector on its head. From Λ to V.
Hi, I tried Unity 2019.3.14f1 but I didn’t see any problems. Did you see any error messages?
I guess some data references are broken when update your project. Please check the render pipeline assets and forward renderer data again.
Or, I noticed that the user interface for ForwardRendererData was changed in newer version of URP. To add ProjectorRendererFeature to a ForwardRendererData, please click “Add Renderer Feature” button at the bottom of Inspector view of the ForwardRemdererData.
No, unfortunately, I didn’t see any error messages. The materials are also looking as they should look and both forward render in my project have the ProjectorRendererFeature assigned to them and the “Check Unity Projector Component Enabled” is Enabled.
I also have the Render Pipeline Asset assigned to the “ForwardRendererWithProjectorPass” and the Render Pipeline Asset is assigned to the Graphics settings but I still don’t see any kind of projection anywhere when I use unity 2019.3.14f1. Maybe it’s a setting issue or it has something to do with importing/updating the scripts to the newest unity version?
Maybe, I know the reason. You have upgraded your project from Unity 2019.2 to Unity 2019.3 right? Unfortunately, it doesn’t work. You need to use ‘master_universalrp’ branch instead of ‘master’ branch.
It works much perfectly now. It was just difficult to get there because there were some issues. When I made a build of it every object in the range of the projector turns pink. Then I discarded every change, tried it again and suddenly only the projector was replaced with a pink square in the build. Next discard everything turned white in the range of the projector outside the build. Then I only switched from your Sample Scene back and to mine and back again and suddenly it worked perfectly and I have no idea why.
This kind of issue is supposed to be fixed at the commit made on May 22. However another person reported me a similar issue which happens only on Vulkan Graphics API.
Are you building for Android? What if Vulkan is removed from Graphics API in Player Settings?
Also, this issue seems to happen only when Fast Shadow Receiver (our paid asset) is used together. I am still investigating it.
Could the projector turn into a pink square, when making a build when using Universal RP 7.3.1 instead of 7.1.7. I don’t think Vulcan was even in use, but I could be wrong. I am not building for android, I chose “PC, Mac & Linux Standalone”. Sadly I don’t think it is possible to downgrade the Universal RP.
Thank you for the information. It seems a different issue than the Vulkan one. I also use Universal RP 7.3.1, but I couldn’t reproduce it on my Mac. Are you using Windows PC?
The issue I fixed on May 22 was caused by shader stripping. I added ProjectorForLWRP/Scripts/Editor/ProjectorMaterialPreprocessor.cs which enables “FSR_PROJECTOR_FOR_LWRP” keywords for each projector material. To make sure that the projector materials have this keyworkd, can you manually add it in the Inspector View? You might need to change the mode from ‘Normal’ to ‘Debug’ by clicking the small ‘three vertical dots’ button on top-right corner of the inspector view.
yes, I use a Windows PC. I have sadly not enough understanding of this so look further into it. I am sorry. Is there maybe a better way to stay in contact? I fear to fill up your side with my many questions even more.
I fixed the Vulkan issue. It was not actually related to Vulkan API. It might happen to other platforms. Please update ProjectorForLWRP from Github, and try again.
If you still have the issue, please contact me via email or contact form.
Hi takao! We’ve purchased Fast Shadow Receiver a while ago and now want to use it with URP (latest version) on 2019.4. The projector component from your GitHub works fine (using the instructions above) but I don’t understand how it relates to FSR. Should we use the Projector *plus* FSR to get better performance, or does FSR give additional features, or can we ignore FSR now? Our use case is rather simple: we have a single flat shadow receiver (a very simple terrain) and multiple, movable shadow casters. Built-in shadows for URP produce too much artefacts and performance is abysmal, so we really want to use your solution to improve performance. Thanks!
Hi, thank you for the purchase of Fast Shadow Receiver.
In your case (single flat shadow receiver and multiple movable shadow casters), FSR will improve the performance a lot. You can use Easy Setup Wizard to set up FSR.
Hello,
It works great – but is there any way to make this working with VR and Single Pass? Now is rendering only to one eye 🙁
Thanks!
Hi, thank you for your feedback!
I fixed the shaders in Projector For LWRP to support VR single pass. I will fix the shaders in Dynamic Shadow Projector and Fast Shadow Receiver as well and submit the updates to Asset Store soon.
Also, I fixed the VR multi pass issue in Dynamic Shadow Projector Extension for LWRP.
Hi,
This is fantastic, and working almost perfectly, however I am experiencing one minor issue with the sample shadow projector. It’s producing some faint, barely visible artifacts on nearby surfaces which are outside the projector frustum. This is most noticeable when I attach the shadow to my character, but it can be recreated within the sample scene by rotating the shadow projector while in play mode. I’m seeing four barely visible dark beams projecting out from where the shadow is cast. I’ve tried playing with the texture import settings, but can’t get them to disappear.
This is really useful, and I’d love to see this issue fixed, or learn a way to mitigate it at least.
Hi,
Thank you for your comment. The shadow texture used in the sample scene was not good. At least 1-pixel border of the texture must be pure white. Also, it is better to disable mipmap generation and compression (If the texture doesn’t have enough margin).
You can also check “Use Stencil Test” in the Inspector View of the projector, but it will affect the performance.
Our paid asset Fast Shadow Receiver can solve this issue and also improve the performance.
when terrain enable draw instance, It’s not usefull when use urp/lwrp, It only works when use built in pipeline. Would you please help fix this ? It’s quite importent for me
sorry for last question? My need is to use dynamic shadow(not a blob shadow) in urp on terrain with draw instanced enabled ,Is there a way?
Hi, it seems like we need a special projector shader for terrain to support draw instanced. That means we will need two projectors for each shadow. One for terrain and one for other objects. I don’t think that is a feasible solution.
Instead, you can use Fast Shadow Receiver to project shadows on a draw instanced terrain. It can also improve the performance.
Any chance you could make the aspect ratio on the projector work?
Hi, thank you for the comment! I didn’t notice this issue until now. There was a bug in projector hash calculation. I fixed it and pushed. Please update the source code.
Good day sir. I am having troubles with projector. I am using projector to project transparent textures onto terrain, I am using it as a target, it works very good but in some spots on some different areas on terrain it just go like under terrain or disappear? I do not know why is that if it has to do something with far and near clippoing planes or upper and lower boundaries or camera distance? Is there any method to solve this or any advice we can try ?
Thank you very much for reply
(Gifs to show a problem)
https://i.gyazo.com/e014121936068014beaa05b5d2e9089b.mp4
https://i.gyazo.com/150bb91da22e9677d84175f7907c0193.mp4
This kind of problem might happen if the LOD of the terrain chosen for rendering the projector is different from the one chosen for rendering the terrain. I don’t know if LOD can actually be different when rendering projector though.
You can try to increase
Offset
and/orOffset Slope Factor
(if exists) of the projector material. Also you can try to decreasePixel Error
of the terrain.Thanks for your help but none of those mentioned worked. I also noticed that in game player camera, if I change FOV then projector sometimes appear sometimes disappear. Lets say FOV on 40 I see projector, FOV 50 I dont see it fov 60 I see it again. Pixel correction did nothing nor offest or Offset slope factor. Also the projector is disappearing in some specific areas of terrain.Even if I move terrain in X Y and Z axis with different Navmesh it still disappear in that same spots. I would gladly take any suggestions I could try.
Also for information, we deleted this from shader as we did not need it and it was giving us error – Fog { Color (1, 1, 1) }
and replaced Blend color to – Blend OneMinusDstColor One
But I dont think so this is why it is happening to us.
Thank you very much for help.
If
Offset
doesn’t work at all, there might be some issues on view culling. I guess, some patches of the terrain were wrongly culled out. But I couldn’t find any such errors on my terrain.Can you try to add the following changes into your projector shader to see all the patches that are drawn for the projector.
1) Insert the following code before the line of
ENDHLSL
in your shader file.float4 frag() : SV_Target
{
return float4(1,0,0,0.5);
}
2) Replace
#pragma fragment xxxxx
with#pragma fragment frag
3) Optionally, you can add
ZTest Always
to make sure that z test has nothing to do with this issue.The above shader code was not able to see the actual projection area. Please use this frag shader:
Hello, thanks again for reply, I have tried everything you said and I am getting some interesting results.
When I apply that “float4…” code alone, nothing changed, projected texture still dissappear.
If I use that “float4…” code with “ZTest Always” Now it can be seen through objects and still disappear. Example1: https://i.gyazo.com/87437f1148959c7ac1f3d5c56f632ddd.mp4
If I use that “float4…” code with “ZTest Always” and ” #pragma fragment frag” I am getting this result. Everything is bright and I dont even see a texture + projected texture still disappears in some angles appears. Example2 : https://i.gyazo.com/3b28cdd97717283b3f19fed1ca56a2c0.mp4
I went with experimenting with few parameters and, if I delete “ZWrite Off” and replace it with “ZTest Always” but keep original shader without your edits, I am getting this result:
https://i.gyazo.com/04a0e171814d77b617af4f1420550fa3.mp4
It seems there is some kind of wall in my point of view and sometimes it clips trough and make my projected texture dissapear. And also wall changes based on my direction where I am looking or going. Also it is same as before in some angles it appears and in some angles it disappears. So I suspect its this “wall” that make my projected texture dissapear, but I have no idea why or what is it.
Thanks again for your help.
Ah and one more thing, I have “Near and Far clip plane” set on really strange numbers because if I mess with them more, disappearing starts happening more frequently on more parts of terrain. For example, on arrow I have it on 100 near and 300 Far, but on target I have it 123 on Near and 200 on Far clip plane. I dont know if this numbers also change things.
Thank you for testing and videos. The result was totally different from my expectation.
What I expected was to see terrain patches like this:
In this image, the terrain patch at bottom-right corner is culled out. My guess was that the patch was culled out even when it is covered with the yellow area.
Are you really casting the projection on the terrain? or casting on some other dummy objects?
Yes, I am casting projection on terrain. I do not use any custom terrain.I use terrain that you can create in unity (GameObject – 3DObejct – terrain). Also did more testing, Occlusion baking did not make any difference, even if my scene is baked for oclussion or not, my projection is still disappearing. One interesting thing is happening-our programmer made custom layer for terrain, we are not using Default layer, we are using our custom made layer. If I switch from our custom terain layer to default one, I can not project anything on terrain then. Also we are using Navmesh for our terrain.
I hope so these information are useful for you to figure out what is happening.
I try to do more experimenting.
Thanks again for reply and help.
Nevermind, forget the part where I talk about custom layer, I forgot to exclude Default layer in ingore layers on projector.
Also tried to increase ortographic size to 1000, projection still dissappear in like really specific parts of terrain https://i.gyazo.com/b4927a8283f27014c0299efea63d06c9.mp4
One last reply before you consider me spamming 😀 you can delete previous messages if you want and keep this discussion cleaner or merge them into one. I found really interesting results. We are using Base Camera with perspective projection and these settings: FOV axis – vertical, set on 60 field of view, clipping planes set to Near 1, Far 200. If I change Clipping planes on that camera lets say Near 0.01 projection starts shaking for unknown reasons if I move even little bit. Example : https://i.gyazo.com/83525f3586c0fe7fc9541a17620b2a71.mp4
So I kept Near clipping planes set to 1. But what I found more interesting is, If I change my Far clipping planes on camera from 200 to 1000, projections start disappearing less frequently and on less specific spots, but If I change Far clipping planes on camera to 5000, projections are not disappearing at all. I would not consider changing far clipping planes to 5000 as a fix because it would really decrease performance, but how does changing Camera clipping planes make projection disappear and appear?
I am really grateful for helping me with this problem.
If the projection is casted on the terrain, it is really strange that you get this result when you use ZTest Always:
because the shape of the red area must be an axis-aligned square. The only one possibility I can think of is that the projection is overwritten by something (terrain or post process).
Is the terrain drawn twice a frame?
Hello. How do I check if terrain is drawn twice a frame? We are also using post-processing called “volume” but even if I turn it off, projections are still disappearing. I found out, if I go to terrain settings and “checkmark” – Draw instanced, I can not see projections at all.
Also the picture you posted in latest comment, is not result of ZTest ALways, it is result of using #pragma fragment frag.
This is what we are using atm:
Shader “Projector For LWRP/Shadow”
{
Properties {
[NoScaleOffset] _ShadowTex (“Cookie”, 2D) = “gray” {}
[NoScaleOffset] _FalloffTex (“FallOff”, 2D) = “white” {}
_Offset (“Offset”, Range (-1, -10)) = -1.0
}
SubShader
{
Tags {“Queue”=”Transparent-1”}
// Shader code
Pass
{
ZWrite Off
ColorMask RGB
Blend OneMinusDstColor One
Offset -1, [_Offset]
HLSLPROGRAM
#pragma vertex p4lwrp_vert_projector
#pragma fragment p4lwrp_frag_projector_shadow
#pragma shader_feature_local FSR_PROJECTOR_FOR_LWRP
#pragma multi_compile_instancing
#include “P4LWRP.cginc”
ENDHLSL
}
}
}
If I replace in this code ZWrite Off with ZTest Always – I am getting this results . https://i.gyazo.com/fb071db234e4a25b07ad1a529613be84.mp4
Now projections can be seen through all objects placed on terrain and I am getting that weird white line, probably it is that axis-aligned square you talked about, but projection are still disappearing in some sections of terrain.
The image I cited is Example 2 which you said “float4…” code with “ZTest Always” and ” #pragma fragment frag”. So, my guess is now the projection is overwritten by something. Also, you said “Base Camera” in the previous comment. That implies you use Overlay camera as well, and I thought the terrain was drawn again by the Overlay camera and overwrite the projection.
Anyway, please use Frame Debugger. You can see how the scene is drawn step by step.
Draw instanced is not supported. Please see the comment by simon and my reply.
Hello, so I did use frame debugger and I was observing three situations. One situation was when my all projections dissappear. When my projections dissappear, I can not found them anywhere in the frame debugger tree.
Another observed situation was, when I could see projections. When I can see projections I can found them here in frame debugger tree: https://i.gyazo.com/f04d41c452b2ede95a94c4a7cf7b67f2.mp4
Last situation was, when I could see arrow projection but not target projection : https://i.gyazo.com/3f14a3be795deac2e40811a5031409c3.mp4
So I do not know why they are not drawn at all when they disappear or why I can not found them in frame debugger tree. It does not seem they are overwritten by something? Well, If I can not found them in frame debugger tree when they dissappear, what does it mean?
Thank you for the investigation. If you cannot see the projector draw calls when projection disappear, that means there are some issues with view culling.
In my some tests, I also observed some strange culling results when camera far clip plane is very small (I used 20). It seems like far clip plane has a special meaning. That is, it is not only used for regular culling but also used with
Layer Culling Distances
and we need to give a right value toScriptableCullingParameters.SetLayerCullingDistance
when clip planes are changed. I still need more investigation because this function is not documented at all, and I don’t know what is the right value.Just for workaround, please open “ProjectorForLWRP/SRP/Scripts/ProjectorForSRP.cs”, and find the following line in
StartCullingIfVisible
function:CullingResults cullingResults = context.Cull(ref cullingParameters);
Then, insert the following code before this line.
I hope it can fix your problem (if not, please try to increase
cullingDistance
). Later, when I found out the right value of culling layer distance, I will commit a fix.I committed the fix. Instead of changing Layer Culling Distances, I decided to keep the far clip plane unchanged. In this fix, I assumed that the far clip plane is the 5th element of the culling plane array. It really depends on undocumented Unity Engine implementation. I know this is not a good fix, but I couldn’t find better solutions than this, and as far as I tested, it worked.
I hope it fixes your problem. Thank you for telling me the issue and your cooperation.
Hello again. You are genius, your fix works brilliantly. Thank you again for 6 days of struggle with me. I am so happy and glad you could provide a help with this.
Thank you again and I bow to you.
Hey! Thanks for this wonderful project. But I have a question – is there any way to increase performance? My project is for mobile devices, there will be a lot of machines with a projector in the scene, at the moment it is noticeable in performance.
Thank you for the comment. Yes, we have the solution. Please try Fast Shadow Receiver.
Hi, Tested on Unity 2020.2.2f1 and 2020.3.16f1, and it works perfect only with 3D project…. with URP don’t work, downloaded DynamicShadowProjectorExtensionForLWRP-master-universalrp and ProjectorForLWRP-master-universalrp but it didn’t helped… Maybe you know what could I do?
Hi, did you follow the instructions above (Setup section)? Try to open Assets/ProjectorForLWRP/Samples/SampleScene and see if the projectors are working. If not, Projector For LWRP is not setup correctly. Also you need to add ‘Projector For LWRP’ component to your existing projector objects.
My bad, haven’t noticed ForwardRendererWithProjectorPass. Working fine, thank you very much 🙂
I am having an issue using the LWRP Projector with the Dynamic Shadow, where it is not being projected vertically (for instance, on walls). With Blob Shadows it’s fine, but not with dynamic ones.
Another issue is that projections clip through opaque meshes (both dynamic and blob shadows). I don’t know if that’s supposed to happen, but, if it is, how can I avoid it?
I would also like that projections could be applied over transparent meshes/shaders. Is there any way to achieve that?
Here’s an image of my game for a better understanding of the issues I mentioned: https://imgur.com/a/JyBGEP5
Hi, the projector shaders in Dynamic Shadow Projector is taking into account the normal vector of the receiver object. That is, the intensity of the shadow is multiplied by N dot L, where N is the normal vector of the receiver object and L is the projection direction. This is reasonable for natural light shadows, but your shadows are more artificial. If you would like to remove N dot L effect, you can use the shader provided in Projector For LWRP.
Regarding the second issue, basically, projector shadows are not occluded by the opaque objects. They are simply rendered on all the receiver objects which intersect with the projection frustum. This is also happen to Unity’s standard realtime shadows. The reason why Unity’s realtime shadow doesn’t have this issue is that their shadows do not overlap each other. So, if the scene has the shadows of occluder objects, the shadow of the ball will not be seen under the occluder objects. However, projector shadows do overlap. Also, in your scene, the shadow of the ball is darker than other shadows. That makes this issue more outstanding. If the shadows of occluder objects are baked on the lightmaps, you can try Fast Shadow Receiver, see this link for more details. But you have to give up the artistic shadows.
Also, you can control far clip plane of the projector when occluder object is detected by ray-cast or something.
Hi, I didn’t notice there were specific shaders for the Projector LWRP (my bad!). Actually I followed your tutorial on how to implement Dynamic Shadows and it didn’t mentioned anything about alternative LWRP shaders. So, if you accept suggestions, I think it would be nice to add that to the tutorial now that URP is becoming more and more the preferred Unity pipeline.
Regarding the other issue, what you’ve said makes total sense! My shadows look like that because I am trying to achieve something similar to what is done in recent Super Mario games, like 3D World and Odyssey. I want it to be a bit “exaggerated” so the player knows where they’re going to land. But taking into account what you’ve said, I see it will require a bit of programming on my side to avoid “clipping” through occluder objects.
What about projections on transparent surfaces? Is there any way I can make that happen easily?
Thank you so much for your help!
Thank you for the suggestion. I updated the tutorial. Also I added a new page regarding projections on transparent surface: Project shadows on transparent objects.
Most parts of this page are written for the next version of Dynamic Shadow Projector which will be available on Asset Store next week (I hope), but if you want to project shadows on transparent surfaces regardless of the alpha channel of the surface texture, you can do so without the new version.
Sounds great, I’m looking forward for the new version. Thank you!
I don’t mean to bother, but since I’ve started using the LWRP Shadow shader for Dynamic Shadows, I’ve noticed a glitch where shadows are also projected upwards, that is, outside of the projector frustum. I guess this isn’t supposed to happen, right?
Here are some pictures from my game, depicting the issue:
Case 1 (Character): https://i.imgur.com/ol3ruRI.png
Case 2 (Collectible): https://i.imgur.com/sEoNLaz.png
I think something is wrong with Falloff texture. Are you using the texture in the sample? Maybe, it is better to disable compression. You can change the format to Alpha 8. Also Wrap Mode should be Clamp.
I fixed the texture. Please update Projector For LWRP. Thanks
Yes, I was using the Falloff texture from the sample.
The issue is fixed now with the update.
Thank you so much for the big help!
How would I incorporate this into shader graph? I want to be able to use this with curved shaders etc
Thank you for the comment. Unfortunately, I have never used shader graph before. I don’t know much about it. I think you can use Custom Function Node.
What you need to do is transform world space vertex position into shadow coords in the vertex shader like this:
and use the shadow coords in the fragment shader to fetch _ShadowTex and _FalloffTex
I am getting an error
FSR_PROJECTOR_FOR_LWRP is not enabled for TargetArea material! Please check ‘Build for Universal RP’ property of the material
on URP with unity version 2021.2.10f1. I can’t find this anywhere or in any documentation.
I made it work by using the included shaders and changing the texture. Not sure why I was getting that error tho.
I got the projector working but I am unable to get the correct transparency using the shadow shader. I am completely unfamiliar with shaders. It was working correctly with alphablend projector shaders for Built in RP.
Hi, sorry for my late response. So, you have “alphablend projector shader” which was working in Builtin RP. If you want to get the same result in URP, please modify the “alphablend projector shader”. The difference of a projector shader between Builtin RP and URP is texture projection matrix. You need to calculate shadow texture UV by using fsrTransformVertex function as described above.
Hello! I’m running into an issue, which may not be an issue at all… just me being dumb. Idk.
So the projector shows up on the terrain even if it isn’t intersecting with the terrain. Here is a video of this problem: https://streamable.com/8kd4ci
Thanks!
Hi, view clipping is based on bounding boxes. It is not so precise. If you need accurate near/far clip, please use ‘Falloff’ texture which has black pixels on left and right edges (if you are using a shader in Projector For LWRP). Or, you can use a custom shader which does precise clipping based on z value of projector coordinate (i.uvShadow.z in the sample code above).
Thank you so much! For some reason never exactly knew what falloff was for.
the projector component is not added automatically when i add the projector for LWRP component. If i try to add the projector after the lwrp component, it says it cannot add projector multiple times. Any help?
I’m sorry about that. Projector component is now hidden to hide a warning message. Properties of Projector components are shown in Projector For LWRP component.
I will update the document. Thanks.
I can run my Material from Project For LWRP,
but when i restart Unity Project it can’t run.
i need reset Project>Graphics>Scriptable Render Pipeline Settings when restart Unity Project it can run.
How can i fix it,help me bro
my material is this
Shader “LSQ/EffectAchievement/AttackCircleRange”
{
Properties
{
_ShadowTex(“Cookie”, 2D) = “” {
}
_MainColor(“ScanColor”, Color) = (1,1,1,1)
_Forward(“Forward”, Range(0, 360)) = 0
_MinRange(“MinRange”, Range(0, 0.25)) = 0
_AttackAngle(“AttackAngle”, Range(0, 360)) = 60
_Power(“Power”, float) = 5
_Strength(“Strength”, float) = 1
_ScanSpeed(“ScanSpeed”, float) = 0.5
_ScanInterval(“ScanInterval”, float) = 3
_ScanStrength(“ScanStrength”, float) = 1
}
Subshader
{
Tags {
“RenderType” = “Transparent” “Queue” = “Transparent”}
Pass
{
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Offset -1, -1
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include “UnityCG.cginc”
struct a2v
{
float4 vertex : POSITION;
};
struct v2f
{
float4 pos : SV_POSITION;
float4 uvShadow : TEXCOORD1;
};
float4x4 unity_Projector;
fixed4 _MainColor;
sampler2D _ShadowTex;
float _Forward;
float _MinRange;
float _AttackAngle;
float _Power;
float _Strength;
float _ScanSpeed;
float _ScanInterval;
float _ScanStrength;
v2f vert(a2v v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uvShadow = mul(unity_Projector, v.vertex);
return o;
}
float2 Rotate(float2 samplePosition, float rotation)
{
const float PI = 3.14159;
float angle = rotation / 180 * PI;
float sine, cosine;
sincos(angle, sine, cosine);
return float2(cosine * samplePosition.x + sine * samplePosition.y,
cosine * samplePosition.y – sine * samplePosition.x);
}
fixed4 frag(v2f i) : SV_Target
{
float2 uv = i.uvShadow – 0.5f;
uv = Rotate(uv, _Forward);
float len = length(uv);
float len2 = uv.x * uv.x + uv.y * uv.y;
float range;
//最小范围
if (len2 < _MinRange)
{
range = 0;
}
else
{
//角度
const float PI = 3.14159;
float angle = atan2(uv.y, uv.x) / PI * 180;
range = 1 – step(smoothstep(_AttackAngle * 0.5, 0, angle) – smoothstep(0, -_AttackAngle * 0.5, angle), 0);
}
//投影
fixed fullMask = tex2Dproj(_ShadowTex, UNITY_PROJ_COORD(i.uvShadow)).a;
//去除边缘拉伸
const float BORDER = 0.001;
if (i.uvShadow.x / i.uvShadow.w 1 – BORDER
|| i.uvShadow.y / i.uvShadow.w 1 – BORDER)
{
fullMask = 0;
}
//最外圈
float alpha = pow(len, _Power) * fullMask * _Strength;
//中心波
float centerWave = 0;
if (alpha > 0)
{
float dis = len + _Time.y * _ScanSpeed;
dis *= _ScanInterval;
float wave = dis – floor(dis);
wave = pow(wave, _Power) * _ScanStrength;
alpha = clamp(alpha + wave, 0, _Strength);
}
return fixed4(_MainColor.rgb, alpha * range);
}
ENDCG
}
}
}
Hi, you cannot use “unity_Projector” uniform parameter because URP does not support Projector. Unity Engine will not set a value to this parameter. Instead you need to use “_FSRWorldToProjector” uniform parameter. As the name indicates, this parameter should be applied to the world position.
If you want to write a shader which can work on both Builtin RP and URP, please read Create a custom projector shader section above.
Thank you very much for your quick reply,i will try your suggest.
Hello! I am having some problems with the projector using Unity 2021.3.11f1 and URP 12.1.7.
The component seems to have some problems when the camera fov is around 90 degrees or when “Use Stencil Test” is not ticked in the component. My assumption is that this is a floating point error somewhere in the code.
Here is a youtube link showing the problem:
https://www.youtube.com/watch?v=allyvfDez3o
Any idea if there is a bad setting on my end?
Hi, it looks like texture repeat issue. Please follow the ‘Material configuration’ section in this page:
https://docs.unity3d.com/Manual/class-Projector.html
and make sure that boarder color is white (1,1,1) for Shadow projector material.
Hey, we tried using this in the 2022 LTS (2022.3.0) and its throwing errors in ProjectorEditor.cs at DrawDefaultInspector(); on line 94
Do you know what the problem may be here? We are not able to see anything in the inspector for the Projector for LWRP component
Hi,
Thank you for the bug report. The error was caused by
renderingLayerMask
property in SRP/Scripts/ProjectorForSRP.cs. I think this is an issue of Unity Editor, and I couldn’t find a proper fix. I need to investigate it more. For now, please add [HideInInspector] attribute to the property like this:Thanks for the quick reply. In the meantime, I am noticing that URP may have very bad frame rate issues with using the Projector for LWRP component. Is that expected or are there any troubleshooting steps we can take to fix this?
We took an empty scene and we are getting over 200fps, but when using one camera with the Projector for LWRP, our framerate goes down to 5fps.
It shouldn’t be so slow. Maybe, you can use FrameDebugger to see what are rendered in the scene.
I managed to fix this issue. Please update Projector for LWRP from Github.
Can it be used in conjunction with “Fast Shadow Receiver”?
Is there any tutorial about it?
Yes, Projector for LWRP can work with Fast Shadow Receiver. You can simply follow the instructions here:
https://nyahoon.com/products/fast-shadow-receiver/easy-setup-wizard-for-projector-manager
Hey, I’m not very experienced when it comes to shaders, but is there a way to add an intensity multiplier to the light projector?
It’s me again, I have another question. I managed to include an intensity multiplier, but I’m experiencing another issue. The light projector is too dark when in dark areas and too bright when in bright areas, is there a way to fix this?
I think, if your scene has both dark areas and bright areas and it is difficult to adjust light projector intensity, you need to use HDR rendering.
https://docs.unity3d.com/Manual/HDR.html