diff --git a/src/index.d.ts b/src/index.d.ts index 1c65256..5474d8a 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -25,6 +25,7 @@ export interface COBEOptions { opacity?: number; offset?: [number, number]; scale?: number; + ambient?: number; context?: WebGLContextAttributes; } diff --git a/src/index.js b/src/index.js index 298f3a5..5167a84 100644 --- a/src/index.js +++ b/src/index.js @@ -15,6 +15,7 @@ const OPT_OFFSET = "offset"; const OPT_SCALE = "scale"; const OPT_OPACITY = "opacity"; const OPT_MAP_BASE_BRIGHTNESS = "mapBaseBrightness"; +const OPT_AMBIENT = "ambient"; const OPT_MAPPING = { [OPT_PHI]: GLSLX_NAME_PHI, @@ -30,6 +31,7 @@ const OPT_MAPPING = { [OPT_SCALE]: GLSLX_NAME_SCALE, [OPT_OPACITY]: GLSLX_NAME_OPACITY, [OPT_MAP_BASE_BRIGHTNESS]: GLSLX_NAME_MAP_BASE_BRIGHTNESS, + [OPT_AMBIENT]: GLSLX_NAME_AMBIENT, }; const { PI, sin, cos, sqrt, atan2, floor, max, pow, log2 } = Math; @@ -192,6 +194,7 @@ export default (canvas, opts) => { [GLSLX_NAME_OFFSET]: createUniform("vec2", OPT_OFFSET, [0, 0]), [GLSLX_NAME_SCALE]: createUniform("float", OPT_SCALE, 1), [GLSLX_NAME_OPACITY]: createUniform("float", OPT_OPACITY, 1), + [GLSLX_NAME_AMBIENT]: createUniform("float", OPT_AMBIENT, 0.1), }, mode: 4, geometry: { diff --git a/src/shader.frag b/src/shader.frag index edc08ec..6b2030f 100644 --- a/src/shader.frag +++ b/src/shader.frag @@ -16,8 +16,9 @@ uniform float markersNum; uniform float dotsBrightness; uniform float diffuse; uniform float dark; -uniform float opacity; +uniform float opacity; uniform float mapBaseBrightness; +uniform float ambient; uniform sampler2D uTexture; @@ -164,7 +165,7 @@ void main() { float lighting = pow(dotNL,diffuse)*dotsBrightness; float sample = mapColor*v * lighting; - float colorFactor = mix((1. - sample) * pow(dotNL,.4), sample, dark) + .1; + float colorFactor = mix((1. - sample) * pow(dotNL,.4), sample, dark) + ambient; layer += vec4(baseColor * colorFactor, 1.); float markerLight = 0.; diff --git a/src/shader.min.js b/src/shader.min.js index 32b9b8b..3a21dad 100644 --- a/src/shader.min.js +++ b/src/shader.min.js @@ -1,4 +1,4 @@ -export const GLSLX_SOURCE_MAIN = "precision highp float;uniform vec2 w,x;uniform vec3 S,T,y;uniform vec4 u[64*2];uniform float z,A,k,B,C,D,E,F,U,G;uniform sampler2D H;float I=1./k;mat3 J(float a,float b){float c=cos(a),d=cos(b),e=sin(a),f=sin(b);return mat3(d,f*e,-f*c,0.,c,e,f,d*-e,d*c);}vec3 K(vec3 c,out float v){c=c.xzy;float p=max(2.,floor(log2(2.236068*k*3.141593*(1.-c.z*c.z))*.72021));vec2 g=floor(pow(1.618034,p)/2.236068*vec2(1,1.618034)+.5),d=fract((g+1.)*.618034)*6.283185-3.883222,e=-2.*g,f=vec2(atan(c.y,c.x),c.z-1.),q=floor(vec2(e.y*f.x-d.y*(f.y*k+1.),-e.x*f.x+d.x*(f.y*k+1.))/(d.x*e.y-e.x*d.y));float n=3.141593;vec3 r;for(float h=0.;h<4.;h+=1.){vec2 s=vec2(mod(h,2.),floor(h*.5));float j=dot(g,q+s);if(j>k)continue;float a=j,b=0.;if(a>=524288.)a-=524288.,b+=.803894;if(a>=262144.)a-=262144.,b+=.901947;if(a>=131072.)a-=131072.,b+=.950973;if(a>=65536.)a-=65536.,b+=.475487;if(a>=32768.)a-=32768.,b+=.737743;if(a>=16384.)a-=16384.,b+=.868872;if(a>=8192.)a-=8192.,b+=.934436;if(a>=4096.)a-=4096.,b+=.467218;if(a>=2048.)a-=2048.,b+=.733609;if(a>=1024.)a-=1024.,b+=.866804;if(a>=512.)a-=512.,b+=.433402;if(a>=256.)a-=256.,b+=.216701;if(a>=128.)a-=128.,b+=.108351;if(a>=64.)a-=64.,b+=.554175;if(a>=32.)a-=32.,b+=.777088;if(a>=16.)a-=16.,b+=.888544;if(a>=8.)a-=8.,b+=.944272;if(a>=4.)a-=4.,b+=.472136;if(a>=2.)a-=2.,b+=.236068;if(a>=1.)a-=1.,b+=.618034;float l=fract(b)*6.283185,i=1.-2.*j*I,m=sqrt(1.-i*i);vec3 o=vec3(cos(l)*m,sin(l)*m,i);float t=length(c-o);if(t=V)break;vec4 q=u[d],O=u[d+1];vec3 P=q.xyz;float r=q.w;vec3 Y=P-m;b=length(Y);if(b.5?mix(e.xyz,O.xyz,s*o):mix(e.xyz,T,s*o);}}e.xyz+=pow(1.-g,4.)*y,t+=e*(1.+U)*.5,j=pow(dot(normalize(vec3(-a,sqrt(1.-c))),vec3(0,0,1)),4.)*smoothstep(0.,1.,.2/(c-.64));}else{float R=sqrt(.2/(c-.64));j=smoothstep(.5,1.,R/(R+1.));}gl_FragColor=t+vec4(j*y,j);}" +export const GLSLX_SOURCE_MAIN = "precision highp float;uniform vec2 w,x;uniform vec3 T,U,y;uniform vec4 u[64*2];uniform float z,A,k,B,C,D,E,F,V,G,H;uniform sampler2D I;float J=1./k;mat3 K(float a,float b){float c=cos(a),d=cos(b),e=sin(a),f=sin(b);return mat3(d,f*e,-f*c,0.,c,e,f,d*-e,d*c);}vec3 L(vec3 c,out float v){c=c.xzy;float p=max(2.,floor(log2(2.236068*k*3.141593*(1.-c.z*c.z))*.72021));vec2 g=floor(pow(1.618034,p)/2.236068*vec2(1,1.618034)+.5),d=fract((g+1.)*.618034)*6.283185-3.883222,e=-2.*g,f=vec2(atan(c.y,c.x),c.z-1.),q=floor(vec2(e.y*f.x-d.y*(f.y*k+1.),-e.x*f.x+d.x*(f.y*k+1.))/(d.x*e.y-e.x*d.y));float n=3.141593;vec3 r;for(float h=0.;h<4.;h+=1.){vec2 s=vec2(mod(h,2.),floor(h*.5));float j=dot(g,q+s);if(j>k)continue;float a=j,b=0.;if(a>=524288.)a-=524288.,b+=.803894;if(a>=262144.)a-=262144.,b+=.901947;if(a>=131072.)a-=131072.,b+=.950973;if(a>=65536.)a-=65536.,b+=.475487;if(a>=32768.)a-=32768.,b+=.737743;if(a>=16384.)a-=16384.,b+=.868872;if(a>=8192.)a-=8192.,b+=.934436;if(a>=4096.)a-=4096.,b+=.467218;if(a>=2048.)a-=2048.,b+=.733609;if(a>=1024.)a-=1024.,b+=.866804;if(a>=512.)a-=512.,b+=.433402;if(a>=256.)a-=256.,b+=.216701;if(a>=128.)a-=128.,b+=.108351;if(a>=64.)a-=64.,b+=.554175;if(a>=32.)a-=32.,b+=.777088;if(a>=16.)a-=16.,b+=.888544;if(a>=8.)a-=8.,b+=.944272;if(a>=4.)a-=4.,b+=.472136;if(a>=2.)a-=2.,b+=.236068;if(a>=1.)a-=1.,b+=.618034;float l=fract(b)*6.283185,i=1.-2.*j*J,m=sqrt(1.-i*i);vec3 o=vec3(cos(l)*m,sin(l)*m,i);float t=length(c-o);if(t=W)break;vec4 q=u[d],P=u[d+1];vec3 Q=q.xyz;float r=q.w;vec3 Z=Q-m;b=length(Z);if(b.5?mix(e.xyz,P.xyz,s*o):mix(e.xyz,U,s*o);}}e.xyz+=pow(1.-g,4.)*y,t+=e*(1.+V)*.5,j=pow(dot(normalize(vec3(-a,sqrt(1.-c))),vec3(0,0,1)),4.)*smoothstep(0.,1.,.2/(c-.64));}else{float S=sqrt(.2/(c-.64));j=smoothstep(.5,1.,S/(S+1.));}gl_FragColor=t+vec4(j*y,j);}" export const GLSLX_NAME_DOTS = "k" export const GLSLX_NAME_MARKERS = "u" @@ -13,7 +13,8 @@ export const GLSLX_NAME_DOTS_BRIGHTNESS = "D" export const GLSLX_NAME_DIFFUSE = "E" export const GLSLX_NAME_DARK = "F" export const GLSLX_NAME_MAP_BASE_BRIGHTNESS = "G" -export const GLSLX_NAME_U_TEXTURE = "H" -export const GLSLX_NAME_BASE_COLOR = "S" -export const GLSLX_NAME_MARKER_COLOR = "T" -export const GLSLX_NAME_OPACITY = "U" +export const GLSLX_NAME_AMBIENT = "H" +export const GLSLX_NAME_U_TEXTURE = "I" +export const GLSLX_NAME_BASE_COLOR = "T" +export const GLSLX_NAME_MARKER_COLOR = "U" +export const GLSLX_NAME_OPACITY = "V" diff --git a/website/pages/docs/api.mdx b/website/pages/docs/api.mdx index 5f558c2..4417c32 100644 --- a/website/pages/docs/api.mdx +++ b/website/pages/docs/api.mdx @@ -25,6 +25,7 @@ An object with the following properties: | theta | The [θ angle](https://en.wikipedia.org/wiki/Spherical_coordinate_system), -π ≤ theta ≤ π | Required | | dark | Display the globe in dark or light mode, 0 ≤ dark ≤ 1 | Required | | diffuse | Control the [diffuse lighting](https://en.wikipedia.org/wiki/Computer_graphics_lighting#:~:text=of%20lighting%20interactions.-,Diffuse,the%20angle%20of%20incoming%20light.), 0 ≤ diffuse | Required | +| ambient | The ambient light intensity, 0 ≤ ambient ≤ 1 | | | mapSamples | Number of dots displayed, 0 ≤ mapSamples ≤ 100000 | Required | | mapBrightness | Brightness of the dots, 0 ≤ mapBrightness | Required | | mapBaseBrightness | Brightness of samples that are not on the map, 0 ≤ mapBaseBrightness | | diff --git a/website/pages/docs/index.mdx b/website/pages/docs/index.mdx index f9d4068..ee6f3fd 100644 --- a/website/pages/docs/index.mdx +++ b/website/pages/docs/index.mdx @@ -1,6 +1,6 @@ # Get Started -COBE does’t rely on any external libraries or UI framework. It is a vanilla JavaScript library that can be used in any web applications. +COBE does’t rely on any external libraries or UI framework. It is a vanilla JavaScript library that can be used in any web applications. The easiest way to use this library is to create a canvas element and use a CDN to import the library: @@ -26,6 +26,7 @@ The easiest way to use this library is to create a canvas element and use a CDN theta: 0, dark: 0, diffuse: 1.2, + ambient: 0.1, scale: 1, mapSamples: 16000, mapBrightness: 6, @@ -85,7 +86,7 @@ Example: [https://codesandbox.io/s/eager-sky-r2q0g](https://codesandbox.io/s/eag Example: [https://stackblitz.com/edit/vitejs-vite-l5a8xk](https://stackblitz.com/edit/vitejs-vite-l5a8xk?file=src%2FApp.vue). -### Svelte +### Svelte Example: [https://codesandbox.io/s/great-visvesvaraya-78yf6](https://codesandbox.io/s/great-visvesvaraya-78yf6?file=/App.svelte). diff --git a/website/pages/index.mdx b/website/pages/index.mdx index d0f4e24..d8466b3 100644 --- a/website/pages/index.mdx +++ b/website/pages/index.mdx @@ -33,6 +33,7 @@ export function Cobe() { theta: 0.2, dark: 1.1, diffuse: 3, + ambient: 0.1, mapSamples: 16000, mapBrightness: 1.8, mapBaseBrightness: .05, diff --git a/website/pages/playground.mdx b/website/pages/playground.mdx index ccbbc41..39ea5d2 100644 --- a/website/pages/playground.mdx +++ b/website/pages/playground.mdx @@ -18,6 +18,7 @@ export function Page() { mapBrightness: { value: 6, min: 0, max: 12 }, mapBaseBrightness: { value: 0, min: 0, max: 1 }, diffuse: { value: 1.2, min: 0, max: 5 }, + ambient: { value: 0.1, min: 0, max: 1 }, dark: { value: 1, min: 0, max: 1 }, baseColor: { r: 60, g: 60, b: 60 }, markerColor: { r: 255, g: 255, b: 255 }, @@ -47,6 +48,7 @@ export function Page() { phi: 0, theta: 0, diffuse: 1.2, + ambient: 0.1, mapSamples: paramsRef.current.mapSamples, mapBrightness: paramsRef.current.mapBrightness, baseColor: [0.3, 0.3, 0.3], @@ -81,6 +83,7 @@ export function Page() { state.mapBrightness = paramsRef.current.mapBrightness state.mapBaseBrightness = paramsRef.current.mapBaseBrightness state.diffuse = paramsRef.current.diffuse + state.ambient = paramsRef.current.ambient state.baseColor = [ paramsRef.current.baseColor.r / 255, paramsRef.current.baseColor.g / 255,