1void Volumetric_fp 2( 3 in const float2 uv : TEXCOORD0, 4 5 out float4 oColor0 : COLOR0, 6 7 uniform sampler sMRT1 : register(s0), // fragment normals 8 uniform sampler sMRT2 : register(s1), // view space position, remember that we are looking down the negative Z axis!!! 9 uniform sampler sRand : register(s2), 10 11 uniform const float4 cViewportSize, // (viewport_width, viewport_height, inverse_viewport_width, inverse_viewport_height) 12 uniform const float cFov, // vertical field of view in radians 13 uniform const float cSampleInScreenspace, // whether to sample in screen or world space 14 uniform const float cSampleLengthScreenSpace, // The sample length in screen space [0, 1] 15 uniform const float cSampleLengthWorldSpace // the sample length in world space in units 16) 17{ 18 const int interleaved = 4; 19 const int m = 8; 20 const int n = 4; 21 const int numSamples = m * n; 22 23 const float2 interleaveOffset = uv * cViewportSize.xy / interleaved; 24 25 const float3 fragmentPosition = tex2D(sMRT2, uv).xyz; // the current fragment in view space 26 const float3 fragmentNormal = tex2D(sMRT1, uv).xyz * float3(1, -1, 1); // the fragment normal 27 28 float rUV = 0; // radius of influence in screen space 29 float r = 0; // radius of influence in world space 30 if (cSampleInScreenspace == 1) 31 { 32 rUV = cSampleLengthScreenSpace; 33 r = tan(rUV * cFov) * -fragmentPosition.z; 34 } 35 else 36 { 37 rUV = atan(cSampleLengthWorldSpace / -fragmentPosition.z) / cFov; // the radius of influence projected into screen space 38 r = cSampleLengthWorldSpace; 39 } 40 41 42 if (rUV < (cViewportSize.z)) // abort if the projected radius of influence is smaller than 1 fragment 43 { 44 oColor0 = 1; 45 return; 46 } 47 48 const float r2 = r/2; 49 const float rUV2 = rUV /2; 50 51 const float3 center = fragmentPosition + fragmentNormal * (r2); 52 const float2 centerUV = uv + fragmentNormal * (rUV2); 53 54 float F = 0; // unoccluded Volume 55 float V = 0; // occluded Volume 56 float invalid = 0; 57 58 for (float i = 0.0f; i < m; i++) 59 for (float j = 0.0f; j < n; j++) 60 { 61 const float2 randomTC = interleaveOffset + float2(i/(interleaved * m), j/(interleaved * n)); 62 const float2 randomVector = (tex2D(sRand, randomTC) * 2 - 1).xy; // unpack to [-1, 1]^2 63 64 const float2 sample = randomVector * (r2); 65 const float2 sampleUV = randomVector * (rUV2); 66 67 const float zEntry = center.z + (r2) * sqrt(1 - sample.x * sample.x - sample.y * sample.y); 68 const float zExit = center.z - (r2) * sqrt(1 - sample.x * sample.x - sample.y * sample.y); 69 const float zStar = tex2D(sMRT2, centerUV + sampleUV).z; 70 71 F += zExit - zEntry; 72 73 if (zExit <= zStar && zStar <= zEntry) 74 V += zStar - zEntry; 75 else //if (zStar < zExit) 76 V += zExit - zEntry; 77 } 78 79 float accessibility = V / F; 80 oColor0 = float4(accessibility.xxx, 1); 81 82} 83