using System.Collections.Generic ;
using System ;
public Cubemap skyHDRI ;
public Texture skyHDRI ;
public float rotation = 0.0f ;
public float exposure = 0.0f ;
public float multiplier = 1.0f ;
const int kSkyCubemapSize = 2 5 6 ;
RenderTexture m_SkyboxCubemapRT = null ;
RenderTexture m_SkyboxGGXCubemapRT = null ;
Material m_GGXConvolveMaterial = null ; // Apply GGX convolution to cubemap
MaterialPropertyBlock m_RenderSkyPropertyBlock = null ;
GameObject [ ] m_CubemapFaceCamera = new GameObject [ 6 ] ;
m_StandardSkyboxMaterial = Utilities . CreateEngineMaterial ( "Skybox/Cubemap" ) ;
m_SkyHDRIMaterial = Utilities . CreateEngineMaterial ( "Hidden/HDRenderLoop/SkyHDRI" ) ;
m_GGXConvolveMaterial = Utilities . CreateEngineMaterial ( "Hidden/HDRenderLoop/GGXConvolve" ) ;
m_RenderSkyPropertyBlock = new MaterialPropertyBlock ( ) ;
m_SkyboxCubemapRT . filterMode = FilterMode . Point ;
m_SkyboxGGXCubemapRT = new RenderTexture ( kSkyCubemapSize , kSkyCubemapSize , 1 , RenderTextureFormat . ARGBHalf ) ;
m_SkyboxGGXCubemapRT . dimension = TextureDimension . Cube ;
m_SkyboxGGXCubemapRT . useMipMap = true ;
m_SkyboxGGXCubemapRT . autoGenerateMips = false ;
m_SkyboxGGXCubemapRT . filterMode = FilterMode . Trilinear ;
m_SkyboxGGXCubemapRT . Create ( ) ;
Matrix4x4 cubeProj = Matrix4x4 . Perspective ( 9 0.0f , 1.0f , 0.1f , 1.0f ) ;
Vector3 [ ] lookAtList = {
{
Utilities . Destroy ( m_StandardSkyboxMaterial ) ;
Utilities . Destroy ( m_SkyHDRIMaterial ) ;
Utilities . Destroy ( m_GGXConvolveMaterial ) ;
Utilities . Destroy ( m_SkyboxGGXCubemapRT ) ;
for ( int i = 0 ; i < 6 ; + + i )
{
{
Mesh skyMesh = BuildSkyMesh ( camera , forceUVBottom ) ;
m_SkyHDRIMaterial . SetTexture ( "_Cubemap" , skyParameters . skyHDRI ) ;
m_SkyHDRIMaterial . SetVector ( "_SkyParam" , new Vector4 ( skyParameters . exposure , skyParameters . multiplier , skyParameters . rotation , 0.0f ) ) ;
m_RenderSkyPropertyBlock . SetTexture ( "_Cubemap" , skyParameters . skyHDRI ) ;
m_RenderSkyPropertyBlock . SetVector ( "_SkyParam" , new Vector4 ( skyParameters . exposure , skyParameters . multiplier , skyParameters . rotation , 0.0f ) ) ;
cmd . DrawMesh ( skyMesh , Matrix4x4 . identity , m_SkyHDRIMaterial ) ;
cmd . DrawMesh ( skyMesh , Matrix4x4 . identity , m_SkyHDRIMaterial , 0 , 0 , m_RenderSkyPropertyBlock ) ;
public void RenderSky ( Camera camera , SkyParameters skyParameters , RenderTargetIdentifier colorBuffer , RenderTargetIdentifier depthBuffer , RenderLoop renderLoop )
private void RenderSkyToCubemap ( SkyParameters skyParameters , RenderTexture target , RenderLoop renderLoop )
using ( new Utilities . ProfilingSample ( "Sky Pass" , renderLoop ) )
for ( int i = 0 ; i < 6 ; + + i )
{
Utilities . SetRenderTarget ( renderLoop , target , 0 , ( CubemapFace ) i ) ;
Camera faceCamera = m_CubemapFaceCamera [ i ] . GetComponent < Camera > ( ) ;
RenderSky ( faceCamera , skyParameters , true , renderLoop ) ;
}
}
//using (new EditorGUI.DisabledScope(m_LookDevEnvLibrary.hdriList.Count <= 1))
if ( IsSkyValid ( skyParameters ) )
private void RenderCubemapGGXConvolution ( Texture input , RenderTexture target , RenderLoop renderLoop )
{
using ( new Utilities . ProfilingSample ( "Sky Pass: GGX Convolution" , renderLoop ) )
using ( new Utilities . ProfilingSample ( "Sky Pass: Render Cubemap" , renderLoop ) )
int mipCount = 1 + ( int ) Mathf . Log ( input . width , 2.0f ) ;
if ( mipCount < ( ( int ) EnvConstants . SpecCubeLodStep + 1 ) )
// Render sky into a cubemap - doesn't happen every frame, can be control
for ( int i = 0 ; i < 6 ; + + i )
{
Utilities . SetRenderTarget ( renderLoop , m_SkyboxCubemapRT , 0 , ( CubemapFace ) i ) ;
Camera faceCamera = m_CubemapFaceCamera [ i ] . GetComponent < Camera > ( ) ;
RenderSky ( faceCamera , skyParameters , true , renderLoop ) ;
}
m_StandardSkyboxMaterial . SetTexture ( "_Tex" , m_SkyboxCubemapRT ) ;
RenderSettings . skybox = m_StandardSkyboxMaterial ; // Setup this material as the default to be use in RenderSettings
RenderSettings . ambientIntensity = 1.0f ; // fix this to 1, this parameter should not exist!
RenderSettings . ambientMode = UnityEngine . Rendering . AmbientMode . Skybox ; // Force skybox for our HDRI
RenderSettings . reflectionIntensity = 1.0f ;
//DynamicGI.UpdateEnvironment();
Debug . LogWarning ( "RenderCubemapGGXConvolution: Cubemap size is too small for GGX convolution, needs at least " + ( ( int ) EnvConstants . SpecCubeLodStep + 1 ) + " mip levels" ) ;
return ;
// Copy the first mip.
// All parameters are neutral because exposure/multiplier have already been applied in the first copy.
SkyParameters skyParams = new SkyParameters ( ) ;
skyParams . exposure = 0.0f ;
skyParams . multiplier = 1.0f ;
skyParams . rotation = 0.0f ;
skyParams . skyHDRI = input ;
RenderSkyToCubemap ( skyParams , target , renderLoop ) ;
// TODO: do a render to texture here
// Do the convolution on remaining mipmaps
float invOmegaP = ( 6.0f * input . width * input . width ) / ( 4.0f * Mathf . PI ) ; // Solid angle associated to a pixel of the cubemap;
// Downsample the cubemap and provide it to Enlighten
m_GGXConvolveMaterial . SetTexture ( "_MainTex" , input ) ;
m_GGXConvolveMaterial . SetFloat ( "_MipMapCount" , mipCount ) ;
m_GGXConvolveMaterial . SetFloat ( "_InvOmegaP" , invOmegaP ) ;
// TODO: currently workaround is to set the cubemap in a Skybox/cubemap material
//m_SkyboxMaterial.SetTexture(cubemap);
for ( int mip = 1 ; mip < ( ( int ) EnvConstants . SpecCubeLodStep + 1 ) ; + + mip )
{
MaterialPropertyBlock propertyBlock = new MaterialPropertyBlock ( ) ;
propertyBlock . SetFloat ( "_Level" , mip ) ;
// Render the sky itself
Utilities . SetRenderTarget ( renderLoop , colorBuffer , depthBuffer ) ;
RenderSky ( camera , skyParameters , false , renderLoop ) ;
for ( int face = 0 ; face < 6 ; + + face )
{
Utilities . SetRenderTarget ( renderLoop , target , mip , ( CubemapFace ) face ) ;
Camera faceCamera = m_CubemapFaceCamera [ face ] . GetComponent < Camera > ( ) ;
Mesh skyMesh = BuildSkyMesh ( faceCamera , true ) ;
var cmd = new CommandBuffer { name = "" } ;
cmd . DrawMesh ( skyMesh , Matrix4x4 . identity , m_GGXConvolveMaterial , 0 , 0 , propertyBlock ) ;
renderLoop . ExecuteCommandBuffer ( cmd ) ;
cmd . Dispose ( ) ;
}
}
}
}
public void RenderSky ( Camera camera , SkyParameters skyParameters , RenderTargetIdentifier colorBuffer , RenderTargetIdentifier depthBuffer , RenderLoop renderLoop )
{
using ( new Utilities . ProfilingSample ( "Sky Pass" , renderLoop ) )
{
//using (new EditorGUI.DisabledScope(m_LookDevEnvLibrary.hdriList.Count <= 1))
if ( IsSkyValid ( skyParameters ) )
{
using ( new Utilities . ProfilingSample ( "Sky Pass: Render Cubemap" , renderLoop ) )
{
// Render sky into a cubemap - doesn't happen every frame, can be controlled
RenderSkyToCubemap ( skyParameters , m_SkyboxCubemapRT , renderLoop ) ;
// Convolve downsampled cubemap
RenderCubemapGGXConvolution ( m_SkyboxCubemapRT , m_SkyboxGGXCubemapRT , renderLoop ) ;
// TODO: Properly send the cubemap to Enlighten. Currently workaround is to set the cubemap in a Skybox/cubemap material
m_StandardSkyboxMaterial . SetTexture ( "_Tex" , m_SkyboxCubemapRT ) ;
RenderSettings . skybox = m_StandardSkyboxMaterial ; // Setup this material as the default to be use in RenderSettings
RenderSettings . ambientIntensity = 1.0f ; // fix this to 1, this parameter should not exist!
RenderSettings . ambientMode = UnityEngine . Rendering . AmbientMode . Skybox ; // Force skybox for our HDRI
RenderSettings . reflectionIntensity = 1.0f ;
RenderSettings . customReflection = null ;
//DynamicGI.UpdateEnvironment();
}
// Render the sky itself
Utilities . SetRenderTarget ( renderLoop , colorBuffer , depthBuffer ) ;
RenderSky ( camera , skyParameters , false , renderLoop ) ;
}
}
}
}