mrDIMAS

Volume fog

Nov 13th, 2016
192
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.54 KB | None | 0 0
  1. #include "common.h"
  2.  
  3. sampler depthSampler : register(s0);
  4. sampler noiseVolume : register(s1);
  5.  
  6. float4x4 invViewProj : register(c0);
  7. float3 boundingBox[2] : register(c4);
  8. float3 cameraPos : register(c6);
  9. float3 fogColor : register(c7);
  10. float fogDensity : register(c8);
  11.  
  12. // original code of ray-box intersection
  13. // https://github.com/hpicgs/cgsee/wiki/Ray-Box-Intersection-on-the-GPU
  14. struct Ray {
  15.     float3 origin;
  16.     float3 direction;
  17.     float3 invDirection;
  18.     int sign[3];
  19. };
  20.  
  21. Ray MakeRay(float3 origin, float3 direction) {
  22.     Ray ray;
  23.     ray.origin = origin;
  24.     ray.direction = direction;
  25.     ray.invDirection = float3(1.0, 1.0, 1.0) / direction;
  26.     ray.sign[0] = (ray.invDirection.x < 0) ? 1 : 0;
  27.     ray.sign[1] = (ray.invDirection.y < 0) ? 1 : 0;
  28.     ray.sign[2] = (ray.invDirection.z < 0) ? 1 : 0;
  29.     return ray;
  30. }
  31.  
  32. void RayBoxIntersection(in Ray ray, in float3 aabb[2],out float tmin, out float tmax) {
  33.     float tymin, tymax, tzmin, tzmax;
  34.     tmin = (aabb[ray.sign[0]].x - ray.origin.x) * ray.invDirection.x;
  35.     tmax = (aabb[1-ray.sign[0]].x - ray.origin.x) * ray.invDirection.x;
  36.     tymin = (aabb[ray.sign[1]].y - ray.origin.y) * ray.invDirection.y;
  37.     tymax = (aabb[1-ray.sign[1]].y - ray.origin.y) * ray.invDirection.y;
  38.     tzmin = (aabb[ray.sign[2]].z - ray.origin.z) * ray.invDirection.z;
  39.     tzmax = (aabb[1-ray.sign[2]].z - ray.origin.z) * ray.invDirection.z;
  40.     tmin = max(max(tmin, tymin), tzmin);
  41.     tmax = min(min(tmax, tymax), tzmax);
  42.     // post condition:
  43.     // if tmin > tmax (in the code above this is represented by a return value of INFINITY)
  44.     //     no intersection
  45.     // else
  46.     //     front intersection point = ray.origin + ray.direction * tmin (normally only this point matters)
  47.     //     back intersection point  = ray.origin + ray.direction * tmax
  48. }
  49.  
  50. float4 main( float2 texCoord : TEXCOORD0 ) : COLOR0 {
  51.     float tmin, tmax;
  52.     float4 outColor = float4(fogColor, 0);
  53.     float3 p = RestorePositionFromDepth(texCoord, invViewProj, depthSampler);
  54.     float3 direction = p - cameraPos;
  55.     float distance = length(direction);
  56.     Ray ray = MakeRay(cameraPos, direction);
  57.    
  58.     RayBoxIntersection(ray, boundingBox, tmin, tmax);
  59.    
  60.     // got intersection
  61.     if(tmin <= tmax) {
  62.         float3 pMin = cameraPos + tmin * direction;
  63.         float3 pMax = cameraPos + tmax * direction;
  64.         float3 v = cameraPos - pMin;
  65.         if(distance > length(v) && dot(v, direction) < 0) {
  66.             float thickness = length(pMax - pMin);     
  67.             float dTarget = length(p - pMin);          
  68.             outColor.a = fogDensity * (dTarget / thickness);           
  69.         }
  70.     }
  71.    
  72.     return outColor;
  73. };
Advertisement
Add Comment
Please, Sign In to add comment