let hash=tokenData.hash;class Random{constructor(){this.useA=!1;let e=function(e){let n=parseInt(e.substring(0,8),16),o=parseInt(e.substring(8,16),16),a=parseInt(e.substring(16,24),16),t=parseInt(e.substring(24,32),16);return function(){let e=((n|=0)+(o|=0)|0)+(t|=0)|0;return t=t+1|0,n=o^o>>>9,o=(a|=0)+(a<<3)|0,a=(a=a<<21|a>>>11)+e|0,(e>>>0)/4294967296}};this.prngA=new e(tokenData.hash.substring(2,34)),this.prngB=new e(tokenData.hash.substring(34,66));for(let e=0;e<1e6;e+=2)this.prngA(),this.prngB()}random_dec(){return this.useA=!this.useA,this.useA?this.prngA():this.prngB()}}let R=new Random;const body=document.querySelector("body"),canvas=document.querySelector("body > .webgl"),scene=new THREE.Scene;document.documentElement.style.margin="0px",document.documentElement.style.padding="0px",document.documentElement.style.overflow="hidden",document.documentElement.style.height="100vh",document.documentElement.style.width="100vw",document.body.style.margin="0px",document.body.style.padding="0px",document.body.style.overflow="hidden",document.body.style.height="100vh",document.body.style.width="100vw";const mainElement=document.createElement("div");mainElement.id="main",mainElement.style.display="flex",mainElement.style.alignItems="center",mainElement.style.justifyContent="center",mainElement.style.height="100%",mainElement.style.width="100%",mainElement.style.boxSizing="border-box",mainElement.style.padding="10px",mainElement.style.position="absolute",mainElement.style.top="0",mainElement.style.left="0",document.body.appendChild(mainElement);const containerElement=document.createElement("div");containerElement.id="container",containerElement.style.backgroundColor="transparent",mainElement.appendChild(containerElement);const aspectRatio=1;let sizes={width:1*window.innerHeight,height:window.innerHeight};const updateSizes=()=>{const e=window.innerHeight,n=window.innerWidth;sizes.height=e,sizes.width=1*e,sizes.width>n&&(sizes.width=n,sizes.height=n/1)},camera=new THREE.PerspectiveCamera(25,sizes.width/sizes.height,.1,1e3);scene.add(camera);const renderer=new THREE.WebGLRenderer({antialias:!0});renderer.shadowMap.enabled=!0,renderer.shadowMap.type=THREE.PCFSoftShadowMap;const setRendererSize=(e,n)=>{e.setSize(n.width,n.height),e.setPixelRatio(Math.min(window.devicePixelRatio,2))};updateSizes(),setRendererSize(renderer,sizes),Object.assign(container.style,{width:sizes.width+"px",height:sizes.height+"px",backgroundColor:"transparent"}),container.appendChild(renderer.domElement);const vertexShader="\n varying vec2 vUv;\n\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n",fragmentShader="\n uniform float aspectRatio;\n uniform vec3 marginColor;\n uniform float marginSize;\n\n varying vec2 vUv;\n\n void main() {\n vec2 uv = vUv * vec2(aspectRatio, 1.0);\n vec2 margin = vec2(marginSize);\n\n if (uv.x < margin.x || uv.y < margin.y || uv.x > 1.0 - margin.x || uv.y > 1.0 - margin.y) {\n gl_FragColor = vec4(marginColor, 1.0);\n } else {\n gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n }\n }\n",shaderMaterial=new THREE.ShaderMaterial({vertexShader:vertexShader,fragmentShader:fragmentShader,uniforms:{aspectRatio:{value:sizes.width/sizes.height},marginColor:{value:new THREE.Color(15527381)},marginSize:{value:.15}},transparent:!0}),geometry=new THREE.PlaneGeometry(2,2),marginPlane=new THREE.Mesh(geometry,shaderMaterial);marginPlane.position.set(0,0,-3.4),scene.add(marginPlane),window.addEventListener("resize",()=>{updateSizes(),camera.aspect=sizes.width/sizes.height,camera.updateProjectionMatrix(),setRendererSize(renderer,sizes),Object.assign(container.style,{width:sizes.width+"px",height:sizes.height+"px"}),shaderMaterial.uniforms.aspectRatio.value=sizes.width/sizes.height}),scene.add(new THREE.AmbientLight(16777215,.6));const addDirectionalLight=(e,n)=>{const o=new THREE.DirectionalLight;o.position.set(...e),o.castShadow=!0,o.intensity=n,o.shadow.mapSize.width=2160,o.shadow.mapSize.height=2700,o.shadow.camera=Object.assign(new THREE.OrthographicCamera(-50,50,50,-50,.1,1e3)),scene.add(o)};addDirectionalLight([-.5,53.3,1],1),addDirectionalLight([-.5,65.6,57],.4);const getRandomColor=e=>e[Math.floor(R.random_dec()*e.length)],randomColor2=getRandomColor([15452134,10344159,13364693,16775324,16697448,16776181,12189688,9281279]),randomColor3=getRandomColor([13940112,14237503,15105183,15096608,1381399,1453381,9875939,7214374,16212562,1577505,10568243,12759445,8551282,13737081,12816345,12893554]),randomColor4=getRandomColor([10048031,4341567,3942945,10066326]),width=window.innerWidth,height=window.innerHeight,createShaderMaterial=(e,n,o)=>new THREE.ShaderMaterial({uniforms:o,vertexShader:e,fragmentShader:n}),wallMaterial=createShaderMaterial("varying vec2 vUv;\nvoid main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n","\nprecision mediump float;\nvarying vec2 vUv;\nuniform vec3 color;\nuniform float seed; // Add seed uniform\n\n// Improved seeded random function\nfloat random(vec2 st) {\n vec3 magic = vec3(1.0, 113.0, 301.0);\n return fract(sin(dot(st + seed, magic.xy)) * magic.z);\n}\n\nvoid main() {\n vec2 uv = vUv;\n \n // Scale the input coordinates to get consistent noise\n float n = random(uv * 1000.0); // Adjust the value (e.g., 50.0) for consistent noise\n \n vec3 finalColor = mix(color, vec3(1.0 - color.r, 1.0 - color.g, 1.0 - color.b), n);\n gl_FragColor = vec4(finalColor, 1.0);\n}",{color:{value:new THREE.Color(randomColor2)},seed:{value:R.random_dec()}}),frameMaterial=createShaderMaterial("varying vec2 vUv;\nvoid main() {\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n vUv = uv;\n}\n","\nvarying vec2 uUv;\nprecision mediump float;\nuniform vec3 uColor;\nvoid main() {\n gl_FragColor = vec4(uColor, 0.8);\n}",{uColor:{value:new THREE.Color(randomColor2)},transparent:!0}),artMaterial=new THREE.ShaderMaterial({uniforms:{seed:{value:R.random_dec()},squareSeed:{value:R.random_dec()},pixelRatio:{value:window.devicePixelRatio||1}},vertexShader:"varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }",fragmentShader:"\n precision mediump float;\n uniform float seed;\n uniform float squareSeed;\n varying vec2 vUv;\n uniform float pixelRatio;\n\n // Improved seeded random function\n float random(vec2 st) {\n vec3 magic = vec3(1.0, 113.0, 301.0);\n return fract(sin(dot(st + seed, magic.xy)) * magic.z);\n }\n\n // Seeded random function for color\n float randomColor(vec2 st) {\n vec3 magic = vec3(1.0, 113.0, 301.0);\n return fract(sin(dot(st + seed + squareSeed, magic.xy)) * magic.z);\n }\n\n vec3 filterGreen(vec3 color) {\n float greenThreshold = 0.2;\n float saturationThreshold = 0.3;\n float brightness = (color.r + color.g + color.b) / 3.0;\n float saturation = max(max(color.r, color.g), color.b) - min(min(color.r, color.g), color.b);\n if (color.g > greenThreshold && brightness > greenThreshold && saturation > saturationThreshold) {\n color.g = greenThreshold;\n }\n return color;\n }\n\n vec3 getColor(float value) {\n vec3 color1 = filterGreen(vec3(randomColor(vec2(squareSeed, 3.0)), randomColor(vec2(squareSeed, 4.0)), randomColor(vec2(squareSeed, 5.0))));\n vec3 color2 = filterGreen(vec3(randomColor(vec2(squareSeed, 6.0)), randomColor(vec2(squareSeed, 7.0)), randomColor(vec2(squareSeed, 8.0))));\n vec3 color3 = filterGreen(vec3(randomColor(vec2(squareSeed, 9.0)), randomColor(vec2(squareSeed, 10.0)), randomColor(vec2(squareSeed, 11.0))));\n vec3 color4 = filterGreen(vec3(randomColor(vec2(squareSeed, 12.0)), randomColor(vec2(squareSeed, 13.0)), randomColor(vec2(squareSeed, 14.0))));\n vec3 color = vec3(0.0);\n if (value < 0.25) {\n color = mix(color1, color2, value * 4.0);\n } else if (value < 0.5) {\n color = mix(color2, color3, (value - 0.25) * 4.0);\n } else if (value < 0.75) {\n color = mix(color3, color4, (value - 0.5) * 4.0);\n } else {\n color = mix(color4, color1, (value - 0.75) * 4.0);\n }\n return color;\n}\n\n void main() {\n float squareSize = mix(4.0, 65.0, squareSeed * 0.5) * pixelRatio; // Multiply by pixelRatio\n vec2 uv = vUv * squareSize;\n vec2 grid = fract(uv) - 0.57;\n float line = min(abs(grid.x), abs(grid.y));\n float noiseValue = random(floor(uv)) * 0.9 + 0.5;\n vec3 color = getColor(noiseValue);\n line = smoothstep(0.05, 0.02, line);\n vec3 gridColor = vec3(random(vec2(seed, 0.0)), random(vec2(seed, 1.0)), random(vec2(seed, 2.0)));\n vec4 finalColor = vec4(mix(color, filterGreen(gridColor), line), 1.0);\n float marginSize = 0.025;\n vec4 marginColor = vec4(0.96, 0.97, 0.85, 1.0);\n if (vUv.x < marginSize || vUv.x > 1.0 - marginSize || vUv.y < marginSize || vUv.y > 1.0 - marginSize) {\n finalColor = marginColor;\n }\n gl_FragColor = finalColor;\n }"}),artMaterial2=new THREE.ShaderMaterial({uniforms:{seed:{value:R.random_dec()},shapeSize:{value:200}},vertexShader:"varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }",fragmentShader:"\n precision mediump float;\n uniform float seed;\n uniform float shapeSize;\n varying vec2 vUv;\n \n // Improved seeded random function\n float random(vec2 st) {\n vec3 magic = vec3(1.0, 113.0, 301.0);\n return fract(sin(dot(st + seed, magic.xy)) * magic.z);\n }\n \n vec3 getColor(float value) {\n value *= 4.0;\n int index = int(floor(value));\n float t = fract(value);\n vec3 colorA = vec3(random(vec2(seed, float(index * 3 + 3))), random(vec2(seed, float(index * 3 + 4))), random(vec2(seed, float(index * 3 + 5))));\n vec3 colorB = vec3(random(vec2(seed, float((index + 1) * 3 + 3))), random(vec2(seed, float((index + 1) * 3 + 4))), random(vec2(seed, float((index + 1) * 3 + 5))));\n return mix(colorA, colorB, t);\n }\n \n void main() {\n vec2 uv = vUv * shapeSize;\n vec2 grid = fract(uv) - 0.5;\n float randomValue = random(floor(uv * 1.5));\n float shape = max(grid.x - grid.y, grid.y - grid.x) * float(randomValue < 0.111) + length(grid) * float(randomValue >= 0.111 && randomValue < 0.333) + max(abs(grid.x), abs(grid.y)) * float(randomValue >= 0.333);\n shape = smoothstep(0.2, 0.001, shape);\n vec3 color = getColor(randomValue);\n vec3 gridColor = vec3(random(vec2(seed, 1.0)), random(vec2(seed, 1.0)), random(vec2(seed, 2.0)));\n vec4 finalColor = vec4(mix(color, gridColor, shape), 1.0);\n float marginSize = 0.025;\n vec4 marginColor = vec4(0.96, 0.97, 0.85, 1.0);\n if (vUv.x < marginSize || vUv.x > 1.0 - marginSize || vUv.y < marginSize || vUv.y > 1.0 - marginSize) {\n finalColor = marginColor;\n }\n gl_FragColor = finalColor;\n }\n "}),artMaterial3=new THREE.ShaderMaterial({uniforms:{time:{value:0},resolution:{value:new THREE.Vector2(window.innerWidth,window.innerHeight)},seed:{value:R.random_dec()}},vertexShader:"varying vec2 vUv;\nvoid main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}",fragmentShader:"\n uniform float time;\n uniform vec2 resolution;\n uniform float seed;\n varying vec2 vUv;\n vec3 permute(vec3 x) {\n return mod(((x * 34.0) + 100.0) * x, 289.0);\n }\n float snoise(vec2 v) {\n const vec4 C = vec4(0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439);\n vec2 i = floor(v + dot(v, C.yy));\n vec2 x0 = v - i + dot(i, C.xx);\n vec2 i1;\n i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n vec4 x12 = x0.xyxy + C.xxzz;\n x12.xy -= i1;\n i = mod(i, 289.0);\n vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 0.5)) + i.x + vec3(0.0, i1.x, 1.0));\n vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0);\n m = m * m;\n m = m * m;\n vec3 x = 2.0 * fract(p * C.www) - 1.0;\n vec3 h = abs(x) - 0.5;\n vec3 ox = floor(x + 0.5);\n vec3 a0 = x - ox;\n m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);\n vec3 g;\n g.x = a0.x * x0.x + h.x * x0.y;\n g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n return 130.0 * dot(m, g);\n }\n float stroke(vec2 st) {\n float noiseValue = mix(0.0, 1.0, snoise(seed * 8.0 + st * 0.4));\n float scale = mix(1.5, 3.5, snoise(seed * 2.0 + st * 0.1));\n float rotation = mix(0.5, 3.14, snoise(seed * 4.0 + st * 0.2));\n int octaves = int(mix(4.0, 7.0, snoise(seed * 6.0 + st * 0.3)));\n for (int i = 0; i < octaves; i++) {\n noiseValue += snoise(seed + st * scale);\n st = vec2(st.x * cos(rotation) - st.y * sin(rotation), st.x * sin(rotation) + st.y * cos(rotation));\n scale *= 1.5;\n rotation += 1.3;\n }\n float sizeVariation = snoise(seed * 3.0 + st * 0.3);\n float minSize = mix(0.1, 0.3, snoise(seed * 5.0 + st * 0.4));\n float maxSize = mix(0.4, 0.8, snoise(seed * 6.0 + st * 0.5));\n float adjustedSize = mix(minSize, maxSize, sizeVariation);\n return smoothstep(adjustedSize - 0.1, adjustedSize, abs(noiseValue));\n }\n void main() {\n vec2 st = vUv;\n float scribble = stroke(st);\n float marginSize = 0.025;\n vec4 marginColor = vec4(0.96, 0.97, 0.85, 1.0);\n vec4 finalColor = vec4(vec3(scribble), 1.0);\n if (vUv.x < marginSize || vUv.x > 1.0 - marginSize || vUv.y < marginSize || vUv.y > 1.0 - marginSize) {\n finalColor = marginColor;\n }\n gl_FragColor = finalColor;\n }"}),group=new THREE.Group;function createBox(e,n,o,a,t,r,i){const l=new THREE.BoxGeometry(1,1,1,10,10),s=new THREE.Mesh(l,i);return s.position.set(e,n,o),s.scale.set(a,t,r),s}const box1=createBox(0,10.88,-2,1.44,18.878,1,wallMaterial),box2=createBox(37.2,9.65,-2,72.959,21.34,1,wallMaterial),box3=createBox(-37.2,9.65,-2,72.959,21.34,1,wallMaterial),planeGeometry=new THREE.PlaneGeometry(5,5,32),planeMaterial=new THREE.MeshStandardMaterial({color:randomColor3}),plane=new THREE.Mesh(planeGeometry,planeMaterial);plane.position.set(0,-1,7.5),plane.scale.set(30,4,1),plane.rotation.x=-.5*Math.PI,plane.receiveShadow=!0;const box4=createBox(-.751,.22,.5,-.06,2.45,.05,frameMaterial),box5=createBox(.751,.22,.5,-.06,2.45,.05,frameMaterial),box6=createBox(0,1.475,.5,1.562,.06,.05,frameMaterial),box7=createBox(38.3,-.97,.5,75,.06,.05,frameMaterial),box8=createBox(-38.3,-.97,.5,75,.06,.05,frameMaterial),frameGroup=new THREE.Group;frameGroup.add(box4,box5,box6,box7,box8);const artGeometry=new THREE.BoxGeometry(1,1,1,10,10),art=new THREE.Mesh(artGeometry,artMaterial);art.position.set(-2.35,1.2,-2),art.scale.set(2.7,3.2,1);const artClone=art.clone();artClone.position.set(2.35,1.2,-2),artClone.scale.set(2.7,3.2,1);const artClone2=art.clone();function getMaterialCombination(e){const n=new Random(e);function o(){const e=[0,1,2];return e[Math.floor(n.random_dec()*e.length)]}function a(e){for(let o=e.length-1;o>0;o--){const a=Math.floor(n.random_dec()*(o+1));[e[o],e[a]]=[e[a],e[o]]}}return function(){const e=[0,1,2],t=n.random_dec();if(t<=.8)return a(e),e;if(t<=.95){const t=o(),r=e.filter(e=>e!==t)[Math.floor(2*n.random_dec())],i=[t,t,r];return a(i),i}{const e=o();return[e,e,e]}}()}artClone2.position.set(0,2.7,-2),artClone2.scale.set(1.6,2.1,1);const[materialIndexForArt,materialIndexForArtClone,materialIndexForArtClone2]=getMaterialCombination(tokenData.hash),materials=[artMaterial,artMaterial2,artMaterial3];function calculateFeatures(e){const[n,o,a]=getMaterialCombination(e.hash);let t;return{"Artwork Type":t=n===o&&o===a?"Triptych":n===o&&n!==a||n===a&&n!==o||o===a&&o!==n?"Diptych":"Varied"}}art.material=materials[materialIndexForArt],artClone.material=materials[materialIndexForArtClone],artClone2.material=materials[materialIndexForArtClone2];const features=calculateFeatures(tokenData.hash);console.log("Features:",features);const tableGroup=new THREE.Group,minLength=.5,maxLength=3,randomLength=.5+2.5*R.random_dec(),tabletopGeometry=new THREE.BoxGeometry(randomLength,.1,1),tabletopMaterial=new THREE.MeshStandardMaterial({color:randomColor4,metalness:.5,roughness:.5}),tabletop=new THREE.Mesh(tabletopGeometry,tabletopMaterial);tabletop.castShadow=!0,tabletop.receiveShadow=!0;const legHeight=.3,legGeometry=new THREE.BoxGeometry(.1,.3,.1),legMaterial=new THREE.MeshStandardMaterial({color:randomColor4,metalness:.5,roughness:.5}),leg1=new THREE.Mesh(legGeometry,legMaterial),leg2=new THREE.Mesh(legGeometry,legMaterial),leg3=new THREE.Mesh(legGeometry,legMaterial),leg4=new THREE.Mesh(legGeometry,legMaterial);leg1.castShadow=!0,leg1.receiveShadow=!0,leg2.castShadow=!0,leg2.receiveShadow=!0,leg3.castShadow=!0,leg3.receiveShadow=!0,leg4.castShadow=!0,leg4.receiveShadow=!0;const legOffsetRatio=(randomLength-.1)/2;leg1.position.set(-legOffsetRatio,-.3/1.55,-.3),leg2.position.set(legOffsetRatio,-.3/1.55,-.3),leg3.position.set(-legOffsetRatio,-.3/1.55,.3),leg4.position.set(legOffsetRatio,-.3/1.55,.3),tableGroup.add(tabletop),tableGroup.add(leg1),tableGroup.add(leg2),tableGroup.add(leg3),tableGroup.add(leg4),group.add(box1),group.add(box2),group.add(box3),group.add(plane),group.add(frameGroup),group.add(art),group.add(artClone),group.add(artClone2);let nTable=-20,numTableClones=40;const cloneTableGroup=(e,n,o)=>{let a=new THREE.Group;e.traverse(e=>{e.isMesh&&(e.castShadow=!0,e.receiveShadow=!0)});for(let t=0;t<o;t++){let o=new THREE.Group;e.children.forEach(function(e){let n=e.clone();o.add(n)}),o.position.z=n*t,a.add(o)}return a},clonedTableGroup=cloneTableGroup(tableGroup,nTable,numTableClones);scene.add(clonedTableGroup);let randomZPosition=10*R.random_dec()+6,randomXPosition=R.random_dec()-.5;clonedTableGroup.position.set(randomXPosition,-.67,randomZPosition);let n=-20,numClones=40;const cloneGroup=(e,n,o)=>{let a=new THREE.Group;for(let t=0;t<o;t++)e.children.forEach(function(e){let o=e.clone();o.position.z=n*t,a.add(o)});return a},clonedGroup=cloneGroup(group,n,numClones);scene.add(clonedGroup);const loop=()=>{renderer.render(scene,camera),window.requestAnimationFrame(loop)};function saveSnapshot(){renderer.render(scene,camera);const e=renderer.domElement.toDataURL("image/png"),n=document.createElement("canvas");n.width=container.clientWidth,n.height=container.clientHeight;const o=n.getContext("2d"),a=getComputedStyle(container).getPropertyValue("background-color"),t=new Image;t.src=e,t.onload=function(){const e=renderer.domElement.getBoundingClientRect(),r=container.getBoundingClientRect(),i=e.left-r.left,l=e.top-r.top;o.fillStyle=a,o.fillRect(0,0,n.width,n.height),o.drawImage(t,i,l);const s=n.toDataURL("image/png"),d=document.createElement("a");d.href=s,d.download="TheCollectorsRoom.png",d.click()}}loop(),document.addEventListener("keydown",e=>{"s"!==e.key&&"S"!==e.key||saveSnapshot()});
↓ show full (19,149 bytes)