UNPKG

speck-renderer

Version:

Browser-based WebGL molecule renderer with the goal of producing figures that are as attractive as they are practical.

78 lines (63 loc) 1.81 kB
const atomsShader = `\ #version 100 precision highp float; attribute vec3 aImposter; attribute vec3 aPosition; attribute float aRadius; attribute vec3 aColor; uniform mat4 uView; uniform mat4 uProjection; uniform mat4 uModel; uniform float uAtomScale; uniform float uRelativeAtomScale; uniform float uAtomShade; varying vec3 vColor; varying vec3 vPosition; varying float vRadius; void main() { vRadius = uAtomScale * (1.0 + (aRadius - 1.0) * uRelativeAtomScale); gl_Position = uProjection * uView * uModel * vec4(vRadius * aImposter + aPosition, 1.0); vColor = mix(aColor, vec3(1,1,1), uAtomShade); vPosition = vec3(uModel * vec4(aPosition, 1)); } // __split__ #version 100 #extension GL_EXT_frag_depth: enable precision highp float; uniform vec2 uBottomLeft; uniform vec2 uTopRight; uniform float uRes; uniform float uDepth; uniform int uMode; varying vec3 vPosition; varying float vRadius; varying vec3 vColor; vec2 res = vec2(uRes, uRes); float raySphereIntersect(vec3 r0, vec3 rd) { float a = dot(rd, rd); vec3 s0_r0 = r0 - vPosition; float b = 2.0 * dot(rd, s0_r0); float c = dot(s0_r0, s0_r0) - (vRadius * vRadius); float disc = b*b - 4.0*a*c; if (disc <= 0.0) { return -1.0; } return (-b - sqrt(disc))/(2.0*a); } void main() { vec3 r0 = vec3(uBottomLeft + (gl_FragCoord.xy/res) * (uTopRight - uBottomLeft), 0.0); vec3 rd = vec3(0, 0, -1); float t = raySphereIntersect(r0, rd); if (t < 0.0) { discard; } vec3 coord = r0 + rd * t; vec3 normal = normalize(coord - vPosition); if (uMode == 0) { gl_FragColor = vec4(vColor, 1); } else if (uMode == 1) { gl_FragColor = vec4(normal * 0.5 + 0.5, 1.0); } gl_FragDepthEXT = -coord.z/uDepth; }` export default atomsShader;