diff --git a/EditorPreview/Editor/PlayerPositionsToShaderPreview.cs b/EditorPreview/Editor/PlayerPositionsToShaderPreview.cs index dc7d5b3..321c96e 100644 --- a/EditorPreview/Editor/PlayerPositionsToShaderPreview.cs +++ b/EditorPreview/Editor/PlayerPositionsToShaderPreview.cs @@ -9,7 +9,6 @@ public static class PlayerPositionsToShaderPreview { const double kTickInterval = 0.1; // seconds static double _nextTick; - static readonly MaterialPropertyBlock _mpb = new MaterialPropertyBlock(); static readonly Dictionary _cache = new Dictionary(); struct Cache @@ -47,7 +46,7 @@ public static class PlayerPositionsToShaderPreview { if (b == null || !b.isActiveAndEnabled) continue; if (EditorUtility.IsPersistent(b)) continue; // skip assets - PushFromUdonBehaviour(b); + PushFromBehaviour(b); } SceneView.RepaintAll(); @@ -82,7 +81,7 @@ public static class PlayerPositionsToShaderPreview } } - static void PushFromUdonBehaviour(PlayerPositionsToShader src) + static void PushFromBehaviour(PlayerPositionsToShader src) { int max = Mathf.Max(1, src.maxLights); EnsureArrays(src, max); @@ -93,6 +92,7 @@ public static class PlayerPositionsToShaderPreview var directions = c.directions; var types = c.types; + // Clear arrays to safe defaults for (int i = 0; i < max; i++) { positions[i] = Vector4.zero; @@ -101,36 +101,61 @@ public static class PlayerPositionsToShaderPreview types[i] = 0f; } - // 🔗 Use the Editor-side function defined on the partial class + // Use the Editor-side function defined on the partial class int count = 0; try { src.Editor_BuildPreview(out positions, out colors, out directions, out types, out count); + // replace cache arrays if sizes changed - if (positions.Length != c.size) EnsureArrays(src, positions.Length); - _cache[src] = new Cache { positions = positions, colors = colors, directions = directions, types = types, size = positions.Length }; + if (positions.Length != c.size) + EnsureArrays(src, positions.Length); + + _cache[src] = new Cache + { + positions = positions, + colors = colors, + directions = directions, + types = types, + size = positions.Length + }; } catch { - // Ultra-safe fallback: nothing to push if the method signature changes unexpectedly + // Fallback: nothing to push if the method signature changes unexpectedly count = 0; } - var rds = src.targets ?? System.Array.Empty(); - for (int r = 0; r < rds.Length; r++) + // Mirror runtime: push as GLOBAL shader properties + // Resolve property IDs only if names are provided + if (!string.IsNullOrEmpty(src.positionsProperty)) { - var rd = rds[r]; - if (rd == null) continue; + int id = Shader.PropertyToID(src.positionsProperty); + Shader.SetGlobalVectorArray(id, positions); + } - rd.GetPropertyBlock(_mpb); + if (!string.IsNullOrEmpty(src.colorProperty)) + { + int id = Shader.PropertyToID(src.colorProperty); + Shader.SetGlobalVectorArray(id, colors); + } - if (!string.IsNullOrEmpty(src.positionsProperty)) _mpb.SetVectorArray(src.positionsProperty, positions); - if (!string.IsNullOrEmpty(src.colorProperty)) _mpb.SetVectorArray(src.colorProperty, colors); - if (!string.IsNullOrEmpty(src.directionsProperty)) _mpb.SetVectorArray(src.directionsProperty, directions); - if (!string.IsNullOrEmpty(src.typeProperty)) _mpb.SetFloatArray (src.typeProperty, types); - if (!string.IsNullOrEmpty(src.countProperty)) _mpb.SetFloat (src.countProperty, count); + if (!string.IsNullOrEmpty(src.directionsProperty)) + { + int id = Shader.PropertyToID(src.directionsProperty); + Shader.SetGlobalVectorArray(id, directions); + } - rd.SetPropertyBlock(_mpb); + if (!string.IsNullOrEmpty(src.typeProperty)) + { + int id = Shader.PropertyToID(src.typeProperty); + Shader.SetGlobalFloatArray(id, types); + } + + if (!string.IsNullOrEmpty(src.countProperty)) + { + int id = Shader.PropertyToID(src.countProperty); + Shader.SetGlobalFloat(id, count); } } } @@ -145,7 +170,7 @@ public class PlayerPositionsToShaderInspector : Editor using (new EditorGUI.DisabledScope(true)) { EditorGUILayout.LabelField("Edit-Mode Preview", EditorStyles.boldLabel); - EditorGUILayout.LabelField("Updates ~10×/s using \"Other Transforms\" as emitters."); + EditorGUILayout.LabelField("Updates ~10×/s using players and Other Light Sources."); } if (GUILayout.Button("Refresh Now")) diff --git a/Scripts/PlayerPositionsToShader.cs b/Scripts/PlayerPositionsToShader.cs index 27239c4..8e398c0 100644 --- a/Scripts/PlayerPositionsToShader.cs +++ b/Scripts/PlayerPositionsToShader.cs @@ -12,8 +12,6 @@ public partial class PlayerPositionsToShader : UdonSharpBehaviour [Tooltip("Place Transforms here which should also emit Light (attach LightdataStorage to them).")] public Transform[] otherLightSources; - [Header("Renderers that use a supported shader")] - public Renderer[] targets; [Header("Strength")] [Tooltip("Local player light range")] @@ -99,7 +97,7 @@ public partial class PlayerPositionsToShader : UdonSharpBehaviour void LateUpdate() { if (Time.time < _nextUpdate) return; - _nextUpdate = Time.time + 0.05f; + _nextUpdate = Time.time + 0.025f; UpdateData(); PushToRenderers(); @@ -266,7 +264,6 @@ public partial class PlayerPositionsToShader : UdonSharpBehaviour private void PushToRenderers() { - if (targets == null || targets.Length == 0) return; // Snapshot which things are dirty this frame bool pushPositions = _positons_isDirty; @@ -274,23 +271,19 @@ public partial class PlayerPositionsToShader : UdonSharpBehaviour bool pushDirs = _directions_isDirty; bool pushTypes = _TypeArray_isDirty && !string.IsNullOrEmpty(typeProperty); - for (int r = 0; r < targets.Length; r++) - { - Renderer rd = targets[r]; - if (!Utilities.IsValid(rd)) continue; - if (pushPositions) VRCShader.SetGlobalVectorArray(UdonID_PlayerPositions, _positions); - if (pushColors) VRCShader.SetGlobalVectorArray(UdonID_LightColors, _lightColors); - if (pushDirs) VRCShader.SetGlobalVectorArray(UdonID_LightDirections, _directions); - if (pushTypes) _mpb.SetFloatArray(UdonID_LightType, _TypeArray); + if (pushPositions) VRCShader.SetGlobalVectorArray(UdonID_PlayerPositions, _positions); + if (pushColors) VRCShader.SetGlobalVectorArray(UdonID_LightColors, _lightColors); + if (pushDirs) VRCShader.SetGlobalVectorArray(UdonID_LightDirections, _directions); + if (pushTypes) _mpb.SetFloatArray(UdonID_LightType, _TypeArray); + + VRCShader.SetGlobalFloat(UdonID_LightCount, currentCount); - VRCShader.SetGlobalFloat(UdonID_LightCount, currentCount); - } // Only now mark them clean - if (pushPositions) { _positons_isDirty = false; Debug.Log("Updated Positions"); } - if (pushColors) { _lightColors_isDirty = false; Debug.Log("Updated LightColors"); } - if (pushDirs) { _directions_isDirty = false; Debug.Log("Updated Directions"); } - if (pushTypes) { _TypeArray_isDirty = false; Debug.Log("Updated TypeArray"); } + if (pushPositions) { _positons_isDirty = false;} + if (pushColors) { _lightColors_isDirty = false;} + if (pushDirs) { _directions_isDirty = false;} + if (pushTypes) { _TypeArray_isDirty = false;} } } diff --git a/Shader/Water.shader b/Shader/Water.shader index fae32f5..3d83b74 100644 --- a/Shader/Water.shader +++ b/Shader/Water.shader @@ -11,6 +11,8 @@ Shader "DeMuenu/World/Hoppou/Water" _NormalMapScrollSpeed ("Normal Map Scroll Speed", Float) = 0.1 _NormalMapScrollSpeed2 ("Normal Map 2 Scroll Speed", Float) = 0.05 + _MinTransparency ("Min Transparency", Range(0,1)) = 0 + //Moonlight _InverseSqareMultiplier ("Inverse Square Multiplier", Float) = 1 _LightCutoffDistance ("Light Cutoff Distance", Float) = 100 @@ -25,12 +27,11 @@ Shader "DeMuenu/World/Hoppou/Water" //Moonlight END _WaveInput ("Wave Input", 2D) = "black" {} - _WaveTex ("Wave Texture", 2D) = "black" {} _CameraScale ("Camera Scale", Float) = 15 _CameraPositionZ ("Camera Position Z", Float) = 0 _CameraPositionX ("Camera Position X", Float) = 0 - - _WaveScale ("Wave Scale", Range(0.001, 100)) = 1 + _WaveScale ("Wave Scale", Range(0.001, 2)) = 1 + _WaveColor ("Wave Color", Color) = (1,1,1,1) } SubShader { @@ -84,6 +85,7 @@ Shader "DeMuenu/World/Hoppou/Water" float _NormalMap2Tiling; float _NormalMapScrollSpeed; float _NormalMapScrollSpeed2; + float _MinTransparency; MoonlightGlobalVariables @@ -99,6 +101,7 @@ Shader "DeMuenu/World/Hoppou/Water" float _CameraPositionZ; float _CameraPositionX; float _WaveScale; + float4 _WaveColor; //Watershader specific END @@ -134,18 +137,10 @@ Shader "DeMuenu/World/Hoppou/Water" float3 NormalOffset1 = UnpackNormal(norm).xyz; float3 NormalOffset2 = UnpackNormal(norm2).xyz; - float2 waveUV = float2(_CameraPositionX - i.worldPos.x, _CameraPositionZ - i.worldPos.z) / _CameraScale / 2 + 0.5; - fixed4 Wave = tex2D(_WaveInput, waveUV); - if ((waveUV.x < 0.1) || (waveUV.x > 0.9) || (waveUV.y < 0.1) || (waveUV.y > 0.9)){ - Wave = float4(0,0,0,0); - } - - //i.vertex += float4(0, Wave.g * _WaveScale, 0, 0); - //i.worldPos += float3(0, Wave.g * _WaveScale, 0); //Moonlight - float3 N = normalize(i.worldNormal + NormalOffset1 * _NormalMapStrength1 + NormalOffset2 * _NormalMapStrength2 + Wave * _WaveScale); //for lambertian diffuse + float3 N = normalize(i.worldNormal + NormalOffset1 * _NormalMapStrength1 + NormalOffset2 * _NormalMapStrength2); //for lambertian diffuse //Waterspecific @@ -188,9 +183,33 @@ Shader "DeMuenu/World/Hoppou/Water" dmax.a = dmax.a * _ReflectionStrength * fres; //Moonlight END + float4 finalColor = col * _Color * dmax; + float2 waveUV = float2(_CameraPositionX - i.worldPos.x, _CameraPositionZ - i.worldPos.z) / _CameraScale / 2 + 0.5; + fixed4 Wave = tex2D(_WaveInput, waveUV); + if ((waveUV.x < 0.1) || (waveUV.x > 0.9) || (waveUV.y < 0.1) || (waveUV.y > 0.9)){ + Wave = float4(0,0,0,0); + } + Wave.a = Wave.r; + Wave *= dmax; + + float2 camXZ = float2(_CameraPositionX, _CameraPositionZ); + float2 posXZ = float2(i.worldPos.x, i.worldPos.z); + + float dist = distance(posXZ, camXZ); + + float distFade = 1.0 - smoothstep(0, _CameraScale, dist); + + float4 waveCol = Wave * _WaveScale * _WaveColor; + + float k = saturate(1 * distFade); + + float4 outCol = finalColor; + outCol.rgb = lerp(outCol.rgb, waveCol.rgb, k); + + outCol.a = max(outCol.a, _MinTransparency); + return outCol; // Final color - return col * _Color * dmax ; } ENDCG } diff --git a/Shader/WaterParticle.shader b/Shader/WaterParticle.shader index 097aba7..957a432 100644 --- a/Shader/WaterParticle.shader +++ b/Shader/WaterParticle.shader @@ -3,13 +3,12 @@ Shader "DeMuenu/World/Hoppou/WaterParticle" Properties { _MainTex ("Texture", 2D) = "white" {} - _AlphaMap ("Alpha Map", 2D) = "white" {} _Color ("Tint", Color) = (1,1,1,1) } SubShader { Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" } - Blend SrcAlpha OneMinusSrcAlpha // normal alpha blend (not additive) + Blend One One ZWrite Off Lighting Off Cull Off @@ -38,7 +37,6 @@ Shader "DeMuenu/World/Hoppou/WaterParticle" sampler2D _MainTex; float4 _MainTex_ST; - sampler2D _AlphaMap; fixed4 _Color; v2f vert (appdata v) @@ -53,8 +51,7 @@ Shader "DeMuenu/World/Hoppou/WaterParticle" fixed4 frag (v2f i) : SV_Target { fixed4 col = tex2D(_MainTex, i.uv) * _Color; - float alpha = tex2D(_AlphaMap, i.uv).r; - return col * alpha * i.color; // col.a drives the blend + return col * i.color; // col.a drives the blend } ENDCG }