DOCTYPE html html lang en head meta charset UTF 8 meta name viewport content width device width initial scale 1 0 title Simple Sphere SDF title style body margin 0 canvas display block style head body canvas id canvas width 500 height 500 canvas script const vertexShaderSource attribute vec3 a_position varying vec3 v_position void main gl_Position vec4 a_position 1 0 v_position a_position const fragmentShaderSource precision highp float uniform float iTime uniform vec2 u_resolution varying vec3 v_position float sdfSphere vec3 testPoint vec3 spherePos float sphereRadius return length spherePos testPoint sphereRadius float sdfCube vec3 testPoint vec3 cubePos vec3 cubeDim vec3 d abs cubePos testPoint cubeDim return min max d x max d y d z 0 0 length max d vec3 0 0 float sdfTet vec3 p return max abs p x p y p z abs p x p y p z 1 sqrt 3 float sdfTetrahedron vec3 zin vec3 z zin int n 0 const int Iterations 5 float Scale 2 0 vec3 Offset vec3 1 for int j 0 j Iterations j if z x z y 0 0 z xy z yx fold 1 if z x z z 0 0 z xz z zx fold 2 if z y z z 0 0 z zy z yz fold 3 z z Scale Offset Scale 1 0 n sdf tetrahedron function return sdfTet z pow Scale float n 0 01 add chunky factor build up tetrahendron from spheres instead of sdftet function return length z pow Scale float n 0 01 float rayCast vec3 ptin float t 0 0 Rotation float x 0 2 iTime float y 0 7 iTime mat4 Rx mat4 vec4 cos x sin x 0 0 0 0 vec4 sin x cos x 0 0 0 0 vec4 0 0 0 0 1 0 0 0 vec4 0 0 0 0 0 0 1 0 mat4 Ry mat4 vec4 cos y 0 0 sin y 0 0 vec4 0 0 1 0 0 0 0 0 vec4 sin y 0 0 cos y 0 0 vec4 0 0 0 0 0 0 1 0 vec3 pt vec4 ptin 1 0 Ry Rx xyz t sdfTetrahedron pt t sdfCube pt vec3 0 vec3 1 0 t max t sdfCube pt vec3 0 vec3 0 7 0 7 2 0 t max t sdfCube pt vec3 0 vec3 0 7 2 0 7 t max t sdfCube pt vec3 0 vec3 2 0 7 0 7 return t float rayTrace vec3 rayPos vec3 rayDir float t 0 0 for int i 0 i 200 i vec3 rayPosition rayPos rayDir t t rayCast rayPosition if t 0 0 t 1000 0 return 0 0 no hit return t vec3 getNormal vec3 pt float d rayCast pt float s 0 01 vec3 a vec3 pt x s pt y pt z vec3 b vec3 pt x pt y s pt z vec3 c vec3 pt x pt y pt z s vec3 normal normalize vec3 rayCast a d rayCast b d rayCast c d return normal void main vec2 uv gl_FragCoord xy u_resolution xy uv uv 2 0 1 0 Map uv coordinates to range 1 1 Convert 2D UV to 3D position vec3 rayDir normalize vec3 uv 2 5 vec3 0 1 0 vec3 rayPos vec3 0 0 2 0 5 0 vec3 fragColor vec3 1 1 1 float res rayTrace rayPos rayDir if res 0 0 fragColor vec3 1 0 0 5 0 0 vec3 n getNormal rayPos rayDir res vec3 lightDirection vec3 0 0 0 0 1 0 fragColor fragColor min dot n lightDirection 1 0 gl_FragColor vec4 fragColor 1 0 function createShader gl type source const shader gl createShader type gl shaderSource shader source gl compileShader shader if gl getShaderParameter shader gl COMPILE_STATUS console error An error occurred compiling the shaders gl getShaderInfoLog shader gl deleteShader shader return null return shader function createProgram gl vertexShader fragmentShader const program gl createProgram gl attachShader program vertexShader gl attachShader program fragmentShader gl linkProgram program if gl getProgramParameter program gl LINK_STATUS console error Unable to initialize the shader program gl getProgramInfoLog program return null return program function main const canvas document getElementById canvas const gl canvas getContext webgl if gl console error Unable to initialize WebGL Your browser may not support it return Compile vertex and fragment shaders const vertexShader createShader gl gl VERTEX_SHADER vertexShaderSource const fragmentShader createShader gl gl FRAGMENT_SHADER fragmentShaderSource Create shader program const program createProgram gl vertexShader fragmentShader gl useProgram program Set up vertex buffer const positionBuffer gl createBuffer gl bindBuffer gl ARRAY_BUFFER positionBuffer const positions 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 gl bufferData gl ARRAY_BUFFER new Float32Array positions gl STATIC_DRAW const positionAttributeLocation gl getAttribLocation program a_position gl enableVertexAttribArray positionAttributeLocation gl vertexAttribPointer positionAttributeLocation 3 gl FLOAT false 0 0 Set resolution uniform const resolutionUniformLocation gl getUniformLocation program u_resolution gl uniform2f resolutionUniformLocation canvas width canvas height let timevalue 1 0 const timeUniformLocation gl getUniformLocation program iTime gl uniform1f timeUniformLocation timevalue Clear canvas gl clearColor 0 0 0 0 0 0 1 0 gl clear gl COLOR_BUFFER_BIT update loop function render Draw gl drawArrays gl TRIANGLES 0 6 timevalue 0 01 gl uniform1f timeUniformLocation timevalue requestAnimationFrame render Looping animation render main script body html
st a d rayCast b d rayCast c d return normal void main vec2 uv gl_FragCoord xy u_resolution xy uv uv 2 0 1 0 Map uv coordinates to range 1 1 Convert 2D UV to 3D position vec3 rayDir normalize vec3 uv 2 5 vec3 0 1 0 vec3 rayPos vec3 0 0 2 0 5 0 vec3 fragColor vec3 1 1 1 float res rayTrace rayPos rayDir if res 0 0 fragColor vec3 1 0 0 5 0 0 vec3 n getNormal rayPos rayDir res vec3 lightDirection vec3 0 0 0 0 1 0 fragColor fragColor min dot n lightDirection 1 0 gl_FragColor vec4 fragColor 1 0 function createShader gl type source const shader gl createShader type gl shaderSource shader source gl compileShader shader if gl getShaderParameter shader gl COMPILE_STATUS console error An error occurred compiling the shaders gl getShaderInfoLog shader gl deleteShader shader return null return shader function createProgram gl vertexShader fragmentShader const program gl createProgram gl attachShader program vertexShader gl attachShader program fragmentShader gl linkProgram program if gl getProgramParameter program gl LINK_STATUS console error Unable to initialize the shader program gl getProgramInfoLog program return null return program function main const canvas document getElementById canvas const gl canvas getContext webgl if gl console error Unable to initialize WebGL Your browser may not support it return Compile vertex and fragment shaders const vertexShader createShader gl gl VERTEX_SHADER vertexShaderSource const fragmentShader createShader gl gl FRAGMENT_SHADER fragmentShaderSource Create shader program const program createProgram gl vertexShader fragmentShader gl useProgram program Set up vertex buffer const positionBuffer gl createBuffer gl bindBuffer gl ARRAY_BUFFER positionBuffer const positions 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 gl bufferData gl ARRAY_BUFFER new Float32Array positions gl STATIC_DRAW const positionAttributeLocation gl getAttribLocation program a_position gl enableVertexAttribArray positionAttributeLocation gl vertexAttribPointer positionAttributeLocation 3 gl FLOAT false 0 0 Set resolution uniform const resolutionUniformLocation gl getUniformLocation program u_resolution gl uniform2f resolutionUniformLocation canvas width canvas height let timevalue 1 0 const timeUniformLocation gl getUniformLocation program iTime gl uniform1f timeUniformLocation timevalue Clear canvas gl clearColor 0 0 0 0 0 0 1 0 gl clear gl COLOR_BUFFER_BIT update loop function render Draw gl drawArrays gl TRIANGLES 0 6 timevalue 0 01 gl uniform1f timeUniformLocation timevalue requestAnimationFrame render Looping animation render main script body html