// Upgrade NOTE: replaced 'defined USE_FORWARD_PLUS' with 'defined (USE_FORWARD_PLUS)' // Upgrade NOTE: replaced 'defined _ADDITIONAL_LIGHTS' with 'defined (_ADDITIONAL_LIGHTS)' // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld' Shader "SEGI/SEGIVoxelizeSceneL" { Properties { _Color("Main Color", Color) = (1,1,1,1) _MainTex("Base (RGB)", 2D) = "white" {} _EmissionColor("Color", Color) = (0,0,0) _EmissionMap("Emission", 2D) = "white" {} _Cutoff("Alpha Cutoff", Range(0,1)) = 0.333 _BlockerValue("Blocker Value", Range(0, 10)) = 0 } SubShader { Cull Off ZTest Always Tags {"LightMode" = "ForwardBase"}// "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" } //v0.1 Lighting On Pass { CGPROGRAM #pragma target 5.0 #pragma vertex vert #pragma fragment frag #pragma geometry geom #include "UnityCG.cginc" #pragma multi_compile _ _ADDITIONAL_LIGHTS #pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS //v0.1 #include "UnityLightingCommon.cginc" #include "UnityShaderVariables.cginc" #include "AutoLight.cginc" #include "UnityDeferredLibrary.cginc" //#include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl" //#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" //#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl" //#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl" //COKKIES #define MAX_VISIBLE_LIGHTS 16 #define URP_LIGHT_TYPE_SPOT 0 #define URP_LIGHT_TYPE_DIRECTIONAL 1 #define URP_LIGHT_TYPE_POINT 2 // Match UnityEngine.TextureWrapMode #define URP_TEXTURE_WRAP_MODE_REPEAT 0 #define URP_TEXTURE_WRAP_MODE_CLAMP 1 #define URP_TEXTURE_WRAP_MODE_MIRROR 2 #define URP_TEXTURE_WRAP_MODE_MIRROR_ONCE 3 // Types #define URP_LIGHT_COOKIE_FORMAT_NONE (-1) #define URP_LIGHT_COOKIE_FORMAT_RGB (0) #define URP_LIGHT_COOKIE_FORMAT_ALPHA (1) #define URP_LIGHT_COOKIE_FORMAT_RED (2) // Textures #define TEXTURE2D(textureName) Texture2D textureName #define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) tex2Dlod(textureName, float4(coord2, 0.0, lod)) // SAMPLER(sampler_LinearClamp); SamplerState sampler_LinearClamp; TEXTURE2D(_MainLightCookieTexture); //TEXTURE2D(_AdditionalLightsCookieAtlasTexture); sampler2D _AdditionalLightsCookieAtlasTexture; float _AdditionalLightsCookieAtlasTextureFormat; float4 _AdditionalLightsCookieAtlasUVRects[MAX_VISIBLE_LIGHTS]; // (xy: uv size, zw: uv offset) float4x4 _AdditionalLightsWorldToLights[MAX_VISIBLE_LIGHTS]; float _AdditionalLightsCookieEnableBits[(MAX_VISIBLE_LIGHTS + 31) / 32]; float _AdditionalLightsLightTypes[MAX_VISIBLE_LIGHTS]; float4 GetLightCookieAtlasUVRect(int lightIndex) { #if USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA return _AdditionalLightsCookieAtlasUVRectBuffer[lightIndex]; #else return _AdditionalLightsCookieAtlasUVRects[lightIndex]; #endif } float4x4 GetLightCookieWorldToLightMatrix(int lightIndex) { #if USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA return _AdditionalLightsWorldToLightBuffer[lightIndex]; #else return _AdditionalLightsWorldToLights[lightIndex]; #endif } int GetLightCookieLightType(int lightIndex) { #if USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA return _AdditionalLightsLightTypeBuffer[lightIndex]; #else return _AdditionalLightsLightTypes[lightIndex]; #endif } bool IsLightCookieEnabled(int lightBufferIndex) { #if 0 float4 uvRect = GetLightCookieAtlasUVRect(lightBufferIndex); return any(uvRect != 0); #else // 2^5 == 32, bit mask for a float/uint. uint elemIndex = ((uint)lightBufferIndex) >> 5; uint bitOffset = (uint)lightBufferIndex & ((1 << 5) - 1); #if USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA uint elem = asuint(_AdditionalLightsCookieEnableBitsBuffer[elemIndex]); #else uint elem = asuint(_AdditionalLightsCookieEnableBits[elemIndex]); #endif return (elem & (1u << bitOffset)) != 0u; #endif } float2 PackNormalOctQuadEncode(float3 n) { //float l1norm = dot(abs(n), 1.0); //float2 res0 = n.xy * (1.0 / l1norm); //float2 val = 1.0 - abs(res0.yx); //return (n.zz < float2(0.0, 0.0) ? (res0 >= 0.0 ? val : -val) : res0); // Optimized version of above code: n *= rcp(max(dot(abs(n), 1.0), 1e-6)); float t = saturate(-n.z); return n.xy + float2(n.x >= 0.0 ? t : -t, n.y >= 0.0 ? t : -t); } float2 ComputeLightCookieUVSpot(float4x4 worldToLightPerspective, float3 samplePositionWS, float4 atlasUVRect) { // Translate, rotate and project 'positionWS' into the light clip space. float4 positionCS = mul(worldToLightPerspective, float4(samplePositionWS, 1)); float2 positionNDC = positionCS.xy / positionCS.w; // Remap NDC to the texture coordinates, from NDC [-1, 1]^2 to [0, 1]^2. float2 positionUV = saturate(positionNDC * 0.5 + 0.5); // Remap into rect in the atlas texture float2 positionAtlasUV = atlasUVRect.xy * float2(positionUV)+atlasUVRect.zw; return positionAtlasUV; } float2 ComputeLightCookieUVPoint(float4x4 worldToLight, float3 samplePositionWS, float4 atlasUVRect) { // Translate and rotate 'positionWS' into the light space. float4 positionLS = mul(worldToLight, float4(samplePositionWS, 1)); float3 sampleDirLS = normalize(positionLS.xyz / positionLS.w); // Project direction to Octahederal quad UV. float2 positionUV = saturate(PackNormalOctQuadEncode(sampleDirLS) * 0.5 + 0.5); // Remap to atlas texture float2 positionAtlasUV = atlasUVRect.xy * float2(positionUV)+atlasUVRect.zw; return positionAtlasUV; } float2 ComputeLightCookieUVDirectional(float4x4 worldToLight, float3 samplePositionWS, float4 atlasUVRect, uint2 uvWrap) { // Translate and rotate 'positionWS' into the light space. // Project point to light "view" plane, i.e. discard Z. float2 positionLS = mul(worldToLight, float4(samplePositionWS, 1)).xy; // Remap [-1, 1] to [0, 1] // (implies the transform has ortho projection mapping world space box to [-1, 1]) float2 positionUV = positionLS * 0.5 + 0.5; // Tile texture for cookie in repeat mode positionUV.x = (uvWrap.x == URP_TEXTURE_WRAP_MODE_REPEAT) ? frac(positionUV.x) : positionUV.x; positionUV.y = (uvWrap.y == URP_TEXTURE_WRAP_MODE_REPEAT) ? frac(positionUV.y) : positionUV.y; positionUV.x = (uvWrap.x == URP_TEXTURE_WRAP_MODE_CLAMP) ? saturate(positionUV.x) : positionUV.x; positionUV.y = (uvWrap.y == URP_TEXTURE_WRAP_MODE_CLAMP) ? saturate(positionUV.y) : positionUV.y; // Remap to atlas texture float2 positionAtlasUV = atlasUVRect.xy * float2(positionUV)+atlasUVRect.zw; return positionAtlasUV; } float4 SampleAdditionalLightsCookieAtlasTexture(float2 uv) { // No mipmap support //return SAMPLE_TEXTURE2D_LOD(_AdditionalLightsCookieAtlasTexture, sampler_LinearClamp, uv, 0); return tex2Dlod(_AdditionalLightsCookieAtlasTexture, float4(uv,0,0)); } bool IsAdditionalLightsCookieAtlasTextureRGBFormat() { return _AdditionalLightsCookieAtlasTextureFormat == URP_LIGHT_COOKIE_FORMAT_RGB; } bool IsAdditionalLightsCookieAtlasTextureAlphaFormat() { return _AdditionalLightsCookieAtlasTextureFormat == URP_LIGHT_COOKIE_FORMAT_ALPHA; } float3 SampleAdditionalLightCookie(int perObjectLightIndex, float3 samplePositionWS) { if (!IsLightCookieEnabled(perObjectLightIndex)) return float3(1,1,1); int lightType = GetLightCookieLightType(perObjectLightIndex); int isSpot = lightType == URP_LIGHT_TYPE_SPOT; int isDirectional = lightType == URP_LIGHT_TYPE_DIRECTIONAL; float4x4 worldToLight = GetLightCookieWorldToLightMatrix(perObjectLightIndex); float4 uvRect = GetLightCookieAtlasUVRect(perObjectLightIndex); float2 uv; if (isSpot) { uv = ComputeLightCookieUVSpot(worldToLight, samplePositionWS, uvRect); } else if (isDirectional) { uv = ComputeLightCookieUVDirectional(worldToLight, samplePositionWS, uvRect, URP_TEXTURE_WRAP_MODE_REPEAT); } else { uv = ComputeLightCookieUVPoint(worldToLight, samplePositionWS, uvRect); } float4 color = SampleAdditionalLightsCookieAtlasTexture(uv); return IsAdditionalLightsCookieAtlasTextureRGBFormat() ? color.rgb : IsAdditionalLightsCookieAtlasTextureAlphaFormat() ? color.aaa : color.rrr; } //SHADOWS half MixRealtimeAndBakedShadows(half realtimeShadow, half bakedShadow, half shadowFade) { #if defined(LIGHTMAP_SHADOW_MIXING) return min(lerp(realtimeShadow, 1, shadowFade), bakedShadow); #else return lerp(realtimeShadow, bakedShadow, shadowFade); #endif } half AdditionalLightRealtimeShadow(int lightIndex, float3 positionWS, half3 lightDirection) { #if defined(ADDITIONAL_LIGHT_CALCULATE_SHADOWS) ShadowSamplingData shadowSamplingData = GetAdditionalLightShadowSamplingData(lightIndex); half4 shadowParams = GetAdditionalLightShadowParams(lightIndex); int shadowSliceIndex = shadowParams.w; if (shadowSliceIndex < 0) return 1.0; half isPointLight = shadowParams.z; UNITY_BRANCH if (isPointLight) { // This is a point light, we have to find out which shadow slice to sample from float cubemapFaceId = CubeMapFaceID(-lightDirection); shadowSliceIndex += cubemapFaceId; } #if USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA float4 shadowCoord = mul(_AdditionalLightsWorldToShadow_SSBO[shadowSliceIndex], float4(positionWS, 1.0)); #else float4 shadowCoord = mul(_AdditionalLightsWorldToShadow[shadowSliceIndex], float4(positionWS, 1.0)); #endif return SampleShadowmap(TEXTURE2D_ARGS(_AdditionalLightsShadowmapTexture, sampler_LinearClampCompare), shadowCoord, shadowSamplingData, shadowParams, true); #else return half(1.0); #endif } half AdditionalLightShadow(int lightIndex, float3 positionWS, half3 lightDirection, half4 shadowMask, half4 occlusionProbeChannels) { half realtimeShadow = AdditionalLightRealtimeShadow(lightIndex, positionWS, lightDirection); #ifdef CALCULATE_BAKED_SHADOWS half bakedShadow = BakedShadow(shadowMask, occlusionProbeChannels); #else half bakedShadow = half(1.0); #endif #ifdef ADDITIONAL_LIGHT_CALCULATE_SHADOWS half shadowFade = GetAdditionalLightShadowFade(positionWS); #else half shadowFade = half(1.0); #endif return MixRealtimeAndBakedShadows(realtimeShadow, bakedShadow, shadowFade); } #define HALF_MIN 6.103515625e-5 // 2^-14, the same value for 10, 11 and 16-bit: https://www.khronos.org/opengl/wiki/Sm… #define HALF_MIN_SQRT 0.0078125 // 2^-7 == sqrt(HALF_MIN), useful for ensuring HALF_MIN after x^2 half4 _AdditionalLightsColor[MAX_VISIBLE_LIGHTS]; half4 _AdditionalLightsAttenuation[MAX_VISIBLE_LIGHTS]; half4 _AdditionalLightsSpotDir[MAX_VISIBLE_LIGHTS]; half4 _AdditionalLightsOcclusionProbes[MAX_VISIBLE_LIGHTS]; float _AdditionalLightsLayerMasks[MAX_VISIBLE_LIGHTS]; float4 _AdditionalLightsPosition[MAX_VISIBLE_LIGHTS]; struct Light { half3 direction; half3 color; float distanceAttenuation; // full-float precision required on some platforms half shadowAttenuation; uint layerMask; }; // Matches Unity Vanilla HINT_NICE_QUALITY attenuation // Attenuation smoothly decreases to light range. float DistanceAttenuation(float distanceSqr, half2 distanceAttenuation) { // We use a shared distance attenuation for additional directional and puctual lights // for directional lights attenuation will be 1 float lightAtten = rcp(distanceSqr); float2 distanceAttenuationFloat = float2(distanceAttenuation); // Use the smoothing factor also used in the Unity lightmapper. half factor = half(distanceSqr * distanceAttenuationFloat.x); half smoothFactor = saturate(half(1.0) - factor * factor); smoothFactor = smoothFactor * smoothFactor; return lightAtten * smoothFactor; } half AngleAttenuation(half3 spotDirection, half3 lightDirection, half2 spotAttenuation) { // Spot Attenuation with a linear falloff can be defined as // (SdotL - cosOuterAngle) / (cosInnerAngle - cosOuterAngle) // This can be rewritten as // invAngleRange = 1.0 / (cosInnerAngle - cosOuterAngle) // SdotL * invAngleRange + (-cosOuterAngle * invAngleRange) // SdotL * spotAttenuation.x + spotAttenuation.y // If we precompute the terms in a MAD instruction half SdotL = dot(spotDirection, lightDirection); half atten = saturate(SdotL * spotAttenuation.x + spotAttenuation.y); return atten * atten; } Light GetAdditionalPerObjectLight(int perObjectLightIndex, float3 positionWS) { // Abstraction over Light input constants #if USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA float4 lightPositionWS = _AdditionalLightsBuffer[perObjectLightIndex].position; half3 color = _AdditionalLightsBuffer[perObjectLightIndex].color.rgb; half4 distanceAndSpotAttenuation = _AdditionalLightsBuffer[perObjectLightIndex].attenuation; half4 spotDirection = _AdditionalLightsBuffer[perObjectLightIndex].spotDirection; uint lightLayerMask = _AdditionalLightsBuffer[perObjectLightIndex].layerMask; #else float4 lightPositionWS = _AdditionalLightsPosition[perObjectLightIndex]; half3 color = _AdditionalLightsColor[perObjectLightIndex].rgb; half4 distanceAndSpotAttenuation = _AdditionalLightsAttenuation[perObjectLightIndex]; half4 spotDirection = _AdditionalLightsSpotDir[perObjectLightIndex]; uint lightLayerMask = asuint(_AdditionalLightsLayerMasks[perObjectLightIndex]); #endif // Directional lights store direction in lightPosition.xyz and have .w set to 0.0. // This way the following code will work for both directional and punctual lights. float3 lightVector = lightPositionWS.xyz - positionWS * lightPositionWS.w; float distanceSqr = max(dot(lightVector, lightVector), HALF_MIN); half3 lightDirection = half3(lightVector * rsqrt(distanceSqr)); // full-float precision required on some platforms float attenuation = DistanceAttenuation(distanceSqr, distanceAndSpotAttenuation.xy) * AngleAttenuation(spotDirection.xyz, lightDirection, distanceAndSpotAttenuation.zw); Light light; light.direction = lightDirection; light.distanceAttenuation = attenuation; light.shadowAttenuation = 1.0; // This value can later be overridden in GetAdditionalLight(uint i, float3 positionWS, half4 shadowMask) light.color = color; light.layerMask = lightLayerMask; return light; } //v1.6 float3 _CutoffGI; //sampler2D _CameraDepthTexture; RWTexture3D RG0; int LayerToVisualize; float4x4 SEGIVoxelViewFront; float4x4 SEGIVoxelViewLeft; float4x4 SEGIVoxelViewTop; sampler2D _MainTex; sampler2D _EmissionMap; float _Cutoff; float4 _MainTex_ST; half4 _EmissionColor; float SEGISecondaryBounceGain; float _BlockerValue; //v0.2 float shadowedLocalPower; float shadowlessLocalPower; float shadowlessLocalOcclusion; struct v2g { float4 pos : SV_POSITION; half4 uv : TEXCOORD0; float3 normal : TEXCOORD1; float angle : TEXCOORD2; half4 worldPos : TEXCOORD3; //v0.1 half4 attenUV : TEXCOORD4; //v0.1 //METHOD2 LIGHTING_COORDS(5, 6) float3 vertexLighting : TEXCOORD7; }; //v0.1 float attenUV(float lightAtten0, float3 _4LightPos, float3 _worldPos) : SV_Target{ float range = (0.005 * sqrt(1000000 - lightAtten0)) / sqrt(lightAtten0); return distance(_4LightPos, _worldPos) / range; } float atten(float _attenUV) : SV_Target{ return saturate(1.0 / (1.0 + 25.0*_attenUV*_attenUV) * saturate((1 - _attenUV) * 5.0)); } float attenTex(sampler2D _LightTextureB, float _attenUV) : SV_Target{ return tex2D(_LightTextureB, (_attenUV * _attenUV).xx).UNITY_ATTEN_CHANNEL; } struct g2f { float4 pos : SV_POSITION; half4 uv : TEXCOORD0; float3 normal : TEXCOORD1; float angle : TEXCOORD2; half4 worldPos : TEXCOORD3; //v0.1 half4 attenUV : TEXCOORD4; //v0.1 //METHOD2 LIGHTING_COORDS(5, 6) float3 vertexLighting : TEXCOORD7; }; half4 _Color; int _visibleLightsCount; v2g vert(appdata_full v) { v2g o; UNITY_INITIALIZE_OUTPUT(v2g, o); float4 vertex = v.vertex; o.normal = UnityObjectToWorldNormal(v.normal); float3 absNormal = abs(o.normal); o.pos = vertex; o.uv = float4(TRANSFORM_TEX(v.texcoord.xy, _MainTex), 1.0, 1.0); //v0.1 float4 worldPos = mul(unity_ObjectToWorld, v.vertex); o.worldPos = worldPos;// mul(unity_ObjectToWorld, v.vertex); o.attenUV.x = attenUV(unity_4LightAtten0.x, float3(unity_4LightPosX0.x, unity_4LightPosY0.x, unity_4LightPosZ0.x), o.worldPos.xyz); o.attenUV.y = attenUV(unity_4LightAtten0.y, float3(unity_4LightPosX0.y, unity_4LightPosY0.y, unity_4LightPosZ0.y), o.worldPos.xyz); o.attenUV.z = attenUV(unity_4LightAtten0.z, float3(unity_4LightPosX0.z, unity_4LightPosY0.z, unity_4LightPosZ0.z), o.worldPos.xyz); o.attenUV.w = attenUV(unity_4LightAtten0.w, float3(unity_4LightPosX0.w, unity_4LightPosY0.w, unity_4LightPosZ0.w), o.worldPos.xyz); //METHOD2 //v0.1a //if (1 == 1)//(spotLight) //{ /* for (int index = 0; index < 4; index++) { float4 lightPosition = float4(unity_4LightPosX0[index], unity_4LightPosY0[index], unity_4LightPosZ0[index], 1.0); float3 vertexToLightSource = float3(lightPosition.xyz - worldPos); float rho = max(0, dot(vertexToLightSource, unity_SpotDirection[index].xyz)); float spotAtt = (rho - unity_LightAtten[index].x) * unity_LightAtten[index].y; if (index == 0) { o.attenUV.x = saturate(spotAtt); } if (index == 1) { o.attenUV.y = saturate(spotAtt); } if (index == 2) { o.attenUV.z = saturate(spotAtt); } if (index == 3) { o.attenUV.w = saturate(spotAtt); } } //} */ o.vertexLighting = float3(0.0, 0.0, 0.0); float3 worldN = mul((float3x3)unity_ObjectToWorld, SCALED_NORMAL); //#ifdef VERTEXLIGHT_ON /* for (int index = 0; index < 4; index++) { float4 lightPosition = float4(unity_4LightPosX0[index], unity_4LightPosY0[index], unity_4LightPosZ0[index], 1.0); //float3 toLight = unity_LightPosition[i].xyz - viewpos.xyz * unity_LightPosition[i].w; float3 vertexToLightSource = float3(lightPosition.xyz - worldPos); float3 lightDirection = normalize(vertexToLightSource); float squaredDistance = dot(vertexToLightSource, vertexToLightSource); float attenuation = 1.0 / (1.0 + unity_4LightAtten0[index] * squaredDistance); //if (1==1)//(spotLight) //{ // float rho = max(0, dot(vertexToLightSource, float3(1,0,1))); // float spotAtt = rho*11111; // attenuation *= saturate(spotAtt); //} float3 diffuseReflection = attenuation * float3(unity_LightColor[index].rgb) * float3(_Color.rgb)* max(0.0, dot(worldN, lightDirection)); o.vertexLighting = o.vertexLighting + diffuseReflection * 2; } //#endif */ //METHOD3 //#ifdef VERTEXLIGHT_ON /*o.vertexLighting += Shade4PointLights( unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0, unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb, unity_4LightAtten0, worldPos, worldN );*/ //#endif // VERTEXLIGHT_ON //o.vertexLighting =1* ShadeVertexLightsFull( // v.vertex, v.normal, 8, true//absNormal//realNormal //); TRANSFER_VERTEX_TO_FRAGMENT(o); return o; } int SEGIVoxelResolution; [maxvertexcount(3)] void geom(triangle v2g input[3], inout TriangleStream triStream) { v2g p[3]; int i = 0; for (i = 0; i < 3; i++) { p[i] = input[i]; p[i].pos = mul(unity_ObjectToWorld, p[i].pos); //v0.1 /* p[i].worldPos = p[i].pos; p[i].attenUV.x = attenUV(unity_4LightAtten0.x, float3(unity_4LightPosX0.x, unity_4LightPosY0.x, unity_4LightPosZ0.x), p[i].worldPos.xyz); p[i].attenUV.y = attenUV(unity_4LightAtten0.y, float3(unity_4LightPosX0.y, unity_4LightPosY0.y, unity_4LightPosZ0.y), p[i].worldPos.xyz); p[i].attenUV.z = attenUV(unity_4LightAtten0.z, float3(unity_4LightPosX0.z, unity_4LightPosY0.z, unity_4LightPosZ0.z), p[i].worldPos.xyz); p[i].attenUV.w = attenUV(unity_4LightAtten0.w, float3(unity_4LightPosX0.w, unity_4LightPosY0.w, unity_4LightPosZ0.w), p[i].worldPos.xyz);*/ } float3 realNormal = float3(0.0, 0.0, 0.0); float3 V = p[1].pos.xyz - p[0].pos.xyz; float3 W = p[2].pos.xyz - p[0].pos.xyz; realNormal.x = (V.y * W.z) - (V.z * W.y); realNormal.y = (V.z * W.x) - (V.x * W.z); realNormal.z = (V.x * W.y) - (V.y * W.x); float3 absNormal = abs(realNormal); //v0.1a // p[i].worldPos = p[i].pos; ////v0.1 //p[i].worldPos = p[i].pos; for (i = 0; i < 3; i++) { //p[i] = input[i]; if (shadowlessLocalOcclusion != 0) { p[i].attenUV.x = shadowlessLocalOcclusion * attenUV(unity_4LightAtten0.x, float3(unity_4LightPosX0.x, unity_4LightPosY0.x, unity_4LightPosZ0.x), p[i].pos.xyz); p[i].attenUV.y = shadowlessLocalOcclusion * attenUV(unity_4LightAtten0.y, float3(unity_4LightPosX0.y, unity_4LightPosY0.y, unity_4LightPosZ0.y), p[i].pos.xyz); p[i].attenUV.z = shadowlessLocalOcclusion * attenUV(unity_4LightAtten0.z, float3(unity_4LightPosX0.z, unity_4LightPosY0.z, unity_4LightPosZ0.z), p[i].pos.xyz); p[i].attenUV.w = shadowlessLocalOcclusion * attenUV(unity_4LightAtten0.w, float3(unity_4LightPosX0.w, unity_4LightPosY0.w, unity_4LightPosZ0.w), p[i].pos.xyz); //p[i].attenUV = input[i].attenUV; } //METHOD3 if (shadowedLocalPower != 0) { //p[i].vertexLighting = Shade4PointLights( // unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0, // unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb, // unity_4LightAtten0, p[i].pos, realNormal//absNormal//realNormal //); //int _visibleLightsCount = 16; #if defined (_ADDITIONAL_LIGHTS) || defined (USE_FORWARD_PLUS) [loop] //v1.9.9.8 - Ethereal v1.1.8h for (int k = 0; k < _visibleLightsCount-1; k++) //v1.9.9.8 - Ethereal v1.1.8h { //LIGHT 1 float distToRayStartA = length(_WorldSpaceCameraPos - p[i].pos);//v1.9.9.8 - Ethereal v1.1.8h //#ifdef URP11//v1.8 Light light = GetAdditionalPerObjectLight(k, p[i].pos); light.shadowAttenuation = AdditionalLightShadow(k, p[i].pos, light.direction, half4(1, 1, 1, 1), half4(0, 0, 0, 0)); //COOKIE //#if defined(_LIGHT_COOKIES) float3 cookieColor = SampleAdditionalLightCookie(k, p[i].pos); light.color *= cookieColor; //#endif //#else // Light light = GetAdditionalPerObjectLight(k, pos);// GetAdditionalLight(k, pos); //v0.4 URP 10 need an extra shadowmask variable //#endif p[i].vertexLighting += light.color *pow(light.shadowAttenuation, 1)* pow(light.distanceAttenuation, 1); //result.rgb *= light.shadowAttenuation; } #endif // // ShadeVertexLightsFull (float4 vertex, float3 normal, int lightCount, bool spotLight) //p[i].vertexLighting += input[i].vertexLighting; // 101*ShadeVertexLightsFull( // p[i].pos.xyzz, realNormal, 8, true//absNormal//realNormal //); } } int angle = 0; if (absNormal.z > absNormal.y && absNormal.z > absNormal.x) { angle = 0; } else if (absNormal.x > absNormal.y && absNormal.x > absNormal.z) { angle = 1; } else if (absNormal.y > absNormal.x && absNormal.y > absNormal.z) { angle = 2; } else { angle = 0; } for (i = 0; i < 3; i++) { //p[i].worldPos = p[i].pos; ///* if (angle == 0) { p[i].pos = mul(SEGIVoxelViewFront, p[i].pos); } else if (angle == 1) { p[i].pos = mul(SEGIVoxelViewLeft, p[i].pos); } else { p[i].pos = mul(SEGIVoxelViewTop, p[i].pos); } //METHOD3 /*p[i].vertexLighting = 1*Shade4PointLights( unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0, unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb, unity_4LightAtten0, p[i].pos, absNormal );*/ p[i].pos = mul(UNITY_MATRIX_P, p[i].pos); #if defined(UNITY_REVERSED_Z) p[i].pos.z = 1.0 - p[i].pos.z; #else p[i].pos.z *= -1.0; #endif p[i].angle = (float)angle; /* //v0.1 // p[i].worldPos = p[i].pos; ////v0.1 //p[i].worldPos = p[i].pos; if (shadowlessLocalOcclusion != 0) { p[i].attenUV.x = shadowlessLocalOcclusion * attenUV(unity_4LightAtten0.x, float3(unity_4LightPosX0.x, unity_4LightPosY0.x, unity_4LightPosZ0.x), p[i].pos.xyz); p[i].attenUV.y = shadowlessLocalOcclusion * attenUV(unity_4LightAtten0.y, float3(unity_4LightPosX0.y, unity_4LightPosY0.y, unity_4LightPosZ0.y), p[i].pos.xyz); p[i].attenUV.z = shadowlessLocalOcclusion * attenUV(unity_4LightAtten0.z, float3(unity_4LightPosX0.z, unity_4LightPosY0.z, unity_4LightPosZ0.z), p[i].pos.xyz); p[i].attenUV.w = shadowlessLocalOcclusion * attenUV(unity_4LightAtten0.w, float3(unity_4LightPosX0.w, unity_4LightPosY0.w, unity_4LightPosZ0.w), p[i].pos.xyz); } //METHOD3 if (shadowedLocalPower != 0) { p[i].vertexLighting += Shade4PointLights( unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0, unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb, unity_4LightAtten0, p[i].pos, realNormal//absNormal//realNormal ); } */ //METHOD3 } triStream.Append(p[0]); triStream.Append(p[1]); triStream.Append(p[2]); } float3 rgb2hsv(float3 c) { float4 k = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); float4 p = lerp(float4(c.bg, k.wz), float4(c.gb, k.xy), step(c.b, c.g)); float4 q = lerp(float4(p.xyw, c.r), float4(c.r, p.yzx), step(p.x, c.r)); float d = q.x - min(q.w, q.y); float e = 1.0e-10; return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); } float3 hsv2rgb(float3 c) { float4 k = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); float3 p = abs(frac(c.xxx + k.xyz) * 6.0 - k.www); return c.z * lerp(k.xxx, saturate(p - k.xxx), c.y); } float4 DecodeRGBAuint(uint value) { uint ai = value & 0x0000007F; uint vi = (value / 0x00000080) & 0x000007FF; uint si = (value / 0x00040000) & 0x0000007F; uint hi = value / 0x02000000; float h = float(hi) / 127.0; float s = float(si) / 127.0; float v = (float(vi) / 2047.0) * 10.0; float a = ai * 2.0; v = pow(v, 3.0); float3 color = hsv2rgb(float3(h, s, v)); return float4(color.rgb, a); } uint EncodeRGBAuint(float4 color) { //7[HHHHHHH] 7[SSSSSSS] 11[VVVVVVVVVVV] 7[AAAAAAAA] float3 hsv = rgb2hsv(color.rgb); hsv.z = pow(hsv.z, 1.0 / 3.0); uint result = 0; uint a = min(127, uint(color.a / 2.0)); uint v = min(2047, uint((hsv.z / 10.0) * 2047)); uint s = uint(hsv.y * 127); uint h = uint(hsv.x * 127); result += a; result += v * 0x00000080; // << 7 result += s * 0x00040000; // << 18 result += h * 0x02000000; // << 25 return result; } void interlockedAddFloat4(RWTexture3D destination, int3 coord, float4 value) { uint writeValue = EncodeRGBAuint(value); uint compareValue = 0; uint originalValue; [allow_uav_condition] for (int i = 0; i < 18; i++)// while (true) { InterlockedCompareExchange(destination[coord], compareValue, writeValue, originalValue); if (compareValue == originalValue) break; compareValue = originalValue; float4 originalValueFloats = DecodeRGBAuint(originalValue); writeValue = EncodeRGBAuint(originalValueFloats + value); } } void interlockedAddFloat4b(RWTexture3D destination, int3 coord, float4 value) { uint writeValue = EncodeRGBAuint(value); uint compareValue = 0; uint originalValue; [allow_uav_condition] for (int i = 0; i < 18; i++)// while (true) { InterlockedCompareExchange(destination[coord], compareValue, writeValue, originalValue); if (compareValue == originalValue) break; compareValue = originalValue; float4 originalValueFloats = DecodeRGBAuint(originalValue); writeValue = EncodeRGBAuint(originalValueFloats + value); } } float4x4 SEGIVoxelToGIProjection; float4x4 SEGIVoxelProjectionInverse; sampler2D SEGISunDepth; float4 SEGISunlightVector; float4 GISunColor; float4 SEGIVoxelSpaceOriginDelta; sampler3D SEGIVolumeTexture1; int SEGIInnerOcclusionLayers; #define VoxelResolution (SEGIVoxelResolution * (1 + SEGIVoxelAA)) int SEGIVoxelAA; float4 frag(g2f input) : SV_TARGET { int3 coord = int3((int)(input.pos.x), (int)(input.pos.y), (int)(input.pos.z * VoxelResolution)); float3 absNormal = abs(input.normal); int angle = 0; angle = (int)input.angle; if (angle == 1) { coord.xyz = coord.zyx; coord.z = VoxelResolution - coord.z - 1; } else if (angle == 2) { coord.xyz = coord.xzy; coord.y = VoxelResolution - coord.y - 1; } float3 fcoord = (float3)(coord.xyz) / VoxelResolution; float4 shadowPos = mul(SEGIVoxelProjectionInverse, float4(fcoord * 2.0 - 1.0, 0.0)); shadowPos = mul(SEGIVoxelToGIProjection, shadowPos); shadowPos.xyz = shadowPos.xyz * 0.5 + 0.5; float sunDepth = tex2Dlod(SEGISunDepth, float4(shadowPos.xy, 0, 0)).x; #if defined(UNITY_REVERSED_Z) sunDepth = 1.0 - sunDepth; #endif float sunVisibility = saturate((sunDepth - shadowPos.z + 0.2525) * 1000.0); float sunNdotL = saturate(dot(input.normal, -SEGISunlightVector.xyz)); float4 tex = tex2D(_MainTex, input.uv.xy); float4 emissionTex = tex2D(_EmissionMap, input.uv.xy); float4 color = _Color; if (length(_Color.rgb) < 0.0001) { color.rgb = float3(1, 1, 1); } //v0.7 float3 col = sunVisibility.xxx * sunNdotL * color.rgb * tex.rgb * GISunColor.rgb * GISunColor.a + _EmissionColor.rgb * (0.1 + (1 - color.a) * 5) * emissionTex.rgb; //1.0g //float3 col = sunVisibility.xxx * sunNdotL * color.rgb * tex.rgb * GISunColor.rgb * GISunColor.a + _EmissionColor.rgb * 0.9 * emissionTex.rgb; float4 prevBounce = tex3D(SEGIVolumeTexture1, fcoord + SEGIVoxelSpaceOriginDelta.xyz); col.rgb += prevBounce.rgb * 1.6 * SEGISecondaryBounceGain * tex.rgb * color.rgb; float4 result = float4(col.rgb, 2.0); const float sqrt2 = sqrt(2.0) * 1.0; coord /= (uint)SEGIVoxelAA + 1u; //v0.1 - 1.6 float depthA = 1 - Linear01Depth(tex2D(_CameraDepthTexture, input.uv.xy).x); if (depthA + 0.02*_CutoffGI.x > length(_WorldSpaceCameraPos - coord.xyz) / (VoxelResolution*_CutoffGI.y)) { result.a += 90.0 * _CutoffGI.z; } if (_BlockerValue > 0.01) { result.a += 20.0; result.a += _BlockerValue; result.rgb = float3(0.0, 0.0, 0.0); } //v0.1 float4 _atten = 0; //float _atten.x = attenTex(_LightTextureB0, f.attenUV.x); _atten.x = atten(input.attenUV.x); _atten.y = atten(input.attenUV.y); _atten.z = atten(input.attenUV.z); _atten.w = atten(input.attenUV.w); //fixed4 col = tex2D(_MainTex, input.uv.xy) * input.color; if (shadowlessLocalPower != 0) { result.rgb += color.rgb * tex.rgb * unity_LightColor[0].rgb *shadowlessLocalPower* (1 / distance(float3(unity_4LightPosX0.x, unity_4LightPosY0.x, unity_4LightPosZ0.x), input.worldPos.xyz)) * _atten.x; result.rgb += color.rgb * tex.rgb * unity_LightColor[1].rgb *shadowlessLocalPower* (1 / distance(float3(unity_4LightPosX0.y, unity_4LightPosY0.y, unity_4LightPosZ0.y), input.worldPos.xyz)) * _atten.y; result.rgb += color.rgb * tex.rgb * unity_LightColor[2].rgb *shadowlessLocalPower* (1 / distance(float3(unity_4LightPosX0.z, unity_4LightPosY0.z, unity_4LightPosZ0.z), input.worldPos.xyz)) * _atten.z; result.rgb += color.rgb * tex.rgb * unity_LightColor[3].rgb *shadowlessLocalPower* (1 / distance(float3(unity_4LightPosX0.w, unity_4LightPosY0.w, unity_4LightPosZ0.w), input.worldPos.xyz)) * _atten.w; } //result.rgb += unity_LightColor[0].rgb * _atten.x; //result.rgb += unity_LightColor[1].rgb * _atten.y; //result.rgb += unity_LightColor[2].rgb * _atten.z; //result.rgb += unity_LightColor[3].rgb * _atten.w; //METHOD3 if (shadowedLocalPower != 0) { //float atten = LIGHT_ATTENUATION(input); //result.rgb += color.rgb * float3(input.vertexLighting.rgb*0.02 * shadowedLocalPower) * tex.rgb* atten; result.rgb += color.rgb * float3(input.vertexLighting.rgb * 0.01 * shadowedLocalPower) * tex.rgb * 1; } float atten = LIGHT_ATTENUATION(input); //result.rgb += ShadeVertexLightsFull(fcoord.xyzz, input.normal, 4, true) * shadowedLocalPower * tex.rgb * atten; //Light mainLight = GetMainLight(input.shadowCoord); interlockedAddFloat4(RG0, coord, result); if (SEGIInnerOcclusionLayers > 0) { interlockedAddFloat4b(RG0, coord - int3((int)(input.normal.x * sqrt2 * 1.0), (int)(input.normal.y * sqrt2 * 1.0), (int)(input.normal.z * sqrt2 * 1.0)), float4(0.0, 0.0, 0.0, 8.0)); } if (SEGIInnerOcclusionLayers > 1) { interlockedAddFloat4b(RG0, coord - int3((int)(input.normal.x * sqrt2 * 2.0), (int)(input.normal.y * sqrt2 * 2.0), (int)(input.normal.z * sqrt2 * 2.0)), float4(0.0, 0.0, 0.0, 22.0)); } return float4(0.0, 0.0, 0.0, 0.0); } ENDCG } } FallBack Off//FallBack "Diffuse"//FallBack Off }