1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Unity】HDRPで単色のSky

Posted at

Unity HDRPでは、VolumeのVirtual Environmentから背景(環境)を設定できます。現状、選べるSky TypeはGradient Sky、HDRI Sky、Physically Based Skyの3つですが、自分でカスタムSkyを作成することも可能です。この記事では単色のSkyを描画するカスタムSkyを作成してみます。

使用しているバージョンは以下のようになっています。

  • Unity: 2021.2.9f1
  • High Definition RP: 12.14

この記事はUnity HDRP公式ドキュメントおよびHDRPのビルトインSky実装を参考にしています。


カスタムSkyを実装するには、以下の三種類のスクリプト(と必要であればSky Settingsのインスペクター拡張)を作成する必要があります。

  • Sky Settings:
    • Volumeコンポーネントに表示され、カスタムSkyのプロパティを管理する
  • Sky Renderer:
    • Sky Settingsのプロパティをもとに、Sky Rendering ShaderでカスタムSkyの描画を行う
  • Sky Rendering Shader:
    • カスタムSkyの描画を行うシェーダー
  • (Sky Settings Editor):
    • Sky Settingsのインスペクター拡張

まず、SkySettingsです。

UniformSky.cs
using System;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;

[VolumeComponentMenu("Sky/Uniform Sky")]
[SkyUniqueID(UNIFORM_SKY_UNIQUE_ID)]
public class UniformSky : SkySettings
{
    const int UNIFORM_SKY_UNIQUE_ID = 782151;

    [Tooltip("Specifies the color of the sky.")]
    public ColorParameter color = new ColorParameter(Color.white, true, false, true);

    public override Type GetSkyRendererType()
    {
        return typeof(UniformSkyRenderer);
    }

    public override int GetHashCode()
    {
        int hash = base.GetHashCode();
        unchecked
        {
# if UNITY_2019_3
            hash = hash * 23 + color.value.GetHashCode();
# else
            hash = hash * 23 + color.GetHashCode();
# endif
        }
        return hash;
    }
}

次に、Sky Rendererです。

UniformSkyRenderer.cs
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;

public class UniformSkyRenderer : SkyRenderer
{
    public static readonly int _Color = Shader.PropertyToID("_Color");
    public static readonly int _SkyIntensity = Shader.PropertyToID("_SkyIntensity");
    Material m_UniformSkyMaterial;

    public override void Build()
    {
        m_UniformSkyMaterial = CoreUtils.CreateEngineMaterial(GetUniformSkyShader());
    }

    Shader GetUniformSkyShader()
    {
        return Shader.Find("Hidden/HDRP/Sky/Custom/UniformSky");
    }

    public override void Cleanup()
    {
        CoreUtils.Destroy(m_UniformSkyMaterial);
    }

    protected override bool Update(BuiltinSkyParameters builtinParams)
    {
        return false;
    }

    public override void RenderSky(BuiltinSkyParameters builtinParams, bool renderForCubemap, bool renderSunDisk)
    {

        var uniformSky = builtinParams.skySettings as UniformSky;
        float intensity = GetSkyIntensity(uniformSky, builtinParams.debugSettings);
        m_UniformSkyMaterial.SetColor(_Color, uniformSky.color.value);
        m_UniformSkyMaterial.SetFloat(_SkyIntensity, GetSkyIntensity(uniformSky, builtinParams.debugSettings));
        CoreUtils.DrawFullScreen(builtinParams.commandBuffer, m_UniformSkyMaterial, null, renderForCubemap ? 0 : 1);
    }
}

最後にSky Rendering Shaderです。UniformSkyRenderer.csShader.Findを使用しているので、このシェーダーをビルドに含めるにはResourcesディレクトリに置くか、Always-included Shadersに含める必要があります。

UniformSky.shader
Shader "Hidden/HDRP/Sky/Custom/UniformSky"
{
    HLSLINCLUDE

    #pragma vertex Vert

    #pragma editor_sync_compilation
    #pragma target 4.5
    #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch

    #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
    #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonLighting.hlsl"
    #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyUtils.hlsl"

    float3 _Color;
    float _SkyIntensity;

    struct Attributes
    {
        uint vertexID : SV_VertexID;
        UNITY_VERTEX_INPUT_INSTANCE_ID
    };

    struct Varyings
    {
        float4 positionCS : SV_POSITION;
        UNITY_VERTEX_OUTPUT_STEREO
    };

    Varyings Vert(Attributes input)
    {
        Varyings output;
        UNITY_SETUP_INSTANCE_ID(input);
        UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
        output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID, UNITY_RAW_FAR_CLIP_VALUE);
        return output;
    }

    float4 RenderSky(Varyings input)
    {
        return float4(_Color * _SkyIntensity, 1.0);
    }

    float4 FragBaking(Varyings input) : SV_Target
    {
        return RenderSky(input);
    }

    float4 FragRender(Varyings input) : SV_Target
    {
        UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
        float4 color = RenderSky(input);
        color.rgb *= GetCurrentExposureMultiplier();
        return color;
    }

    ENDHLSL

    SubShader
    {
        Tags{ "RenderPipeline" = "HDRenderPipeline" }
        Pass
        {
            ZWrite Off
            ZTest Always
            Blend Off
            Cull Off

            HLSLPROGRAM
                #pragma fragment FragBaking
            ENDHLSL
        }

        Pass
        {
            ZWrite Off
            ZTest LEqual
            Blend Off
            Cull Off

            HLSLPROGRAM
                #pragma fragment FragRender
            ENDHLSL
        }
    }
    Fallback Off
}

ここまで作成すると、Virtual EnvironmentのSky TypeでUniform Skyが選択できるようになり、かつVolumeコンポーネントのAdd OverrideでUniform Skyを追加できます。Uniform Skyを適用するとColorプロパティで選択した色でSkyが描画されます。
Volume.PNG

Uniform Sky自体はここまでのスクリプトで機能しますが、余分なプロパティが表示されているのでインスペクター拡張を作成して必要なプロパティのみ表示します。

UniformSkyEditor.cs
using UnityEditor;
using UnityEditor.Rendering;
using UnityEditor.Rendering.HighDefinition;

[CanEditMultipleObjects]
[VolumeComponentEditor(typeof(UniformSky))]
public class UniformSkyEditor : SkySettingsEditor
{
    SerializedDataParameter m_Color;

    public override void OnEnable()
    {
        base.OnEnable();
        m_CommonUIElementsMask = (uint)SkySettingsUIElement.UpdateMode
            | (uint)SkySettingsUIElement.SkyIntensity;
        var o = new PropertyFetcher<UniformSky>(serializedObject);
        m_Color = Unpack(o.Find(x => x.color));
    }

    public override void OnInspectorGUI()
    {
        PropertyField(m_Color);
        base.CommonSkySettingsGUI();
    }
}

以上でUnity HDRPで単色Skyの完成です。
UniformSky04.gif

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?