浏览代码

Merge pull request #119 from EvgeniiG/master

Tweak the behavior of the procedural sky
/main
GitHub 8 年前
当前提交
906bb804
共有 4 个文件被更改,包括 59 次插入49 次删除
  1. 30
      Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/ProceduralSky/ProceduralSkyParameters.cs
  2. 39
      Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/ProceduralSky/ProceduralSkyRenderer.cs
  3. 35
      Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/ProceduralSky/Resources/AtmosphericScattering.hlsl
  4. 4
      Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/ProceduralSky/Resources/SkyProcedural.shader

30
Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/ProceduralSky/ProceduralSkyParameters.cs


public Gradient worldMieColorRamp = null;
public float worldMieDensity = 15f;
public float worldMieExtinctionFactor = 0f;
public float worldMieNearScatterPush = 0f;
public float worldNearScatterPush = 0f;
public float worldNormalDistance = 1000f;
public float worldRayleighColorIntensity = 1f;
public Gradient worldRayleighColorRamp = null;

public float worldRayleighNearScatterPush = 0f;
public float heightNearScatterPush = 0f;
public float heightMieNearScatterPush = 0f;
public float heightRayleighNearScatterPush = 0f;
public float heightSeaLevel = 0f;
/*

public void OnValidate()
{
worldMieDensity = Mathf.Clamp(worldMieDensity, 0f, 1000f);
worldMiePhaseAnisotropy = Mathf.Clamp01(worldMiePhaseAnisotropy);
worldNearScatterPush = Mathf.Clamp(worldNearScatterPush, -200f, 300f);
worldNormalDistance = Mathf.Clamp(worldNormalDistance, 1f, 10000f);
worldRayleighDensity = Mathf.Clamp(worldRayleighDensity, 0, 1000f);
worldRayleighIndirectScatter = Mathf.Clamp(worldRayleighIndirectScatter, 0f, 1f);
worldMieDensity = Mathf.Clamp(worldMieDensity, 0f, 1000f);
worldMiePhaseAnisotropy = Mathf.Clamp01(worldMiePhaseAnisotropy);
worldMieNearScatterPush = Mathf.Clamp(worldMieNearScatterPush, -200f, 300f);
worldNormalDistance = Mathf.Clamp(worldNormalDistance, 1f, 10000f);
worldRayleighDensity = Mathf.Clamp(worldRayleighDensity, 0, 1000f);
worldRayleighIndirectScatter = Mathf.Clamp(worldRayleighIndirectScatter, 0f, 1f);
worldRayleighNearScatterPush = Mathf.Clamp(worldRayleighNearScatterPush, -200f, 300f);
heightMieDensity = Mathf.Clamp(heightMieDensity, 0, 1000f);
heightNearScatterPush = Mathf.Clamp(heightNearScatterPush, -200f, 300f);
heightNormalDistance = Mathf.Clamp(heightNormalDistance, 1f, 10000f);
heightRayleighDensity = Mathf.Clamp(heightRayleighDensity, 0, 1000f);
heightMieDensity = Mathf.Clamp(heightMieDensity, 0, 1000f);
heightMieNearScatterPush = Mathf.Clamp(heightMieNearScatterPush, -200f, 300f);
heightNormalDistance = Mathf.Clamp(heightNormalDistance, 1f, 10000f);
heightRayleighDensity = Mathf.Clamp(heightRayleighDensity, 0, 1000f);
heightRayleighNearScatterPush = Mathf.Clamp(heightRayleighNearScatterPush, -200f, 300f);
worldScaleExponent = Mathf.Clamp(worldScaleExponent, 1f, 2f);
worldScaleExponent = Mathf.Clamp(worldScaleExponent, 1f, 2f);
/*
occlusionBias = Mathf.Clamp01(occlusionBias);

39
Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/ProceduralSky/ProceduralSkyRenderer.cs


Utilities.SetRenderTarget(builtinParams.renderContext, builtinParams.colorBuffer);
}
void SetKeywords(BuiltinSkyParameters builtinParams, ProceduralSkyParameters param)
void SetKeywords(BuiltinSkyParameters builtinParams, ProceduralSkyParameters param, bool renderForCubemap)
{
// Ensure that all preprocessor symbols are initially undefined.
m_ProceduralSkyMaterial.DisableKeyword("ATMOSPHERICS");

*/
// Expected to be valid for the sky pass, and invalid for the cube map generation pass.
if (builtinParams.depthBuffer != BuiltinSkyParameters.nullRT)
if (!renderForCubemap)
{
m_ProceduralSkyMaterial.EnableKeyword("PERFORM_SKY_OCCLUSION_TEST");
}

}
}
void SetUniforms(BuiltinSkyParameters builtinParams, ProceduralSkyParameters param, ref MaterialPropertyBlock properties)
void SetUniforms(BuiltinSkyParameters builtinParams, ProceduralSkyParameters param, bool renderForCubemap, ref MaterialPropertyBlock properties)
{
properties.SetTexture("_Cubemap", param.skyHDRI);
properties.SetVector("_SkyParam", new Vector4(param.exposure, param.multiplier, param.rotation, 0.0f));

m_ProceduralSkyMaterial.SetFloat("_WorldScaleExponent", param.worldScaleExponent);
m_ProceduralSkyMaterial.SetFloat("_WorldNormalDistanceRcp", 1f / param.worldNormalDistance);
m_ProceduralSkyMaterial.SetFloat("_WorldNearScatterPush", -Mathf.Pow(Mathf.Abs(param.worldNearScatterPush), param.worldScaleExponent) * Mathf.Sign(param.worldNearScatterPush));
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.SetVector("_MieColorP20", (Vector4)mieColorP20 * param.worldMieColorIntensity);
m_ProceduralSkyMaterial.SetFloat("_HeightNormalDistanceRcp", 1f / param.heightNormalDistance);
m_ProceduralSkyMaterial.SetFloat("_HeightNearScatterPush", -Mathf.Pow(Mathf.Abs(param.heightNearScatterPush), param.worldScaleExponent) * Mathf.Sign(param.heightNearScatterPush));
m_ProceduralSkyMaterial.SetFloat("_HeightRayleighDensity", -param.heightRayleighDensity / 100000f);
m_ProceduralSkyMaterial.SetFloat("_HeightMieDensity", -param.heightMieDensity / 100000f);
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.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 flip the screens-space Y axis in case we follow the D3D convention.
properties.SetFloat("_FlipY", 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);
}
override public void RenderSky(BuiltinSkyParameters builtinParams, SkyParameters skyParameters, bool renderForCubemap)

MaterialPropertyBlock properties = new MaterialPropertyBlock();
// Define select preprocessor symbols.
SetKeywords(builtinParams, proceduralSkyParams);
SetKeywords(builtinParams, proceduralSkyParams, renderForCubemap);
SetUniforms(builtinParams, proceduralSkyParams, ref properties);
SetUniforms(builtinParams, proceduralSkyParams, renderForCubemap, ref properties);
// 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.
if (builtinParams.depthBuffer != BuiltinSkyParameters.nullRT)
if (!renderForCubemap)
properties.SetFloat("_DisableSkyOcclusionTest", 0.0f);
properties.SetFloat("_FlipY", 0.0f);
}
else
{
properties.SetFloat("_DisableSkyOcclusionTest", 1.0f);
properties.SetFloat("_FlipY", 1.0f);
}
cmd.DrawMesh(builtinParams.skyMesh, Matrix4x4.identity, m_ProceduralSkyMaterial, 0, 0, properties);

35
Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/ProceduralSky/Resources/AtmosphericScattering.hlsl


uniform float _WorldScaleExponent;
uniform float _WorldNormalDistanceRcp;
uniform float _WorldNearScatterPush;
uniform float _WorldRayleighNearScatterPush;
uniform float _WorldMieNearScatterPush;
uniform float _WorldRayleighDensity;
uniform float _WorldMieDensity;

uniform float3 _MieColorP45;
uniform float _HeightNormalDistanceRcp;
uniform float _HeightNearScatterPush;
uniform float _HeightMieNearScatterPush;
uniform float _HeightRayleighNearScatterPush;
uniform float _HeightRayleighDensity;
uniform float _HeightMieDensity;
uniform float _HeightSeaLevel;

if(angleY >= 0.f) mieColor = lerp(_MieColorO00, _MieColorP20, saturate(angleY / angle20));
else mieColor = lerp(_MieColorM20, _MieColorO00, saturate((angleY + angle20) / angle20));
const float pushedDistance = max(0.f, worldVecLen + _WorldNearScatterPush);
const float pushedDensity = /*HeightDensity **/ pushedDistance /** exp(-scaledWorldPos.y / 8000.f)*/;
const float rayleighScatter = (1.f - exp(_WorldRayleighDensity * pushedDensity)) * rayleighPh;
const float pushedMieDistance = max(0.f, worldVecLen + _WorldMieNearScatterPush);
const float pushedRayleighDistance = max(0.f, worldVecLen + _WorldRayleighNearScatterPush);
const float pushedMieDensity = /*HeightDensity **/ pushedMieDistance /** exp(-scaledWorldPos.y / 8000.f)*/;
const float pushedRayleighDensity = /*HeightDensity **/ pushedRayleighDistance /** exp(-scaledWorldPos.y / 8000.f)*/;
const float rayleighScatter = (1.f - exp(_WorldRayleighDensity * pushedRayleighDensity)) * rayleighPh;
const float mieScatter = (1.f - exp(_WorldMieDensity * pushedDensity));
const float mieScatter = (1.f - exp(_WorldMieDensity * pushedMieDensity));
const float mieScatter = (1.f - exp(_WorldMieDensity * pushedDensity)) * miePh;
const float mieScatter = (1.f - exp(_WorldMieDensity * pushedMieDensity)) * miePh;
const float pushedHeightDistance = max(0.f, worldVecLen + _HeightNearScatterPush);
const float heightScatter = (1.f - exp(_HeightRayleighDensity * pushedHeightDistance)) * HeightDensity;
const float pushedRayleighHeightDistance = max(0.f, worldVecLen + _HeightRayleighNearScatterPush);
const float pushedMieHeightDistance = max(0.f, worldVecLen + _HeightMieNearScatterPush);
const float heightRayleighScatter = (1.f - exp(_HeightRayleighDensity * pushedRayleighHeightDistance)) * HeightDensity;
const float heightMieScatter = (1.f - exp(_HeightMieDensity * pushedHeightDistance)) * HeightDensity;
const float heightMieScatter = (1.f - exp(_HeightMieDensity * pushedMieHeightDistance)) * HeightDensity;
const float heightMieScatter = (1.f - exp(_HeightMieDensity * pushedHeightDistance)) * HeightDensity * miePh;
const float heightMieScatter = (1.f - exp(_HeightMieDensity * pushedMieHeightDistance)) * HeightDensity * miePh;
rayleighColor = lerp(Luminance(rayleighColor).rrr, rayleighColor, saturate(pushedDistance * _WorldNormalDistanceRcp));
float3 heightRayleighColor = lerp(Luminance(_HeightRayleighColor.xyz).rrr, _HeightRayleighColor.xyz, saturate(pushedHeightDistance * _HeightNormalDistanceRcp));
rayleighColor = lerp(Luminance(rayleighColor).rrr, rayleighColor, saturate(pushedRayleighDistance * _WorldNormalDistanceRcp));
float3 heightRayleighColor = lerp(Luminance(_HeightRayleighColor.xyz).rrr, _HeightRayleighColor.xyz, saturate(pushedRayleighHeightDistance * _HeightNormalDistanceRcp));
coords3.rgb = saturate(heightScatter) * heightRayleighColor;
coords3.a = heightScatter;
coords3.rgb = saturate(heightRayleighScatter) * heightRayleighColor;
coords3.a = heightRayleighScatter;
coords2.rgb = mieScatter * mieColor + saturate(heightMieScatter) * mieColor;
coords2.a = mieScatter;

4
Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/ProceduralSky/Resources/SkyProcedural.shader


sincos(phi, sinPhi, cosPhi);
float3 rotDirX = float3(cosPhi, 0, -sinPhi);
float3 rotDirY = float3(sinPhi, 0, cosPhi);
dir = float3(dot(rotDirX, dir), dir.y, dot(rotDirY, dir));
float3 rotatedDir = float3(dot(rotDirX, dir), dir.y, dot(rotDirY, dir));
// input.positionCS is SV_Position
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw);

if (skyTexWeight == 1.0)
{
skyColor = SAMPLE_TEXTURECUBE_LOD(_Cubemap, sampler_Cubemap, dir, 0).rgb;
skyColor = SAMPLE_TEXTURECUBE_LOD(_Cubemap, sampler_Cubemap, rotatedDir, 0).rgb;
skyColor *= exp2(_SkyParam.x) * _SkyParam.y;
opacity = 1.0; // Fully overwrite unoccluded scene regions.
}

正在加载...
取消
保存