_xiaofang/xiaofang/Assets/Obi/Editor/Resources/DistanceFieldPreview.shader
杨号敬 bcc74f0465 add
2024-12-18 02:18:45 +08:00

121 lines
3.1 KiB
Plaintext

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
Shader "Obi/Distance Field Preview" {
Properties {
_Volume ("Texture", 3D) = "" {}
_AABBMin("AABB Min",Vector) = (-0.5,-0.5,-0.5)
_AABBMax("AABB Max",Vector) = (0.5,0.5,0.5)
_InsideColor("Inside color",Color) = (1,1,1,1)
_OutsideColor("Outside color",Color) = (0,0,0,1)
_Absorption("Absorption",Float) = 1.5
_StepSize("Step size",Float) = 0.01
_MaxSteps("Max steps",Int) = 300
}
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma exclude_renderers flash gles
#include "UnityCG.cginc"
struct vs_input {
float4 vertex : POSITION;
};
struct ps_input {
float4 pos : SV_POSITION;
float3 eyeOrigin : TEXCOORD0;
float3 eyeDir : TEXCOORD1;
};
ps_input vert (vs_input v)
{
ps_input o;
o.pos = UnityObjectToClipPos (v.vertex);
o.eyeOrigin = mul((float3x3)unity_WorldToObject, _WorldSpaceCameraPos); // object space eye origin
o.eyeDir = -ObjSpaceViewDir(v.vertex); // object space eye direction
return o;
}
sampler3D _Volume;
float3 _AABBMin;
float3 _AABBMax;
float _Absorption;
float _StepSize;
int _MaxSteps;
half4 _InsideColor;
half4 _OutsideColor;
bool IntersectBox(float3 rayOrigin, float3 rayDir, float3 aabbMin, float3 aabbMax, out float t0, out float t1)
{
float3 invR = 1.0 / rayDir;
float3 tbot = invR * (aabbMin-rayOrigin);
float3 ttop = invR * (aabbMax-rayOrigin);
float3 tmin = min(ttop, tbot);
float3 tmax = max(ttop, tbot);
float2 t = max(tmin.xx, tmin.yz);
t0 = max(t.x, t.y);
t = min(tmax.xx, tmax.yz);
t1 = min(t.x, t.y);
return t0 <= t1;
}
float4 frag (ps_input input) : COLOR
{
float4 dst = float4(0.0, 0.0, 0.0, 0.0);
// Calculate ray direction
float3 eyeDirection = normalize(input.eyeDir);
//Calculate intersection with bounding box:
float tnear, tfar;
if (IntersectBox(input.eyeOrigin,eyeDirection,_AABBMin,_AABBMax,tnear,tfar)){
if (tnear < 0.0) tnear = 0.0;
//Calculate ray start and stop positions:
float3 rayStart = input.eyeOrigin + eyeDirection * tnear;
float3 rayStop = input.eyeOrigin + eyeDirection * tfar;
// Transform from object space bounds to texture coordinate space:
float3 aabbSize = _AABBMax-_AABBMin;
rayStart = (rayStart-_AABBMin) / aabbSize;
rayStop = (rayStop-_AABBMin) / aabbSize;
// Raytrace:
float3 pos = rayStart;
float3 step = normalize(rayStop-rayStart) * _StepSize;
float travel = distance(rayStop,rayStart);
for (int i=0; i < _MaxSteps && travel > 0.0; ++i, pos += step, travel -= _StepSize) {
float value = tex3Dlod(_Volume, float4(pos,0)).a;
float4 color;
if (value > 0.5){ //outside the surface.
color = _OutsideColor * (1 - value) * 2;
}else{ //inside the surface.
color = _InsideColor * value * 2;
}
dst += color * _StepSize * _Absorption;
}
}
return dst;
}
ENDCG
}
}
Fallback "VertexLit"
}