/** * Copyright (c) 2019-2022 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose */ export const spheres_frag = ` precision highp float; precision highp int; #define bumpEnabled #include common #include common_frag_params #include color_frag_params #include light_frag_params #include common_clip uniform mat4 uInvView; varying float vRadius; varying float vRadiusSq; varying vec3 vPoint; varying vec3 vPointViewPosition; bool SphereImpostor(out vec3 modelPos, out vec3 cameraPos, out vec3 cameraNormal, out bool interior, out float fragmentDepth, out bool clipped){ vec3 cameraSpherePos = -vPointViewPosition; vec3 rayOrigin = mix(vec3(0.0, 0.0, 0.0), vPoint, uIsOrtho); vec3 rayDirection = mix(normalize(vPoint), vec3(0.0, 0.0, 1.0), uIsOrtho); vec3 cameraSphereDir = mix(cameraSpherePos, rayOrigin - cameraSpherePos, uIsOrtho); float B = dot(rayDirection, cameraSphereDir); float det = B * B + vRadiusSq - dot(cameraSphereDir, cameraSphereDir); if (det < 0.0) return false; float sqrtDet = sqrt(det); float posT = mix(B + sqrtDet, B - sqrtDet, uIsOrtho); float negT = mix(B - sqrtDet, B + sqrtDet, uIsOrtho); cameraPos = rayDirection * negT + rayOrigin; modelPos = (uInvView * vec4(cameraPos, 1.0)).xyz; fragmentDepth = calcDepth(cameraPos); #if defined(dClipVariant_pixel) && dClipObjectCount != 0 if (clipTest(vec4(modelPos, 0.0))) { clipped = true; fragmentDepth = -1.0; } #endif if (fragmentDepth > 0.0) { cameraNormal = normalize(cameraPos - cameraSpherePos); interior = false; return true; } else if (uDoubleSided) { cameraPos = rayDirection * posT + rayOrigin; modelPos = (uInvView * vec4(cameraPos, 1.0)).xyz; fragmentDepth = calcDepth(cameraPos); cameraNormal = -normalize(cameraPos - cameraSpherePos); interior = true; return true; } return false; } void main(void){ vec3 modelPos; vec3 cameraPos; vec3 cameraNormal; float fragmentDepth; bool clipped = false; bool hit = SphereImpostor(modelPos, cameraPos, cameraNormal, interior, fragmentDepth, clipped); if (!hit) discard; if (fragmentDepth < 0.0) discard; if (fragmentDepth > 1.0) discard; vec3 vViewPosition = cameraPos; vec3 vModelPosition = modelPos; if (interior && !clipped) { fragmentDepth = 0.0 + (0.0000001 / vRadius); } gl_FragDepthEXT = fragmentDepth; #include clip_pixel #include assign_material_color #if defined(dRenderVariant_pick) #include check_picking_alpha #ifdef requiredDrawBuffers gl_FragColor = vObject; gl_FragData[1] = vInstance; gl_FragData[2] = vGroup; gl_FragData[3] = packDepthToRGBA(fragmentDepth); #else gl_FragColor = vColor; #endif #elif defined(dRenderVariant_depth) gl_FragColor = material; #elif defined(dRenderVariant_marking) gl_FragColor = material; #elif defined(dRenderVariant_color) vec3 normal = -cameraNormal; #include apply_light_color #include apply_interior_color #include apply_marker_color #include apply_fog #include wboit_write #include dpoit_write #endif } `;