/* * Copyright (c) Meta Platforms, Inc. and affiliates. * All rights reserved. * * Licensed under the Oculus SDK License Agreement (the "License"); * you may not use the Oculus SDK except in compliance with the License, * which is provided at the time of installation or download, or which * otherwise accompanies this software in either electronic or hard copy form. * * You may obtain a copy of the License at * * https://developer.oculus.com/licenses/oculussdk/ * * Unless required by applicable law or agreed to in writing, the Oculus SDK * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ Shader "TheWorldBeyond/OppyDimension" { Properties { _SaturationAmount("Saturation Amount", Range(0 , 1)) = 1 //_SaturationDistance("Saturation Distance", Range(0 , 1)) = 1 _FogCubemap("Fog Cubemap", CUBE) = "white" {} _FogStrength("Fog Strength", Range(0 , 1)) = 1 _FogStartDistance("Fog Start Distance", Range(0 , 100)) = 1 _FogEndDistance("Fog End Distance", Range(0 , 2000)) = 100 _FogExponent("Fog Exponent", Range(0 , 1)) = 1 _LightingRamp("Lighting Ramp", 2D) = "white" {} _MainTex("MainTex", 2D) = "white" {} _TriPlanarFalloff("Triplanar Falloff", Range(0 , 10)) = 1 _OppyPosition("Oppy Position", Vector) = (0,1000,0,0) _OppyRippleStrength("Oppy Ripple Strength", Range(0 , 1)) = 1 _MaskRippleStrength("Mask Ripple Strength", Range(0, 1)) = 0 _Color("Color", Color) = (0,0,0,0) _EffectPosition("Effect Position", Vector) = (0,1000,0,1) _EffectTimer("Effect Timer", Range(0.0,1.0)) = 1.0 _InvertedMask("Inverted Mask", float) = 1 [HideInInspector] _texcoord("", 2D) = "white" {} } SubShader { Tags{ "RenderType" = "Opaque" "Queue" = "Geometry+0" } LOD 100 CGINCLUDE #pragma target 3.0 ENDCG AlphaToMask Off Cull Back ColorMask RGBA ZWrite On ZTest LEqual // the blending here (specifically the second part of each line: Min, One Zero) is what reveals Passthrough BlendOp Add, Min Blend One Zero, One Zero Offset 0 , 0 Pass { Name "Base" Tags { "LightMode" = "ForwardBase" } CGPROGRAM #ifndef UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX // only defining to not throw compilation error over Unity 5.5 #define UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input) #endif #pragma vertex vert #pragma fragment frag #pragma multi_compile_instancing #include "UnityCG.cginc" #include "Lighting.cginc" #include "UnityShaderVariables.cginc" #include "AutoLight.cginc" struct vertexInput { float4 vertex : POSITION; half3 normal : NORMAL; half4 texcoord : TEXCOORD0; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct vertexOutput { float4 vertex : SV_POSITION; float3 worldPos : TEXCOORD0; half3 worldNormal : TEXCOORD1; half3 projNormal : TEXCOORD2; half3 normalSign : TEXCOORD3; half3 worldViewDirection : TEXCOORD4; half foggingRange : TEXCOORD5; UNITY_VERTEX_INPUT_INSTANCE_ID UNITY_VERTEX_OUTPUT_STEREO }; uniform sampler2D _LightingRamp; uniform sampler2D _MainTex; uniform half4 _MainTex_ST; uniform half _TriPlanarFalloff; uniform half4 _Color; uniform samplerCUBE _FogCubemap; uniform half _FogStartDistance; uniform half _FogEndDistance; uniform half _FogExponent; uniform half _SaturationAmount; uniform half _FogStrength; uniform float3 _OppyPosition; uniform half _OppyRippleStrength; uniform half _MaskRippleStrength; uniform float4 _EffectPosition; uniform float _EffectTimer; uniform float _InvertedMask; inline half4 TriplanarSampler(sampler2D projectedTexture, float3 worldPos, half3 normalSign, half3 projNormal, half2 tiling) { half4 xNorm = tex2D(projectedTexture, tiling * worldPos.zy * half2(normalSign.x, 1.0) + _MainTex_ST.zw); half4 yNorm = tex2D(projectedTexture, tiling * worldPos.xz * half2(normalSign.y, 1.0) + _MainTex_ST.zw); half4 zNorm = tex2D(projectedTexture, tiling * worldPos.xy * half2(-normalSign.z, 1.0) + _MainTex_ST.zw); return ( xNorm * projNormal.x ) + ( yNorm * projNormal.y ) + ( zNorm * projNormal.z ); } half3 fastPow(half3 a, half b) { return a / ((1.0 - b) * a + b); } vertexOutput vert(vertexInput v) { vertexOutput o; UNITY_SETUP_INSTANCE_ID(v); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); UNITY_TRANSFER_INSTANCE_ID(v, o); o.worldNormal = UnityObjectToWorldNormal(v.normal); o.vertex = UnityObjectToClipPos(v.vertex); o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; o.worldViewDirection = normalize(UnityWorldSpaceViewDir(o.worldPos)); o.projNormal= (pow(abs(o.worldNormal.xyz), _TriPlanarFalloff)); o.projNormal /= (o.projNormal.x + o.projNormal.y + o.projNormal.z) + 0.00001; o.normalSign = sign(o.worldNormal.xyz); o.foggingRange = clamp(((distance(_WorldSpaceCameraPos, o.worldPos) - _FogStartDistance) / (_FogEndDistance - _FogStartDistance)), 0.0, 1.0); o.foggingRange = fastPow(o.foggingRange, _FogExponent); return o; } fixed4 frag(vertexOutput i) : SV_Target { UNITY_SETUP_INSTANCE_ID(i); UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); // main texture half4 mainTextureTriPlanar = TriplanarSampler(_MainTex, i.worldPos, i.normalSign, i.projNormal, _MainTex_ST.xy ); // distance gradient half distanceToOppy = pow(distance(_OppyPosition, i.worldPos), 1.5); half distanceToOppyMask = saturate(1 - (distanceToOppy * 0.2)); half distanceRipple = saturate(sin((distanceToOppy * 6) + (_Time.w * 2) ) * 0.5 + 0.25) * distanceToOppyMask * 4; // noisy mask half noisyMask = ((((_Time.y * 0.06 + (mainTextureTriPlanar.b * 1.73)) + (_Time.y * 0.19 + (mainTextureTriPlanar.g * 1.52))) % 1.0)); noisyMask = abs(noisyMask - 0.5) * 2; // lighting half halfLambert = dot(_WorldSpaceLightPos0.xyz, i.worldNormal) * 0.5 + 0.5; half4 lightingRamp = tex2D(_LightingRamp, halfLambert.xx); half4 finalLighting = (half4(_LightColor0.rgb, 0.0) * lightingRamp) + (half4(UNITY_LIGHTMODEL_AMBIENT.xyz, 0)); half4 litTexture = (finalLighting * _Color) + (mainTextureTriPlanar.rrrr * ((noisyMask * 0.85) + (distanceRipple * _OppyRippleStrength))); // fogging half4 foggingColor = texCUBE(_FogCubemap, i.worldViewDirection); half4 foggedColor = lerp(litTexture, foggingColor , (i.foggingRange * _FogStrength)); // desaturating half desaturatedColor = dot(foggedColor, half3(0.299, 0.587, 0.114)); // saturating with distance half3 finalColor = lerp( desaturatedColor.xxx, foggedColor, _SaturationAmount); finalColor = fastPow(finalColor, 0.455); // clip out pixels when toggling walls // this allows depth writing to still happen, ensuring that transparent effects aren't visible "through" the wall float radialDist = distance(i.worldPos, _EffectPosition) * 10; float dist = saturate(radialDist + 5 - _EffectTimer * 50); // "max" the ring radius if (_EffectTimer >= 1.0) { dist = 0; } float alpha = lerp(dist, 1 - dist, _InvertedMask); clip(alpha.r - 0.5); half distanceToBall = distance(_OppyPosition, i.worldPos); half maskRipple = saturate(sin((distanceToBall * 20) + (_Time.w * 2)) * 0.5 + 0.25) * saturate(1 - (distanceToBall * 0.5)) * 0.7; maskRipple *= saturate((distanceToBall-0.2)*5); return half4(finalColor, maskRipple * _MaskRippleStrength); } ENDCG } } }