/// <summary> /// Renders the aerial perspective /// </summary> /// <param name="_Scattering">The final scattering texture to render to</param> /// <param name="_Layers">Up to 4 cloud layers that will be composed with the sky</param> /// <param name="_ShadowMap">The shadow map cast by the clouds</param> /// <param name="_Background">The background map where satellites are rendered</param> internal void Render( RenderTexture _Scattering, ICloudLayer[] _Layers, Texture _ShadowMap, Texture _Background ) { NuajMaterial.SetGlobalFloat( "_bComputePlanetShadow", m_bComputePlanetShadow ? 1 : 0 ); RenderTexture DownScaledZBuffer = null; switch ( m_SkyModel ) { ////////////////////////////////////////////////////////////////////////// // Complex Sky Model case SKY_MODEL.COMPLEX: { SetupSkyParameters( m_MaterialRenderSkyComplex, _Layers, _ShadowMap, false ); m_Owner.SetupLayerOrderingData( m_MaterialRenderSkyComplex ); // Downscale the ZBuffer DownScaledZBuffer = m_Owner.DownScaleZBuffer( m_DownScaleFactor ); // Render sky in downscaled target m_MaterialRenderSkyComplex.SetTexture( "_TexDownScaledZBuffer", DownScaledZBuffer ); m_MaterialRenderSkyComplex.Blit( null, m_RTScattering, _Layers.Length ); // The amount of layers guides the index of the shader here... ////////////////////////////////////////////////////////////////////////// // Mix sky with clouds m_MaterialComposeSkyComplex.CopyPropertiesFromMaterial( m_MaterialRenderSkyComplex ); // Same properties as render sky m_MaterialComposeSkyComplex.SetVector( "_dUV", new Vector4( 1.0f / m_Width, 1.0f / m_Height, 0.0f, 0.0f ) ); m_MaterialComposeSkyComplex.SetVector( "_InvdUV", new Vector4( m_Width, m_Height, 0.0f, 0.0f ) ); m_MaterialComposeSkyComplex.SetTexture( "_TexDownScaledZBuffer", DownScaledZBuffer ); m_MaterialComposeSkyComplex.SetFloat( "_ZBufferDiscrepancyThreshold", m_Owner.ZBufferDiscrepancyThreshold ); m_MaterialComposeSkyComplex.SetFloat( "_ShowZBufferDiscrepancies", m_Owner.ShowZBufferDiscrepancies ? 1.0f : 0.0f ); m_MaterialComposeSkyComplex.SetTextureRAW( "_TexBackground", _Background ); int ShaderIndex = _Layers.Length; // The amount of layers guides the index of the shader here... if ( m_Owner.UpScaleTechnique != NuajManager.UPSCALE_TECHNIQUE.ACCURATE ) ShaderIndex += 5; // Don't use accurate refinement m_MaterialComposeSkyComplex.Blit( m_RTScattering, _Scattering, ShaderIndex ); break; } ////////////////////////////////////////////////////////////////////////// // Simple Sky Model case SKY_MODEL.SIMPLE: { SetupSkyParametersSimple( m_MaterialRenderSkySimple, _Layers, false ); m_Owner.SetupLayerOrderingData( m_MaterialRenderSkySimple ); // Downscale the ZBuffer DownScaledZBuffer = m_Owner.DownScaleZBuffer( m_DownScaleFactor ); // Render sky in downscaled target m_MaterialRenderSkySimple.SetTexture( "_TexDownScaledZBuffer", DownScaledZBuffer ); m_MaterialRenderSkySimple.Blit( null, m_RTScattering, _Layers.Length ); // The amount of layers guides the index of the shader here... ////////////////////////////////////////////////////////////////////////// // Mix sky with clouds m_MaterialComposeSkySimple.CopyPropertiesFromMaterial( m_MaterialRenderSkySimple ); // Same properties as render sky m_MaterialComposeSkySimple.SetVector( "_dUV", new Vector4( 1.0f / m_Width, 1.0f / m_Height, 0.0f, 0.0f ) ); m_MaterialComposeSkySimple.SetVector( "_InvdUV", new Vector4( m_Width, m_Height, 0.0f, 0.0f ) ); m_MaterialComposeSkySimple.SetTexture( "_TexDownScaledZBuffer", DownScaledZBuffer ); m_MaterialComposeSkySimple.SetFloat( "_ZBufferDiscrepancyThreshold", m_Owner.ZBufferDiscrepancyThreshold ); m_MaterialComposeSkySimple.SetFloat( "_ShowZBufferDiscrepancies", m_Owner.ShowZBufferDiscrepancies ? 1.0f : 0.0f ); m_MaterialComposeSkySimple.SetTextureRAW( "_TexBackground", _Background ); int ShaderIndex = _Layers.Length; // The amount of layers guides the index of the shader here... if ( m_Owner.UpScaleTechnique != NuajManager.UPSCALE_TECHNIQUE.ACCURATE ) ShaderIndex += 5; // Don't use accurate refinement m_MaterialComposeSkySimple.Blit( m_RTScattering, _Scattering, ShaderIndex ); break; } ////////////////////////////////////////////////////////////////////////// // Empty Sky Model case SKY_MODEL.NONE: ////////////////////////////////////////////////////////////////////////// // Mix sky with clouds SetupSkyParametersNone( m_MaterialComposeSkyNone, _Layers, false ); m_Owner.SetupLayerOrderingData( m_MaterialComposeSkyNone ); m_MaterialComposeSkyNone.SetTextureRAW( "_TexBackground", _Background ); m_MaterialComposeSkyNone.Blit( null, _Scattering, _Layers.Length ); // The amount of layers guides the index of the shader here... break; } }
/// <summary> /// Renders the environment map with the GPU for accurate scene lighting /// </summary> /// <param name="_Layers">Up to 4 cloud layers that will be composed with the sky</param> /// <param name="_ShadowMap">The shadow map cast by the clouds</param> /// <param name="_Background">The background environment map where satellites are rendered</param> public void RenderEnvironmentHardware( ICloudLayer[] _Layers, RenderTexture _ShadowMap, RenderTexture _Background ) { if ( IsInErrorState ) return; // Compute the luminance we are using for scaling // Use a somewhat wrong "below the horizon" test float LuminanceScale = Math.Max( NuajManager.MIN_LUMINANCE_AT_NIGHT, m_Owner.SunIntensity * Mathf.Clamp01( 10.0f * Vector3.Dot( m_Owner.SunDirection, m_Owner.PlanetNormal ) ) ); switch ( m_SkyModel ) { ////////////////////////////////////////////////////////////////////////// // Complex Sky Model case SKY_MODEL.COMPLEX: { SetupSkyParameters( m_MaterialRenderEnvironmentComplex, _Layers, _ShadowMap, true ); m_MaterialRenderEnvironmentComplex.SetTexture( "_TexBackground", _Background ); // Render sky environment map WITHOUT clouds (used for clouds lighting, but only on next frame as the clouds have already been rendered) m_MaterialRenderEnvironmentComplex.Blit( null, m_RTSkyMaps[0], 0 ); DownScaleSkyEnvMap( m_RTSkyMaps[0], m_RTSkyEnvMap, false ); // Render sky environment map WITH clouds (used by scene as ambient light) m_MaterialRenderEnvironmentComplex.Blit( null, m_RTSkyMaps[0], 1 ); Vector3 EnvSkyColor = DownScaleSkyEnvMapForCPU( m_RTSkyMaps[0], 1, LuminanceScale ); m_SumEnvSkyColor += EnvSkyColor - m_AveragedSkyColor[m_AverageEnvironmentIndex]; m_AveragedSkyColor[m_AverageEnvironmentIndex] = EnvSkyColor; // Render Sun map (used by scene as directional light's color) SetupSunCloudMaps( m_MaterialComposeSkyComplex, _Layers ); Vector3 EnvSunColor = CPUReadBack( null, m_MaterialRenderEnvironmentComplex, 2, 2, LuminanceScale ); m_SumEnvSunColor += EnvSunColor - m_AveragedSunColor[m_AverageEnvironmentIndex]; m_AveragedSunColor[m_AverageEnvironmentIndex] = EnvSunColor; break; } ////////////////////////////////////////////////////////////////////////// // Simple Sky Model case SKY_MODEL.SIMPLE: { SetupSkyParametersSimple( m_MaterialRenderEnvironmentSimple, _Layers, true ); m_MaterialRenderEnvironmentSimple.SetTexture( "_TexBackground", _Background ); // Render sky environment map WITHOUT clouds (used for clouds lighting, but only on next frame as the clouds have already been rendered) m_MaterialRenderEnvironmentSimple.Blit( null, m_RTSkyMaps[0], 0 ); DownScaleSkyEnvMap( m_RTSkyMaps[0], m_RTSkyEnvMap, false ); // Render sky environment map WITH clouds (used by scene as ambient light) m_MaterialRenderEnvironmentSimple.Blit( null, m_RTSkyMaps[0], 1 ); Vector3 EnvSkyColor = DownScaleSkyEnvMapForCPU( m_RTSkyMaps[0], 1, LuminanceScale ); m_SumEnvSkyColor += EnvSkyColor - m_AveragedSkyColor[m_AverageEnvironmentIndex]; m_AveragedSkyColor[m_AverageEnvironmentIndex] = EnvSkyColor; // Render Sun map (used by scene as directional light's color) SetupSunCloudMaps( m_MaterialRenderEnvironmentSimple, _Layers ); Vector3 EnvSunColor = CPUReadBack( null, m_MaterialRenderEnvironmentSimple, 2, 2, LuminanceScale ); m_SumEnvSunColor += EnvSunColor - m_AveragedSunColor[m_AverageEnvironmentIndex]; m_AveragedSunColor[m_AverageEnvironmentIndex] = EnvSunColor; break; } ////////////////////////////////////////////////////////////////////////// // Empty Sky Model case SKY_MODEL.NONE: { SetupSkyParametersNone( m_MaterialRenderEnvironmentNone, _Layers, true ); m_MaterialRenderEnvironmentNone.SetTexture( "_TexBackground", _Background ); // Render sky environment map WITHOUT clouds (used for clouds lighting, but only on next frame as the clouds have already been rendered) m_MaterialRenderEnvironmentNone.Blit( null, m_RTSkyMaps[0], 0 ); DownScaleSkyEnvMap( m_RTSkyMaps[0], m_RTSkyEnvMap, false ); // Render sky environment map WITH clouds (used by scene as ambient light) m_MaterialRenderEnvironmentNone.Blit( null, m_RTSkyMaps[0], 1 ); Vector3 EnvSkyColor = DownScaleSkyEnvMapForCPU( m_RTSkyMaps[0], 1, LuminanceScale ); m_SumEnvSkyColor += EnvSkyColor - m_AveragedSkyColor[m_AverageEnvironmentIndex]; m_AveragedSkyColor[m_AverageEnvironmentIndex] = EnvSkyColor; // Render Sun map (used by scene as directional light's color) SetupSunCloudMaps( m_MaterialRenderEnvironmentNone, _Layers ); Vector3 EnvSunColor = CPUReadBack( null, m_MaterialRenderEnvironmentNone, 2, 2, LuminanceScale ); m_SumEnvSunColor += EnvSunColor - m_AveragedSunColor[m_AverageEnvironmentIndex]; m_AveragedSunColor[m_AverageEnvironmentIndex] = EnvSunColor; break; } } m_AverageEnvironmentIndex = (m_AverageEnvironmentIndex+1) % ENVIRONMENT_AVERAGED_OVER_FRAMES; // Average Sun/Sky across several frames m_EnvSunColor = m_SumEnvSunColor / ENVIRONMENT_AVERAGED_OVER_FRAMES; m_EnvSkyColor = m_SumEnvSkyColor / ENVIRONMENT_AVERAGED_OVER_FRAMES; // Update global constants NuajMaterial.SetGlobalTexture( "_TexAmbientSky", m_RTSkyEnvMap ); NuajMaterial.SetGlobalVector( "_SoftAmbientSky", Vector3.zero ); NuajMaterial.SetGlobalVector( "_AmbientSkyFromGround", m_EnvSkyColor ); NuajMaterial.SetGlobalVector( "_SunColorFromGround", m_EnvSunColor ); }
protected void SetupSunCloudMaps( NuajMaterial _Material, ICloudLayer[] _Layers ) { switch ( _Layers.Length ) { case 0: _Material.SetTexture( "_TexCloudLayer0", m_Owner.m_TextureEmptyCloud, true ); _Material.SetTexture( "_TexCloudLayer1", m_Owner.m_TextureEmptyCloud, true ); _Material.SetTexture( "_TexCloudLayer2", m_Owner.m_TextureEmptyCloud, true ); _Material.SetTexture( "_TexCloudLayer3", m_Owner.m_TextureEmptyCloud, true ); break; case 1: _Material.SetTexture( "_TexCloudLayer0", _Layers[0].EnvironmentRenderTargetSun ); _Material.SetTexture( "_TexCloudLayer1", m_Owner.m_TextureEmptyCloud, true ); _Material.SetTexture( "_TexCloudLayer2", m_Owner.m_TextureEmptyCloud, true ); _Material.SetTexture( "_TexCloudLayer3", m_Owner.m_TextureEmptyCloud, true ); break; case 2: _Material.SetTexture( "_TexCloudLayer0", _Layers[0].EnvironmentRenderTargetSun ); _Material.SetTexture( "_TexCloudLayer1", _Layers[1].EnvironmentRenderTargetSun ); _Material.SetTexture( "_TexCloudLayer2", m_Owner.m_TextureEmptyCloud, true ); _Material.SetTexture( "_TexCloudLayer3", m_Owner.m_TextureEmptyCloud, true ); break; case 3: _Material.SetTexture( "_TexCloudLayer0", _Layers[0].EnvironmentRenderTargetSun ); _Material.SetTexture( "_TexCloudLayer1", _Layers[1].EnvironmentRenderTargetSun ); _Material.SetTexture( "_TexCloudLayer2", _Layers[2].EnvironmentRenderTargetSun ); _Material.SetTexture( "_TexCloudLayer3", m_Owner.m_TextureEmptyCloud, true ); break; case 4: _Material.SetTexture( "_TexCloudLayer0", _Layers[0].EnvironmentRenderTargetSun ); _Material.SetTexture( "_TexCloudLayer1", _Layers[1].EnvironmentRenderTargetSun ); _Material.SetTexture( "_TexCloudLayer2", _Layers[2].EnvironmentRenderTargetSun ); _Material.SetTexture( "_TexCloudLayer3", _Layers[3].EnvironmentRenderTargetSun ); break; } }
protected void SetupSkyParametersSimple( NuajMaterial _Material, ICloudLayer[] _Layers, bool _bIsEnvironmentRendering ) { // Build the GPU & CPU density textures if they do not already exist ComputeDensityTexture(); _Material.SetTexture( "_TexDensity", m_DensityTexture ); _Material.SetVector( "_Sigma_Rayleigh", m_SigmaRayleigh ); _Material.SetFloat( "_Sigma_Mie", m_SigmaMie ); _Material.SetFloat( "_MiePhaseAnisotropy", Mathf.Clamp( m_ScatteringAnisotropy, -0.99f, +0.99f ) ); _Material.SetFloat( "_PlanetRadiusOffsetKm", m_PlanetRadiusOffsetKm ); // Prepare cloud Mie factors & cloud layers' textures switch ( _Layers.Length ) { case 0: _Material.SetTexture( "_TexCloudLayer0", m_Owner.m_TextureEmptyCloud, true ); _Material.SetTexture( "_TexCloudLayer1", m_Owner.m_TextureEmptyCloud, true ); _Material.SetTexture( "_TexCloudLayer2", m_Owner.m_TextureEmptyCloud, true ); _Material.SetTexture( "_TexCloudLayer3", m_Owner.m_TextureEmptyCloud, true ); break; case 1: _Material.SetTexture( "_TexCloudLayer0", _bIsEnvironmentRendering ? _Layers[0].EnvironmentRenderTargetSky : _Layers[0].RenderTarget ); _Material.SetTexture( "_TexCloudLayer1", m_Owner.m_TextureEmptyCloud, true ); _Material.SetTexture( "_TexCloudLayer2", m_Owner.m_TextureEmptyCloud, true ); _Material.SetTexture( "_TexCloudLayer3", m_Owner.m_TextureEmptyCloud, true ); break; case 2: _Material.SetTexture( "_TexCloudLayer0", _bIsEnvironmentRendering ? _Layers[0].EnvironmentRenderTargetSky : _Layers[0].RenderTarget ); _Material.SetTexture( "_TexCloudLayer1", _bIsEnvironmentRendering ? _Layers[1].EnvironmentRenderTargetSky : _Layers[1].RenderTarget ); _Material.SetTexture( "_TexCloudLayer2", m_Owner.m_TextureEmptyCloud, true ); _Material.SetTexture( "_TexCloudLayer3", m_Owner.m_TextureEmptyCloud, true ); break; case 3: _Material.SetTexture( "_TexCloudLayer0", _bIsEnvironmentRendering ? _Layers[0].EnvironmentRenderTargetSky : _Layers[0].RenderTarget ); _Material.SetTexture( "_TexCloudLayer1", _bIsEnvironmentRendering ? _Layers[1].EnvironmentRenderTargetSky : _Layers[1].RenderTarget ); _Material.SetTexture( "_TexCloudLayer2", _bIsEnvironmentRendering ? _Layers[2].EnvironmentRenderTargetSky : _Layers[2].RenderTarget ); _Material.SetTexture( "_TexCloudLayer3", m_Owner.m_TextureEmptyCloud, true ); break; case 4: _Material.SetTexture( "_TexCloudLayer0", _bIsEnvironmentRendering ? _Layers[0].EnvironmentRenderTargetSky : _Layers[0].RenderTarget ); _Material.SetTexture( "_TexCloudLayer1", _bIsEnvironmentRendering ? _Layers[1].EnvironmentRenderTargetSky : _Layers[1].RenderTarget ); _Material.SetTexture( "_TexCloudLayer2", _bIsEnvironmentRendering ? _Layers[2].EnvironmentRenderTargetSky : _Layers[2].RenderTarget ); _Material.SetTexture( "_TexCloudLayer3", _bIsEnvironmentRendering ? _Layers[3].EnvironmentRenderTargetSky : _Layers[3].RenderTarget ); break; } }
protected void SetupSkyParametersNone( NuajMaterial _Material, ICloudLayer[] _Layers, bool _bIsEnvironmentRendering ) { // Prepare cloud Mie factors & cloud layers' textures switch ( _Layers.Length ) { case 0: _Material.SetTexture( "_TexCloudLayer0", m_Owner.m_TextureEmptyCloud, true ); _Material.SetTexture( "_TexCloudLayer1", m_Owner.m_TextureEmptyCloud, true ); _Material.SetTexture( "_TexCloudLayer2", m_Owner.m_TextureEmptyCloud, true ); _Material.SetTexture( "_TexCloudLayer3", m_Owner.m_TextureEmptyCloud, true ); break; case 1: _Material.SetTexture( "_TexCloudLayer0", _bIsEnvironmentRendering ? _Layers[0].EnvironmentRenderTargetSky : _Layers[0].RenderTarget ); _Material.SetTexture( "_TexCloudLayer1", m_Owner.m_TextureEmptyCloud, true ); _Material.SetTexture( "_TexCloudLayer2", m_Owner.m_TextureEmptyCloud, true ); _Material.SetTexture( "_TexCloudLayer3", m_Owner.m_TextureEmptyCloud, true ); break; case 2: _Material.SetTexture( "_TexCloudLayer0", _bIsEnvironmentRendering ? _Layers[0].EnvironmentRenderTargetSky : _Layers[0].RenderTarget ); _Material.SetTexture( "_TexCloudLayer1", _bIsEnvironmentRendering ? _Layers[1].EnvironmentRenderTargetSky : _Layers[1].RenderTarget ); _Material.SetTexture( "_TexCloudLayer2", m_Owner.m_TextureEmptyCloud, true ); _Material.SetTexture( "_TexCloudLayer3", m_Owner.m_TextureEmptyCloud, true ); break; case 3: _Material.SetTexture( "_TexCloudLayer0", _bIsEnvironmentRendering ? _Layers[0].EnvironmentRenderTargetSky : _Layers[0].RenderTarget ); _Material.SetTexture( "_TexCloudLayer1", _bIsEnvironmentRendering ? _Layers[1].EnvironmentRenderTargetSky : _Layers[1].RenderTarget ); _Material.SetTexture( "_TexCloudLayer2", _bIsEnvironmentRendering ? _Layers[2].EnvironmentRenderTargetSky : _Layers[2].RenderTarget ); _Material.SetTexture( "_TexCloudLayer3", m_Owner.m_TextureEmptyCloud, true ); break; case 4: _Material.SetTexture( "_TexCloudLayer0", _bIsEnvironmentRendering ? _Layers[0].EnvironmentRenderTargetSky : _Layers[0].RenderTarget ); _Material.SetTexture( "_TexCloudLayer1", _bIsEnvironmentRendering ? _Layers[1].EnvironmentRenderTargetSky : _Layers[1].RenderTarget ); _Material.SetTexture( "_TexCloudLayer2", _bIsEnvironmentRendering ? _Layers[2].EnvironmentRenderTargetSky : _Layers[2].RenderTarget ); _Material.SetTexture( "_TexCloudLayer3", _bIsEnvironmentRendering ? _Layers[3].EnvironmentRenderTargetSky : _Layers[3].RenderTarget ); break; } }
/// <summary> /// Setups the sky parameters for the sky material /// </summary> /// <param name="_Material">The material to setup</param> /// <param name="_Layers">The array of cloud layers (from 0 to 4 elements)</param> /// <param name="_ShadowMap">The shadow map</param> /// <param name="_bIsEnvironmentRendering"></param> protected void SetupSkyParameters( NuajMaterial _Material, ICloudLayer[] _Layers, Texture _ShadowMap, bool _bIsEnvironmentRendering ) { // Build the GPU & CPU density textures if they do not already exist ComputeDensityTexture(); _Material.SetTexture( "_TexDensity", m_DensityTexture ); _Material.SetTextureRAW( "_TexShadowMap", _ShadowMap ); _Material.SetFloat( "_DensitySeaLevel_Rayleigh", m_DensityRayleigh ); _Material.SetVector( "_Sigma_Rayleigh", m_SigmaRayleigh ); _Material.SetFloat( "_DensitySeaLevel_Mie", m_DensityMie ); _Material.SetFloat( "_Sigma_Mie", m_SigmaMie ); _Material.SetFloat( "_MiePhaseAnisotropy", Mathf.Clamp( m_ScatteringAnisotropy, -0.99f, +0.99f ) ); _Material.SetFloat( "_SkyStepsCount", m_SkyStepsCount );//+ (_Layers.Length == 0 ? m_UnderCloudsMinStepsCount : 0) ); // Use higher resolution if no cloud layers _Material.SetFloat( "_UnderCloudsMinStepsCount", m_bGodRays ? m_UnderCloudsMinStepsCount : 0 ); _Material.SetFloat( "_bGodRays", m_bGodRays ? 1 : 0 ); _Material.SetFloat( "_PlanetRadiusOffsetKm", m_PlanetRadiusOffsetKm ); // Prepare cloud Mie factors & cloud layers' textures switch ( _Layers.Length ) { case 0: _Material.SetTexture( "_TexCloudLayer0", m_Owner.m_TextureEmptyCloud, true ); _Material.SetTexture( "_TexCloudLayer1", m_Owner.m_TextureEmptyCloud, true ); _Material.SetTexture( "_TexCloudLayer2", m_Owner.m_TextureEmptyCloud, true ); _Material.SetTexture( "_TexCloudLayer3", m_Owner.m_TextureEmptyCloud, true ); break; case 1: _Material.SetTexture( "_TexCloudLayer0", _bIsEnvironmentRendering ? _Layers[0].EnvironmentRenderTargetSky : _Layers[0].RenderTarget ); _Material.SetTexture( "_TexCloudLayer1", m_Owner.m_TextureEmptyCloud, true ); _Material.SetTexture( "_TexCloudLayer2", m_Owner.m_TextureEmptyCloud, true ); _Material.SetTexture( "_TexCloudLayer3", m_Owner.m_TextureEmptyCloud, true ); break; case 2: _Material.SetTexture( "_TexCloudLayer0", _bIsEnvironmentRendering ? _Layers[0].EnvironmentRenderTargetSky : _Layers[0].RenderTarget ); _Material.SetTexture( "_TexCloudLayer1", _bIsEnvironmentRendering ? _Layers[1].EnvironmentRenderTargetSky : _Layers[1].RenderTarget ); _Material.SetTexture( "_TexCloudLayer2", m_Owner.m_TextureEmptyCloud, true ); _Material.SetTexture( "_TexCloudLayer3", m_Owner.m_TextureEmptyCloud, true ); break; case 3: _Material.SetTexture( "_TexCloudLayer0", _bIsEnvironmentRendering ? _Layers[0].EnvironmentRenderTargetSky : _Layers[0].RenderTarget ); _Material.SetTexture( "_TexCloudLayer1", _bIsEnvironmentRendering ? _Layers[1].EnvironmentRenderTargetSky : _Layers[1].RenderTarget ); _Material.SetTexture( "_TexCloudLayer2", _bIsEnvironmentRendering ? _Layers[2].EnvironmentRenderTargetSky : _Layers[2].RenderTarget ); _Material.SetTexture( "_TexCloudLayer3", m_Owner.m_TextureEmptyCloud, true ); break; case 4: _Material.SetTexture( "_TexCloudLayer0", _bIsEnvironmentRendering ? _Layers[0].EnvironmentRenderTargetSky : _Layers[0].RenderTarget ); _Material.SetTexture( "_TexCloudLayer1", _bIsEnvironmentRendering ? _Layers[1].EnvironmentRenderTargetSky : _Layers[1].RenderTarget ); _Material.SetTexture( "_TexCloudLayer2", _bIsEnvironmentRendering ? _Layers[2].EnvironmentRenderTargetSky : _Layers[2].RenderTarget ); _Material.SetTexture( "_TexCloudLayer3", _bIsEnvironmentRendering ? _Layers[3].EnvironmentRenderTargetSky : _Layers[3].RenderTarget ); break; } }