1
4

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 1 year has passed since last update.

[Unity]色のついた影を付ける[URP]

Last updated at Posted at 2022-04-15

結果

影が黒色の場合

image.png

影が水色の場合

image.png

二つの画像の影を比較すると,黒色と水色の影をを確認することができます.

コード

ReceiveShadowOnly.shader
Shader "Universal Render Pipeline/Simple Lit"
{
    Properties
    {
        // 影の色をここで指定
        _ShadowColor("Shadow Color", Color) = (0, 0, 0, 0)
    }

    SubShader
    {
        Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "SimpleLit" "IgnoreProjector" = "True" "ShaderModel"="4.5"}
        LOD 300

        Pass
        {
            Name "ForwardLit"
            Tags { "LightMode" = "UniversalForward" }


            HLSLPROGRAM
            #pragma exclude_renderers gles gles3 glcore
            #pragma target 4.5

            // -------------------------------------
            // Material Keywords
            #pragma shader_feature_local _RECEIVE_SHADOWS_OFF

            // -------------------------------------
            // Universal Pipeline keywords
            #pragma multi_compile _ _MAIN_LIGHT_SHADOWS
            //--------------------------------------

            #pragma vertex LitPassVertexSimple
            #pragma fragment LitPassFragmentSimple

            #include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
            
            struct Attributes
            {
                float4 positionOS    : POSITION;
                float2 texcoord      : TEXCOORD0;
            };

            struct Varyings
            {
                float2 uv                       : TEXCOORD0;
                float3 positionWS               : TEXCOORD2;
                float4 positionCS               : SV_POSITION;
            };
            
            half4 _ShadowColor;


            Varyings LitPassVertexSimple(Attributes input)
            {
                Varyings output = (Varyings)0;

                VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
                
                output.positionWS.xyz = vertexInput.positionWS;
                output.positionCS = vertexInput.positionCS;

                return output;
            }


            Light MyGetMainLight(float4 shadowCoord)
            {
                Light light = GetMainLight();


                /// RealTimeShadowの計算 ///
                half4 shadowParams = GetMainLightShadowParams();
                half shadowStrength = shadowParams.x;
                ShadowSamplingData shadowSamplingData = GetMainLightShadowSamplingData();
                
                half attenuation;
                attenuation = SAMPLE_TEXTURE2D_SHADOW(_MainLightShadowmapTexture, sampler_MainLightShadowmapTexture, shadowCoord.xyz);
                attenuation = SampleShadowmapFiltered(TEXTURE2D_SHADOW_ARGS(_MainLightShadowmapTexture, sampler_MainLightShadowmapTexture), shadowCoord, shadowSamplingData);;
                attenuation = LerpWhiteTo(attenuation, shadowStrength);
                
                half shadowAttenuation = BEYOND_SHADOW_FAR(shadowCoord) ? 1.0 : attenuation;
                ///
                
                light.shadowAttenuation = shadowAttenuation;
                
                return light;
            }
            
            half4 LitPassFragmentSimple(Varyings input) : SV_Target
            {
                half4 shadowCoord = TransformWorldToShadowCoord(input.positionWS);
                
                Light mainLight = MyGetMainLight(shadowCoord);

                half3 white = half3(1, 1, 1);
                half3 finalColor = lerp(_ShadowColor.rgb, white,  mainLight.shadowAttenuation);
                
                return half4(finalColor, 1);
            }
            ENDHLSL
        }
    }
}

影を受けとるオブジェクトにこのシェーダーを用いたマテリアルを貼りつけることで,色付影を付けられます.
SimpleLit.shaderを参考にし,必要な部分だけ抽出しました.

方法

Unityでは,リアルタイムの影をレンダリングするためにシャドウマッピングと呼ばれる技術を使用しています.
影を付けるにはシャドウマップをサンプリングして,ライトがオブジェクトに遮られているかどうかを判別します.

フラグメントシェーダー内では次のように処理をします.

  1. ワールド座標からShadowMapをサンプリングする際に使用するshadowCoordを得る
  2. メインライト(Directional Light)から,影が付くかどうかを表すshadowAttenuationを求める
  3. shadowAttenuationを影が付いているかどうかを表すマスクであると考え,lerpを使って影の部分は影の色,影出ない部分は白色にする

おわりに

影に模様とか付けてみたいですね

参考

SimpleLit.shader内のForward部分のFragmentPassが書かれてあります.
SimpleLitForwardPass.hlsl

Lighting.hlsl
Shadow.hlsl

1
4
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
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?