您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

179 行
11 KiB

using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
public class ProceduralSkyRenderer : SkyRenderer
{
Material m_ProceduralSkyMaterial = null; // Renders a cubemap into a render texture (can be cube or 2D)
private ProceduralSkySettings m_ProceduralSkySettings;
public ProceduralSkyRenderer(ProceduralSkySettings proceduralSkySettings)
{
m_ProceduralSkySettings = proceduralSkySettings;
}
public override void Build()
{
m_ProceduralSkyMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/Sky/SkyProcedural");
}
public override void Cleanup()
{
Utilities.Destroy(m_ProceduralSkyMaterial);
}
public override bool IsSkyValid()
{
if (m_ProceduralSkyMaterial == null || m_ProceduralSkySettings == null)
return false;
return m_ProceduralSkySettings.skyHDRI != null &&
m_ProceduralSkySettings.worldMieColorRamp != null &&
m_ProceduralSkySettings.worldRayleighColorRamp != null;
}
public override void SetRenderTargets(BuiltinSkyParameters builtinParams)
{
// We do not bind the depth buffer as a depth-stencil target since it is
// bound as a color texture which is then sampled from within the shader.
Utilities.SetRenderTarget(builtinParams.commandBuffer, builtinParams.colorBuffer);
}
void SetKeywords(BuiltinSkyParameters builtinParams, ProceduralSkySettings param, bool renderForCubemap)
{
// Ensure that all preprocessor symbols are initially undefined.
m_ProceduralSkyMaterial.DisableKeyword("ATMOSPHERICS");
m_ProceduralSkyMaterial.DisableKeyword("ATMOSPHERICS_PER_PIXEL");
m_ProceduralSkyMaterial.DisableKeyword("ATMOSPHERICS_DEBUG");
m_ProceduralSkyMaterial.DisableKeyword("ATMOSPHERICS_OCCLUSION");
m_ProceduralSkyMaterial.DisableKeyword("ATMOSPHERICS_OCCLUSION_EDGE_FIXUP");
m_ProceduralSkyMaterial.DisableKeyword("ATMOSPHERICS_OCCLUSION_FULLSKY");
m_ProceduralSkyMaterial.DisableKeyword("ATMOSPHERICS_SUNRAYS");
m_ProceduralSkyMaterial.DisableKeyword("PERFORM_SKY_OCCLUSION_TEST");
m_ProceduralSkyMaterial.EnableKeyword("ATMOSPHERICS_PER_PIXEL");
/*
if (useOcclusion)
{
m_ProceduralSkyMaterial.EnableKeyword("ATMOSPHERICS_OCCLUSION");
if(occlusionDepthFixup && occlusionDownscale != OcclusionDownscale.x1)
m_ProceduralSkyMaterial.EnableKeyword("ATMOSPHERICS_OCCLUSION_EDGE_FIXUP");
if(occlusionFullSky)
m_ProceduralSkyMaterial.EnableKeyword("ATMOSPHERICS_OCCLUSION_FULLSKY");
}
*/
// Expected to be valid for the sky pass, and invalid for the cube map generation pass.
if (!renderForCubemap)
{
m_ProceduralSkyMaterial.EnableKeyword("PERFORM_SKY_OCCLUSION_TEST");
}
if (param.debugMode != ProceduralSkySettings.ScatterDebugMode.None)
{
m_ProceduralSkyMaterial.EnableKeyword("ATMOSPHERICS_DEBUG");
}
}
void SetUniforms(BuiltinSkyParameters builtinParams, ProceduralSkySettings param, bool renderForCubemap, ref MaterialPropertyBlock properties)
{
properties.SetTexture("_Cubemap", param.skyHDRI);
properties.SetVector("_SkyParam", new Vector4(param.exposure, param.multiplier, param.rotation, 0.0f));
properties.SetMatrix("_InvViewProjMatrix", builtinParams.invViewProjMatrix);
properties.SetVector("_CameraPosWS", builtinParams.cameraPosWS);
properties.SetVector("_ScreenSize", builtinParams.screenSize);
m_ProceduralSkyMaterial.SetInt("_AtmosphericsDebugMode", (int)param.debugMode);
Vector3 sunDirection = (builtinParams.sunLight != null) ? -builtinParams.sunLight.transform.forward : Vector3.zero;
m_ProceduralSkyMaterial.SetVector("_SunDirection", sunDirection);
var pixelRect = new Rect(0f, 0f, builtinParams.screenSize.x, builtinParams.screenSize.y);
var scale = 1.0f; //(float)(int)occlusionDownscale;
var depthTextureScaledTexelSize = new Vector4(scale / pixelRect.width,
scale / pixelRect.height,
-scale / pixelRect.width,
-scale / pixelRect.height);
properties.SetVector("_DepthTextureScaledTexelSize", depthTextureScaledTexelSize);
/*
m_ProceduralSkyMaterial.SetFloat("_ShadowBias", useOcclusion ? occlusionBias : 1f);
m_ProceduralSkyMaterial.SetFloat("_ShadowBiasIndirect", useOcclusion ? occlusionBiasIndirect : 1f);
m_ProceduralSkyMaterial.SetFloat("_ShadowBiasClouds", useOcclusion ? occlusionBiasClouds : 1f);
m_ProceduralSkyMaterial.SetVector("_ShadowBiasSkyRayleighMie", useOcclusion ? new Vector4(occlusionBiasSkyRayleigh, occlusionBiasSkyMie, 0f, 0f) : Vector4.zero);
m_ProceduralSkyMaterial.SetFloat("_OcclusionDepthThreshold", occlusionDepthThreshold);
m_ProceduralSkyMaterial.SetVector("_OcclusionTexture_TexelSize", ???);
*/
m_ProceduralSkyMaterial.SetFloat("_WorldScaleExponent", param.worldScaleExponent);
m_ProceduralSkyMaterial.SetFloat("_WorldNormalDistanceRcp", 1f / param.worldNormalDistance);
m_ProceduralSkyMaterial.SetFloat("_WorldMieNearScatterPush", -Mathf.Pow(Mathf.Abs(param.worldMieNearScatterPush), param.worldScaleExponent) * Mathf.Sign(param.worldMieNearScatterPush));
m_ProceduralSkyMaterial.SetFloat("_WorldRayleighNearScatterPush", -Mathf.Pow(Mathf.Abs(param.worldRayleighNearScatterPush), param.worldScaleExponent) * Mathf.Sign(param.worldRayleighNearScatterPush));
m_ProceduralSkyMaterial.SetFloat("_WorldRayleighDensity", -param.worldRayleighDensity / 100000f);
m_ProceduralSkyMaterial.SetFloat("_WorldMieDensity", -param.worldMieDensity / 100000f);
m_ProceduralSkyMaterial.SetFloat("_SkyDepth", 1.0f / param.maxSkyDistance);
var rayleighColorM20 = param.worldRayleighColorRamp.Evaluate(0.00f);
var rayleighColorM10 = param.worldRayleighColorRamp.Evaluate(0.25f);
var rayleighColorO00 = param.worldRayleighColorRamp.Evaluate(0.50f);
var rayleighColorP10 = param.worldRayleighColorRamp.Evaluate(0.75f);
var rayleighColorP20 = param.worldRayleighColorRamp.Evaluate(1.00f);
var mieColorM20 = param.worldMieColorRamp.Evaluate(0.00f);
var mieColorO00 = param.worldMieColorRamp.Evaluate(0.50f);
var mieColorP20 = param.worldMieColorRamp.Evaluate(1.00f);
m_ProceduralSkyMaterial.SetVector("_RayleighColorM20", (Vector4)rayleighColorM20 * param.worldRayleighColorIntensity);
m_ProceduralSkyMaterial.SetVector("_RayleighColorM10", (Vector4)rayleighColorM10 * param.worldRayleighColorIntensity);
m_ProceduralSkyMaterial.SetVector("_RayleighColorO00", (Vector4)rayleighColorO00 * param.worldRayleighColorIntensity);
m_ProceduralSkyMaterial.SetVector("_RayleighColorP10", (Vector4)rayleighColorP10 * param.worldRayleighColorIntensity);
m_ProceduralSkyMaterial.SetVector("_RayleighColorP20", (Vector4)rayleighColorP20 * param.worldRayleighColorIntensity);
m_ProceduralSkyMaterial.SetVector("_MieColorM20", (Vector4)mieColorM20 * param.worldMieColorIntensity);
m_ProceduralSkyMaterial.SetVector("_MieColorO00", (Vector4)mieColorO00 * param.worldMieColorIntensity);
m_ProceduralSkyMaterial.SetVector("_MieColorP20", (Vector4)mieColorP20 * param.worldMieColorIntensity);
m_ProceduralSkyMaterial.SetFloat("_HeightNormalDistanceRcp", 1f / param.heightNormalDistance);
m_ProceduralSkyMaterial.SetFloat("_HeightMieNearScatterPush", -Mathf.Pow(Mathf.Abs(param.heightMieNearScatterPush), param.worldScaleExponent) * Mathf.Sign(param.heightMieNearScatterPush));
m_ProceduralSkyMaterial.SetFloat("_HeightRayleighNearScatterPush", -Mathf.Pow(Mathf.Abs(param.heightRayleighNearScatterPush), param.worldScaleExponent) * Mathf.Sign(param.heightRayleighNearScatterPush));
// m_ProceduralSkyMaterial.SetFloat("_HeightRayleighDensity", -param.heightRayleighDensity / 100000f);
// m_ProceduralSkyMaterial.SetFloat("_HeightMieDensity", -param.heightMieDensity / 100000f);
m_ProceduralSkyMaterial.SetFloat("_HeightSeaLevel", param.heightSeaLevel);
m_ProceduralSkyMaterial.SetVector("_HeightPlaneShift", param.heightPlaneShift);
m_ProceduralSkyMaterial.SetFloat("_HeightDistanceRcp", 1f / param.heightDistance);
m_ProceduralSkyMaterial.SetVector("_HeightRayleighColor", (Vector4)param.heightRayleighColor * param.heightRayleighIntensity);
m_ProceduralSkyMaterial.SetFloat("_HeightExtinctionFactor", param.heightExtinctionFactor);
m_ProceduralSkyMaterial.SetVector("_RayleighInScatterPct", new Vector4(1f - param.worldRayleighIndirectScatter, param.worldRayleighIndirectScatter, 0f, 0f));
m_ProceduralSkyMaterial.SetFloat("_RayleighExtinctionFactor", param.worldRayleighExtinctionFactor);
m_ProceduralSkyMaterial.SetFloat("_MiePhaseAnisotropy", param.worldMiePhaseAnisotropy);
m_ProceduralSkyMaterial.SetFloat("_MieExtinctionFactor", param.worldMieExtinctionFactor);
// Since we use the material for rendering the sky both into the cubemap, and
// during the fullscreen pass, setting the 'PERFORM_SKY_OCCLUSION_TEST' keyword has no effect.
properties.SetFloat("_DisableSkyOcclusionTest", renderForCubemap ? 1.0f : 0.0f);
// We do not render the height fog into the sky IBL cubemap.
properties.SetFloat("_HeightRayleighDensity", renderForCubemap ? -0.0f : -param.heightRayleighDensity / 100000f);
properties.SetFloat("_HeightMieDensity", renderForCubemap ? -0.0f : -param.heightMieDensity / 100000f);
properties.SetMatrix(HDShaderIDs._PixelCoordToViewDirWS, builtinParams.pixelCoordToViewDirMatrix);
}
override public void RenderSky(BuiltinSkyParameters builtinParams, SkySettings skyParameters, bool renderForCubemap)
{
MaterialPropertyBlock properties = new MaterialPropertyBlock();
// Define select preprocessor symbols.
SetKeywords(builtinParams, m_ProceduralSkySettings, renderForCubemap);
// Set shader constants.
SetUniforms(builtinParams, m_ProceduralSkySettings, renderForCubemap, ref properties);
Utilities.DrawFullScreen(builtinParams.commandBuffer, m_ProceduralSkyMaterial, properties);
}
}
}