Skip to content
Snippets Groups Projects
Commit 1dffe1bc authored by Philip Trettner's avatar Philip Trettner
Browse files

Merge branch 'ak/shader_ortho' into 'develop'

fixed shader bug for ray tracing (Points, Lines) in orthographic rendering mode

See merge request Glow/glow-extras!130
parents 5bac719a 8d97d240
Branches
No related tags found
No related merge requests found
...@@ -356,7 +356,18 @@ void LineRenderable::init() ...@@ -356,7 +356,18 @@ void LineRenderable::init()
vOut.LineWidth = 2 * s; vOut.LineWidth = 2 * s;
} }
vec3 viewDir = normalize(pos0 - uCamPos); vec4 pos0VS = uView * vec4(pos0, 1);
vec4 pos0CS = uProj * pos0VS;
vec3 pos0NDC = pos0CS.xyz / pos0CS.w;
// clip position to near plane in NDC and get ray origin by transforming into WS (required for orthographic rendering)
vec4 p0NearNDC = vec4(pos0NDC.xy, -1, 1);
vec4 p0NearCS = p0NearNDC * pos0CS.w;
vec4 p0NearVS = uInvProj * p0NearCS;
p0NearVS /= p0NearVS.w;
vec4 p0NearWS = uInvView * p0NearVS;
vec3 viewDir = normalize(pos0 - p0NearWS.xyz);
vec3 diff = pos1 - pos0; vec3 diff = pos1 - pos0;
vec3 right = normalize(diff); vec3 right = normalize(diff);
vec3 up = normalize(cross(right, viewDir)); vec3 up = normalize(cross(right, viewDir));
...@@ -394,7 +405,18 @@ void LineRenderable::init() ...@@ -394,7 +405,18 @@ void LineRenderable::init()
vOut.LineWidth = 2 * s; vOut.LineWidth = 2 * s;
} }
viewDir = normalize(pos1 - uCamPos); vec4 pos1VS = uView * vec4(pos1, 1);
vec4 pos1CS = uProj * pos1VS;
vec3 pos1NDC = pos1CS.xyz / pos1CS.w;
// clip position to near plane in NDC and get ray origin by transforming into WS (required for orthographic rendering)
vec4 p1NearNDC = vec4(pos1NDC.xy, -1, 1);
vec4 p1NearCS = p1NearNDC * pos1CS.w;
vec4 p1NearVS = uInvProj * p1NearCS;
p1NearVS /= p1NearVS.w;
vec4 p1NearWS = uInvView * p1NearVS;
viewDir = normalize(pos1 - p1NearWS.xyz);
up = normalize(cross(right, viewDir)); up = normalize(cross(right, viewDir));
back = normalize(cross(right, up)); back = normalize(cross(right, up));
r = s * right; r = s * right;
...@@ -521,8 +543,14 @@ float distance2(vec3 a, vec3 b) ...@@ -521,8 +543,14 @@ float distance2(vec3 a, vec3 b)
// s: the amount to go back on the ray dir to get to the intersection point // s: the amount to go back on the ray dir to get to the intersection point
// TODO in this shader code // TODO in this shader code
sb.addFragmentShaderCode(R"( sb.addFragmentShaderCode(R"(
vec3 rayOrigin = uCamPos; // clip FragCoord to near plane in NDC and transform back into WS (required for orhtographic rendering)
vec3 rayDir = normalize(vIn.fragPosWS - uCamPos); vec3 rayOriginNDC = vec3((gl_FragCoord.x / uScreenSize.x) * 2 - 1, (gl_FragCoord.y / uScreenSize.y) * 2 - 1, uIsReverseZEnabled ? 1 : -1);
vec4 rayOriginCS = vec4(rayOriginNDC,1) / gl_FragCoord.w;
vec4 rayOriginVS = (uInvProj * rayOriginCS);
rayOriginVS /= rayOriginVS.w;
vec3 rayOrigin = (uInvView * rayOriginVS).xyz;
vec3 rayDir = normalize(vIn.fragPosWS - rayOrigin);
float cosA = dot(gLineDir, rayDir); float cosA = dot(gLineDir, rayDir);
float sinA2 = 1 - cosA * cosA; float sinA2 = 1 - cosA * cosA;
......
...@@ -56,6 +56,7 @@ void PointRenderable::renderPoints(const RenderInfo& info) ...@@ -56,6 +56,7 @@ void PointRenderable::renderPoints(const RenderInfo& info)
auto const tanHalfFovY = 1.f / tg::abs(info.proj[1][1]); auto const tanHalfFovY = 1.f / tg::abs(info.proj[1][1]);
shader["uTanFov2"] = tanHalfFovY; shader["uTanFov2"] = tanHalfFovY;
shader["uScreenHeight"] = float(info.resolution.height); shader["uScreenHeight"] = float(info.resolution.height);
shader["uScreenWidth"] = float(info.resolution.width);
} }
if (getColorMapping()) if (getColorMapping())
...@@ -138,6 +139,7 @@ void glow::viewer::PointRenderable::renderPicking(RenderInfo const& info, int32_ ...@@ -138,6 +139,7 @@ void glow::viewer::PointRenderable::renderPicking(RenderInfo const& info, int32_
shader["uInvProj"] = inverse(info.proj); shader["uInvProj"] = inverse(info.proj);
shader["uScreenSize"] = tg::vec2(info.resolution); shader["uScreenSize"] = tg::vec2(info.resolution);
shader["uCamPos"] = info.camPos; shader["uCamPos"] = info.camPos;
shader["uCamDir"] = info.camForward;
shader["uRenderableID"] = renderableID; shader["uRenderableID"] = renderableID;
shader["uClipPlane"] = getClipPlane(); shader["uClipPlane"] = getClipPlane();
...@@ -283,7 +285,8 @@ void PointRenderable::init() ...@@ -283,7 +285,8 @@ void PointRenderable::init()
// build shader // build shader
{ {
// Shared functionality // Shared functionality
auto createNonFragmentShaderParts = [&](detail::MeshShaderBuilder& sb) { auto createNonFragmentShaderParts = [&](detail::MeshShaderBuilder& sb)
{
sb.addUniform("mat4", "uModel"); sb.addUniform("mat4", "uModel");
sb.addUniform("mat4", "uInvModel"); sb.addUniform("mat4", "uInvModel");
...@@ -292,6 +295,7 @@ void PointRenderable::init() ...@@ -292,6 +295,7 @@ void PointRenderable::init()
sb.addUniform("mat4", "uProj"); sb.addUniform("mat4", "uProj");
sb.addUniform("mat4", "uInvProj"); sb.addUniform("mat4", "uInvProj");
sb.addUniform("vec3", "uCamPos"); sb.addUniform("vec3", "uCamPos");
sb.addUniform("vec3", "uCamDir");
sb.addUniform("vec4", "uClipPlane"); sb.addUniform("vec4", "uClipPlane");
...@@ -301,6 +305,7 @@ void PointRenderable::init() ...@@ -301,6 +305,7 @@ void PointRenderable::init()
sb.addUniform("mat4", "uViewTranspose"); sb.addUniform("mat4", "uViewTranspose");
sb.addUniform("float", "uTanFov2"); sb.addUniform("float", "uTanFov2");
sb.addUniform("float", "uScreenHeight"); sb.addUniform("float", "uScreenHeight");
sb.addUniform("float", "uScreenWidth");
} }
sb.addAttribute("vec2", "aQuadPos"); sb.addAttribute("vec2", "aQuadPos");
...@@ -325,19 +330,30 @@ void PointRenderable::init() ...@@ -325,19 +330,30 @@ void PointRenderable::init()
vOut.SphereCenter = vec3(uModel * vec4(aPosition, 1.0)); vOut.SphereCenter = vec3(uModel * vec4(aPosition, 1.0));
vec4 vpos = uView * uModel * vec4(aPosition, 1.0); vec4 vpos = uView * uModel * vec4(aPosition, 1.0);
vec3 fwd = normalize(vpos.xyz); vec4 vposCS = uProj * vpos;
vec2 vposNDC = vposCS.xy / vposCS.w;
// clip position to near plane in NDC and get orientation by transforming back into VS (required for orthographic rendering)
vec4 pNearNDC = vec4(vposNDC, -1, 1);
vec4 pNearCS = pNearNDC * vposCS.w;
vec4 pNearVS = uInvProj * pNearCS;
pNearVS /= pNearVS.w;
vec3 fwd = normalize(vpos.xyz - pNearVS.xyz);
vec3 left = normalize(cross(vec3(0,1,0), fwd)); vec3 left = normalize(cross(vec3(0,1,0), fwd));
vec3 up = cross(fwd, left); vec3 up = normalize(cross(fwd, left));
vec2 qp = aQuadPos * 2 - 1; vec2 qp = aQuadPos * 2 - 1;
vpos.xyz -= left * qp.x * aPointSize; vpos.xyz -= left * qp.x * aPointSize;
vpos.xyz += up * qp.y * aPointSize; vpos.xyz += up * qp.y * aPointSize;
vpos.xyz -= fwd * aPointSize; vpos.xyz -= fwd * aPointSize;
vpos = uInvModel * uInvView * vpos; vpos = uInvView * vpos;
vOut.Normal = vec3(0,0,0); vOut.Normal = vec3(0,0,0);
vOut.fragPosWS = vec3(uModel * vec4(vpos.xyz, 1.0)); vOut.fragPosWS = vpos.xyz;
gl_Position = uProj * uView * uModel * vec4(vpos.xyz, 1.0); gl_Position = uProj * uView * vec4(vpos.xyz, 1.0);
)"); )");
} }
else else
...@@ -467,12 +483,22 @@ void PointRenderable::init() ...@@ -467,12 +483,22 @@ void PointRenderable::init()
} }
)"); )");
sbForward.addFragmentShaderCode(R"( sbForward.addFragmentShaderCode(R"(
vec3 rayOrigin = uCamPos; // clip FragCoord to near plane in NDC and transform back into VS (required for orhtographic rendering)
vec3 rayDir = normalize(vIn.fragPosWS - uCamPos); vec3 rayOriginNDC = vec3((gl_FragCoord.x / uScreenSize[0]) * 2 - 1, (gl_FragCoord.y / uScreenSize[1]) * 2 - 1, uIsReverseZEnabled ? 1 : -1);
vec3 closestP = rayOrigin + rayDir * dot(rayDir, vSphereCenter - rayOrigin); vec4 rayOriginCS = vec4(rayOriginNDC,1) / gl_FragCoord.w;
float sphereDis2 = distance2(closestP, vSphereCenter); vec4 rayOriginVS = (uInvProj * rayOriginCS);
rayOriginVS /= rayOriginVS.w;
vec4 rayTargetVS = (uView * vec4(vIn.fragPosWS, 1));
vec3 rayDirVS = normalize(rayTargetVS.xyz - rayOriginVS.xyz);
vec3 sphereCenterVS = (uView * vec4(vSphereCenter, 1)).xyz;
vec3 closestP = rayOriginVS.xyz + rayDirVS * dot(rayDirVS, sphereCenterVS - rayOriginVS.xyz);
float sphereDis2 = distance2(closestP, sphereCenterVS);
if (dot(uClipPlane.xyz, vSphereCenter) > uClipPlane.w) if (dot(uClipPlane.xyz, vSphereCenter) > uClipPlane.w)
discard; discard;
...@@ -480,21 +506,24 @@ void PointRenderable::init() ...@@ -480,21 +506,24 @@ void PointRenderable::init()
if (sphereDis2 > vSphereRadius * vSphereRadius) if (sphereDis2 > vSphereRadius * vSphereRadius)
discard; discard;
vec3 spherePos = closestP - rayDir * sqrt(vSphereRadius * vSphereRadius - sphereDis2); vec3 spherePosVS = closestP - rayDirVS * sqrt(vSphereRadius * vSphereRadius - sphereDis2);
vec4 spherePosCS = uProj * vec4(spherePosVS, 1);
spherePosCS /= spherePosCS.w;
vec3 sphereN = normalize(spherePos - vSphereCenter); float depthNDC = spherePosCS.z;
vec4 spherePosCS = uProj * uView * vec4(spherePos, 1); vec3 spherePosWS = (uInvView * vec4(spherePosVS, 1)).xyz;
float depthNDC = spherePosCS.z / spherePosCS.w; vec3 sphereWS_N = normalize(spherePosWS - vSphereCenter);
if(uIsReverseZEnabled) if(uIsReverseZEnabled)
gl_FragDepth = (depthNDC - gl_DepthRange.near) / gl_DepthRange.diff; gl_FragDepth = (depthNDC - gl_DepthRange.near) / gl_DepthRange.diff;
else else
gl_FragDepth = depthNDC * 0.5 + 0.5; gl_FragDepth = depthNDC * 0.5 + 0.5;
fColor.rgb = vec3(vColor) * (sphereN.y * .5 + .5); fColor.rgb = vec3(vColor) * (sphereWS_N.y * .5 + .5);
fColor.a = 1; fColor.a = 1;
fNormal = sphereN;
fNormal = sphereWS_N;
)"); )");
} }
else else
...@@ -574,6 +603,8 @@ void PointRenderable::init() ...@@ -574,6 +603,8 @@ void PointRenderable::init()
float sphereDis2 = distance2(closestP, vSphereCenter); float sphereDis2 = distance2(closestP, vSphereCenter);
if (sphereDis2 > vSphereRadius * vSphereRadius) if (sphereDis2 > vSphereRadius * vSphereRadius)
discard; discard;
)"); )");
} }
else else
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment