// Multiple sims run at different scales in the world. Count how many sims this interaction will overlap, so that // we can normalize the interaction force for the number of sims. bool LateUpdateCountOverlappingSims(out int simsActive, out int simsPresent) { simsActive = 0; simsPresent = 0; var thisRect = new Rect(new Vector2(transform.position.x, transform.position.z), Vector3.zero); var minLod = LodDataMgrAnimWaves.SuggestDataLOD(thisRect); if (minLod == -1) { // Outside all lods, nothing to update! return(false); } // How many active wave sims currently apply to this object - ideally this would eliminate sims that are too // low res, by providing a max grid size param LodDataMgrDynWaves.CountWaveSims(minLod, out simsPresent, out simsActive); if (simsPresent == 0) { return(false); } // No sims running - abort return(simsActive > 0); }
private void CleanUp() { foreach (var lodData in _lodDatas) { lodData.OnDisable(); } _lodDatas.Clear(); #if UNITY_EDITOR if (!EditorApplication.isPlaying && Root != null) { DestroyImmediate(Root.gameObject); } else #endif if (Root != null) { Destroy(Root.gameObject); } Root = null; _lodTransform = null; _lodDataAnimWaves = null; _lodDataClipSurface = null; _lodDataDynWaves = null; _lodDataFlow = null; _lodDataFoam = null; _lodDataSeaDepths = null; _lodDataShadow = null; }
void CombinePassPingPong(CommandBuffer buf) { var lodCount = OceanRenderer.Instance.CurrentLodCount; const int shaderPassCombineIntoAux = 0, shaderPassCopyResultBack = 1; // combine waves for (int lodIdx = lodCount - 1; lodIdx >= 0; lodIdx--) { // The per-octave wave buffers BindWaveBuffer(_combineMaterial[lodIdx], false); // Bind this LOD data (displacements). Option to disable the combine pass - very useful debugging feature. if (_shapeCombinePass) { BindResultData(_combineMaterial[lodIdx]); } else { BindNull(_combineMaterial[lodIdx]); } // Dynamic waves if (OceanRenderer.Instance._lodDataDynWaves) { OceanRenderer.Instance._lodDataDynWaves.BindCopySettings(_combineMaterial[lodIdx]); OceanRenderer.Instance._lodDataDynWaves.BindResultData(_combineMaterial[lodIdx]); } else { LodDataMgrDynWaves.BindNull(_combineMaterial[lodIdx]); } // Flow if (OceanRenderer.Instance._lodDataFlow) { OceanRenderer.Instance._lodDataFlow.BindResultData(_combineMaterial[lodIdx]); } else { LodDataMgrFlow.BindNull(_combineMaterial[lodIdx]); } _combineMaterial[lodIdx].SetInt(sp_LD_SliceIndex, lodIdx); // Combine this LOD's waves with waves from the LODs above into auxiliary combine buffer buf.SetRenderTarget(_combineBuffer); buf.DrawProcedural(Matrix4x4.identity, _combineMaterial[lodIdx].material, shaderPassCombineIntoAux, MeshTopology.Triangles, 3); // Copy combine buffer back to lod texture array buf.SetRenderTarget(_targets, 0, CubemapFace.Unknown, lodIdx); _combineMaterial[lodIdx].SetTexture(Shader.PropertyToID("_CombineBuffer"), _combineBuffer); buf.DrawProcedural(Matrix4x4.identity, _combineMaterial[lodIdx].material, shaderPassCopyResultBack, MeshTopology.Triangles, 3); } }
public override void BuildCommandBuffer(OceanRenderer ocean, CommandBuffer buf) { base.BuildCommandBuffer(ocean, buf); var lodCount = OceanRenderer.Instance.CurrentLodCount; // lod-dependent data _filterWavelength._lodCount = lodCount; for (int lodIdx = lodCount - 1; lodIdx >= 0; lodIdx--) { buf.SetRenderTarget(_waveBuffers, 0, CubemapFace.Unknown, lodIdx); buf.ClearRenderTarget(false, true, Color.black); foreach (var gerstner in _gerstnerComponents) { gerstner.BuildCommandBuffer(lodIdx, ocean, buf); } // draw any data with lod preference _filterWavelength._lodIdx = lodIdx; _filterWavelength._lodMaxWavelength = OceanRenderer.Instance._lodTransform.MaxWavelength(lodIdx); _filterWavelength._lodMinWavelength = _filterWavelength._lodMaxWavelength / 2f; SubmitDrawsFiltered(lodIdx, buf, _filterWavelength); } int combineShaderKernel = krnl_ShapeCombine; int combineShaderKernel_lastLOD = krnl_ShapeCombine_DISABLE_COMBINE; { bool isFlowOn = OceanRenderer.Instance._lodDataFlow != null; bool isDynWavesOn = OceanRenderer.Instance._lodDataDynWaves != null; // set the shader kernels that we will use. if (isFlowOn && isDynWavesOn) { combineShaderKernel = krnl_ShapeCombine_FLOW_ON_DYNAMIC_WAVE_SIM_ON; combineShaderKernel_lastLOD = krnl_ShapeCombine_FLOW_ON_DYNAMIC_WAVE_SIM_ON_DISABLE_COMBINE; } else if (isFlowOn) { combineShaderKernel = krnl_ShapeCombine_FLOW_ON; combineShaderKernel_lastLOD = krnl_ShapeCombine_FLOW_ON_DISABLE_COMBINE; } else if (isDynWavesOn) { combineShaderKernel = krnl_ShapeCombine_DYNAMIC_WAVE_SIM_ON; combineShaderKernel_lastLOD = krnl_ShapeCombine_DYNAMIC_WAVE_SIM_ON_DISABLE_COMBINE; } } // combine waves for (int lodIdx = lodCount - 1; lodIdx >= 0; lodIdx--) { int selectedShaderKernel; if (lodIdx < lodCount - 1 && _shapeCombinePass) { selectedShaderKernel = combineShaderKernel; } else { selectedShaderKernel = combineShaderKernel_lastLOD; } _combineProperties.Initialise(buf, _combineShader, selectedShaderKernel); BindWaveBuffer(_combineProperties); BindResultData(_combineProperties); // dynamic waves if (OceanRenderer.Instance._lodDataDynWaves) { OceanRenderer.Instance._lodDataDynWaves.BindCopySettings(_combineProperties); OceanRenderer.Instance._lodDataDynWaves.BindResultData(_combineProperties); } else { LodDataMgrDynWaves.BindNull(_combineProperties); } // flow if (OceanRenderer.Instance._lodDataFlow) { OceanRenderer.Instance._lodDataFlow.BindResultData(_combineProperties); } else { LodDataMgrFlow.BindNull(_combineProperties); } // Set the animated waves texture where the results will be combined. _combineProperties.SetTexture( sp_LD_TexArray_AnimatedWaves_Compute, DataTexture ); _combineProperties.SetFloat(OceanRenderer.sp_LD_SliceIndex, lodIdx); _combineProperties.DispatchShader(); } // lod-independent data for (int lodIdx = lodCount - 1; lodIdx >= 0; lodIdx--) { buf.SetRenderTarget(_targets, 0, CubemapFace.Unknown, lodIdx); // draw any data that did not express a preference for one lod or another SubmitDrawsFiltered(lodIdx, buf, _filterNoLodPreference); } }
void LateUpdate() { if (OceanRenderer.Instance == null) { return; } // which lod is this object in (roughly)? var thisRect = new Rect(new Vector2(transform.position.x, transform.position.z), Vector3.zero); var minLod = LodDataMgrAnimWaves.SuggestDataLOD(thisRect); if (minLod == -1) { // outside all lods, nothing to update! return; } // how many active wave sims currently apply to this object - ideally this would eliminate sims that are too // low res, by providing a max grid size param int simsPresent, simsActive; LodDataMgrDynWaves.CountWaveSims(minLod, out simsPresent, out simsActive); // counting non-existent sims is expensive - stop updating if none found if (simsPresent == 0) { enabled = false; return; } // no sims running - abort. don't bother switching off renderer - camera wont be active if (simsActive == 0) { return; } transform.position = transform.parent.TransformPoint(_localOffset) + _velocityPositionOffset * _boat.Velocity; var ocean = OceanRenderer.Instance; // feed in water velocity var vel = (transform.position - _posLast) / ocean.DeltaTimeDynamics; if (ocean.DeltaTimeDynamics < 0.0001f) { vel = Vector3.zero; } { _sampleFlowHelper.Init(transform.position, _boat.ObjectWidth); _sampleFlowHelper.Sample(out var surfaceFlow); vel -= new Vector3(surfaceFlow.x, 0, surfaceFlow.y); } vel.y *= _weightUpDownMul; var speedKmh = vel.magnitude * 3.6f; if (speedKmh > _teleportSpeed) { // teleport detected vel *= 0f; if (_warnOnTeleport) { Debug.LogWarning("Teleport detected (speed = " + speedKmh.ToString() + "), velocity discarded.", this); } } else if (speedKmh > _maxSpeed) { // limit speed to max vel *= _maxSpeed / speedKmh; if (_warnOnSpeedClamp) { Debug.LogWarning("Speed (" + speedKmh.ToString() + ") exceeded max limited, clamped.", this); } } var dt = 1f / ocean._lodDataDynWaves.Settings._simulationFrequency; var weight = _boat.InWater ? 1f / simsActive : 0f; _renderer.GetPropertyBlock(_mpb); _mpb.SetVector("_Velocity", vel); _mpb.SetFloat("_SimDeltaTime", dt); // Weighting with this value helps keep ripples consistent for different gravity values var gravityMul = Mathf.Sqrt(ocean._lodDataDynWaves.Settings._gravityMultiplier / 25f); _mpb.SetFloat("_Weight", weight * gravityMul); _renderer.SetPropertyBlock(_mpb); _posLast = transform.position; }
void CreateDestroySubSystems() { { if (_lodDataAnimWaves == null) { _lodDataAnimWaves = new LodDataMgrAnimWaves(this); _lodDatas.Add(_lodDataAnimWaves); } } if (CreateClipSurfaceData) { if (_lodDataClipSurface == null) { _lodDataClipSurface = new LodDataMgrClipSurface(this); _lodDatas.Add(_lodDataClipSurface); } } else { if (_lodDataClipSurface != null) { _lodDataClipSurface.OnDisable(); _lodDatas.Remove(_lodDataClipSurface); _lodDataClipSurface = null; } } if (CreateDynamicWaveSim) { if (_lodDataDynWaves == null) { _lodDataDynWaves = new LodDataMgrDynWaves(this); _lodDatas.Add(_lodDataDynWaves); } } else { if (_lodDataDynWaves != null) { _lodDataDynWaves.OnDisable(); _lodDatas.Remove(_lodDataDynWaves); _lodDataDynWaves = null; } } if (CreateFlowSim) { if (_lodDataFlow == null) { _lodDataFlow = new LodDataMgrFlow(this); _lodDatas.Add(_lodDataFlow); } if (FlowProvider != null && !(FlowProvider is QueryFlow)) { FlowProvider.CleanUp(); FlowProvider = null; } } else { if (_lodDataFlow != null) { _lodDataFlow.OnDisable(); _lodDatas.Remove(_lodDataFlow); _lodDataFlow = null; } if (FlowProvider != null && FlowProvider is QueryFlow) { FlowProvider.CleanUp(); FlowProvider = null; } } if (FlowProvider == null) { FlowProvider = _lodDataAnimWaves.Settings.CreateFlowProvider(this); } if (CreateFoamSim) { if (_lodDataFoam == null) { _lodDataFoam = new LodDataMgrFoam(this); _lodDatas.Add(_lodDataFoam); } } else { if (_lodDataFoam != null) { _lodDataFoam.OnDisable(); _lodDatas.Remove(_lodDataFoam); _lodDataFoam = null; } } if (CreateSeaFloorDepthData) { if (_lodDataSeaDepths == null) { _lodDataSeaDepths = new LodDataMgrSeaFloorDepth(this); _lodDatas.Add(_lodDataSeaDepths); } } else { if (_lodDataSeaDepths != null) { _lodDataSeaDepths.OnDisable(); _lodDatas.Remove(_lodDataSeaDepths); _lodDataSeaDepths = null; } } if (CreateShadowData) { if (_lodDataShadow == null) { _lodDataShadow = new LodDataMgrShadow(this); _lodDatas.Add(_lodDataShadow); } } else { if (_lodDataShadow != null) { _lodDataShadow.OnDisable(); _lodDatas.Remove(_lodDataShadow); _lodDataShadow = null; } } // Potential extension - add 'type' field to collprovider and change provider if settings have changed - this would support runtime changes. if (CollisionProvider == null) { CollisionProvider = _lodDataAnimWaves.Settings.CreateCollisionProvider(); } }
void CombinePassCompute(CommandBuffer buf) { var lodCount = OceanRenderer.Instance.CurrentLodCount; int combineShaderKernel = krnl_ShapeCombine; int combineShaderKernel_lastLOD = krnl_ShapeCombine_DISABLE_COMBINE; { bool isFlowOn = OceanRenderer.Instance._lodDataFlow != null; bool isDynWavesOn = OceanRenderer.Instance._lodDataDynWaves != null; // set the shader kernels that we will use. if (isFlowOn && isDynWavesOn) { combineShaderKernel = krnl_ShapeCombine_FLOW_ON_DYNAMIC_WAVE_SIM_ON; combineShaderKernel_lastLOD = krnl_ShapeCombine_FLOW_ON_DYNAMIC_WAVE_SIM_ON_DISABLE_COMBINE; } else if (isFlowOn) { combineShaderKernel = krnl_ShapeCombine_FLOW_ON; combineShaderKernel_lastLOD = krnl_ShapeCombine_FLOW_ON_DISABLE_COMBINE; } else if (isDynWavesOn) { combineShaderKernel = krnl_ShapeCombine_DYNAMIC_WAVE_SIM_ON; combineShaderKernel_lastLOD = krnl_ShapeCombine_DYNAMIC_WAVE_SIM_ON_DISABLE_COMBINE; } } // combine waves for (int lodIdx = lodCount - 1; lodIdx >= 0; lodIdx--) { int selectedShaderKernel; if (lodIdx < lodCount - 1 && _shapeCombinePass) { selectedShaderKernel = combineShaderKernel; } else { selectedShaderKernel = combineShaderKernel_lastLOD; } _combineProperties.Initialise(buf, _combineShader, selectedShaderKernel); // The per-octave wave buffers BindWaveBuffer(_combineProperties); // Bind this LOD data (displacements) Bind(_combineProperties); // Dynamic waves LodDataMgrDynWaves.Bind(_combineProperties); if (OceanRenderer.Instance._lodDataDynWaves != null) { OceanRenderer.Instance._lodDataDynWaves.BindCopySettings(_combineProperties); } // Flow LodDataMgrFlow.Bind((_combineProperties)); // Set the animated waves texture where the results will be combined. _combineProperties.SetTexture( sp_LD_TexArray_AnimatedWaves_Compute, DataTexture ); _combineProperties.SetInt(sp_LD_SliceIndex, lodIdx); buf.DispatchCompute(_combineShader, selectedShaderKernel, OceanRenderer.Instance.LodDataResolution / THREAD_GROUP_SIZE_X, OceanRenderer.Instance.LodDataResolution / THREAD_GROUP_SIZE_Y, 1); } }
void LateUpdate() { // which lod is this object in (roughly)? var thisRect = new Rect(new Vector2(transform.position.x, transform.position.z), Vector3.zero); var minLod = LodDataMgrAnimWaves.SuggestDataLOD(thisRect); if (minLod == -1) { // outside all lods, nothing to update! return; } // how many active wave sims currently apply to this object - ideally this would eliminate sims that are too // low res, by providing a max grid size param int simsPresent, simsActive; LodDataMgrDynWaves.CountWaveSims(minLod, out simsPresent, out simsActive); // counting non-existent sims is expensive - stop updating if none found if (simsPresent == 0) { enabled = false; return; } // no sims running - abort. don't bother switching off renderer - camera wont be active if (simsActive == 0) { return; } var disp = _boat.CalculateDisplacementToObject(); transform.position = transform.parent.TransformPoint(_localOffset) - disp + _velocityPositionOffset * _boat.Velocity; var ocean = OceanRenderer.Instance; var rnd = 1f + _noiseAmp * (2f * Mathf.PerlinNoise(_noiseFreq * ocean.CurrentTime, 0.5f) - 1f); // feed in water velocity var vel = (transform.position - _posLast) / ocean.DeltaTimeDynamics; if (ocean.DeltaTimeDynamics < 0.0001f) { vel = Vector3.zero; } if (QueryFlow.Instance) { _sampleFlowHelper.Init(transform.position, _boat.ObjectWidth); Vector2 surfaceFlow = Vector2.zero; _sampleFlowHelper.Sample(ref surfaceFlow); vel -= new Vector3(surfaceFlow.x, 0, surfaceFlow.y); } vel.y *= _weightUpDownMul; var speedKmh = vel.magnitude * 3.6f; if (speedKmh > _teleportSpeed) { // teleport detected vel *= 0f; if (_warnOnTeleport) { Debug.LogWarning("Teleport detected (speed = " + speedKmh.ToString() + "), velocity discarded.", this); } } else if (speedKmh > _maxSpeed) { // limit speed to max vel *= _maxSpeed / speedKmh; if (_warnOnSpeedClamp) { Debug.LogWarning("Speed (" + speedKmh.ToString() + ") exceeded max limited, clamped.", this); } } float dt; int steps; ocean._lodDataDynWaves.GetSimSubstepData(ocean.DeltaTimeDynamics, out steps, out dt); float weight = _boat.InWater ? _weight / simsActive : 0f; _renderer.GetPropertyBlock(_mpb); _mpb.SetVector("_Velocity", vel); _mpb.SetFloat("_Weight", weight); _mpb.SetFloat("_SimDeltaTime", dt); _renderer.SetPropertyBlock(_mpb); _posLast = transform.position; }
void CreateDestroyLodDatas() { { if (_lodDataAnimWaves == null) { _lodDataAnimWaves = new LodDataMgrAnimWaves(this); _lodDatas.Add(_lodDataAnimWaves); } } if (CreateClipSurfaceData) { if (_lodDataClipSurface == null) { _lodDataClipSurface = new LodDataMgrClipSurface(this); _lodDatas.Add(_lodDataClipSurface); } } else { if (_lodDataClipSurface != null) { _lodDataClipSurface.OnDisable(); _lodDatas.Remove(_lodDataClipSurface); _lodDataClipSurface = null; } } if (CreateDynamicWaveSim) { if (_lodDataDynWaves == null) { _lodDataDynWaves = new LodDataMgrDynWaves(this); _lodDatas.Add(_lodDataDynWaves); } } else { if (_lodDataDynWaves != null) { _lodDataDynWaves.OnDisable(); _lodDatas.Remove(_lodDataDynWaves); _lodDataDynWaves = null; } } if (CreateFlowSim) { if (_lodDataFlow == null) { _lodDataFlow = new LodDataMgrFlow(this); _lodDatas.Add(_lodDataFlow); } } else { if (_lodDataFlow != null) { _lodDataFlow.OnDisable(); _lodDatas.Remove(_lodDataFlow); _lodDataFlow = null; } } if (CreateFoamSim) { if (_lodDataFoam == null) { _lodDataFoam = new LodDataMgrFoam(this); _lodDatas.Add(_lodDataFoam); } } else { if (_lodDataFoam != null) { _lodDataFoam.OnDisable(); _lodDatas.Remove(_lodDataFoam); _lodDataFoam = null; } } if (CreateSeaFloorDepthData) { if (_lodDataSeaDepths == null) { _lodDataSeaDepths = new LodDataMgrSeaFloorDepth(this); _lodDatas.Add(_lodDataSeaDepths); } } else { if (_lodDataSeaDepths != null) { _lodDataSeaDepths.OnDisable(); _lodDatas.Remove(_lodDataSeaDepths); _lodDataSeaDepths = null; } } if (CreateShadowData) { if (_lodDataShadow == null) { _lodDataShadow = new LodDataMgrShadow(this); _lodDatas.Add(_lodDataShadow); } } else { if (_lodDataShadow != null) { _lodDataShadow.OnDisable(); _lodDatas.Remove(_lodDataShadow); _lodDataShadow = null; } } }
public override void BuildCommandBuffer(OceanRenderer ocean, CommandBuffer buf) { base.BuildCommandBuffer(ocean, buf); var lodCount = OceanRenderer.Instance.CurrentLodCount; // lod-dependent data for (int lodIdx = lodCount - 1; lodIdx >= 0; lodIdx--) { buf.SetRenderTarget(_waveBuffers[lodIdx]); buf.ClearRenderTarget(false, true, Color.black); foreach (var gerstner in _gerstnerComponents) { gerstner.BuildCommandBuffer(lodIdx, ocean, buf); } // draw any data with lod preference var lodMaxWavelength = OceanRenderer.Instance._lods[lodIdx].MaxWavelength(); var lodMinWavelength = lodMaxWavelength / 2f; DrawFilter filter = (data) => { var drawOctaveWavelength = (data as RegisterAnimWavesInput).OctaveWavelength; return(lodMinWavelength <= drawOctaveWavelength && drawOctaveWavelength < lodMaxWavelength); }; SubmitDrawsFiltered(lodIdx, buf, filter); } // combine waves for (int lodIdx = lodCount - 1; lodIdx >= 0; lodIdx--) { // this lod data BindWaveBuffer(lodIdx, 0, _combineMaterial[lodIdx], false); // combine data from next larger lod into this one if (lodIdx < lodCount - 1 && _shapeCombinePass) { BindResultData(lodIdx + 1, 1, _combineMaterial[lodIdx]); } else { // this binds black texture BindWaveBuffer(lodIdx, 1, _combineMaterial[lodIdx], true); } // dynamic waves if (OceanRenderer.Instance._lodDataDynWaves) { OceanRenderer.Instance._lodDataDynWaves.BindCopySettings(_combineMaterial[lodIdx]); OceanRenderer.Instance._lodDataDynWaves.BindResultData(lodIdx, 0, _combineMaterial[lodIdx]); } else { LodDataMgrDynWaves.BindNull(0, _combineMaterial[lodIdx]); } // flow if (OceanRenderer.Instance._lodDataFlow) { OceanRenderer.Instance._lodDataFlow.BindResultData(lodIdx, 0, _combineMaterial[lodIdx]); } else { LodDataMgrFlow.BindNull(0, _combineMaterial[lodIdx]); } buf.Blit(null, DataTexture(lodIdx), _combineMaterial[lodIdx]); } // lod-independent data for (int lodIdx = lodCount - 1; lodIdx >= 0; lodIdx--) { buf.SetRenderTarget(DataTexture(lodIdx)); // draw any data that did not express a preference for one lod or another DrawFilter filter = (data) => { return((data as RegisterAnimWavesInput).OctaveWavelength == 0f); }; SubmitDrawsFiltered(lodIdx, buf, filter); } }
void LateUpdate() { // which lod is this object in (roughly)? var thisRect = new Rect(new Vector2(transform.position.x, transform.position.z), Vector3.zero); var minLod = LodDataMgrAnimWaves.SuggestDataLOD(thisRect); if (minLod == -1) { // outside all lods, nothing to update! return; } // how many active wave sims currently apply to this object - ideally this would eliminate sims that are too // low res, by providing a max grid size param int simsPresent, simsActive; LodDataMgrDynWaves.CountWaveSims(minLod, out simsPresent, out simsActive); // counting non-existent sims is expensive - stop updating if none found if (simsPresent == 0) { enabled = false; return; } // no sims running - abort. don't bother switching off renderer - camera wont be active if (simsActive == 0) { return; } var disp = _boat.CalculateDisplacementToObject(); transform.position = transform.parent.TransformPoint(_localOffset) - disp + _velocityPositionOffset * _boat.RB.velocity; var rnd = 1f + _noiseAmp * (2f * Mathf.PerlinNoise(_noiseFreq * OceanRenderer.Instance.CurrentTime, 0.5f) - 1f); // feed in water velocity var vel = (transform.position - _posLast) / Time.deltaTime; if (OceanRenderer.Instance._simSettingsFlow != null && OceanRenderer.Instance._simSettingsFlow._readbackData && GPUReadbackFlow.Instance) { var position = transform.position; var samplingArea = new Rect(position.x, position.z, 0f, 0f); GPUReadbackFlow.Instance.GetSamplingData(ref samplingArea, _boat.ObjectWidth, _samplingDataFlow); Vector2 surfaceFlow; GPUReadbackFlow.Instance.SampleFlow(ref position, _samplingDataFlow, out surfaceFlow); vel -= new Vector3(surfaceFlow.x, 0, surfaceFlow.y); GPUReadbackFlow.Instance.ReturnSamplingData(_samplingDataFlow); } vel.y *= _weightUpDownMul; var speedKmh = vel.magnitude * 3.6f; if (speedKmh > _teleportSpeed) { // teleport detected vel *= 0f; if (_warnOnTeleport) { Debug.LogWarning("Teleport detected (speed = " + speedKmh.ToString() + "), velocity discarded.", this); } } else if (speedKmh > _maxSpeed) { // limit speed to max vel *= _maxSpeed / speedKmh; if (_warnOnSpeedClamp) { Debug.LogWarning("Speed (" + speedKmh.ToString() + ") exceeded max limited, clamped.", this); } } float dt; int steps; OceanRenderer.Instance._lodDataDynWaves.GetSimSubstepData(Time.deltaTime, out steps, out dt); float weight = _boat.InWater ? _weight / simsActive : 0f; for (int mati = 0; mati < _dynWavesInput.MaterialCount; mati++) { var mat = _dynWavesInput.GetMaterial(mati); mat.SetVector("_Velocity", vel); mat.SetFloat("_Weight", weight); mat.SetFloat("_SimDeltaTime", dt); } _posLast = transform.position; }
public override void BuildCommandBuffer(OceanRenderer ocean, CommandBuffer buf) { base.BuildCommandBuffer(ocean, buf); var lodCount = OceanRenderer.Instance.CurrentLodCount; // lod-dependent data _filterWavelength._lodCount = lodCount; for (int lodIdx = lodCount - 1; lodIdx >= 0; lodIdx--) { buf.SetRenderTarget(_waveBuffers[lodIdx]); buf.ClearRenderTarget(false, true, Color.black); foreach (var gerstner in _gerstnerComponents) { gerstner.BuildCommandBuffer(lodIdx, ocean, buf); } // draw any data with lod preference _filterWavelength._lodIdx = lodIdx; _filterWavelength._lodMaxWavelength = OceanRenderer.Instance._lods[lodIdx].MaxWavelength(); _filterWavelength._lodMinWavelength = _filterWavelength._lodMaxWavelength / 2f; SubmitDrawsFiltered(lodIdx, buf, _filterWavelength); } // combine waves for (int lodIdx = lodCount - 1; lodIdx >= 0; lodIdx--) { // this lod data BindWaveBuffer(lodIdx, 0, _combineProperties[lodIdx], false); // combine data from next larger lod into this one if (lodIdx < lodCount - 1 && _shapeCombinePass) { BindResultData(lodIdx + 1, 1, _combineProperties[lodIdx]); } else { // this binds black texture BindWaveBuffer(lodIdx, 1, _combineProperties[lodIdx], true); } // dynamic waves if (OceanRenderer.Instance._lodDataDynWaves) { OceanRenderer.Instance._lodDataDynWaves.BindCopySettings(_combineProperties[lodIdx]); OceanRenderer.Instance._lodDataDynWaves.BindResultData(lodIdx, 0, _combineProperties[lodIdx]); } else { LodDataMgrDynWaves.BindNull(0, _combineProperties[lodIdx]); } // flow if (OceanRenderer.Instance._lodDataFlow) { OceanRenderer.Instance._lodDataFlow.BindResultData(lodIdx, 0, _combineProperties[lodIdx]); } else { LodDataMgrFlow.BindNull(0, _combineProperties[lodIdx]); } buf.SetRenderTarget(DataTexture(lodIdx)); buf.DrawProcedural(Matrix4x4.identity, _combineMaterial, 0, MeshTopology.Triangles, 3, 1, _combineProperties[lodIdx].materialPropertyBlock); } // lod-independent data for (int lodIdx = lodCount - 1; lodIdx >= 0; lodIdx--) { buf.SetRenderTarget(DataTexture(lodIdx)); // draw any data that did not express a preference for one lod or another SubmitDrawsFiltered(lodIdx, buf, _filterNoLodPreference); } }