#if !defined(MY_LIGHTING_INCLUDED) #define MY_LIGHTING_INCLUDED #include "UnityCG.cginc" #include "Lighting.cginc" #include "UnityPBSLighting.cginc" #include "AutoLight.cginc" #include "PoiShatterHelpers.cginc" //Structs struct appdata { float4 vertex: POSITION; float3 normal: NORMAL; float4 tangent: TANGENT; float2 texcoord: TEXCOORD0; float2 texcoord1: TEXCOORD1; }; struct v2g { float2 uv: TEXCOORD0; float3 normal: TEXCOORD1; #if defined(BINORMAL_PER_FRAGMENT) float4 tangent: TEXCOORD2; #else float3 tangent: TEXCOORD2; float3 binormal: TEXCOORD3; #endif float4 pos: SV_POSITION; float4 worldPos: TEXCOORD4; float4 localPos: TEXCOORD5; SHADOW_COORDS(6) }; struct g2f { float2 uv: TEXCOORD0; float3 normal: TEXCOORD1; #if defined(BINORMAL_PER_FRAGMENT) float4 tangent: TEXCOORD2; #else float3 tangent: TEXCOORD2; float3 binormal: TEXCOORD3; #endif float4 pos: SV_POSITION; float4 worldPos: TEXCOORD4; float4 localPos: TEXCOORD5; float4 waveSettings: TEXCOORD6; SHADOW_COORDS(7) }; //Properties float4 _Color; float _Desaturation; sampler2D _MainTex; float4 _MainTex_ST; sampler2D _BumpMap; float4 _BumpMap_ST; sampler2D _DetailNormalMap; float4 _DetailNormalMap_ST; float _BumpScale; float _DetailNormalMapScale; sampler2D _WaveTexture; float4 _WaveTexture_ST; sampler2D _UnderWaveTexture; float4 _UnderWaveTexture_ST; float _ShowUnderWave; float4 _WaveSpeed; float4 _WaveSlope; float4 _WaveDensity; float _HeightThreshold; float4 _WaveColor; float _WaveEmission; float _UnderWaveEmission; float4 _underWaveColor; float _WaveHeight; samplerCUBE _CubeMap; float _SampleWorld; float _AdditiveClearCoat; float _PurelyAdditive; sampler2D _MetallicMap; float4 _MetallicMap_ST; float _Metallic; sampler2D _RoughnessMap; float4 _RoughnessMap_ST; float _Roughness; sampler2D _Matcap; sampler2D _MatcapMap; float4 _MatcapMap_ST; float4 _MatcapColor; float _MatcapStrength; float _ReplaceWithMatcap; float _MultiplyMatcap; float _AddMatcap; sampler2D _SpecularMap; float4 _SpecularMap_ST; float _Gloss; float4 _EmissionColor; sampler2D _EmissionMap; float4 _EmissionMap_ST; sampler2D _EmissionMask; float4 _EmissionMask_ST; float _EmissionStrength; float4 _EmissiveScroll_Direction; float4 _EmissionScrollSpeed; float _EmissiveScroll_Width; float _EmissiveScroll_Velocity; float _EmissiveScroll_Interval; float _EmissiveBlink_Min; float _EmissiveBlink_Max; float _EmissiveBlink_Velocity; float _ScrollingEmission; sampler2D _Ramp; float _ForceLightDirection; float _ShadowStrength; float _ShadowOffset; float3 _LightDirection; float _ForceShadowStrength; float _MinBrightness; float _MaxDirectionalIntensity; sampler2D _AdditiveRamp; float _FlatOrFullAmbientLighting; float4 _SpecularColor; float _SpecularBias; float _SpecularStrength; float _SpecularSize; float _HardSpecular; float4 _RimLightColor; float _RimWidth; float _RimStrength; float _RimSharpness; float _RimLightColorBias; float4 _RimTexPanSpeed; sampler2D _RimTex; float4 _RimTex_ST; float _Clip; float3 getCameraPosition() { #ifdef USING_STEREO_MATRICES return lerp(unity_StereoWorldSpaceCameraPos[0], unity_StereoWorldSpaceCameraPos[1], 0.5); #endif return _WorldSpaceCameraPos; } float3 getCameraForward() { #if UNITY_SINGLE_PASS_STEREO float3 p1 = mul(unity_StereoCameraToWorld[0], float4(0, 0, 1, 1)); float3 p2 = mul(unity_StereoCameraToWorld[0], float4(0, 0, 0, 1)); #else float3 p1 = mul(unity_CameraToWorld, float4(0, 0, 1, 1)); float3 p2 = mul(unity_CameraToWorld, float4(0, 0, 0, 1)); #endif return normalize(p2 - p1); } v2g vert(appdata v) { v2g o; TANGENT_SPACE_ROTATION; o.localPos = v.vertex; o.pos = UnityObjectToClipPos(v.vertex); o.worldPos = mul(unity_ObjectToWorld, v.vertex); o.uv = v.texcoord.xy; o.normal = UnityObjectToWorldNormal(v.normal); #if defined(BINORMAL_PER_FRAGMENT) o.tangent = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w); #else o.tangent = UnityObjectToWorldDir(v.tangent.xyz); o.binormal = CreateBinormal(o.normal, o.tangent, v.tangent.w); #endif TRANSFER_SHADOW(i); return o; } float3 WaveHeight(float3 position) { return(sin( 2 * pow(((sin((position.x + _Time.x * _WaveSpeed.x) * _WaveDensity.x + sin(_Time.y * _WaveSpeed.x)) + 1) / 2), _WaveSlope.x) + 2 * pow(((sin((position.y + _Time.x * _WaveSpeed.y) * _WaveDensity.y + sin(_Time.y * _WaveSpeed.y)) + 1) / 2), _WaveSlope.y) + 2 * pow(((sin((position.z + _Time.x * _WaveSpeed.z) * _WaveDensity.z + sin(_Time.y * _WaveSpeed.z)) + 1) / 2), _WaveSlope.z) ) + 1) / 2; } [maxvertexcount(6)] void geom(triangle v2g IN[3], inout TriangleStream < g2f > tristream) { float4 mid = (IN[0].localPos + IN[1].localPos + IN[2].localPos) / 3; float4 objectPosition = mul(unity_ObjectToWorld, float4(0, 0, 0, 1)); float4 WavePosition = objectPosition; float hash = random(mid); float distanceToWave = clamp(WaveHeight(mid.xyz), 0, 1); if (distanceToWave <= _HeightThreshold) { distanceToWave = 0; } float range = 1 - _HeightThreshold; float delta = 1 - distanceToWave; float percent = delta / range; percent = saturate(percent); if(percent == 0) return; g2f o; g2f milk[3]; float count = 0; float3 edgeA = IN[1].localPos - IN[0].localPos; float3 edgeB = IN[2].localPos - IN[0].localPos; float3 c = cross(edgeA, edgeB); float3 outDir = normalize(c); float3 normalDir = normalize(c); float4 pos = float4(0, 0, 0, 0); float3 over = cos(IN[1].localPos * 1234.56); for (int i = 0; i < 3; i ++) { if(percent < .5) { over = normalize(over); pos.xyz = (lerp(over, 0, percent * 2) + normalDir) * _WaveHeight; } else { pos.xyz = normalDir * _WaveHeight * (1 - percent) * 2 ; } o.localPos = IN[i].localPos + pos; o.worldPos = mul(unity_ObjectToWorld, o.localPos); o.pos = UnityObjectToClipPos(IN[i].localPos + pos); o.uv = IN[i].uv; // r = wave height percentage // g = isUnderside? o.waveSettings = float4(0, 0, 0, 0); o.normal = IN[i].normal; #if defined(BINORMAL_PER_FRAGMENT) o.tangent = IN[i].tangent; #else o.tangent = IN[i].tangent; o.binormal = IN[i].binormal; #endif if (distanceToWave > 0) { o.waveSettings = float4(1-percent, 0, 0, 0); milk[i].binormal = IN[i].binormal; milk[i].localPos = IN[i].localPos; milk[i].normal = IN[i].normal; milk[i].pos = IN[i].pos; milk[i].tangent = IN[i].tangent; milk[i].uv = IN[i].uv; if(distanceToWave > 0) { milk[i].waveSettings = float4(1-percent, 1, 0, 0); } milk[i].worldPos = IN[i].worldPos; count ++ ; } tristream.Append(o); } if(_ShowUnderWave) { tristream.RestartStrip(); if(count == 3) { for (int i = 0; i < 3; i ++) { for (int i = 0; i < 3; i ++) { tristream.Append(milk[i]); } } } } tristream.RestartStrip(); } void InitializeFragmentNormal(inout g2f i) { float3 mainNormal = UnpackScaleNormal(tex2D(_BumpMap, TRANSFORM_TEX(i.uv, _BumpMap)), _BumpScale); float3 detailNormal = UnpackScaleNormal(tex2D(_DetailNormalMap, TRANSFORM_TEX(i.uv, _DetailNormalMap)), _DetailNormalMapScale); float3 tangentSpaceNormal = BlendNormals(mainNormal, detailNormal); #if defined(BINORMAL_PER_FRAGMENT) float3 binormal = CreateBinormal(i.normal, i.tangent.xyz, i.tangent.w); #else float3 binormal = i.binormal; #endif i.normal = normalize( tangentSpaceNormal.x * i.tangent + tangentSpaceNormal.y * binormal + tangentSpaceNormal.z * i.normal ); } float4 frag(g2f i, float facing: VFACE): SV_Target { float Pi = 3.141592654; #ifdef FORWARD_BASE_PASS float3 _light_direction_var = normalize(_LightDirection); if(!any(_WorldSpaceLightPos0) == 0 && _ForceLightDirection == 0) { _light_direction_var = _WorldSpaceLightPos0; } #else #if defined(POINT) || defined(SPOT) float3 _light_direction_var = normalize(_WorldSpaceLightPos0.xyz - i.worldPos); #elif defined(DIRECTIONAL) return 0; float3 _light_direction_var = _WorldSpaceLightPos0; #endif #endif // diffuse float4 _main_tex_var = tex2D(_MainTex, TRANSFORM_TEX(i.uv, _MainTex)); float4 _diffuse_var = float4(lerp(_main_tex_var.rgb, dot(_main_tex_var.rgb, float3(0.3, 0.59, 0.11)), _Desaturation) * _Color.rgb, _main_tex_var.a * _Color.a); float4 _underwave_tex_var = tex2D(_UnderWaveTexture, TRANSFORM_TEX(i.uv, _UnderWaveTexture)) * _underWaveColor; // cutout #ifndef TRANSPARENT clip(_diffuse_var.a - _Clip); #endif // shatterDiffuse float4 _wave_tex_var = tex2D(_WaveTexture, TRANSFORM_TEX(i.uv, _WaveTexture)) * _WaveColor; if (i.waveSettings.r > 0) { _diffuse_var = lerp(_diffuse_var, _wave_tex_var, i.waveSettings.r); } // math InitializeFragmentNormal(i); float3 _camera_to_vert_var = normalize(getCameraPosition() - i.worldPos); float3 _camera_to_vert_vr_var = normalize(_WorldSpaceCameraPos - i.worldPos); float3 _camera_vert_dot_var = abs(dot(_camera_to_vert_var, i.normal)); // metal float _metallic_map_var = tex2D(_MetallicMap, TRANSFORM_TEX(i.uv, _MetallicMap)); float _final_metalic_var = _metallic_map_var * _Metallic; float _roughness_map_var = tex2D(_RoughnessMap, TRANSFORM_TEX(i.uv, _RoughnessMap)); float roughness = (1 - _final_metalic_var * _Roughness * _roughness_map_var); roughness *= 1.7 - 0.7 * roughness; float3 reflectedDir = reflect(-_camera_to_vert_vr_var, i.normal); float3 reflection = float3(0, 0, 0); float4 envSample = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, reflectedDir, roughness * UNITY_SPECCUBE_LOD_STEPS); float interpolator = unity_SpecCube0_BoxMin.w; UNITY_BRANCH if (interpolator < 0.99999) { //Probe 1 float4 reflectionData0 = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, reflectedDir, roughness * UNITY_SPECCUBE_LOD_STEPS); float3 reflectionColor0 = DecodeHDR(reflectionData0, unity_SpecCube0_HDR); //Probe 2 float4 reflectionData1 = UNITY_SAMPLE_TEXCUBE_SAMPLER_LOD(unity_SpecCube1, unity_SpecCube0, reflectedDir, roughness * UNITY_SPECCUBE_LOD_STEPS); float3 reflectionColor1 = DecodeHDR(reflectionData1, unity_SpecCube1_HDR); reflection = lerp(reflectionColor1, reflectionColor0, interpolator); } else { float4 reflectionData = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, reflectedDir, roughness * UNITY_SPECCUBE_LOD_STEPS); reflection = DecodeHDR(reflectionData, unity_SpecCube0_HDR); } bool no_probe = unity_SpecCube0_HDR.a == 0 && envSample.a == 0; float lighty_boy_uwu_var = 0; if (no_probe || _SampleWorld) { lighty_boy_uwu_var = 1; reflection = texCUBElod(_CubeMap, float4(reflectedDir, roughness * UNITY_SPECCUBE_LOD_STEPS)); } // matcap / spehere textures half2 matcapUV = getMatcapUV(_camera_to_vert_vr_var, i.normal); float _matcapMap_var = tex2D(_MatcapMap, TRANSFORM_TEX(i.uv, _MatcapMap)); float3 _matcap_var = tex2D(_Matcap, matcapUV) * _MatcapColor * _MatcapStrength; //rim lighting float4 rimColor = tex2D(_RimTex, TRANSFORM_TEX(i.uv, _RimTex) + (_Time.y * _RimTexPanSpeed.xy)) * _RimLightColor; float rim = pow((1 - _camera_vert_dot_var), (1 - _RimWidth) * 10); _RimSharpness /= 2; rim = (smoothstep(_RimSharpness, 1 - _RimSharpness, rim)); // lighting UNITY_LIGHT_ATTENUATION(attenuation, i, i.worldPos.xyz); float nDotL = dot(i.normal, _light_direction_var); float fakeLight = clamp((nDotL + 1) / 2 + _ShadowOffset, 0, 1); float4 LightingRamp = tex2D(_Ramp, float2(fakeLight, fakeLight)); #if defined(FORWARD_BASE_PASS) //return float4(ShadeSH9(half4(0.0, 0.0, 0.0, 1.0)),1); float3 _flat_lighting_var = 1; float3 ambient = ShadeSH9(float4(i.normal * _FlatOrFullAmbientLighting, 1)); if (any(_LightColor0.rgb)) { float4 lightZero = min(_LightColor0, _MaxDirectionalIntensity); if(_ForceShadowStrength == 0) { _flat_lighting_var = ambient + lightZero.rgb * lerp(1, LightingRamp, _ShadowStrength); _flat_lighting_var = clamp(_flat_lighting_var, _MinBrightness, max(lightZero.a, ambient)); } else { _flat_lighting_var = (ambient + lightZero.rgb) * lerp(1, LightingRamp, _ShadowStrength); _flat_lighting_var = clamp(_flat_lighting_var, _MinBrightness, max(lightZero.a, ambient)); } } else { _flat_lighting_var = clamp(ambient + ambient * lerp(1, LightingRamp, _ShadowStrength) - ambient * (_ShadowStrength * lerp(.75, 1, _ForceShadowStrength)), _MinBrightness, ambient); } //return float4(_flat_lighting_var, 1); #else float3 _flat_lighting_var = _LightColor0.rgb * attenuation * tex2D(_AdditiveRamp, .5 * nDotL + .5); #endif // emission float4 _Emissive_Tex_var = tex2D(_EmissionMap, TRANSFORM_TEX(i.uv, _EmissionMap) + _Time.y * _EmissionScrollSpeed); /// float4 _emission_var = _Emissive_Tex_var * _EmissionColor * _EmissionStrength; // scrolling emission if (_ScrollingEmission == 1) { float phase = dot(i.localPos, _EmissiveScroll_Direction); phase -= _Time.y * _EmissiveScroll_Velocity; phase /= _EmissiveScroll_Interval; phase -= floor(phase); float width = _EmissiveScroll_Width; phase = (pow(phase, width) + pow(1 - phase, width * 4)) * 0.5; _emission_var *= phase; } // blinking emission float amplitude = (_EmissiveBlink_Max - _EmissiveBlink_Min) * 0.5f; float base = _EmissiveBlink_Min + amplitude; float emissiveBlink = sin(_Time.y * _EmissiveBlink_Velocity) * amplitude + base; _emission_var *= emissiveBlink; float _Emission_mask_var = tex2D(_EmissionMask, TRANSFORM_TEX(i.uv, _EmissionMask)); _emission_var *= _Emission_mask_var; // add it all up float4 finalColor = _diffuse_var; float3 _rim_color_var = lerp(finalColor.rgb, rimColor, _RimLightColorBias); finalColor.rgb = lerp(finalColor.rgb, _rim_color_var, rim * _RimLightColor.a * rimColor.a); finalColor.rgb = lerp(finalColor, _matcap_var, _ReplaceWithMatcap * _matcapMap_var); finalColor.rgb *= lerp(1, _matcap_var, _MultiplyMatcap * _matcapMap_var); finalColor.rgb += _matcap_var * _AddMatcap * _matcapMap_var; float4 finalColorBeforeLighting = finalColor; finalColor.rgb *= _flat_lighting_var; #ifdef FORWARD_BASE_PASS float3 finalreflections = reflection.rgb * lerp(finalColorBeforeLighting.rgb, 1, _PurelyAdditive); finalColor.rgb = finalColor.rgb * lerp((1 - _final_metalic_var), 1, _AdditiveClearCoat); finalColor.rgb += (finalreflections * ((1 - roughness + _final_metalic_var) / 2)) * lerp(1, _flat_lighting_var, lighty_boy_uwu_var); #endif // specular #if (defined(POINT) || defined(SPOT)) _SpecularColor.rgb = _LightColor0.rgb; _SpecularBias = 0; #endif float specular_map_var = tex2D(_SpecularMap, TRANSFORM_TEX(i.uv, _SpecularMap)); float3 specularColor = ((finalColor.a * _SpecularStrength) * lerp(finalColor.rgb * _LightColor0.rgb, _SpecularColor.rgb, _SpecularBias)); float specPow = exp2(_Gloss * 20.0 + 1.0); float normTerm = (specPow + 10) / (10 * Pi); float3 halfDirection = normalize(_camera_to_vert_vr_var + _light_direction_var); float3 _specular_var = float3(0, 0, 0); if(_HardSpecular == 1) { _specular_var = step(1 - (.5 * dot(halfDirection, i.normal) + .5), _SpecularSize) * _SpecularColor * _SpecularBias * specular_map_var; } else { _specular_var = pow(max(0, dot(halfDirection, i.normal)), specPow) * normTerm * specularColor * _SpecularStrength * specular_map_var; } #if defined(FORWARD_BASE_PASS) finalColor.rgb += _specular_var * _flat_lighting_var; finalColor.rgb += lerp(_emission_var, _wave_tex_var * _WaveEmission, i.waveSettings.r) + ((rim * _rim_color_var * _RimStrength) * rimColor.a); if(i.waveSettings.g > 0) { finalColor.rgb = _underwave_tex_var.rgb * _flat_lighting_var; finalColor.rgb += _underwave_tex_var.rgb * _UnderWaveEmission; } #else finalColor.rgb += _specular_var; #endif #if(defined(POINT) || defined(SPOT)) finalColor *= (1 - _final_metalic_var); #endif return finalColor; } #endif