Skip to content

Instantly share code, notes, and snippets.

@rngtm
Last active April 30, 2023 16:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rngtm/495b2f3ef94c1441d49eea980cad2e22 to your computer and use it in GitHub Desktop.
Save rngtm/495b2f3ef94c1441d49eea980cad2e22 to your computer and use it in GitHub Desktop.
デプスマップを使った影のレンダリングの勉強
#ifndef MYTOON_BASE_INCLUDED
#define MYTOON_BASE_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
float4x4 _LightVP; // Projection * View
float4 _LightPos; // ライト位置
sampler2D _SelfShadowMap;
sampler2D _MainTex;
float _DepthOffset;
struct Attributes
{
float4 vertex : POSITION;
};
struct Varyings
{
float4 vertex : SV_POSITION;
float3 worldPos : TEXCOORD1;
};
Varyings vert(Attributes v)
{
Varyings o = (Varyings)0;
o.worldPos = TransformObjectToWorld(v.vertex);
o.vertex = TransformObjectToHClip(v.vertex);
return o;
}
half4 frag(Varyings i) : SV_Target
{
float4 lightHClip = mul(_LightVP, i.worldPos - _LightPos);
float lightDepth01 = lightHClip.z; // クリップ空間のz値は深度値になる
float2 lightUV = lightHClip.xy * 0.5 + 0.5; // シャドウマップ用のUVをクリップ座標から計算 (-1, 1) -> (0, 1)
float4 color = tex2D(_MainTex, lightUV.xy);
float depth = tex2D(_SelfShadowMap, lightUV.xy).r; // デプスマップから深度値をサンプリング
depth = Linear01Depth(depth, _ZBufferParams);
float shadow = step(depth, 1.0 - lightDepth01 + _DepthOffset);
if (lightDepth01 < 0.001) // 描画点がライト基準のクリップ空間の外側(画面の手前)にある
{
return 0;
}
if (lightDepth01 > 0.999) // 描画点がライト基準のクリップ空間の外側(画面の奥)にある
{
return 0;
}
return (color * 0.2 + shadow)
* step(0, lightUV.x)
* step(lightUV.x, 1)
* step(0,lightUV.y)
* step(lightUV.y, 1)
;
}
#endif
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace MyToon
{
public class SelfShadowPass : ScriptableRenderPass
{
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
{
var camera = renderingData.cameraData.camera;
var cameraData = renderingData.cameraData;
var cameraAspect = 1f;
Matrix4x4 projectionMatrix = cameraData.GetProjectionMatrix();
Matrix4x4 viewMatrix = cameraData.GetViewMatrix();
Vector4 lightPos = camera.transform.position;
lightPos.w = 0;
Shader.SetGlobalVector(SelfShadowFeature.ShaderPropertyId.LightPos, lightPos);
Shader.SetGlobalTexture(SelfShadowFeature.ShaderPropertyId.SelfShadowMap, camera.targetTexture);
// 列優先で行列を乗じる
Shader.SetGlobalMatrix(SelfShadowFeature.ShaderPropertyId.LightVP, projectionMatrix * viewMatrix);
}
}
}
@rngtm
Copy link
Author

rngtm commented Apr 30, 2023

影レンダリング用のカメラにRenderTextureをアタッチしておく
image

影の部分が白く描画される
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment