123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- /**
- * Copyright (c) 2020-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
- export const cylinders_frag = `
- precision highp float;
- precision highp int;
- #define bumpEnabled
- #define multiColor
- uniform mat4 uView;
- varying mat4 vTransform;
- varying vec3 vStart;
- varying vec3 vEnd;
- varying float vSize;
- varying float vCap;
- varying float vColorMode;
- uniform vec3 uCameraDir;
- uniform vec3 uCameraPosition;
- uniform mat4 uInvView;
- #include common
- #include common_frag_params
- #include color_frag_params
- #include light_frag_params
- #include common_clip
- #ifdef dSolidInterior
- const bool solidInterior = true;
- #else
- const bool solidInterior = false;
- #endif
- // adapted from https://www.shadertoy.com/view/4lcSRn
- // The MIT License, Copyright 2016 Inigo Quilez
- bool CylinderImpostor(
- in vec3 rayOrigin, in vec3 rayDir,
- in vec3 start, in vec3 end, in float radius,
- out vec3 cameraNormal, out bool interior,
- out vec3 modelPosition, out vec3 viewPosition, out float fragmentDepth
- ){
- vec3 ba = end - start;
- vec3 oc = rayOrigin - start;
- float baba = dot(ba, ba);
- float bard = dot(ba, rayDir);
- float baoc = dot(ba, oc);
- float k2 = baba - bard * bard;
- float k1 = baba * dot(oc, rayDir) - baoc * bard;
- float k0 = baba * dot(oc, oc) - baoc * baoc - radius * radius * baba;
- float h = k1 * k1 - k2 * k0;
- if (h < 0.0) return false;
- bool topCap = (vCap > 0.9 && vCap < 1.1) || vCap >= 2.9;
- bool bottomCap = (vCap > 1.9 && vCap < 2.1) || vCap >= 2.9;
- #ifdef dSolidInterior
- bool topInterior = !topCap;
- bool bottomInterior = !bottomCap;
- topCap = true;
- bottomCap = true;
- #else
- bool topInterior = false;
- bool bottomInterior = false;
- #endif
- bool clipped = false;
- bool objectClipped = false;
- // body outside
- h = sqrt(h);
- float t = (-k1 - h) / k2;
- float y = baoc + t * bard;
- if (y > 0.0 && y < baba) {
- interior = false;
- cameraNormal = (oc + t * rayDir - ba * y / baba) / radius;
- modelPosition = rayOrigin + t * rayDir;
- viewPosition = (uView * vec4(modelPosition, 1.0)).xyz;
- fragmentDepth = calcDepth(viewPosition);
- #if defined(dClipVariant_pixel) && dClipObjectCount != 0
- if (clipTest(vec4(modelPosition, 0.0))) {
- objectClipped = true;
- fragmentDepth = -1.0;
- #ifdef dSolidInterior
- topCap = !topInterior;
- bottomCap = !bottomInterior;
- #endif
- }
- #endif
- if (fragmentDepth > 0.0) return true;
- clipped = true;
- }
- if (!clipped) {
- if (topCap && y < 0.0) {
- // top cap
- t = -baoc / bard;
- if (abs(k1 + k2 * t) < h) {
- interior = topInterior;
- cameraNormal = -ba / baba;
- modelPosition = rayOrigin + t * rayDir;
- viewPosition = (uView * vec4(modelPosition, 1.0)).xyz;
- fragmentDepth = calcDepth(viewPosition);
- #if defined(dClipVariant_pixel) && dClipObjectCount != 0
- if (clipTest(vec4(modelPosition, 0.0))) {
- objectClipped = true;
- fragmentDepth = -1.0;
- #ifdef dSolidInterior
- topCap = !topInterior;
- bottomCap = !bottomInterior;
- #endif
- }
- #endif
- if (fragmentDepth > 0.0) {
- #ifdef dSolidInterior
- if (interior) cameraNormal = -rayDir;
- #endif
- return true;
- }
- }
- } else if (bottomCap && y >= 0.0) {
- // bottom cap
- t = (baba - baoc) / bard;
- if (abs(k1 + k2 * t) < h) {
- interior = bottomInterior;
- cameraNormal = ba / baba;
- modelPosition = rayOrigin + t * rayDir;
- viewPosition = (uView * vec4(modelPosition, 1.0)).xyz;
- fragmentDepth = calcDepth(viewPosition);
- #if defined(dClipVariant_pixel) && dClipObjectCount != 0
- if (clipTest(vec4(modelPosition, 0.0))) {
- objectClipped = true;
- fragmentDepth = -1.0;
- #ifdef dSolidInterior
- topCap = !topInterior;
- bottomCap = !bottomInterior;
- #endif
- }
- #endif
- if (fragmentDepth > 0.0) {
- #ifdef dSolidInterior
- if (interior) cameraNormal = -rayDir;
- #endif
- return true;
- }
- }
- }
- }
- if (uDoubleSided || solidInterior) {
- // body inside
- h = -h;
- t = (-k1 - h) / k2;
- y = baoc + t * bard;
- if (y > 0.0 && y < baba) {
- interior = true;
- cameraNormal = -(oc + t * rayDir - ba * y / baba) / radius;
- modelPosition = rayOrigin + t * rayDir;
- viewPosition = (uView * vec4(modelPosition, 1.0)).xyz;
- fragmentDepth = calcDepth(viewPosition);
- if (fragmentDepth > 0.0) {
- #ifdef dSolidInterior
- if (!objectClipped) {
- fragmentDepth = 0.0 + (0.0000002 / vSize);
- cameraNormal = -rayDir;
- }
- #endif
- return true;
- }
- }
- if (topCap && y < 0.0) {
- // top cap
- t = -baoc / bard;
- if (abs(k1 + k2 * t) < -h) {
- interior = true;
- cameraNormal = ba / baba;
- modelPosition = rayOrigin + t * rayDir;
- viewPosition = (uView * vec4(modelPosition, 1.0)).xyz;
- fragmentDepth = calcDepth(viewPosition);
- if (fragmentDepth > 0.0) {
- #ifdef dSolidInterior
- if (!objectClipped) {
- fragmentDepth = 0.0 + (0.0000002 / vSize);
- cameraNormal = -rayDir;
- }
- #endif
- return true;
- }
- }
- } else if (bottomCap && y >= 0.0) {
- // bottom cap
- t = (baba - baoc) / bard;
- if (abs(k1 + k2 * t) < -h) {
- interior = true;
- cameraNormal = -ba / baba;
- modelPosition = rayOrigin + t * rayDir;
- viewPosition = (uView * vec4(modelPosition, 1.0)).xyz;
- fragmentDepth = calcDepth(viewPosition);
- if (fragmentDepth > 0.0) {
- #ifdef dSolidInterior
- if (!objectClipped) {
- fragmentDepth = 0.0 + (0.0000002 / vSize);
- cameraNormal = -rayDir;
- }
- #endif
- return true;
- }
- }
- }
- }
- return false;
- }
- void main() {
- vec3 rayOrigin = vModelPosition;
- vec3 rayDir = mix(normalize(vModelPosition - uCameraPosition), uCameraDir, uIsOrtho);
- vec3 cameraNormal;
- vec3 modelPosition;
- vec3 viewPosition;
- float fragmentDepth;
- bool hit = CylinderImpostor(rayOrigin, rayDir, vStart, vEnd, vSize, cameraNormal, interior, modelPosition, viewPosition, fragmentDepth);
- if (!hit) discard;
- if (fragmentDepth < 0.0) discard;
- if (fragmentDepth > 1.0) discard;
- gl_FragDepthEXT = fragmentDepth;
- vec3 vViewPosition = viewPosition;
- vec3 vModelPosition = modelPosition;
- #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)
- mat3 normalMatrix = transpose3(inverse3(mat3(uView)));
- vec3 normal = normalize(normalMatrix * -normalize(cameraNormal));
- #include apply_light_color
- #include apply_interior_color
- #include apply_marker_color
- #include apply_fog
- #include wboit_write
- #include dpoit_write
- #endif
- }
- `;
|