Firstborn/Assets/Fog/Volume Fog/Volume Fog V2/Materials and Shaders/volumeFog from Texture Cube...

140 lines
4.2 KiB
HLSL
Raw Permalink Normal View History

// https://gamedev.stackexchange.com/a/18459/147473
float2 rayBoxDst(float3 boundsMin, float3 boundsMax, float3 rayOrigin, float3 invRaydir) {
float t1 = (boundsMin.x - rayOrigin.x)*invRaydir.x;
float t2 = (boundsMax.x - rayOrigin.x)*invRaydir.x;
float t3 = (boundsMin.y - rayOrigin.y)*invRaydir.y;
float t4 = (boundsMax.y - rayOrigin.y)*invRaydir.y;
float t5 = (boundsMin.z - rayOrigin.z)*invRaydir.z;
float t6 = (boundsMax.z - rayOrigin.z)*invRaydir.z;
float tmin = max(max(min(t1, t2), min(t3, t4)), min(t5, t6));
float tmax = min(min(max(t1, t2), max(t3, t4)), max(t5, t6));
return float2(tmin, tmax);
}
float Unity_RandomRange_float(float2 Seed)
{
float randomno = frac(sin(dot(Seed, float2(12.9898, 78.233)))*43758.5453);
return randomno - 0.5;
}
SAMPLER(sampler_linear_repeat);
float SamplePoint (
Texture3D NoiseTexture,
Texture2D Noise2DTexture,
float Noise2DScale,
float Noise2DPower,
float3 distanceToMinBounds,
float3 distanceToMaxBounds,
float3 randVec,
float3 PositionOffset,
float3 Size,
float Threshold,
float Multiplier,
float BoundsFade,
float3 p
) {
float n3D = SAMPLE_TEXTURE3D(NoiseTexture, sampler_linear_repeat, p).x;
float n = (SAMPLE_TEXTURE2D(Noise2DTexture, sampler_linear_repeat , p.xz * Noise2DScale).x - .5) * Noise2DPower;
float noise = n + n3D ;
float bordersFade = min(
min(distanceToMinBounds.x, distanceToMaxBounds.x),
min(min(distanceToMinBounds.y, distanceToMaxBounds.y),
min(distanceToMinBounds.z, distanceToMaxBounds.z))
);
float noiseAdjusted = (noise - Threshold) * Multiplier;
float fade = saturate((bordersFade * .025 * BoundsFade));
return saturate(noiseAdjusted * fade* fade);
}
void volumeFog_float(
Texture3D NoiseTexture,
Texture2D Noise2DTexture,
float Noise2DScale,
float Noise2DPower,
float Samples,
float MeshDistance,
float BoundsFade,
float Randomness,
float3 Size,
float Threshold,
float Multiplier,
float3 PositionOffset,
float3 Position,
float3 View,
out float Fog
) {
float3 objectPosition = SHADERGRAPH_OBJECT_POSITION;
float3 objectScale = float3(length(float3(UNITY_MATRIX_M[0].x, UNITY_MATRIX_M[1].x, UNITY_MATRIX_M[2].x)),
length(float3(UNITY_MATRIX_M[0].y, UNITY_MATRIX_M[1].y, UNITY_MATRIX_M[2].y)),
length(float3(UNITY_MATRIX_M[0].z, UNITY_MATRIX_M[1].z, UNITY_MATRIX_M[2].z)));
float3 cameraPosition = _WorldSpaceCameraPos;
float3 boundsMin = objectPosition - objectScale / 2;
float3 boundsMax = objectPosition + objectScale / 2;
float2 rayToContainerInfo = rayBoxDst(boundsMin, boundsMax, cameraPosition, 1/View);
float distanceToStart = rayToContainerInfo.y;
float OverallDistance = -abs(rayToContainerInfo.y - rayToContainerInfo.x);
Samples = min(Samples, 40) ; // 40 will be the maximum samples, you can change this value if needed
float Distance = max(OverallDistance, -MeshDistance) / Samples;
float random = Unity_RandomRange_float(View.xz);
float3 randVec = random * Randomness * View * (Distance / 10);
float3 p;
float3 vectorToAdd;
float3 distanceToMinBounds;
float3 distanceToMaxBounds;
Fog = 1;
for (int i = 0; i < Samples ; i++) {
vectorToAdd = View * Distance * i;
p = Position + vectorToAdd;
float3 distanceToMinBounds = abs(p - boundsMin);
float3 distanceToMaxBounds = abs(p - boundsMax);
float3 offset = (randVec + PositionOffset) * 0.01;
p -= offset;
p *= Size;
p += offset;
float density = SamplePoint (
NoiseTexture,
Noise2DTexture,
Noise2DScale,
Noise2DPower,
distanceToMinBounds,
distanceToMaxBounds,
randVec,
PositionOffset,
Size,
Threshold,
Multiplier,
BoundsFade,
p
);
if (density > 0) {
Fog *= exp(-density);
// Exit early if T is close to zero as further samples won't affect the result much
if (Fog < 0.01) {
break;
}
}
}
}