您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
109 行
3.7 KiB
109 行
3.7 KiB
Shader "MobileRenderloop/ClassicDeferredReflections" {
|
|
Properties
|
|
{
|
|
_SrcBlend ("", Float) = 1
|
|
_DstBlend ("", Float) = 1
|
|
_SrcABlend ("", Float) = 1
|
|
_DstABlend ("", Float) = 1
|
|
_CullMode ("", Float) = 0
|
|
_CompareFunc ("", Float) = 0
|
|
}
|
|
|
|
SubShader {
|
|
|
|
// Calculates reflection contribution from a single probe (rendered as cubes) or default reflection (rendered as full screen quad)
|
|
// Finite: Blend DstAlpha One, DstAlpha Zero
|
|
// clipping near plane: Cull Front; ZTest GEqual; Blend DstAlpha One, DstAlpha Zero
|
|
// renderAsQuad: Cull Off; ZTest Always; Blend DstAlpha One, DstAlpha Zero
|
|
|
|
Pass {
|
|
ZWrite Off
|
|
Cull [_CullMode]
|
|
ZTest [_CompareFunc]
|
|
Blend [_SrcBlend] [_DstBlend], [_SrcABlend] [_DstABlend]
|
|
|
|
CGPROGRAM
|
|
#pragma target 4.5
|
|
#pragma vertex onchip_vert_deferred
|
|
#pragma fragment frag
|
|
|
|
#include "UnityCG.cginc"
|
|
#include "UnityDeferredLibrary.cginc"
|
|
#include "UnityStandardUtils.cginc"
|
|
#include "UnityGBuffer.cginc"
|
|
#include "UnityStandardBRDF.cginc"
|
|
#include "UnityPBSLighting.cginc"
|
|
|
|
#include "LightingTemplate.hlsl"
|
|
|
|
half3 distanceFromAABB(half3 p, half3 aabbMin, half3 aabbMax)
|
|
{
|
|
return max(max(p - aabbMax, aabbMin - p), half3(0.0, 0.0, 0.0));
|
|
}
|
|
|
|
|
|
half4 frag (unity_v2f_deferred i) : SV_TARGET
|
|
{
|
|
float2 uv;
|
|
float4 viewPos;
|
|
float3 worldPos;
|
|
|
|
float depth = UNITY_READ_FRAMEBUFFER_INPUT(3, i.pos);
|
|
OnChipDeferredFragSetup(i, uv, viewPos, worldPos, depth);
|
|
|
|
half4 gbuffer0 = UNITY_READ_FRAMEBUFFER_INPUT(0, i.pos);
|
|
half4 gbuffer1 = UNITY_READ_FRAMEBUFFER_INPUT(1, i.pos);
|
|
half4 gbuffer2 = UNITY_READ_FRAMEBUFFER_INPUT(2, i.pos);
|
|
UnityStandardData data = UnityStandardDataFromGbuffer(gbuffer0, gbuffer1, gbuffer2);
|
|
|
|
float3 eyeVec = normalize(worldPos - _WorldSpaceCameraPos);
|
|
half oneMinusReflectivity = 1 - SpecularStrength(data.specularColor);
|
|
|
|
// ---
|
|
|
|
half3 worldNormalRefl = reflect(eyeVec, data.normalWorld);
|
|
|
|
// Unused member don't need to be initialized
|
|
UnityGIInput d;
|
|
d.worldPos = worldPos;
|
|
d.worldViewDir = -eyeVec;
|
|
d.probeHDR[0] = unity_SpecCube0_HDR;
|
|
|
|
float blendDistance = unity_SpecCube1_ProbePosition.w; // will be set to blend distance for this probe
|
|
#ifdef UNITY_SPECCUBE_BOX_PROJECTION
|
|
d.probePosition[0] = unity_SpecCube0_ProbePosition;
|
|
d.boxMin[0].xyz = unity_SpecCube0_BoxMin - float4(blendDistance,blendDistance,blendDistance,0);
|
|
d.boxMin[0].w = 1; // 1 in .w allow to disable blending in UnityGI_IndirectSpecular call
|
|
d.boxMax[0].xyz = unity_SpecCube0_BoxMax + float4(blendDistance,blendDistance,blendDistance,0);
|
|
#endif
|
|
|
|
Unity_GlossyEnvironmentData g = UnityGlossyEnvironmentSetup(data.smoothness, d.worldViewDir, data.normalWorld, data.specularColor);
|
|
|
|
half3 env0 = UnityGI_IndirectSpecular(d, data.occlusion, g);
|
|
|
|
UnityLight light;
|
|
light.color = half3(0, 0, 0);
|
|
light.dir = half3(0, 1, 0);
|
|
|
|
UnityIndirect ind;
|
|
ind.diffuse = 0;
|
|
ind.specular = env0;
|
|
|
|
half3 rgb = UNITY_BRDF_PBS (0, data.specularColor, oneMinusReflectivity, data.smoothness, data.normalWorld, -eyeVec, light, ind).rgb;
|
|
|
|
// Calculate falloff value, so reflections on the edges of the probe would gradually blend to previous reflection.
|
|
// Also this ensures that pixels not located in the reflection probe AABB won't
|
|
// accidentally pick up reflections from this probe.
|
|
half3 distance = distanceFromAABB(worldPos, unity_SpecCube0_BoxMin.xyz, unity_SpecCube0_BoxMax.xyz);
|
|
half falloff = saturate(1.0 - length(distance)/blendDistance);
|
|
|
|
// UNITY_BRDF_PBS1 writes out alpha 1 to our emission alpha. TODO: Should preclear emission alpha after gbuffer pass in case this ever changes
|
|
return half4(rgb*falloff, 1-falloff);
|
|
}
|
|
|
|
ENDCG
|
|
}
|
|
|
|
}
|
|
Fallback Off
|
|
}
|