"//! Normalized pixel coordinates.\n"
"in vec2 vPixel;\n"
"\n"
- "//! Sub-pixel offset in X direction for FSAA.\n"
- "uniform float uOffsetX = 0.f;\n"
+ "//! Sub-pixel offset in for FSAA.\n"
+ "uniform vec2 uFsaaOffset;\n"
"//! Sub-pixel offset in Y direction for FSAA.\n"
- "uniform float uOffsetY = 0.f;\n"
+ "uniform float uOffsetY;\n"
"\n"
"//! Origin of viewing ray in left-top corner.\n"
"uniform vec3 uOriginLT;\n"
"#endif\n"
"\n"
"//! Top color of gradient background.\n"
- "uniform vec4 uBackColorTop = vec4 (0.0);\n"
+ "uniform vec4 uBackColorTop;\n"
"//! Bottom color of gradient background.\n"
- "uniform vec4 uBackColorBot = vec4 (0.0);\n"
+ "uniform vec4 uBackColorBot;\n"
"\n"
"//! Aperture radius of camera used for depth-of-field\n"
- "uniform float uApertureRadius = 0.f;\n"
+ "uniform float uApertureRadius;\n"
"\n"
"//! Focal distance of camera used for depth-of field\n"
- "uniform float uFocalPlaneDist = 10.f;\n"
+ "uniform float uFocalPlaneDist;\n"
"\n"
"//! Camera position used for projective mode\n"
"uniform vec3 uEyeOrig;\n"
"struct SRay\n"
"{\n"
" vec3 Origin;\n"
- "\n"
" vec3 Direct;\n"
"};\n"
"\n"
"struct SIntersect\n"
"{\n"
" float Time;\n"
- "\n"
" vec2 UV;\n"
- "\n"
" vec3 Normal;\n"
"};\n"
"\n"
+ "//! Stores triangle's vertex indexes and vertexes itself\n"
+ "struct STriangle\n"
+ "{\n"
+ " ivec4 TriIndex;\n"
+ " vec3 Points[3];\n"
+ "};\n"
+ "\n"
"/////////////////////////////////////////////////////////////////////////////////////////\n"
"// Some useful constants\n"
"\n"
"#define TRG_OFFSET(treelet) treelet.SubData.w\n"
"\n"
"//! Identifies the absence of intersection.\n"
- "#define INALID_HIT ivec4 (-1)\n"
+ "#define INVALID_HIT ivec4 (-1)\n"
"\n"
"//! Global stack shared between traversal functions.\n"
"int Stack[STACK_SIZE];\n"
"// function : SceneNearestHit\n"
"// purpose : Finds intersection with nearest scene triangle\n"
"// =======================================================================\n"
- "ivec4 SceneNearestHit (in SRay theRay, in vec3 theInverse, inout SIntersect theHit, out int theTrsfId)\n"
+ "STriangle SceneNearestHit (in SRay theRay, in vec3 theInverse, inout SIntersect theHit, out int theTrsfId)\n"
"{\n"
- " ivec4 aTriIndex = INALID_HIT;\n"
+ " STriangle aTriangle = STriangle (INVALID_HIT, vec3[](vec3(0.0), vec3(0.0), vec3(0.0)));\n"
"\n"
" int aNode = 0; // node to traverse\n"
" int aHead = -1; // pointer of stack\n"
"\n"
" for (int anIdx = aData.y; anIdx <= aData.z; ++anIdx)\n"
" {\n"
- " ivec4 aTriangle = texelFetch (uGeometryTriangTexture, anIdx + TRG_OFFSET (aSubTree));\n"
+ " ivec4 aTriIndex = texelFetch (uGeometryTriangTexture, anIdx + TRG_OFFSET (aSubTree));\n"
+ " vec3 aPoints[3];\n"
"\n"
- " vec3 aPoint0 = texelFetch (uGeometryVertexTexture, aTriangle.x += VRT_OFFSET (aSubTree)).xyz;\n"
- " vec3 aPoint1 = texelFetch (uGeometryVertexTexture, aTriangle.y += VRT_OFFSET (aSubTree)).xyz;\n"
- " vec3 aPoint2 = texelFetch (uGeometryVertexTexture, aTriangle.z += VRT_OFFSET (aSubTree)).xyz;\n"
+ " aPoints[0] = texelFetch (uGeometryVertexTexture, aTriIndex.x += VRT_OFFSET (aSubTree)).xyz;\n"
+ " aPoints[1] = texelFetch (uGeometryVertexTexture, aTriIndex.y += VRT_OFFSET (aSubTree)).xyz;\n"
+ " aPoints[2] = texelFetch (uGeometryVertexTexture, aTriIndex.z += VRT_OFFSET (aSubTree)).xyz;\n"
"\n"
- " IntersectTriangle (aSubTree.TrsfRay, aPoint0, aPoint1, aPoint2, aTimeUV, aNormal);\n"
+ " IntersectTriangle (aSubTree.TrsfRay, aPoints[0], aPoints[1], aPoints[2], aTimeUV, aNormal);\n"
"\n"
" if (aTimeUV.x < theHit.Time)\n"
" {\n"
- " aTriIndex = aTriangle;\n"
+ " aTriangle.TriIndex = aTriIndex;\n"
+ " for (int i = 0; i < 3; ++i)\n"
+ " {\n"
+ " aTriangle.Points[i] = aPoints[i];\n"
+ " }\n"
"\n"
" theTrsfId = TRS_OFFSET (aSubTree);\n"
"\n"
" }\n"
" }\n"
"\n"
- " return aTriIndex;\n"
+ " return aTriangle;\n"
"}\n"
"\n"
"// =======================================================================\n"
"// purpose : Interpolates UV coordinates across the triangle\n"
"// =======================================================================\n"
"#ifdef USE_TEXTURES\n"
- "vec2 SmoothUV (in vec2 theUV, in ivec4 theTriangle)\n"
+ "vec2 SmoothUV (in vec2 theUV, in ivec4 theTriangle, out vec2[3] theUVs)\n"
"{\n"
- " vec2 aTexCrd0 = texelFetch (uGeometryTexCrdTexture, theTriangle.x).st;\n"
- " vec2 aTexCrd1 = texelFetch (uGeometryTexCrdTexture, theTriangle.y).st;\n"
- " vec2 aTexCrd2 = texelFetch (uGeometryTexCrdTexture, theTriangle.z).st;\n"
+ " theUVs[0] = texelFetch (uGeometryTexCrdTexture, theTriangle.x).st;\n"
+ " theUVs[1] = texelFetch (uGeometryTexCrdTexture, theTriangle.y).st;\n"
+ " theUVs[2] = texelFetch (uGeometryTexCrdTexture, theTriangle.z).st;\n"
+ "\n"
+ " return theUVs[1] * theUV.x +\n"
+ " theUVs[2] * theUV.y +\n"
+ " theUVs[0] * (1.0f - theUV.x - theUV.y);\n"
+ "}\n"
"\n"
- " return aTexCrd1 * theUV.x +\n"
- " aTexCrd2 * theUV.y +\n"
- " aTexCrd0 * (1.0f - theUV.x - theUV.y);\n"
+ "vec2 SmoothUV (in vec2 theUV, in ivec4 theTriangle)\n"
+ "{\n"
+ " vec2 aUVs[3];\n"
+ " return SmoothUV (theUV, theTriangle, aUVs);\n"
"}\n"
"#endif\n"
"\n"
" int aTrsfId;\n"
"\n"
" float aRaytraceDepth = MAXFLOAT;\n"
+ " float aRefractionIdx = 0.0;\n"
"\n"
" for (int aDepth = 0; aDepth < NB_BOUNCES; ++aDepth)\n"
" {\n"
" SIntersect aHit = SIntersect (MAXFLOAT, vec2 (ZERO), ZERO);\n"
"\n"
- " ivec4 aTriIndex = SceneNearestHit (theRay, theInverse, aHit, aTrsfId);\n"
+ " ivec4 aTriIndex = SceneNearestHit (theRay, theInverse, aHit, aTrsfId).TriIndex;\n"
"\n"
" if (aTriIndex.x == -1)\n"
" {\n"
" vec4 aColor = vec4 (0.0);\n"
"\n"
- " if (bool(uEnvMapForBack) || aWeight.w == 0.0f /* reflection */)\n"
+ " if (bool(uEnvMapForBack) || aWeight.w == 0.0 /* reflection */)\n"
" {\n"
- " float aTime = IntersectSphere (theRay, uSceneRadius);\n"
+ " float aRadius = uSceneRadius;\n"
+ " vec3 aTexCoord = vec3 (0.0);\n"
+ "\n"
+ " if (aDepth == 0 || (aRefractionIdx == 1.0 && aWeight.w != 0.0))\n"
+ " {\n"
+ " vec2 aPixel = uEyeSize * (vPixel - vec2 (0.5)) * 2.0;\n"
+ " vec2 anAperturePnt = sampleUniformDisk() * uApertureRadius;\n"
+ " vec3 aLocalDir = normalize (vec3 (aPixel * uFocalPlaneDist - anAperturePnt, uFocalPlaneDist));\n"
+ " vec3 aDirect = uEyeView * aLocalDir.z +\n"
+ " uEyeSide * aLocalDir.x +\n"
+ " uEyeVert * aLocalDir.y;\n"
+ " \n"
+ " aTexCoord = aDirect * uSceneRadius;\n"
+ " aRadius = length (aTexCoord);\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " float aTime = IntersectSphere (theRay, uSceneRadius);\n"
+ " aTexCoord = theRay.Direct * aTime + theRay.Origin;\n"
+ " }\n"
"\n"
- " aColor = FetchEnvironment (theRay.Direct * aTime + theRay.Origin, uSceneRadius, aWeight.w != 0.0);\n"
+ " aColor = FetchEnvironment (aTexCoord, aRadius, aWeight.w != 0.0);\n"
" }\n"
" else\n"
" {\n"
" vec4 aNDCPoint = uViewMat * vec4 (theRay.Origin, 1.f);\n"
"\n"
" float aPolygonOffset = PolygonOffset (aHit.Normal, theRay.Origin);\n"
+ " #ifdef THE_ZERO_TO_ONE_DEPTH\n"
+ " aRaytraceDepth = (aNDCPoint.z / aNDCPoint.w + aPolygonOffset * POLYGON_OFFSET_SCALE);\n"
+ " #else\n"
" aRaytraceDepth = (aNDCPoint.z / aNDCPoint.w + aPolygonOffset * POLYGON_OFFSET_SCALE) * 0.5f + 0.5f;\n"
+ " #endif\n"
" }\n"
"\n"
" vec3 aNormal = SmoothNormal (aHit.UV, aTriIndex);\n"
" if (aOpacity.x != 1.0f)\n"
" {\n"
" aWeight *= aOpacity.y;\n"
+ " aRefractionIdx = aOpacity.z;\n"
"\n"
" if (aOpacity.z != 1.0f)\n"
" {\n"