Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Three.js Shader Example</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r82/three.min.js"></script>
</head>
<body>
  <canvas class="webgl"></canvas>
<script id="vertexShader" type="x-shader/x-vertex">
varying vec2 vertexUV;
void main() {
    vertexUV = uv;
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
precision highp float;
uniform vec3 iResolution;
uniform float iTime;
uniform sampler2D iChannel0;
#define M_NONE -1.0
#define M_NOISE 1.0
float hash(float h) {
    return fract(sin(h) * 43758.5453123);
}
float noise(vec3 x) {
    vec3 p = floor(x);
    vec3 f = fract(x);
    f = f * f * (3.0 - 2.0 * f);
    float n = p.x + p.y * 157.0 + 113.0 * p.z;
    return mix(
            mix(mix(hash(n + 0.0), hash(n + 1.0), f.x),
                    mix(hash(n + 157.0), hash(n + 158.0), f.x), f.y),
            mix(mix(hash(n + 113.0), hash(n + 114.0), f.x),
                    mix(hash(n + 270.0), hash(n + 271.0), f.x), f.y), f.z);
}
#define OCTAVES 4
float fbm(vec3 x) {
    float v = 0.0;
    float a = 0.5;
    vec3 shift = vec3(100);
    for (int i = 0; i < OCTAVES; ++i) {
        v += a * noise(x);
        x = x * 2.0 + shift;
        a *= 0.5;
    }
    return v;
}
const int MAX_MARCHING_STEPS = 200;
const float MIN_DIST = 0.0;
const float MAX_DIST = 100.0;
const float EPSILON = 0.002;
float sdBox(vec3 p, vec3 b) {
    vec3 q = abs(p) - b;
    return length(max(q, 0.0)) + min(max(q.x, max(q.y, q.z)), 0.0) - 2.0;
}
float opSmI(float d1, float d2, float k) {
    float h = clamp(0.5 - 0.5 * (d2 - d1) / k, 0.0, 1.0);
    return mix(d2, d1, h) + k * h * (1.0 - h);
}
mat3 rotateY(float t) {
    float c = cos(t);
    float s = sin(t);
    return mat3(vec3(c, 0, s),
                vec3(0, 1, 0),
                vec3(-s, 0, c));
}
mat3 rotateX(float t) {
    float c = cos(t);
    float s = sin(t);
    return mat3(vec3(1, 0, 0),
                vec3(0, c, -s),
                vec3(0, s, c));
}
mat3 rotateZ(float t) {
    float c = cos(t);
    float s = sin(t);
    return mat3(vec3(c, -s, 0),
                vec3(s, c, 0),
                vec3(0, 0, 1));
}
float sdCapsule(vec3 p, vec3 a, vec3 b, float r) {
    vec3 pa = p - a;
    vec3 ba = b - a;
    float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
    return length(pa - ba * h) - r;
}
float sceneSDF(vec3 sP) {
    float f = sdCapsule(sP, vec3(-1.7, 0., 0.), vec3(1.7, 0., 0.), 0.3);
    float d = 0.02 * sin(sP.x * 5.0) * sin((sin(sP.x * 2.0 + iTime) + 1.0) * sP.x * 20.0) + noise(vec3(sP.z * 2.5 - iTime * 1.0)) - 1.2;
    return f + 0.5 * d;
}
vec2 shortestDistanceToSurface(vec3 eye, vec3 marchingDirection, float start, float end) {
    float depth = start;
    for (int i = 0; i < MAX_MARCHING_STEPS; i++) {
        float dist = sceneSDF(eye + depth * marchingDirection);
        if (dist < EPSILON) {
            return vec2(depth, float(i + 1));
        }
        depth += dist;
        if (depth >= end) {
            return vec2(end, 0.0);
        }
    }
    return vec2(end, 0.0);
}
vec3 rayDirection(float fieldOfView, vec2 size, vec2 fragCoord) {
    vec2 xy = fragCoord - size / 2.0;
    float z = size.y / tan(radians(fieldOfView) / 2.0);
    return normalize(vec3(xy, -z));
}
vec3 estimateNormal(vec3 p) {
    return normalize(vec3(
        sceneSDF(vec3(p.x + EPSILON, p.y, p.z)) - sceneSDF(vec3(p.x - EPSILON, p.y, p.z)),
        sceneSDF(vec3(p.x, p.y + EPSILON, p.z)) - sceneSDF(vec3(p.x, p.y - EPSILON, p.z)),
        sceneSDF(vec3(p.x, p.y, p.z + EPSILON)) - sceneSDF(vec3(p.x, p.y, p.z - EPSILON))
    ));
}
vec3 phongContribForLight(vec3 k_d, vec3 k_s, float alpha, vec3 p, vec3 eye,
                          vec3 lightPos, vec3 lightIntensity) {
    vec3 N = estimateNormal(p);
    vec3 L = normalize(lightPos - p);
    vec3 V = normalize(eye - p);
    vec3 R = normalize(reflect(-L, N));
    
    vec3 ref = reflect(p - eye, N);
    
    float dotLN = dot(L, N);
    float dotRV = dot(R, V);
    
    if (dotLN < 0.0) {
        return vec3(0.0, 0.0, 0.0);
    }
    
    if (dotRV < 0.0) {
        return lightIntensity * (k_d * dotLN);
    }
    return (lightIntensity * (k_d * dotLN + k_s * pow(dotRV, alpha)) * 0.5 + 0.5 * texture(iChannel0, ref.xy).xyz);
}
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec3 dir = rayDirection(45.0, iResolution.xy, fragCoord);
    vec3 eye = vec3(0.0, 0.0, 5.0);
    vec2 sdf = shortestDistanceToSurface(eye, dir, MIN_DIST, MAX_DIST);
    float dist = sdf.x;
    
    if (dist > MAX_DIST - EPSILON) {
        fragColor = vec4(0.0, 0.0, 0.0, 0.0);
        return;
    }
    
    vec3 p = eye + dist * dir;
    vec3 N = estimateNormal(p);
    
    float l1 = length(cross(vec3(0., 0.0, 1.), N));
    l1 = smoothstep(0.65, 0.6, l1) - smoothstep(l1, 0.65, 0.6);
    float l2 = length(cross(vec3(0., 0.01, 1.05), N));
    l2 = smoothstep(0.65, 0.6, l2) - smoothstep(l2, 0.65, 0.6);
    float l3 = length(cross(vec3(0.02, 0.0, 1.1), N));
    l3 = smoothstep(0.65, 0.59, l3) - smoothstep(l3, 0.65, 0.59);
    vec3 color = vec3(l1, l2, l3);
    
    fragColor = vec4(color, 1.0);
}
</script>
<script>
  // Canvas
  const canvas = document.querySelector('canvas.webgl')
  // Scene
  const scene = new THREE.Scene();
  // Objects
  const geometry = new THREE.SphereGeometry(5, 50, 50);
  // Materials
  const loader = new THREE.TextureLoader();
  const material = new THREE.ShaderMaterial({
    vertexShader: document.getElementById('vertexShader').textContent,
    fragmentShader: document.getElementById('fragmentShader').textContent,
    uniforms: {
      iResolution: { value: new THREE.Vector3(window.innerWidth, window.innerHeight, 1) },
      iTime: { value: 0 },
      iChannel0: { value: loader.load('https://i.ibb.co/CsjHTSQ/test.png') }
    }
  });
  // Mesh
  const mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);
  // Camera
  const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
  camera.position.z = 5;
  // Renderer
  const renderer = new THREE.WebGLRenderer({ canvas });
  renderer.setSize(window.innerWidth, window.innerHeight);
  // Animation loop
  function animate() {
    requestAnimationFrame(animate);
    // Update uniforms
    material.uniforms.iTime.value += 0.05;
    renderer.render(scene, camera);
  }
  animate();
</script>
</body>
</html>
 
// // Canvas
// const canvas = document.querySelector('canvas.webgl')
// // Scene
// const scene = new THREE.Scene();
// // Objects
// const geometry = new THREE.SphereGeometry(5, 50, 50);
// // Materials
// const loader = new THREE.TextureLoader();
// const material = new THREE.ShaderMaterial({
//   vertexShader: document.getElementById('vertexShader').textContent,
//   fragmentShader: document.getElementById('fragmentShader').textContent,
//   uniforms: {
//     iResolution: { value: new THREE.Vector3(window.innerWidth, window.innerHeight, 1) },
//     iTime: { value: 0 },
//     globeTexture: {
//       value: loader.load('https://threejs.org/examples/textures/uv_grid_opengl.jpg')
//     }
//   }
// });
// // Mesh
// const sphere = new THREE.Mesh(geometry, material)
// scene.add(sphere)
// // Lights
// const pointLight = new THREE.PointLight(0xffffff, 0.1)
// pointLight.position.x = 2
// pointLight.position.y = 3
// pointLight.position.z = 4
// scene.add(pointLight)
// /**
//  * Sizes
//  */
// const sizes = {
//   width: window.innerWidth,
//   height: window.innerHeight
// }
// window.addEventListener('resize', () => {
//   // Update sizes
//   sizes.width = window.innerWidth
//   sizes.height = window.innerHeight
//   // Update camera
//   camera.aspect = sizes.width / sizes.height
//   camera.updateProjectionMatrix()
//   // Update renderer
//   renderer.setSize(sizes.width, sizes.height)
//   renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
// })
// /**
//  * Camera
//  */
// // Base camera
// const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 0.1, 100)
// camera.position.x = 0
// camera.position.y = 0
// camera.position.z = 20
// scene.add(camera)
// /**
//  * Renderer
//  */
// var context = canvas.getContext( 'webgl2' );
// var renderer = new THREE.WebGLRenderer( { canvas: canvas, context: context } );
// renderer.setSize(sizes.width, sizes.height)
// renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
// /**
//  * Animate
//  */
// // const clock = new THREE.Clock();
// // const tick = () => {
// //   const elapsedTime = clock.getElapsedTime();
// //   // Update uniform values
// //   material.uniforms.iTime.value = elapsedTime;
// //   material.uniforms.iResolution.value.set(window.innerWidth, window.innerHeight, 1);
// //   // Update objects
// //   sphere.rotation.y = .5 * elapsedTime;
// //   // Render
// //   renderer.render(scene, camera);
// //   // Call tick again on the next frame
// //   window.requestAnimationFrame(tick);
// // }
// // tick();
// const clock = new THREE.Clock()
// const tick = () => {
//   const elapsedTime = clock.getElapsedTime()
//   // Update objects
//   sphere.rotation.y = .5 * elapsedTime
//   // Render
//   renderer.render(scene, camera)
//   // Call tick again on the next frame
//   window.requestAnimationFrame(tick)
// }
// tick()
Output 300px

This bin was created anonymously and its free preview time has expired (learn why). — Get a free unrestricted account

Dismiss x
public
Bin info
anonymouspro
0viewers