Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "common.h"
- sampler depthSampler : register(s0);
- sampler fogTexture : register(s1);
- float4x4 invViewProj : register(c0);
- float3 boundingBox[2] : register(c4);
- float3 cameraPos : register(c6);
- float3 fogColor : register(c7);
- float fogDensity : register(c8);
- float3 fogOffset : register(c9);
- // original code of ray-box intersection
- // https://github.com/hpicgs/cgsee/wiki/Ray-Box-Intersection-on-the-GPU
- struct Ray {
- float3 origin;
- float3 direction;
- float3 invDirection;
- int sign[3];
- };
- Ray MakeRay(float3 origin, float3 direction) {
- Ray ray;
- ray.origin = origin;
- ray.direction = direction;
- ray.invDirection = float3(1.0, 1.0, 1.0) / direction;
- ray.sign[0] = (ray.invDirection.x < 0) ? 1 : 0;
- ray.sign[1] = (ray.invDirection.y < 0) ? 1 : 0;
- ray.sign[2] = (ray.invDirection.z < 0) ? 1 : 0;
- return ray;
- }
- void RayBoxIntersection(in Ray ray, in float3 aabb[2],out float tmin, out float tmax) {
- float tymin, tymax, tzmin, tzmax;
- tmin = (aabb[ray.sign[0]].x - ray.origin.x) * ray.invDirection.x;
- tmax = (aabb[1-ray.sign[0]].x - ray.origin.x) * ray.invDirection.x;
- tymin = (aabb[ray.sign[1]].y - ray.origin.y) * ray.invDirection.y;
- tymax = (aabb[1-ray.sign[1]].y - ray.origin.y) * ray.invDirection.y;
- tzmin = (aabb[ray.sign[2]].z - ray.origin.z) * ray.invDirection.z;
- tzmax = (aabb[1-ray.sign[2]].z - ray.origin.z) * ray.invDirection.z;
- tmin = max(max(tmin, tymin), tzmin);
- tmax = min(min(tmax, tymax), tzmax);
- }
- float4 main( float2 texCoord : TEXCOORD0 ) : COLOR0 {
- float tmin, tmax;
- float4 outColor = float4(fogColor, 0);
- float3 p = RestorePositionFromDepth(texCoord, invViewProj, depthSampler);
- float3 direction = p - cameraPos;
- float distance = length(direction);
- Ray ray = MakeRay(cameraPos, direction);
- RayBoxIntersection(ray, boundingBox, tmin, tmax);
- // got intersection
- if(tmin <= tmax) {
- if(tmin > 0) { // camera is outside the fog
- float3 pMin = cameraPos + tmin * direction;
- float3 pMax = cameraPos + tmax * direction;
- float3 v = cameraPos - pMin;
- if(distance > length(v)) { // "z-cull"
- float thickness = length(pMax - pMin);
- float dTarget = length(p - pMin);
- outColor.a = fogDensity * (dTarget / thickness);
- // modulate density
- for(float k = 0; k < 0.5; k += 0.05) {
- float3 trace = 0.05f * (cameraPos + (tmin + k) * direction);
- float4 density = tex3Dlod(fogTexture, float4(fogOffset + trace, 0));
- outColor.a += 0.05 * dot(float4(1, 0.5, 0.25, 0.125), density);
- }
- }
- } else if(tmin <= 0 && tmax > 0) { // camera is inside the fog
- float thickness = length(tmax * direction);
- float dTarget = length(p - cameraPos);
- outColor.a = fogDensity * (dTarget / thickness);
- // modulate density
- for(float k = 0; k < 0.5; k += 0.05) {
- float3 trace = 0.05f * ((tmax + k) * direction);
- float4 density = tex3Dlod(fogTexture, float4(fogOffset + trace, 0));
- outColor.a += 0.05 * dot(float4(1, 0.5, 0.25, 0.125), density);
- }
- }
- }
- return outColor;
- };
Advertisement
Add Comment
Please, Sign In to add comment