Home

Awesome

Projector For LWRP

Overview

This project provides Unity C# scripts and shaders to use Projector component with Lightweight Render Pipeline.

Online Document

Important Change History

13/Sep/2021

Added Additional Projector Renderer component to draw more than one projections with a single projector.

1/April/2021

Added Terrain Render Flags property and Terrains To Be Filtered With Render Flags property to Projector For SRP class.

23/Jun/2020

Switch the default branch to master-universal.

17/Jun/2020

Added Projector For SRP class which is a base component of Projector For LWRP and moved non LWRP specific functions to it.

In conjunction with this change, the following properties are removed for simplification.

17/Apr/2020

Add Is Dynamic property for projectors whose properties are frequently changed at runtime. (Removed by the changes on 17/Jun/2020)

Add Camera Tags property to specify cameras where the projector is rendered. (Removed by the changes on 17/Jun/2020)

FSR_PROJECTOR_FOR_LWRP shader keyword is separated from other FSR_XXXX keywords. Please use #pragma shader_feature for this keyword.

See Sample Code section below for the details.

22/Dec/2019

Stop disabling the original Projector component. Also, the renderer will check if the original Projector component is enabled or not, and if not, the projector will not be rendered.

If you are updating from older version, please manually enable the original Projector components in your existing scenes. If it is inconvenient to manually enable the original Projector components, you can uncheck Check Unity Projector Component Enabled field of ProjectorRendererFeature in your ForwardRendererData asset. (Removed by the changes on 17/Jun/2020)

Verified LWRP version

6.9.0

Branches

Branch nameDescription
masterA branch for Lightweight Render Pipeline (Unity 2019.2 or below).
master-universalrpA branch for Universal Render Pipeline (Unity 2019.3 or higher). This is the default branch.

Install

Clone (or submodule add) master branch into the Assets folder in your Unity Project. Zip file is also available for non git users.

Clone:

cd Pass-to-Your-Unity-Project/Assets
git clone -b master https://github.com/nyahoon-games/ProjectorForLWRP.git

Submodule Add:

cd Pass-to-Your-Unity-Project
git submodule add -b master https://github.com/nyahoon-games/ProjectorForLWRP.git Assets/ProjectorForLWRP

Download Zip:

Click here to download a zip file and extract it in your Assets folder.

Setup

If you already have a ForwardRendererData asset and assigned it to the LightweightRenderPipelineAsset, add a ProjectorRendererFeature to your ForwardRendererData.

If you don’t have a ForwardRendererData asset yet, you can use Assets/ProjectorForLWRP/Data/ForwardRendererWithProjectorPass. Go to Graphics Settings and double click LightweightRenderPipelineAsset in Scriptable Render Pipeline Settings. Then, in Inspector View, change Renderer Type to custom and assign Assets/ProjectorForLWRP/Data/ForwardRendererWithProjectorPass to Data.

How to Use

  1. Select an existing GameObject that has Projector component, or create a new empty GameObject.
  2. Press Add Component button in Inspector View, and select Scripts > ProjectorForLWRP > Projector For LWRP.
  3. The GameObject will contain Projector component and Projector For LWRP component. You still need to setup Projector 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 shaders if needed. Shaders in Dynamic Shadow Projector and Fast Shadow Receiver are also available (if you have old version, you might need update them).
  4. 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

PropertyDescription
Rendering Layer MaskOnly the renderers whose renderingLayerMask property contains any layers in this property can receive projection.
Render Queue Lower/Upper BoundOnly the renderers of which the render queue values of their materials are within this range can receive projection.
Terrain Render FlagsThis 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 FlagsA 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 ListAn 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 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 EventAn 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 DataKinds of per object data (other than transform matrix) that are required by the projector's material.
Use Stencil TestStencil 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 drawIf 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 after 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 overwritingIf 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.

Additional Projector Renderer component

Additional Projector Renderer draws extra projection in addition to the normal projector rendering, with a different material / different Render Queue bounds / different Render Pass Event.

Projector Shaders

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:

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_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
		}
	} 
}