-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathDepthRelightingMotif.shader
151 lines (126 loc) · 5.46 KB
/
DepthRelightingMotif.shader
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (the "License");
* you may not use the Oculus SDK except in compliance with the License,
* which is provided at the time of installation or download, or which
* otherwise accompanies this software in either electronic or hard copy form.
*
* You may obtain a copy of the License at
*
* https://developer.oculus.com/licenses/oculussdk/
*
* Unless required by applicable law or agreed to in writing, the Oculus SDK
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Shader "Meta/DepthRelightingMotif"
{
Properties
{
_Color ("Color", Color) = (1,1,1,1)
_Intensity ("Intensity", Float) = 1
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 200
ZTest Always
ZWrite Off
Cull Front
Blend One OneMinusSrcAlpha
Pass {
HLSLPROGRAM
#pragma target 4.5
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
CBUFFER_START(UnityPerMaterial)
half4 _Color;
half _Intensity;
CBUFFER_END
Texture2DArray<float> _EnvironmentDepthTexture;
SamplerState bilinearClampSampler;
float4 _EnvironmentDepthZBufferParams;
float4x4 _EnvironmentDepthReprojectionMatrices[2];
float4x4 _EnvironmentDepthInverseReprojectionMatrices[2];
float SampleDepthNDC(float2 uv, int eye = 0)
{
return _EnvironmentDepthTexture.SampleLevel(bilinearClampSampler, float3(uv.xy, eye), 0).r;
}
float3 WorldtoNDC(float3 worldPos, int eye = 0)
{
float4 hcs = mul(_EnvironmentDepthReprojectionMatrices[eye], float4(worldPos, 1));
return (hcs.xyz / hcs.w) * 0.5 + 0.5;
}
float3 NDCtoWorld(float3 ndc, int eye = 0)
{
float4 hcs = float4(ndc * 2.0 - 1.0, 1);
float4 worldH = mul(_EnvironmentDepthInverseReprojectionMatrices[eye], hcs);
return worldH.xyz / worldH.w;
}
float SampleEnvironmentDepthLinear(float2 uv)
{
float inputDepthEye = SampleDepthNDC(uv);
float inputDepthNdc = inputDepthEye * 2.0 - 1.0;
float linearDepth = (1.0f / (inputDepthNdc + _EnvironmentDepthZBufferParams.y)) * _EnvironmentDepthZBufferParams.x;
return linearDepth;
}
struct Attributes
{
float4 positionOS : POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float4 positionHCS : SV_POSITION;
float4 positionHCSTexCoord : TEXCOORD0;
float3 positionWS : TEXCOORD1;
UNITY_VERTEX_OUTPUT_STEREO
};
Varyings vert(Attributes IN)
{
Varyings OUT;
UNITY_SETUP_INSTANCE_ID(IN);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
OUT.positionHCSTexCoord = OUT.positionHCS;
OUT.positionWS = TransformObjectToWorld(IN.positionOS.xyz);
return OUT;
}
half4 frag(Varyings IN) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(IN);
int eye = unity_StereoEyeIndex;
// Compute NDC (Normalized Device Coordinates)
float3 ndc = WorldtoNDC(IN.positionWS, eye);
// Sample linear depth from the environment depth texture
float depthNDC = SampleDepthNDC(ndc.xy, eye);
// Convert NDC to World coordinates using precomputed inverse matrices
float3 depthWorld = NDCtoWorld(float3(ndc.xy, depthNDC), eye);
// Light calculations
float3 lightPos = mul(unity_ObjectToWorld, float4(0, 0, 0, 1)).xyz;
float3 diff = lightPos - depthWorld;
float3 lightDir = normalize(diff);
// Calculate surface normal using finite differences
float2 uvH = ndc.xy + float2(0.001, 0);
float2 uvV = ndc.xy + float2(0, 0.001);
float3 depthWorldH = NDCtoWorld(float3(uvH, SampleDepthNDC(uvH, eye)), eye);
float3 depthWorldV = NDCtoWorld(float3(uvV, SampleDepthNDC(uvV, eye)), eye);
float3 hDeriv = depthWorldH - depthWorld;
float3 vDeriv = depthWorldV - depthWorld;
float3 worldNorm = -normalize(cross(hDeriv, vDeriv));
// Calculate intensity based on normal and light direction
float dist = length(diff);
float rad = length(mul(unity_ObjectToWorld, float4(1, 0, 0, 0))) / 2;
float intensity = max(dot(worldNorm, lightDir), 0.0) * pow(max(0, 1 - dist / rad), 2) * _Intensity;
// Output color
return float4(_Color.rgb * intensity, 0);
}
ENDHLSL
}
}
}