Public
Edited
Mar 16, 2024
Fork of Rainforest
2 forks
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
// with `return run()` observable displays "RuntimeError: unreachable" and swallows the error.
// when directly evaluating without `return` the stack trace is displayed in the console.
run(/* wgsl */`
#import prelude::{screen, time}
// basic raymarching

fn sphereMap(p: float3) -> float
{
return length(p) - 1.; // distance to a sphere of radius 1
}

fn rayMarchSphere(ro: float3, rd: float3, tmin: float, tmax: float) -> float
{
var t = tmin;
for(var i=0; i<400; i++ )
{
let pos = ro + t*rd;
let d = sphereMap( pos );
t += d;
if( t>tmax ) { break; };
}

return t;
}

@compute @workgroup_size(16, 16)
fn main_image(@builtin(global_invocation_id) id: uint3) {
let screen_size = uint2(textureDimensions(screen));
if (id.x >= screen_size.x || id.y >= screen_size.y) { return; }
let fragCoord = float2(id.xy) + .5;
let resolution = float2(screen_size);

var ignore = time.elapsed / time.elapsed; // to avoid rewriting run without the time bindings.
var uv = (fragCoord * 2. - resolution.xy) / resolution.y * ignore;
// var uv = (fragCoord * 2. - resolution.xy) / resolution.y;

// camera
let ro = vec3(0.0, 0, -3.0);
let rd = normalize(vec3(uv, 1.));

//----------------------------------
// raycast terrain and tree envelope
//----------------------------------
const tmax = 2000.0;
let t = rayMarchSphere(ro, rd, 0, tmax);
let col = vec3(t * .2);
textureStore(screen, int2(id.xy), float4(col, 1.));
}

`)
}
Insert cell
Insert cell
run(/* wgsl */`
#import prelude::{screen, time}
// basic raymarching

fn sphereMap(p: float3) -> float
{
return length(p) - 1.; // distance to a sphere of radius 1
}

fn rayMarchSphere(ro: float3, rd: float3, tmin: float, tmax: float) -> float
{
var t = tmin;
for(var i=0; i<400; i++ )
{
let pos = ro + t*rd;
let d = sphereMap( pos );
t += d;
if( t>tmax ) { break; };
}

return t;
}

@compute @workgroup_size(16, 16)
fn main_image(@builtin(global_invocation_id) id: uint3) {
let screen_size = uint2(textureDimensions(screen));
if (id.x >= screen_size.x || id.y >= screen_size.y) { return; }
let fragCoord = float2(id.xy) + .5;
let resolution = float2(screen_size);

// var ignore = time.elapsed / time.elapsed; // to avoid rewriting run without the time bindings.
// var uv = (fragCoord * 2. - resolution.xy) / resolution.y * ignore;
var uv = (fragCoord * 2. - resolution.xy) / resolution.y;

// camera
let ro = vec3(0.0, 0, -3.0);
let rd = normalize(vec3(uv, 1.));

//----------------------------------
// raycast terrain and tree envelope
//----------------------------------
const tmax = 2000.0;
let t = rayMarchSphere(ro, rd, 0, tmax);
let col = vec3(t * .2);
textureStore(screen, int2(id.xy), float4(col, 1.));
}

`)
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more