123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 |
- Shader "Lux URP/FX/Sphere Volume"
- {
- Properties
- {
- [HeaderHelpLuxURP_URL(t98mzd66fi0m)]
- [Header(Surface Options)]
- [Space(8)]
- [Enum(UnityEngine.Rendering.CompareFunction)]
- _ZTest ("ZTest", Int) = 8
- [Enum(UnityEngine.Rendering.CullMode)]
- _Cull ("Culling", Float) = 1
- [Toggle(ORTHO_SUPPORT)]
- _OrthoSpport ("Enable Orthographic Support", Float) = 0
- [Header(Surface Inputs)]
- [Space(8)]
- _Color ("Color", Color) = (1, 1, 1, 1)
- [Toggle(_ENABLEGRADIENT)]
- _EnableGradient ("Enable Gradient", Float) = 0
- [NoScaleOffset]
- _MainTex (" Thickness Gradient", 2D) = "white" {}
- [Header(Thickness Remap)]
- [Space(8)]
- _Lower (" Lower", Range(0,1)) = 0
- _Upper (" Upper", Range(0,4)) = 1
- //[Space(5)]
- //_SoftEdge (" Soft Edge Factor", Float) = 2.0
- [Space(5)]
- [Toggle(_APPLYFOG)]
- _ApplyFog ("Enable Fog", Float) = 0.0
- [Toggle(_HQFOG)]
- _HQFog (" HQ Fog", Float) = 0.0
- }
- SubShader
- {
-
- Tags
- {
- "RenderPipeline" = "UniversalPipeline"
- "RenderType"="Opaque"
- "Queue"= "Transparent+50"
- }
- Pass
- {
- Name "StandardUnlit"
- Tags{"LightMode" = "UniversalForward"}
- Blend SrcAlpha OneMinusSrcAlpha
-
- // As we want to be able to enter the volume we have to draw the back faces
- Cull [_Cull]
- // We fully rely on the depth texture sample!
- ZTest [_ZTest]
- ZWrite Off
- ColorMask RGB
- HLSLPROGRAM
- // Required to compile gles 2.0 with standard srp library
- #pragma prefer_hlslcc gles
- #pragma exclude_renderers d3d11_9x
- #pragma target 2.0
- #pragma shader_feature_local _ENABLEGRADIENT
- #pragma shader_feature_local _APPLYFOG
- #pragma shader_feature_local ORTHO_SUPPORT
- // -------------------------------------
- // Unity defined keywords
- #if defined(_APPLYFOG)
- #pragma multi_compile_fog
- #pragma shader_feature_local _HQFOG
- #endif
- //--------------------------------------
- // GPU Instancing
- #pragma multi_compile_instancing
- #pragma vertex vert
- #pragma fragment frag
- #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
- #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
- #include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl"
- CBUFFER_START(UnityPerMaterial)
- half4 _Color;
- half _Lower;
- half _Upper;
- //half _SoftEdge;
- CBUFFER_END
- // Stereo-related bits - backported to LWRP
- #if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED)
- #define LUX_SLICE_ARRAY_INDEX unity_StereoEyeIndex
- #define LUX_TEXTURE2D_X TEXTURE2D_ARRAY
- #define LUX_TEXTURE2D_X_FLOAT TEXTURE2D_ARRAY_FLOAT
- #define LUX_LOAD_TEXTURE2D_X(textureName, unCoord2) LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, LUX_SLICE_ARRAY_INDEX)
- #define LUX_SAMPLE_TEXTURE2D_X(textureName, samplerName, coord2) SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, LUX_SLICE_ARRAY_INDEX)
- #else
- #define LUX_SLICE_ARRAY_INDEX 0
- #define LUX_TEXTURE2D_X TEXTURE2D
- #define LUX_TEXTURE2D_X_FLOAT TEXTURE2D_FLOAT
- #define LUX_LOAD_TEXTURE2D_X LOAD_TEXTURE2D
- #define LUX_SAMPLE_TEXTURE2D_X SAMPLE_TEXTURE2D
- #endif
- #if defined(_ENABLEGRADIENT)
- TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
- #endif
- #if defined(SHADER_API_GLES)
- TEXTURE2D(_CameraDepthTexture); SAMPLER(sampler_CameraDepthTexture);
- #else
- LUX_TEXTURE2D_X_FLOAT(_CameraDepthTexture);
- #endif
- float4 _CameraDepthTexture_TexelSize;
-
- struct VertexInput
- {
- float4 vertex : POSITION;
- UNITY_VERTEX_INPUT_INSTANCE_ID
- };
- struct VertexOutput
- {
- float4 positionCS : SV_POSITION;
- float3 positionWS : TEXCOORD1;
- float2 projectedPosition : TEXCOORD2;
- float3 cameraPositionOS : TEXCOORD4;
- float scale : TEXCOORD5;
- #if defined(_APPLYFOG)
- half fogCoord : TEXCOORD0;
- #endif
- UNITY_VERTEX_INPUT_INSTANCE_ID
- UNITY_VERTEX_OUTPUT_STEREO
- };
- VertexOutput vert (VertexInput input)
- {
- VertexOutput o = (VertexOutput)0;
- UNITY_SETUP_INSTANCE_ID(input);
- UNITY_TRANSFER_INSTANCE_ID(input, o);
- UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
- VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
- o.positionCS = vertexInput.positionCS;
- o.positionWS = vertexInput.positionWS;
- o.projectedPosition = vertexInput.positionNDC.xy;
- o.cameraPositionOS = mul(GetWorldToObjectMatrix(), float4(_WorldSpaceCameraPos, 1)).xyz;
- float4x4 ObjectToWorldMatrix = GetObjectToWorldMatrix();
- float3 worldScale = float3(
- length(ObjectToWorldMatrix._m00_m10_m20), // scale x axis
- length(ObjectToWorldMatrix._m01_m11_m21), // scale y axis
- length(ObjectToWorldMatrix._m02_m12_m22) // scale z axis
- );
- o.scale = 1.0f / max(worldScale.x, max(worldScale.y, worldScale.z));
- #if defined(_APPLYFOG)
- o.fogCoord = ComputeFogFactor(o.positionCS.z);
- #endif
- return o;
- }
- // Ray-sphere intersection.
- // Returns the distance to the first and second intersection.
- bool IntersectRaySphere (float3 rayStart, float3 rayDir, float3 sc, float radius, out float2 intersections)
- {
- rayStart -= sc;
- float a = dot(rayDir, rayDir);
- float b = dot(rayStart, rayDir) * 2.0f;
- float c = dot(rayStart, rayStart) - radius * radius; // radius is fixed: 0.5, should be optimized by the compiler
- float discriminant = b * b - 4.0f * a * c;
- if (discriminant < 0.0f) {
- return false;
- }
- else {
- discriminant = sqrt(discriminant);
- intersections = float2(-b - discriminant, -b + discriminant) / (2.0f * a);
- // When the camera is inside the volume we may get negative values so the sphere from behind the camera gets "mirrored" into the view.
- intersections.x = max(intersections.x, 0);
- return true;
- }
- }
- real LuxComputeFogFactor(float z)
- {
- float clipZ_01 = UNITY_Z_0_FAR_FROM_CLIPSPACE(z);
- #if defined(FOG_LINEAR)
- // factor = (end-z)/(end-start) = z * (-1/(end-start)) + (end/(end-start))
- float fogFactor = saturate(clipZ_01 * unity_FogParams.z + unity_FogParams.w);
- return real(fogFactor);
- #elif defined(FOG_EXP) || defined(FOG_EXP2)
- // factor = exp(-(density*z)^2)
- // -density * z computed at vertex
- return real(unity_FogParams.x * clipZ_01);
- #else
- return 0.0h;
- #endif
- }
- // ------------------------------------------------------------------
- // Helper functions to handle orthographic / perspective projection
- inline float GetOrthoDepthFromZBuffer (float rawDepth) {
- #if defined(UNITY_REVERSED_Z)
- // Needed to handle openGL
- #if UNITY_REVERSED_Z == 1
- rawDepth = 1.0f - rawDepth;
- #endif
- #endif
- return lerp(_ProjectionParams.y, _ProjectionParams.z, rawDepth);
- }
- inline float GetProperEyeDepth (float rawDepth) {
- #if defined(ORTHO_SUPPORT)
- float perspectiveSceneDepth = LinearEyeDepth(rawDepth, _ZBufferParams);
- float orthoSceneDepth = GetOrthoDepthFromZBuffer(rawDepth);
- return lerp(perspectiveSceneDepth, orthoSceneDepth, unity_OrthoParams.w);
- #else
- return LinearEyeDepth(rawDepth, _ZBufferParams);
- #endif
- }
- half4 frag (VertexOutput input) : SV_Target
- {
- UNITY_SETUP_INSTANCE_ID(input);
- UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
- half4 color = half4(1,1,1,0);
- #if defined(ORTHO_SUPPORT)
- input.positionCS.w = lerp(input.positionCS.w, 1.0f, unity_OrthoParams.w);
- #endif
- float2 screenUV = input.projectedPosition.xy / input.positionCS.w;
- // Fix screenUV for Single Pass Stereo Rendering
- #if defined(UNITY_SINGLE_PASS_STEREO)
- screenUV.x = screenUV.x * 0.5f + (float)unity_StereoEyeIndex * 0.5f;
- #endif
- float3 viewDirWS = normalize(input.positionWS - _WorldSpaceCameraPos);
- // Scene depth as linear eye depth
- #if defined(SHADER_API_GLES)
- float sceneZ = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, sampler_CameraDepthTexture, screenUV, 0);
- #else
- float sceneZ = LUX_LOAD_TEXTURE2D_X(_CameraDepthTexture, _CameraDepthTexture_TexelSize.zw * screenUV).x;
- #endif
- sceneZ = GetProperEyeDepth(sceneZ);
- // Convert linear eye depth to distance in world space
- float3 camForward = UNITY_MATRIX_V[2].xyz;
- float sceneDistance = sceneZ / dot(-viewDirWS, camForward);
-
- float3 rayDir = mul(GetWorldToObjectMatrix(), float4(viewDirWS, 0)).xyz;
- float3 rayStart = input.cameraPositionOS;
- float2 intersections = 0;
- bool intersect = IntersectRaySphere(rayStart , rayDir, float3(0, 0, 0), 0.5, intersections);
- // Not needed if we use a sphere.
- // UNITY_BRANCH
- // if (intersect) {
-
- // Entry point in world space
- float3 entry = mul(GetObjectToWorldMatrix(), float4(rayStart + rayDir * intersections.x, 1)).xyz;
-
- float distanceToEntry = length(entry - _WorldSpaceCameraPos);
- float sceneToEntry = sceneDistance - distanceToEntry;
-
- // Nothing to do if the scene is in front of the entry point
- clip(sceneToEntry);
- // Exit point in world space
- float3 exit = mul(GetObjectToWorldMatrix(), float4(rayStart + rayDir * intersections.y, 1)).xyz;
- float maxTravel = distance(exit, entry);
- float denom = min(sceneToEntry, maxTravel);
- float percentage = maxTravel / denom;
- percentage = rcp(percentage);
- // This only attenuates alpha in object space :(
- float3 mid = rayStart + rayDir * (intersections.x + intersections.y) * 0.5;
- float alpha = 1 - length(mid) * 2.0;
- // Smooth falloff - only the object space falloff
- alpha = smoothstep(_Lower, _Upper, alpha);
- // In order to factor in object scale and dimensions we multiply alpha by maxTravel. / Not really correct
- alpha *= maxTravel * input.scale * percentage;
- // Smooth falloff
- //alpha = smoothstep(_Lower, _Upper, alpha);
- // Scene blending
- //alpha *= saturate(sceneToEntry / _SoftEdge);
- // saturate eliminates artifacts at grazing angles
- color.a = saturate(alpha);
-
- #if defined(_ENABLEGRADIENT)
- color.rgb = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, float2(alpha, 0.5)).rgb;
- #endif
- // }
-
- color *= _Color;
- #if defined(_APPLYFOG)
- #if defined(_HQFOG)
- float3 exitFog = mul(GetObjectToWorldMatrix(), float4(rayStart + rayDir * intersections.y * sqrt(percentage), 1)).xyz;
- float4 FogClipSpace = TransformWorldToHClip(exitFog);
- float fogFactor = LuxComputeFogFactor( FogClipSpace.z);
- color.rgb = MixFog(color.rgb, fogFactor);
- #else
- color.rgb = MixFog(color.rgb, input.fogCoord);
- #endif
- #endif
- return color;
- }
- ENDHLSL
- }
- }
- FallBack "Hidden/InternalErrorShader"
- }
|