248 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			248 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|  | #include "Packages/com.unity.render-pipelines.universal/Runtime/VFXGraph/Shaders/VFXLit.hlsl" | ||
|  | #if !defined(SHADERPASS) | ||
|  | #error SHADERPASS_is_not_define | ||
|  | #endif | ||
|  | 
 | ||
|  | #ifdef _DECAL_LAYERS | ||
|  | #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareRenderingLayerTexture.hlsl" | ||
|  | #endif | ||
|  | 
 | ||
|  | #if defined(DECAL_LOAD_NORMAL) | ||
|  | #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl" | ||
|  | #endif | ||
|  | 
 | ||
|  | #if defined(DECAL_PROJECTOR) || defined(DECAL_RECONSTRUCT_NORMAL) | ||
|  | #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl" | ||
|  | #endif | ||
|  | 
 | ||
|  | void GetSurfaceDataFromSurfaceDecalData(DecalSurfaceData decalSurfaceData, inout SurfaceData surfaceData) | ||
|  | { | ||
|  |     surfaceData.albedo = decalSurfaceData.baseColor.rgb; | ||
|  |     surfaceData.metallic = saturate(decalSurfaceData.metallic); | ||
|  |     surfaceData.specular = 0; | ||
|  |     surfaceData.smoothness = saturate(decalSurfaceData.smoothness); | ||
|  |     surfaceData.occlusion = decalSurfaceData.occlusion; | ||
|  |     surfaceData.emission = decalSurfaceData.emissive; | ||
|  |     surfaceData.alpha = saturate(decalSurfaceData.baseColor.w); | ||
|  |     surfaceData.clearCoatMask = 0; | ||
|  |     surfaceData.clearCoatSmoothness = 1; | ||
|  | } | ||
|  | 
 | ||
|  | void VFXGetSurfaceDecalData(out DecalSurfaceData surfaceData, out PositionInputs posInputs, out half3 receiverNormalWS, VFX_VARYING_PS_INPUTS i) | ||
|  | { | ||
|  | 	ZERO_INITIALIZE(DecalSurfaceData, surfaceData); | ||
|  | 	VFXTransformPSInputs(i); | ||
|  | 
 | ||
|  |     float2 positionCS = i.pos.xy; | ||
|  |     // Only screen space needs flip logic, other passes do not setup needed properties so we skip here | ||
|  | #if SHADERPASS == SHADERPASS_DECAL_SCREEN_SPACE_PROJECTOR | ||
|  |     TransformScreenUV(positionCS, _ScreenSize.y); | ||
|  | #endif | ||
|  | 
 | ||
|  | //Check Rendering layer | ||
|  | #ifdef _DECAL_LAYERS | ||
|  |     #ifdef _RENDER_PASS_ENABLED | ||
|  |         uint surfaceRenderingLayer = LOAD_FRAMEBUFFER_X_INPUT(GBUFFER4, positionCS.xy).r; | ||
|  |     #else | ||
|  |         uint surfaceRenderingLayer = LoadSceneRenderingLayer(positionCS.xy); | ||
|  |     #endif | ||
|  |     ${VFXLoadParameter:{decalLayerMask}} | ||
|  |     clip((surfaceRenderingLayer & decalLayerMask) - 0.1); | ||
|  | #endif | ||
|  | 
 | ||
|  | 
 | ||
|  | #if _RENDER_PASS_ENABLED | ||
|  |     float depth = LOAD_FRAMEBUFFER_X_INPUT(GBUFFER3, positionCS.xy).x; | ||
|  | #else | ||
|  |     float depth = LoadSceneDepth(positionCS.xy); | ||
|  | #endif | ||
|  | #if !UNITY_REVERSED_Z | ||
|  |     depth = lerp(UNITY_NEAR_CLIP_VALUE, 1.0f, depth); | ||
|  | #endif | ||
|  | 
 | ||
|  |     float2 positionSS = i.pos.xy * _ScreenSize.zw; | ||
|  | 	float3 positionWS = ComputeWorldSpacePosition(positionSS, depth, UNITY_MATRIX_I_VP); | ||
|  | 
 | ||
|  |     posInputs = GetPositionInput(positionSS, _ScreenSize.zw, positionWS); | ||
|  | 
 | ||
|  | 	float4x4 worldToElement; | ||
|  |     worldToElement[0] = i.worldToDecal[0]; | ||
|  |     worldToElement[1] = i.worldToDecal[1]; | ||
|  |     worldToElement[2] = -i.worldToDecal[2]; | ||
|  | 	worldToElement[3] = float4(0,0,0,1); | ||
|  | 
 | ||
|  |     float3 positionDS = mul(worldToElement, float4(positionWS,1.0f)).xyz; | ||
|  | 	clip(0.5f - abs(positionDS)); | ||
|  | 
 | ||
|  |     float3x3 normalToWorld = transpose(float3x3( | ||
|  |                                     VFXSafeNormalize(worldToElement[0].xyz), | ||
|  |                                     VFXSafeNormalize(worldToElement[1].xyz), | ||
|  |                                     VFXSafeNormalize(worldToElement[2].xyz))); | ||
|  | 
 | ||
|  | 	float2 uv = positionDS.xy + float2(0.5, 0.5); | ||
|  | 	VFXUVData uvData = GetUVData(i,uv); | ||
|  |     float angleFadeFactor = 1.0f; | ||
|  | 
 | ||
|  |     receiverNormalWS = half3(0,1,0); | ||
|  | #if defined(DECAL_RECONSTRUCT_NORMAL) | ||
|  |     #if defined(_DECAL_NORMAL_BLEND_HIGH) | ||
|  |         receiverNormalWS = half3(ReconstructNormalTap9(i.pos.xy)); | ||
|  |     #elif defined(_DECAL_NORMAL_BLEND_MEDIUM) | ||
|  |         receiverNormalWS = half3(ReconstructNormalTap5(i.pos.xy)); | ||
|  |     #else | ||
|  |         receiverNormalWS = half3(ReconstructNormalDerivative(i.pos.xy)); | ||
|  |     #endif | ||
|  | #elif defined(DECAL_LOAD_NORMAL) | ||
|  |         receiverNormalWS = half3(LoadSceneNormals(i.pos.xy)); | ||
|  | #endif | ||
|  | 
 | ||
|  | 	#ifdef DECAL_ANGLE_FADE | ||
|  | 	if (i.VFX_VARYING_ANGLEFADE.y < 0.0f) // if angle fade is enabled | ||
|  | 	{ | ||
|  |         float3 decalNormal = float3(normalToWorld[0].z, normalToWorld[1].z, normalToWorld[2].z); | ||
|  | 		float dotAngle = dot(receiverNormalWS, decalNormal); | ||
|  |         float2 angleFade = i.VFX_VARYING_ANGLEFADE; | ||
|  | 		angleFadeFactor = saturate(angleFade.x + angleFade.y * (dotAngle * (dotAngle - 2.0))); | ||
|  | 	} | ||
|  | 	#endif | ||
|  | 
 | ||
|  | 	float fadeFactor = i.VFX_VARYING_FADEFACTOR; | ||
|  | 	fadeFactor *= angleFadeFactor; | ||
|  | 
 | ||
|  | //Compute color even for emissive, to have the correct opacity | ||
|  |     float4 color = float4(1,1,1,1); | ||
|  |     #if URP_USE_BASE_COLOR | ||
|  |         color *= VFXGetParticleColor(i); | ||
|  |     #elif URP_USE_ADDITIONAL_BASE_COLOR | ||
|  |         #if defined(VFX_VARYING_COLOR) | ||
|  |         color.xyz *= i.VFX_VARYING_COLOR; | ||
|  |         #endif | ||
|  |         #if defined(VFX_VARYING_ALPHA) | ||
|  |         color.a *= i.VFX_VARYING_ALPHA; | ||
|  |         #endif | ||
|  |     #endif | ||
|  |     #if URP_USE_BASE_COLOR_MAP | ||
|  |         float4 colorMap = SampleTexture(VFX_SAMPLER(baseColorMap),uvData); | ||
|  |         #if URP_USE_BASE_COLOR_MAP_COLOR | ||
|  |         color.xyz *= colorMap.xyz; | ||
|  |         #endif | ||
|  |         #if URP_USE_BASE_COLOR_MAP_ALPHA | ||
|  |         color.a *= colorMap.a; | ||
|  |         #endif | ||
|  |     #endif | ||
|  | 	color.a *= fadeFactor; | ||
|  |     VFXClipFragmentColor(color.a,i); | ||
|  | 
 | ||
|  |     #if (SHADERPASS == SHADERPASS_DBUFFER_PROJECTOR) || (SHADERPASS == SHADERPASS_DECAL_SCREEN_SPACE_PROJECTOR) || (SHADERPASS == SHADERPASS_DECAL_GBUFFER_PROJECTOR) | ||
|  | 
 | ||
|  |         surfaceData.baseColor.rgb = saturate(color.rgb); | ||
|  | 	    surfaceData.baseColor.a = color.a; | ||
|  | 
 | ||
|  | 	    float albedoMapBlend = surfaceData.baseColor.a; | ||
|  | 	    float maskMapBlend = fadeFactor; | ||
|  | 
 | ||
|  |         surfaceData.metallic = 0.0f; | ||
|  |         surfaceData.occlusion = 1.0f; | ||
|  | 
 | ||
|  |         #ifdef VFX_VARYING_METALLIC | ||
|  |             surfaceData.metallic = i.VFX_VARYING_METALLIC; | ||
|  |         #endif | ||
|  |         #ifdef VFX_VARYING_AMBIENT_OCCLUSION | ||
|  |             surfaceData.occlusion *= i.VFX_VARYING_AMBIENT_OCCLUSION; | ||
|  |         #endif | ||
|  | 
 | ||
|  |         surfaceData.smoothness = 0.5f; | ||
|  |         #ifdef VFX_VARYING_SMOOTHNESS | ||
|  |             surfaceData.smoothness = i.VFX_VARYING_SMOOTHNESS; | ||
|  |         #endif | ||
|  | 
 | ||
|  |         float4 metallicMapSample = (float4)1.0f; | ||
|  |         float4 specularMapSample = (float4)1.0f; | ||
|  |         #if URP_USE_METALLIC_MAP | ||
|  |             metallicMapSample = SampleTexture(VFX_SAMPLER(metallicMap), uvData); | ||
|  |             surfaceData.metallic *= metallicMapSample.r; | ||
|  |             maskMapBlend *= metallicMapSample.b; | ||
|  |         #endif | ||
|  | 
 | ||
|  |         #if URP_USE_OCCLUSION_MAP | ||
|  |             float4 mask = SampleTexture(VFX_SAMPLER(occlusionMap),uvData); | ||
|  |             surfaceData.occlusion *= mask.g; | ||
|  |         #endif | ||
|  | 
 | ||
|  |         #if URP_USE_SMOOTHNESS_IN_ALBEDO | ||
|  |             surfaceData.smoothness *= albedoMapBlend; | ||
|  |         #elif URP_USE_SMOOTHNESS_IN_METALLIC | ||
|  |             surfaceData.smoothness *= metallicMapSample.a; | ||
|  |         #elif URP_USE_SMOOTHNESS_IN_SPECULAR | ||
|  |             surfaceData.smoothness *= albedoMapBlend;//TODO: Not implemented yet; | ||
|  |         #endif | ||
|  | 
 | ||
|  |         #if  VFX_MAOS_BLEND_BASE_COLOR_ALPHA | ||
|  | 	        surfaceData.MAOSAlpha = albedoMapBlend; | ||
|  |         #elif VFX_MAOS_BLEND_METALLIC_BLUE | ||
|  | 	        surfaceData.MAOSAlpha = maskMapBlend; | ||
|  |         #endif | ||
|  | 
 | ||
|  |         float normalAlpha = 1.0f; | ||
|  | 
 | ||
|  |         //No Decal Surface Gradient in URP implementation of Decals | ||
|  |         #if USE_NORMAL_MAP | ||
|  |             float3 normalTS = SampleNormalMap(VFX_SAMPLER(normalMap),uvData); | ||
|  |         #else //USE_NORMAL_MAP | ||
|  | 	        float3 normalTS = float3(0.0f,0.0f,1.0f); | ||
|  | 	    #endif //USE_NORMAL_MAP | ||
|  |         float3 normalWS = mul(normalToWorld, normalTS); | ||
|  | 	    normalWS = normalize(normalWS); | ||
|  | 
 | ||
|  | 	    surfaceData.normalWS.xyz = normalWS; | ||
|  |         #ifdef VFX_VARYING_NORMALALPHA | ||
|  |             surfaceData.normalWS.w = i.VFX_VARYING_NORMALALPHA; | ||
|  |         #else | ||
|  |             surfaceData.normalWS.w = 0.0f; | ||
|  |         #endif | ||
|  | 
 | ||
|  | 	    #if VFX_NORMAL_BLEND_BASE_COLOR_ALPHA | ||
|  | 	        surfaceData.normalWS.w *= albedoMapBlend; | ||
|  | 	    #elif VFX_NORMAL_BLEND_METALLIC_BLUE | ||
|  | 	        surfaceData.normalWS.w *= maskMapBlend; | ||
|  | 	    #endif | ||
|  |     #endif | ||
|  | 
 | ||
|  | 	#if (SHADERPASS == SHADERPASS_FORWARD_EMISSIVE_PROJECTOR)  || (SHADERPASS == SHADERPASS_DECAL_SCREEN_SPACE_PROJECTOR) || (SHADERPASS == SHADERPASS_DECAL_GBUFFER_PROJECTOR) | ||
|  |         surfaceData.baseColor.a = color.a; | ||
|  |         surfaceData.emissive = float3(1,1,1) * fadeFactor; | ||
|  |         #if defined(VFX_VARYING_EMISSIVE) && (URP_USE_EMISSIVE_COLOR || URP_USE_ADDITIONAL_EMISSIVE_COLOR) | ||
|  | 		    surfaceData.emissive *= i.VFX_VARYING_EMISSIVE; | ||
|  | 		#else | ||
|  |             surfaceData.emissive = float3(0,0,0); | ||
|  |         #endif | ||
|  | 		#ifdef URP_USE_EMISSIVE_MAP | ||
|  | 		    float emissiveScale = 1.0f; | ||
|  | 		    #ifdef VFX_VARYING_EMISSIVESCALE | ||
|  | 		        emissiveScale = i.VFX_VARYING_EMISSIVESCALE; | ||
|  | 		    #endif | ||
|  | 		    surfaceData.emissive *= SampleTexture(VFX_SAMPLER(emissiveMap), uvData).rgb * emissiveScale; | ||
|  | 		#endif | ||
|  | 	#endif | ||
|  | } | ||
|  | 
 | ||
|  | void PrepareSurfaceAndInputData(VFX_VARYING_PS_INPUTS i, inout SurfaceData surfaceData, inout DecalSurfaceData decalSurfaceData, inout InputData inputData) | ||
|  | { | ||
|  |     PositionInputs posInput; | ||
|  |     ZERO_INITIALIZE(PositionInputs, posInput); | ||
|  |     half3 receiverNormalWS; | ||
|  |     VFXGetSurfaceDecalData(decalSurfaceData, posInput, receiverNormalWS, i); | ||
|  | 
 | ||
|  |     GetSurfaceDataFromSurfaceDecalData(decalSurfaceData, surfaceData); | ||
|  | 
 | ||
|  | #if (SHADERPASS == SHADERPASS_DECAL_SCREEN_SPACE_PROJECTOR) | ||
|  |     decalSurfaceData.normalWS.xyz = normalize(lerp(receiverNormalWS.xyz, decalSurfaceData.normalWS.xyz, decalSurfaceData.normalWS.w)); | ||
|  | #endif | ||
|  | 
 | ||
|  |     inputData = VFXGetInputData(i, posInput, decalSurfaceData.normalWS.xyz, true); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 |