protected override void InitData() { base.InitData(); _combineProperties = new PropertyWrapperMaterial[OceanRenderer.Instance.CurrentLodCount]; for (int i = 0; i < _combineProperties.Length; i++) { _combineProperties[i] = new PropertyWrapperMaterial( new Material(Shader.Find("Hidden/Crest/Simulation/Combine Animated Wave LODs")) ); } Debug.Assert(SystemInfo.SupportsRenderTextureFormat(TextureFormat), "The graphics device does not support the render texture format " + TextureFormat.ToString()); int resolution = OceanRenderer.Instance.LodDataResolution; var desc = new RenderTextureDescriptor(resolution, resolution, TextureFormat, 0); _waveBuffers = new RenderTexture[OceanRenderer.Instance.CurrentLodCount]; for (int i = 0; i < _waveBuffers.Length; i++) { _waveBuffers[i] = new RenderTexture(desc); _waveBuffers[i].wrapMode = TextureWrapMode.Clamp; _waveBuffers[i].antiAliasing = 1; _waveBuffers[i].filterMode = FilterMode.Bilinear; _waveBuffers[i].anisoLevel = 0; _waveBuffers[i].useMipMap = false; _waveBuffers[i].name = "WaveBuffer_" + i + "_1"; } }
public override void Start() { base.Start(); { _renderMaterial = new PropertyWrapperMaterial[OceanRenderer.Instance.CurrentLodCount]; var shader = Shader.Find("Hidden/Crest/Simulation/Update Shadow"); for (int i = 0; i < _renderMaterial.Length; i++) { _renderMaterial[i] = new PropertyWrapperMaterial(shader); } } #if UNITY_EDITOR if (OceanRenderer.Instance.OceanMaterial != null && OceanRenderer.Instance.OceanMaterial.HasProperty(MATERIAL_KEYWORD_PROPERTY) && !OceanRenderer.Instance.OceanMaterial.IsKeywordEnabled(MATERIAL_KEYWORD)) { Debug.LogWarning(ERROR_MATERIAL_KEYWORD_MISSING + " " + ERROR_MATERIAL_KEYWORD_MISSING_FIX, _ocean); } #endif // Enable sample shadows custom pass. SampleShadows.Enable(); }
protected override void SetAdditionalSimParams(int lodIdx, PropertyWrapperMaterial simMaterial) { base.SetAdditionalSimParams(lodIdx, simMaterial); simMaterial.SetFloat(sp_Damping, Settings._damping); simMaterial.SetFloat(sp_Gravity, OceanRenderer.Instance.Gravity); float laplacianKernelAngle = _rotateLaplacian ? Mathf.PI * 2f * Random.value : 0f; simMaterial.SetVector(sp_LaplacianAxisX, new Vector2(Mathf.Cos(laplacianKernelAngle), Mathf.Sin(laplacianKernelAngle))); // assign sea floor depth - to slot 1 current frame data. minor bug here - this depth will actually be from the previous frame, // because the depth is scheduled to render just before the animated waves, and this sim happens before animated waves. if (OceanRenderer.Instance._lodDataSeaDepths) { OceanRenderer.Instance._lodDataSeaDepths.BindResultData(lodIdx, 1, simMaterial); } else { LodDataMgrSeaFloorDepth.BindNull(1, simMaterial); } if (OceanRenderer.Instance._lodDataFlow) { OceanRenderer.Instance._lodDataFlow.BindResultData(lodIdx, 1, simMaterial); } else { LodDataMgrFlow.BindNull(1, simMaterial); } }
void InitMaterials() { foreach (var child in transform) { Destroy((child as Transform).gameObject); } // num octaves plus one, because there is an additional last bucket for large wavelengths _materials = new PropertyWrapperMaterial[OceanRenderer.Instance.CurrentLodCount]; _drawLOD = new bool[_materials.Length]; for (int i = 0; i < _materials.Length; i++) { _materials[i] = new PropertyWrapperMaterial(new Material(_waveShader)); if (_directTowardsPoint) { _materials[i].material.EnableKeyword(DIRECT_TOWARDS_POINT_KEYWORD); } _drawLOD[i] = false; } _materialBigWaveTransition = new PropertyWrapperMaterial(new Material(_waveShader)); if (_directTowardsPoint) { _materialBigWaveTransition.material.EnableKeyword(DIRECT_TOWARDS_POINT_KEYWORD); } _drawLODTransitionWaves = false; }
protected override void InitData() { base.InitData(); // Setup the RenderTexture and compute shader for combining // different animated wave LODs. As we use a single texture array // for all LODs, we employ a compute shader as only they can // read and write to the same texture. _combineShader = Resources.Load <ComputeShader>(ShaderName); krnl_ShapeCombine = _combineShader.FindKernel("ShapeCombine"); krnl_ShapeCombine_DISABLE_COMBINE = _combineShader.FindKernel("ShapeCombine_DISABLE_COMBINE"); krnl_ShapeCombine_FLOW_ON = _combineShader.FindKernel("ShapeCombine_FLOW_ON"); krnl_ShapeCombine_FLOW_ON_DISABLE_COMBINE = _combineShader.FindKernel("ShapeCombine_FLOW_ON_DISABLE_COMBINE"); krnl_ShapeCombine_DYNAMIC_WAVE_SIM_ON = _combineShader.FindKernel("ShapeCombine_DYNAMIC_WAVE_SIM_ON"); krnl_ShapeCombine_DYNAMIC_WAVE_SIM_ON_DISABLE_COMBINE = _combineShader.FindKernel("ShapeCombine_DYNAMIC_WAVE_SIM_ON_DISABLE_COMBINE"); krnl_ShapeCombine_FLOW_ON_DYNAMIC_WAVE_SIM_ON = _combineShader.FindKernel("ShapeCombine_FLOW_ON_DYNAMIC_WAVE_SIM_ON"); krnl_ShapeCombine_FLOW_ON_DYNAMIC_WAVE_SIM_ON_DISABLE_COMBINE = _combineShader.FindKernel("ShapeCombine_FLOW_ON_DYNAMIC_WAVE_SIM_ON_DISABLE_COMBINE"); _combineProperties = new PropertyWrapperCompute(); int resolution = OceanRenderer.Instance.LodDataResolution; var desc = new RenderTextureDescriptor(resolution, resolution, TextureFormat, 0); _waveBuffers = CreateLodDataTextures(desc, "WaveBuffer", false); _combineBuffer = CreateCombineBuffer(desc); var combineShader = Shader.Find("Hidden/Crest/Simulation/Combine Animated Wave LODs"); _combineMaterial = new PropertyWrapperMaterial[OceanRenderer.Instance.CurrentLodCount]; for (int i = 0; i < _combineMaterial.Length; i++) { var mat = new Material(combineShader); _combineMaterial[i] = new PropertyWrapperMaterial(mat); } }
protected override void SetAdditionalSimParams(int lodIdx, PropertyWrapperMaterial simMaterial) { base.SetAdditionalSimParams(lodIdx, simMaterial); simMaterial.SetFloat(sp_FoamFadeRate, Settings._foamFadeRate); simMaterial.SetFloat(sp_WaveFoamStrength, Settings._waveFoamStrength); simMaterial.SetFloat(sp_WaveFoamCoverage, Settings._waveFoamCoverage); simMaterial.SetFloat(sp_ShorelineFoamMaxDepth, Settings._shorelineFoamMaxDepth); simMaterial.SetFloat(sp_ShorelineFoamStrength, Settings._shorelineFoamStrength); // assign animated waves - to slot 1 current frame data OceanRenderer.Instance._lodDataAnimWaves.BindResultData(lodIdx, 1, simMaterial); // assign sea floor depth - to slot 1 current frame data if (OceanRenderer.Instance._lodDataSeaDepths) { OceanRenderer.Instance._lodDataSeaDepths.BindResultData(lodIdx, 1, simMaterial); } else { LodDataMgrSeaFloorDepth.BindNull(1, simMaterial); } // assign flow - to slot 1 current frame data if (OceanRenderer.Instance._lodDataFlow) { OceanRenderer.Instance._lodDataFlow.BindResultData(lodIdx, 1, simMaterial); } else { LodDataMgrFlow.BindNull(1, simMaterial); } }
protected override void Start() { base.Start(); { _renderMaterial = new PropertyWrapperMaterial[OceanRenderer.Instance.CurrentLodCount]; var shader = Shader.Find("Hidden/Crest/Simulation/Update Shadow"); for (int i = 0; i < _renderMaterial.Length; i++) { _renderMaterial[i] = new PropertyWrapperMaterial(shader); } } _cameraMain = Camera.main; if (_cameraMain == null) { var viewpoint = OceanRenderer.Instance.Viewpoint; _cameraMain = viewpoint != null?viewpoint.GetComponent <Camera>() : null; if (_cameraMain == null) { Debug.LogError("Could not find main camera, disabling shadow data", this); enabled = false; return; } } #if UNITY_EDITOR if (!OceanRenderer.Instance.OceanMaterial.IsKeywordEnabled("_SHADOWS_ON")) { Debug.LogWarning("Shadowing is not enabled on the current ocean material and will not be visible.", this); } #endif }
public void BindSourceData(int lodIdx, int shapeSlot, PropertyWrapperMaterial properties, bool paramsOnly, bool usePrevTransform) { var rd = usePrevTransform ? OceanRenderer.Instance._lods[lodIdx]._renderDataPrevFrame.Validate(BuildCommandBufferBase._lastUpdateFrame - Time.frameCount, this) : OceanRenderer.Instance._lods[lodIdx]._renderData.Validate(0, this); BindData(lodIdx, shapeSlot, properties, paramsOnly ? Texture2D.blackTexture : (Texture)_sources[lodIdx], true, ref rd); }
public void Draw(CommandBuffer buf, float weight, int isTransition, int lodIdx) { if (Enabled && weight > 0f) { PropertyWrapperMaterial mat = GetMaterial(isTransition); mat.SetFloat(RegisterLodDataInputBase.sp_Weight, weight); buf.DrawRenderer(_rend, mat.material); } }
public void Draw(CommandBuffer buf, float weight, int isTransition) { if (Enabled && weight > 0f) { PropertyWrapperMaterial mat = GetMaterial(isTransition); mat.SetFloat(RegisterLodDataInputBase.sp_Weight, weight); buf.DrawMesh(RasterMesh(), Matrix4x4.identity, mat.material); } }
public override void Start() { base.Start(); #if UNITY_2018 Debug.LogError("Shadowing not enabled on preview versions of URP. Upgrade to 2019 is required.", this); #endif { _renderMaterial = new PropertyWrapperMaterial[OceanRenderer.Instance.CurrentLodCount]; var shader = Shader.Find("Hidden/Crest/Simulation/Update Shadow"); for (int i = 0; i < _renderMaterial.Length; i++) { _renderMaterial[i] = new PropertyWrapperMaterial(shader); } } if (!SampleShadows.Created #if UNITY_EDITOR // Not excited about this but it seems that the SampleShadows may not be immediately created when in edit mode. TODO - detect directly on render // pipeline renderer asset? && UnityEditor.EditorApplication.isPlaying #endif ) { Debug.LogError("To support shadowing, a Custom renderer must be configured on the pipeline asset, and this custom renderer data must have the Sample Shadows feature added.", GraphicsSettings.renderPipelineAsset); } _cameraMain = Camera.main; if (_cameraMain == null) { var viewpoint = OceanRenderer.Instance.Viewpoint; _cameraMain = viewpoint != null?viewpoint.GetComponent <Camera>() : null; if (_cameraMain == null) { Debug.LogError("Could not find main camera, disabling shadow data", _ocean); enabled = false; return; } } #if UNITY_EDITOR if (!OceanRenderer.Instance.OceanMaterial.IsKeywordEnabled("_SHADOWS_ON")) { Debug.LogWarning("Shadowing is not enabled on the current ocean material and will not be visible.", _ocean); } #endif var asset = GraphicsSettings.renderPipelineAsset as UniversalRenderPipelineAsset; if (asset && asset.shadowCascadeOption == ShadowCascadesOption.NoCascades) { Debug.LogError("Crest shadowing requires shadow cascades to be enabled on the pipeline asset.", asset); enabled = false; return; } }
public void Draw(CommandBuffer buf, float weight, int isTransition, int lodIdx) { HasWaves = false; _gerstner.UpdateBatch(this, _batchIndex); if (HasWaves && weight > 0f) { PropertyWrapperMaterial mat = GetMaterial(isTransition); mat.SetFloat(RegisterLodDataInputBase.sp_Weight, weight); buf.DrawRenderer(_rend, mat.material); } }
void CreateMaterials(int lodCount) { _renderSimMaterial = new PropertyWrapperMaterial[MAX_SIM_STEPS, lodCount]; var shader = Shader.Find(ShaderSim); for (int stepi = 0; stepi < MAX_SIM_STEPS; stepi++) { for (int i = 0; i < lodCount; i++) { _renderSimMaterial[stepi, i] = new PropertyWrapperMaterial(shader); } } }
protected override void InitData() { base.InitData(); // Setup the RenderTexture and compute shader for combining // different animated wave LODs. As we use a single texture array // for all LODs, we employ a compute shader as only they can // read and write to the same texture. int resolution = OceanRenderer.Instance.LodDataResolution; var desc = new RenderTextureDescriptor(resolution, resolution, CompatibleTextureFormat, 0); _waveBuffers = CreateLodDataTextures(desc, "WaveBuffer", false); _combineBuffer = CreateCombineBuffer(desc); // Combine graphics shader - for 'ping pong' approach (legacy hardware) var combineShaderNameGraphics = "Hidden/Crest/Simulation/Combine Animated Wave LODs"; var combineShaderGraphics = Shader.Find(combineShaderNameGraphics); Debug.Assert(combineShaderGraphics != null, $"Could not load shader {combineShaderNameGraphics}. Try right clicking the Crest folder in the Project view and selecting Reimport, and checking for errors.", OceanRenderer.Instance); if (combineShaderGraphics != null) { _combineMaterial = new PropertyWrapperMaterial[OceanRenderer.Instance.CurrentLodCount]; for (int i = 0; i < _combineMaterial.Length; i++) { var mat = new Material(combineShaderGraphics); _combineMaterial[i] = new PropertyWrapperMaterial(mat); } } // Combine compute shader - modern hardware _combineShader = ComputeShaderHelpers.LoadShader(ShaderName); if (_combineShader == null) { enabled = false; return; } krnl_ShapeCombine = _combineShader.FindKernel("ShapeCombine"); krnl_ShapeCombine_DISABLE_COMBINE = _combineShader.FindKernel("ShapeCombine_DISABLE_COMBINE"); krnl_ShapeCombine_FLOW_ON = _combineShader.FindKernel("ShapeCombine_FLOW_ON"); krnl_ShapeCombine_FLOW_ON_DISABLE_COMBINE = _combineShader.FindKernel("ShapeCombine_FLOW_ON_DISABLE_COMBINE"); krnl_ShapeCombine_DYNAMIC_WAVE_SIM_ON = _combineShader.FindKernel("ShapeCombine_DYNAMIC_WAVE_SIM_ON"); krnl_ShapeCombine_DYNAMIC_WAVE_SIM_ON_DISABLE_COMBINE = _combineShader.FindKernel("ShapeCombine_DYNAMIC_WAVE_SIM_ON_DISABLE_COMBINE"); krnl_ShapeCombine_FLOW_ON_DYNAMIC_WAVE_SIM_ON = _combineShader.FindKernel("ShapeCombine_FLOW_ON_DYNAMIC_WAVE_SIM_ON"); krnl_ShapeCombine_FLOW_ON_DYNAMIC_WAVE_SIM_ON_DISABLE_COMBINE = _combineShader.FindKernel("ShapeCombine_FLOW_ON_DYNAMIC_WAVE_SIM_ON_DISABLE_COMBINE"); _combineProperties = new PropertyWrapperCompute(); }
public GerstnerBatch(Shader gerstnerShader, bool directTowardsPoint) { _materials = new PropertyWrapperMaterial[] { new PropertyWrapperMaterial(new Material(gerstnerShader)), new PropertyWrapperMaterial(new Material(gerstnerShader)) }; if (directTowardsPoint) { _materials[0].material.EnableKeyword(DIRECT_TOWARDS_POINT_KEYWORD); _materials[1].material.EnableKeyword(DIRECT_TOWARDS_POINT_KEYWORD); } }
void SetupUnderwaterEffect() { if (_underwaterEffectMaterial?.material == null) { _underwaterEffectMaterial = new PropertyWrapperMaterial(SHADER_UNDERWATER_EFFECT); } if (_underwaterEffectCommandBuffer == null) { _underwaterEffectCommandBuffer = new CommandBuffer() { name = "Underwater Pass", }; } }
void SetupOceanMask() { if (_oceanMaskMaterial?.material == null) { _oceanMaskMaterial = new PropertyWrapperMaterial(SHADER_OCEAN_MASK); } if (_oceanMaskCommandBuffer == null) { _oceanMaskCommandBuffer = new CommandBuffer() { name = "Ocean Mask", }; } }
public GerstnerBatch(MeshRenderer rend, bool directTowardsPoint) { _materials = new PropertyWrapperMaterial[] { new PropertyWrapperMaterial(new Material(rend.sharedMaterial ?? rend.material)), new PropertyWrapperMaterial(new Material(rend.sharedMaterial ?? rend.material)) }; if (directTowardsPoint) { _materials[0].material.EnableKeyword(DIRECT_TOWARDS_POINT_KEYWORD); _materials[1].material.EnableKeyword(DIRECT_TOWARDS_POINT_KEYWORD); } _rend = rend; }
public override void Start() { base.Start(); { _renderMaterial = new PropertyWrapperMaterial[OceanRenderer.Instance.CurrentLodCount]; var shader = Shader.Find("Hidden/Crest/Simulation/Update Shadow"); for (int i = 0; i < _renderMaterial.Length; i++) { _renderMaterial[i] = new PropertyWrapperMaterial(shader); } } // Enable sample shadows custom pass. SampleShadows.Enable(); }
protected override void Start() { base.Start(); #if UNITY_2018 Debug.LogError("Shadowing not enabled on preview versions of LWRP. Upgrade to 2019 is required.", this); #endif { _renderMaterial = new PropertyWrapperMaterial[OceanRenderer.Instance.CurrentLodCount]; var shader = Shader.Find("Hidden/Crest/Simulation/Update Shadow"); for (int i = 0; i < _renderMaterial.Length; i++) { _renderMaterial[i] = new PropertyWrapperMaterial(shader); } } if (!SampleShadows.Created) { Debug.LogError("To support shadowing, a Custom renderer must be configured on the pipeline asset, and this custom renderer data must have the Sample Shadows feature added.", GraphicsSettings.renderPipelineAsset); } _cameraMain = Camera.main; if (_cameraMain == null) { var viewpoint = OceanRenderer.Instance.Viewpoint; _cameraMain = viewpoint != null?viewpoint.GetComponent <Camera>() : null; if (_cameraMain == null) { Debug.LogError("Could not find main camera, disabling shadow data", this); enabled = false; return; } } #if UNITY_EDITOR if (!OceanRenderer.Instance.OceanMaterial.IsKeywordEnabled("_SHADOWS_ON")) { Debug.LogWarning("Shadowing is not enabled on the current ocean material and will not be visible.", this); } #endif }
public GerstnerBatch(ShapeGerstnerBatched gerstner, int batchIndex, MeshRenderer rend, bool directTowardsPoint) { _gerstner = gerstner; _batchIndex = batchIndex; _materials = new PropertyWrapperMaterial[] { new PropertyWrapperMaterial(new Material(rend.sharedMaterial ?? rend.material)), new PropertyWrapperMaterial(new Material(rend.sharedMaterial ?? rend.material)) }; if (directTowardsPoint) { _materials[0].material.EnableKeyword(DIRECT_TOWARDS_POINT_KEYWORD); _materials[1].material.EnableKeyword(DIRECT_TOWARDS_POINT_KEYWORD); } _rend = rend; Enabled = true; }
public GerstnerBatch(ShapeGerstnerBatched gerstner, int batchIndex, MeshRenderer rend, bool directTowardsPoint) { _gerstner = gerstner; _batchIndex = batchIndex; _materials = new PropertyWrapperMaterial[] { new PropertyWrapperMaterial(new Material(rend.sharedMaterial ?? rend.material)), new PropertyWrapperMaterial(new Material(rend.sharedMaterial ?? rend.material)) }; if (directTowardsPoint) { _materials[0].material.EnableKeyword(DIRECT_TOWARDS_POINT_KEYWORD); _materials[1].material.EnableKeyword(DIRECT_TOWARDS_POINT_KEYWORD); } _rend = rend; // Enabled stays true, because we don't sort the waves into buckets until Draw time, so we don't know if something should // be drawn in advance. Enabled = true; }
private void LateUpdate() { // find which lod this object is overlapping var rect = new Rect(transform.position.x, transform.position.z, 0f, 0f); var idx = WaveDataCam.SuggestCollisionLOD(rect); if (idx > -1) { var pwm = new PropertyWrapperMaterial(_mat); var wdcs = OceanRenderer.Instance.Builder._shapeWDCs; wdcs[idx].ApplyMaterialParams(0, pwm); int idx1 = Mathf.Min(idx + 1, wdcs.Length - 1); wdcs[idx1].ApplyMaterialParams(1, pwm); // blend LOD 0 shape in/out to avoid pop, if the ocean might scale up later (it is smaller than its maximum scale) bool needToBlendOutShape = idx == 0 && OceanRenderer.Instance.ScaleCouldIncrease; float meshScaleLerp = needToBlendOutShape ? OceanRenderer.Instance.ViewerAltitudeLevelAlpha : 0f; // blend furthest normals scale in/out to avoid pop, if scale could reduce bool needToBlendOutNormals = idx == wdcs.Length - 1 && OceanRenderer.Instance.ScaleCouldDecrease; float farNormalsWeight = needToBlendOutNormals ? OceanRenderer.Instance.ViewerAltitudeLevelAlpha : 1f; pwm.SetVector("_InstanceData", new Vector4(meshScaleLerp, farNormalsWeight, idx)); } }
/// <summary> /// Set any sim-specific shader params. /// </summary> protected virtual void SetAdditionalSimParams(int lodIdx, PropertyWrapperMaterial simMaterial) { }
public void BindSourceData(int lodIdx, int slot, PropertyWrapperMaterial simMaterial, bool paramsOnly) { var rd = OceanRenderer.Instance._lods[lodIdx]._renderDataPrevFrame.Validate(BuildCommandBufferBase._lastUpdateFrame - Time.frameCount, this); BindData(lodIdx, slot, simMaterial, paramsOnly ? Texture2D.blackTexture : (_sources[lodIdx] as Texture), true, ref rd); }
internal static void UpdatePostProcessMaterial( RenderTexture source, Camera camera, PropertyWrapperMaterial underwaterPostProcessMaterialWrapper, UnderwaterSphericalHarmonicsData sphericalHarmonicsData, bool isMeniscusEnabled, bool copyParamsFromOceanMaterial, bool debugViewPostProcessMask, float horizonSafetyMarginMultiplier, float farPlaneMultiplier, int dataSliceOffset ) { Material underwaterPostProcessMaterial = underwaterPostProcessMaterialWrapper.material; if (copyParamsFromOceanMaterial) { // Measured this at approx 0.05ms on dell laptop underwaterPostProcessMaterial.CopyPropertiesFromMaterial(OceanRenderer.Instance.OceanMaterial); } // Enable/Disable meniscus. if (isMeniscusEnabled) { underwaterPostProcessMaterial.EnableKeyword("CREST_MENISCUS"); } else { underwaterPostProcessMaterial.DisableKeyword("CREST_MENISCUS"); } // Enabling/disabling keywords each frame don't seem to have large measurable overhead if (debugViewPostProcessMask) { underwaterPostProcessMaterial.EnableKeyword(DEBUG_VIEW_OCEAN_MASK); } else { underwaterPostProcessMaterial.DisableKeyword(DEBUG_VIEW_OCEAN_MASK); } underwaterPostProcessMaterial.SetFloat(LodDataMgr.sp_LD_SliceIndex, 0); underwaterPostProcessMaterial.SetVector(sp_InstanceData, new Vector4(OceanRenderer.Instance.ViewerAltitudeLevelAlpha, 0f, 0f, OceanRenderer.Instance.CurrentLodCount)); LodDataMgrAnimWaves.Bind(underwaterPostProcessMaterialWrapper); LodDataMgrSeaFloorDepth.Bind(underwaterPostProcessMaterialWrapper); LodDataMgrShadow.Bind(underwaterPostProcessMaterialWrapper); float seaLevel = OceanRenderer.Instance.SeaLevel; { // We only apply the horizon safety margin multiplier to horizon if and only if // concrete height of the camera relative to the water and the height of the camera // relative to the sea-level are the same. This ensures that in incredibly turbulent // water - if in doubt - use the neutral horizon. float seaLevelHeightDifference = camera.transform.position.y - seaLevel; if (seaLevelHeightDifference >= 0.0f ^ OceanRenderer.Instance.ViewerHeightAboveWater >= 0.0f) { horizonSafetyMarginMultiplier = 0.0f; } } { underwaterPostProcessMaterial.SetFloat(sp_OceanHeight, seaLevel); underwaterPostProcessMaterial.SetInt(sp_DataSliceOffset, dataSliceOffset); float maxOceanVerticalDisplacement = OceanRenderer.Instance.MaxVertDisplacement * 0.5f; float cameraYPosition = camera.transform.position.y; float nearPlaneFrustumWorldHeight; { float current = camera.ViewportToWorldPoint(new Vector3(0f, 0f, camera.nearClipPlane)).y; float maxY = current, minY = current; current = camera.ViewportToWorldPoint(new Vector3(0f, 1f, camera.nearClipPlane)).y; maxY = Mathf.Max(maxY, current); minY = Mathf.Min(minY, current); current = camera.ViewportToWorldPoint(new Vector3(1f, 0f, camera.nearClipPlane)).y; maxY = Mathf.Max(maxY, current); minY = Mathf.Min(minY, current); current = camera.ViewportToWorldPoint(new Vector3(1f, 1f, camera.nearClipPlane)).y; maxY = Mathf.Max(maxY, current); minY = Mathf.Min(minY, current); nearPlaneFrustumWorldHeight = maxY - minY; } // We don't both setting the horizon value if we know we are going to be having to apply the post-processing // effect full-screen anyway. bool forceFullShader = (cameraYPosition + nearPlaneFrustumWorldHeight + maxOceanVerticalDisplacement) <= seaLevel; underwaterPostProcessMaterial.SetFloat(sp_OceanHeight, seaLevel); if (forceFullShader) { underwaterPostProcessMaterial.EnableKeyword(FULL_SCREEN_EFFECT); } else { underwaterPostProcessMaterial.DisableKeyword(FULL_SCREEN_EFFECT); } } // Have to set these explicitly as the built-in transforms aren't in world-space for the blit function if (XRHelpers.IsSinglePass) { XRHelpers.SetViewProjectionMatrices(camera); Matrix4x4 cameraProjectionMatrix = camera.projectionMatrix; camera.projectionMatrix = XRHelpers.LeftEyeProjectionMatrix; var inverseViewProjectionMatrix = (XRHelpers.LeftEyeProjectionMatrix * camera.worldToCameraMatrix).inverse; underwaterPostProcessMaterial.SetMatrix(sp_InvViewProjection, inverseViewProjectionMatrix); { GetHorizonPosNormal(camera, Camera.MonoOrStereoscopicEye.Left, seaLevel, horizonSafetyMarginMultiplier, farPlaneMultiplier, out Vector2 pos, out Vector2 normal); underwaterPostProcessMaterial.SetVector(sp_HorizonPosNormal, new Vector4(pos.x, pos.y, normal.x, normal.y)); } camera.projectionMatrix = XRHelpers.RightEyeProjectionMatrix; var inverseViewProjectionMatrixRightEye = (XRHelpers.RightEyeProjectionMatrix * camera.worldToCameraMatrix).inverse; underwaterPostProcessMaterial.SetMatrix(sp_InvViewProjectionRight, inverseViewProjectionMatrixRightEye); { GetHorizonPosNormal(camera, Camera.MonoOrStereoscopicEye.Right, seaLevel, horizonSafetyMarginMultiplier, farPlaneMultiplier, out Vector2 pos, out Vector2 normal); underwaterPostProcessMaterial.SetVector(sp_HorizonPosNormalRight, new Vector4(pos.x, pos.y, normal.x, normal.y)); } // Revert to original matrix. Not sure if we need to do this. camera.projectionMatrix = cameraProjectionMatrix; } else { if (XRHelpers.IsNewSDKRunning) { XRHelpers.SetViewProjectionMatrices(camera); } var inverseViewProjectionMatrix = (camera.projectionMatrix * camera.worldToCameraMatrix).inverse; underwaterPostProcessMaterial.SetMatrix(sp_InvViewProjection, inverseViewProjectionMatrix); { GetHorizonPosNormal(camera, Camera.MonoOrStereoscopicEye.Mono, seaLevel, horizonSafetyMarginMultiplier, farPlaneMultiplier, out Vector2 pos, out Vector2 normal); underwaterPostProcessMaterial.SetVector(sp_HorizonPosNormal, new Vector4(pos.x, pos.y, normal.x, normal.y)); } } // Not sure why we need to do this - blit should set it...? underwaterPostProcessMaterial.SetTexture(sp_MainTex, source); // Compute ambient lighting SH { // We could pass in a renderer which would prime this lookup. However it doesnt make sense to use an existing render // at different position, as this would then thrash it and negate the priming functionality. We could create a dummy invis GO // with a dummy Renderer which might be enoguh, but this is hacky enough that we'll wait for it to become a problem // rather than add a pre-emptive hack. UnityEngine.Profiling.Profiler.BeginSample("Underwater sample spherical harmonics"); LightProbes.GetInterpolatedProbe(OceanRenderer.Instance.ViewCamera.transform.position, null, out SphericalHarmonicsL2 sphericalHarmonicsL2); sphericalHarmonicsL2.Evaluate(sphericalHarmonicsData._shDirections, sphericalHarmonicsData._ambientLighting); underwaterPostProcessMaterial.SetVector(sp_AmbientLighting, sphericalHarmonicsData._ambientLighting[0]); UnityEngine.Profiling.Profiler.EndSample(); } }
public void BindCopySettings(PropertyWrapperMaterial target) { target.SetFloat(sp_HorizDisplace, Settings._horizDisplace); target.SetFloat(sp_DisplaceClamp, Settings._displaceClamp); }