Name
*
Code
{"properties":{"frame":0,"maxFrame":600,"maxFrameLocked":false,"realtimeState":true,"mainCameraPath":"/cameras/cameras:sopGroup/perspectiveCamera1","versions":{"polygonjs":"1.5.82"}},"root":{"type":"root","nodes":{"geo1":{"type":"geo","nodes":{"box1":{"type":"box","params":{"sizes":[3,1,3]}},"material1":{"type":"material","params":{"material":"../MAT/rayMarchingBuilder1"},"inputs":["box1"],"flags":{"display":true}},"MAT":{"type":"materialsNetwork","nodes":{"rayMarchingBuilder1":{"type":"rayMarchingBuilder","nodes":{"globals1":{"type":"globals"},"output1":{"type":"output","inputs":[{"index":0,"inputName":"SDFContext","node":"SDFContext1","output":"SDFContext"}]},"SDFContext1":{"type":"SDFContext","params":{"sdf":{"type":"float","default_value":0,"options":{"spare":true,"editable":false,"computeOnDirty":true,"dependentOnFoundParam":false}},"material":{"type":"string","default_value":"DefaultSDFMaterial()","options":{"spare":true,"editable":false,"computeOnDirty":true,"dependentOnFoundParam":false},"overriden_options":{}}},"inputs":[{"index":0,"inputName":"sdf","node":"SDFUnion3","output":"union"},{"index":1,"inputName":"material","node":"SDFMaterial1","output":"SDFMaterial"}],"connection_points":{"in":[{"name":"sdf","type":"float"},{"name":"material","type":"SDFMaterial"}],"out":[{"name":"SDFContext","type":"SDFContext"}]}},"SDFMaterial1":{"type":"SDFMaterial","params":{"color":{"overriden_options":{}},"diffuse":{"overriden_options":{}},"emissive":{"overriden_options":{}},"envMapTint":{"overriden_options":{}},"envMapIntensity":{"overriden_options":{}},"envMapRoughness":{"overriden_options":{}},"envMapFresnel":{"overriden_options":{}},"envMapFresnelPower":{"overriden_options":{}},"reflectionTint":{"overriden_options":{}},"reflectivity":{"overriden_options":{}},"reflectionBiasMult":{"overriden_options":{}},"refractionTint":{"overriden_options":{}},"ior":{"overriden_options":{}},"iorOffset":{"overriden_options":{}},"transmission":{"overriden_options":{}},"absorption":{"overriden_options":{}},"refractionMaxDist":{"overriden_options":{}},"refractionBiasMult":{"overriden_options":{}}},"inputs":[{"index":0,"inputName":"color","node":"mix1","output":"mix"}]},"SDFSphere1":{"type":"SDFSphere","params":{"position":{"overriden_options":{}},"center":{"raw_input":[-0.1,0,0],"overriden_options":{}},"radius":{"raw_input":0.2,"overriden_options":{}}},"inputs":[{"index":0,"inputName":"position","node":"globals1","output":"position"}]},"SDFSphere2":{"type":"SDFSphere","params":{"position":{"overriden_options":{}},"center":{"raw_input":[0.1,0,0],"overriden_options":{}},"radius":{"raw_input":0.2,"overriden_options":{}}},"inputs":[{"index":0,"inputName":"position","node":"globals1","output":"position"},{"index":1,"inputName":"center","node":"floatToVec3_1","output":"vec3"}]},"SDFUnion1":{"type":"SDFUnion","params":{"sdf0":{"type":"float","default_value":0,"options":{"spare":true,"editable":false,"computeOnDirty":true,"dependentOnFoundParam":false}},"sdf1":{"type":"float","default_value":0,"options":{"spare":true,"editable":false,"computeOnDirty":true,"dependentOnFoundParam":false}},"smoothFactor":{"type":"float","default_value":0,"options":{"spare":true,"editable":true,"computeOnDirty":true,"dependentOnFoundParam":false},"raw_input":0.3},"matBlendDist":{"type":"float","default_value":0,"options":{"spare":true,"editable":true,"computeOnDirty":true,"dependentOnFoundParam":false}}},"inputs":[{"index":0,"inputName":"sdf0","node":"SDFSphere1","output":"float"},{"index":1,"inputName":"sdf1","node":"SDFSphere2","output":"float"}],"connection_points":{"in":[{"name":"sdf0","type":"float"},{"name":"sdf1","type":"float"},{"name":"smoothFactor","type":"float"},{"name":"matBlendDist","type":"float"}],"out":[{"name":"union","type":"float"}]}},"floatToVec3_1":{"type":"floatToVec3","params":{"x":{"overriden_options":{}},"y":{"overriden_options":{}},"z":{"overriden_options":{}}},"inputs":[{"index":0,"inputName":"x","node":"cos1","output":"val"}]},"cos1":{"type":"cos","params":{"radians":{"type":"float","default_value":0,"options":{"spare":true,"editable":false,"computeOnDirty":true,"dependentOnFoundParam":false}}},"inputs":[{"index":0,"inputName":"radians","node":"globals1","output":"time"}],"connection_points":{"in":[{"name":"radians","type":"float"}],"out":[{"name":"val","type":"float"}]}},"constant1":{"type":"constant","params":{"type":4,"color":[1,1,1],"asColor":1},"connection_points":{"in":[],"out":[{"name":"val","type":"vec3"}]}},"SDFSphere3":{"type":"SDFSphere","params":{"center":[-0.25,0,0],"radius":0.2}},"SDFSphere4":{"type":"SDFSphere","params":{"center":[0.25,0,0],"radius":0.2}},"SDFUnion2":{"type":"SDFUnion","params":{"sdf0":{"type":"float","default_value":0,"options":{"spare":true,"editable":false,"computeOnDirty":true,"dependentOnFoundParam":false}},"sdf1":{"type":"float","default_value":0,"options":{"spare":true,"editable":false,"computeOnDirty":true,"dependentOnFoundParam":false}},"smoothFactor":{"type":"float","default_value":0,"options":{"spare":true,"editable":true,"computeOnDirty":true,"dependentOnFoundParam":false},"raw_input":0.31},"matBlendDist":{"type":"float","default_value":0,"options":{"spare":true,"editable":true,"computeOnDirty":true,"dependentOnFoundParam":false}}},"inputs":[{"index":0,"inputName":"sdf0","node":"SDFSphere3","output":"float"},{"index":1,"inputName":"sdf1","node":"SDFSphere4","output":"float"}],"connection_points":{"in":[{"name":"sdf0","type":"float"},{"name":"sdf1","type":"float"},{"name":"smoothFactor","type":"float"},{"name":"matBlendDist","type":"float"}],"out":[{"name":"union","type":"float"}]}},"SDFPlane1":{"type":"SDFPlane","params":{"center":[0,-0.2,0]}},"SDFUnion3":{"type":"SDFUnion","params":{"sdf0":{"type":"float","default_value":0,"options":{"spare":true,"editable":false,"computeOnDirty":true,"dependentOnFoundParam":false}},"sdf1":{"type":"float","default_value":0,"options":{"spare":true,"editable":false,"computeOnDirty":true,"dependentOnFoundParam":false}},"smoothFactor":{"type":"float","default_value":0,"options":{"spare":true,"editable":true,"computeOnDirty":true,"dependentOnFoundParam":false},"raw_input":0.31},"matBlendDist":{"type":"float","default_value":0,"options":{"spare":true,"editable":true,"computeOnDirty":true,"dependentOnFoundParam":false}}},"inputs":[{"index":0,"inputName":"sdf0","node":"SDFUnion2","output":"union"},{"index":1,"inputName":"sdf1","node":"SDFPlane1","output":"float"}],"connection_points":{"in":[{"name":"sdf0","type":"float"},{"name":"sdf1","type":"float"},{"name":"smoothFactor","type":"float"},{"name":"matBlendDist","type":"float"}],"out":[{"name":"union","type":"float"}]}},"grid1":{"type":"grid"},"checkers1":{"type":"checkers","params":{"uv":{"overriden_options":{}},"freq":{"overriden_options":{}},"freqMult":{"raw_input":1.8,"overriden_options":{}}},"inputs":[{"index":0,"inputName":"uv","node":"floatToVec2_1","output":"vec2"}]},"mix1":{"type":"mix","params":{"value0":{"type":"vector3","default_value":[0,0,0],"options":{"spare":true,"editable":false,"computeOnDirty":true,"dependentOnFoundParam":false}},"value1":{"type":"vector3","default_value":[0,0,0],"options":{"spare":true,"editable":false,"computeOnDirty":true,"dependentOnFoundParam":false},"overriden_options":{}},"blend":{"type":"float","default_value":0.5,"options":{"spare":true,"editable":false,"computeOnDirty":true,"dependentOnFoundParam":false}}},"inputs":[{"index":0,"inputName":"value0","node":"constant2","output":"val"},{"index":1,"inputName":"value1","node":"constant3","output":"val"},{"index":2,"inputName":"blend","node":"checkers1","output":"checker"}],"connection_points":{"in":[{"name":"value0","type":"vec3"},{"name":"value1","type":"vec3"},{"name":"blend","type":"float"}],"out":[{"name":"mix","type":"vec3"}]}},"constant2":{"type":"constant","params":{"type":4,"color":[0.04091519690055698,0.19806931954941637,0.5271151256969157],"asColor":1},"connection_points":{"in":[],"out":[{"name":"val","type":"vec3"}]}},"constant3":{"type":"constant","params":{"type":4,"color":[0.3049873140591091,0.4452011945063733,0.623960391667596],"asColor":true},"connection_points":{"in":[],"out":[{"name":"val","type":"vec3"}]}},"globals2":{"type":"globals"},"vec3ToFloat1":{"type":"vec3ToFloat","params":{"vec":{"overriden_options":{}}},"inputs":[{"index":0,"inputName":"vec","node":"globals2","output":"position"}]},"floatToVec2_1":{"type":"floatToVec2","params":{"x":{"overriden_options":{}},"y":{"overriden_options":{}}},"inputs":[{"index":0,"inputName":"x","node":"vec3ToFloat1","output":"x"},{"index":1,"inputName":"y","node":"vec3ToFloat1","output":"z"}]}},"persisted_config":{"material":{"metadata":{"version":4.6,"type":"Material","generator":"Material.toJSON"},"uuid":"/geo1/MAT/rayMarchingBuilder1-main","type":"ShaderMaterial","side":1,"transparent":true,"blendColor":0,"alphaTest":0.5,"forceSinglePass":true,"fog":false,"glslVersion":null,"uniforms":{"diffuse":{"type":"c","value":16777215},"opacity":{"value":1},"map":{"value":null},"mapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"alphaMap":{"value":null},"alphaMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"alphaTest":{"value":0},"envMap":{"value":null},"flipEnvMap":{"value":-1},"reflectivity":{"value":1},"ior":{"value":1.5},"refractionRatio":{"value":0.98},"aoMap":{"value":null},"aoMapIntensity":{"value":1},"aoMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"lightMap":{"value":null},"lightMapIntensity":{"value":1},"lightMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"emissiveMap":{"value":null},"emissiveMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"bumpMap":{"value":null},"bumpMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"bumpScale":{"value":1},"normalMap":{"value":null},"normalMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"normalScale":{"type":"v2","value":[1,1]},"displacementMap":{"value":null},"displacementMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"displacementScale":{"value":1},"displacementBias":{"value":0},"roughnessMap":{"value":null},"roughnessMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"metalnessMap":{"value":null},"metalnessMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"fogDensity":{"value":0.00025},"fogNear":{"value":1},"fogFar":{"value":2000},"fogColor":{"type":"c","value":16777215},"ambientLightColor":{"value":[0,0,0]},"lightProbe":{"value":[{"x":0,"y":0,"z":0},{"x":0,"y":0,"z":0},{"x":0,"y":0,"z":0},{"x":0,"y":0,"z":0},{"x":0,"y":0,"z":0},{"x":0,"y":0,"z":0},{"x":0,"y":0,"z":0},{"x":0,"y":0,"z":0},{"x":0,"y":0,"z":0}]},"directionalLights":{"value":[]},"directionalLightShadows":{"value":[]},"directionalShadowMap":{"value":[]},"directionalShadowMatrix":{"value":[]},"spotLights":{"value":[{"position":{"x":-1.2852502799192873,"y":1.1507848233748126,"z":1.4267067456548526},"direction":{"x":-0.3770858317507352,"y":0.19704278327897823,"z":0.9049753682009969},"color":16777215,"distance":10,"coneCos":0.7071067811865476,"penumbraCos":0.7604059656000309,"decay":0.1}]},"spotLightShadows":{"value":[{"shadowBias":0.0001,"shadowNormalBias":0,"shadowRadius":0,"shadowMapSize":{"x":1024,"y":1024}}]},"spotLightMap":{"value":[]},"spotShadowMap":{"value":[{"metadata":{"version":4.6,"type":"Texture","generator":"Texture.toJSON"},"uuid":"56085f82-7703-480c-978a-0582ef73ad79","name":"spotLight1.shadowMap","image":"84de04b9-f175-4938-a796-84924082b48a","mapping":300,"channel":0,"repeat":[1,1],"offset":[0,0],"center":[0,0],"rotation":0,"wrap":[1001,1001],"format":1023,"internalFormat":null,"type":1009,"colorSpace":"","minFilter":1003,"magFilter":1003,"anisotropy":1,"flipY":false,"generateMipmaps":false,"premultiplyAlpha":false,"unpackAlignment":4}]},"spotLightMatrix":{"value":[{"elements":[0.5000000000000001,0,0,0,-0.21288964578253625,0.23952388045047365,-0.4300800924899722,-0.4257792915650725,-0.4524135262330098,-0.6653031720155461,-0.913966719662646,-0.9048270524660196,1.6540227520477755,1.3373332836846683,3.24045000413692,3.308045504095551]}]},"pointLights":{"value":[]},"pointLightShadows":{"value":[]},"pointShadowMap":{"value":[]},"pointShadowMatrix":{"value":[]},"hemisphereLights":{"value":[{"direction":{"x":1.3877787807814457e-17,"y":0.9655392056456817,"z":0.26025764611458757},"skyColor":12566463,"groundColor":0}]},"rectAreaLights":{"value":[]},"ltc_1":{"value":null},"ltc_2":{"value":null},"emissive":{"type":"c","value":0},"roughness":{"value":1},"metalness":{"value":0},"envMapIntensity":{"value":1},"MAX_STEPS":{"value":100},"MAX_DIST":{"value":100},"SURF_DIST":{"value":0.001},"NORMALS_BIAS":{"value":0.01},"SHADOW_BIAS":{"value":0},"debugMinSteps":{"value":0},"debugMaxSteps":{"value":128},"debugMinDepth":{"value":0},"debugMaxDepth":{"value":128},"shadowDistanceMin":{"value":0},"shadowDistanceMax":{"value":100},"shadowDepthMin":{"value":0},"shadowDepthMax":{"value":100},"envMapRotationY":{"value":0},"spotLightsRayMarching":{"value":[{"penumbra":0,"shadowBiasAngle":0.01,"shadowBiasDistance":0.1}]},"directionalLightsRayMarching":{"value":[]},"pointLightsRayMarching":{"value":[]}},"defines":{"ENVMAP_TYPE_CUBE_UV":0,"CUBEUV_TEXEL_WIDTH":"0.1","CUBEUV_TEXEL_HEIGHT":"0.1","CUBEUV_MAX_MIP":"1.0","ROTATE_ENV_MAP_Y":0},"vertexShader":"precision highp float;\nprecision highp int;\n\nvarying vec3 vPw;\nvarying mat4 vModelMatrix;\nvarying mat4 vInverseModelMatrix;\nvarying mat4 VViewMatrix;\n\n#include <common>\n\n// // for depth material\n// varying vec2 vHighPrecisionZW;\n\nvoid main()\t{\n\n\tvModelMatrix = modelMatrix;\n\tvInverseModelMatrix = inverse(modelMatrix);\n\tVViewMatrix = viewMatrix;\n\tvPw = (modelMatrix * vec4( position, 1.0 )).xyz;\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n\t// vHighPrecisionZW = gl_Position.zw;\n}","fragmentShader":"precision highp float;\nprecision highp int;\n\n// --- applyMaterial constants definition\nuniform int MAX_STEPS;\nuniform float MAX_DIST;\nuniform float SURF_DIST;\nuniform float NORMALS_BIAS;\nuniform float SHADOW_BIAS;\n#define ZERO 0\nuniform float debugMinSteps;\nuniform float debugMaxSteps;\nuniform float debugMinDepth;\nuniform float debugMaxDepth;\n\n#include <common>\n#include <packing>\n#include <lightmap_pars_fragment>\n#include <bsdfs>\n#include <cube_uv_reflection_fragment>\n#include <lights_pars_begin>\n#include <lights_physical_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <fog_pars_fragment>\n\n#if defined( SHADOW_DISTANCE )\n\tuniform float shadowDistanceMin;\n\tuniform float shadowDistanceMax;\n#endif \n#if defined( SHADOW_DEPTH )\n\tuniform float shadowDepthMin;\n\tuniform float shadowDepthMax;\n#endif\n\n// varying vec2 vHighPrecisionZW;\n\nvarying vec3 vPw;\nvarying mat4 vModelMatrix;\nvarying mat4 vInverseModelMatrix;\nvarying mat4 VViewMatrix;\n\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform SpotLightRayMarching spotLightsRayMarching[ NUM_SPOT_LIGHTS ];\n\t#if NUM_SPOT_LIGHT_COORDS > 0\n\n\t\tuniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];\n\n\t#endif\n#endif\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform DirectionalLightRayMarching directionalLightsRayMarching[ NUM_DIR_LIGHTS ];\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\n\t#endif\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform PointLightRayMarching pointLightsRayMarching[ NUM_POINT_LIGHTS ];\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\n\t#endif\n#endif\n\n\nstruct SDFContext {\n\tfloat d;\n\tint stepsCount;\n\tint matId;\n\tint matId2;\n\tfloat matBlend;\n};\n\nSDFContext DefaultSDFContext(){\n\treturn SDFContext( 0., 0, 0, 0, 0. );\n}\nint DefaultSDFMaterial(){\n\treturn 0;\n}\n\n// start raymarching builder define code\n\n\n\n// /geo1/MAT/rayMarchingBuilder1/SDFSphere3\nfloat dot2( in vec2 v ) { return dot(v,v); }\nfloat dot2( in vec3 v ) { return dot(v,v); }\nfloat ndot( in vec2 a, in vec2 b ) { return a.x*b.x - a.y*b.y; }\n// https://iquilezles.org/articles/distfunctions/\n\n\n/*\n*\n* SDF PRIMITIVES\n*\n*/\nfloat sdSphere( vec3 p, float s )\n{\n\treturn length(p)-s;\n}\nfloat sdCutSphere( vec3 p, float r, float h )\n{\n\t// sampling independent computations (only depend on shape)\n\tfloat w = sqrt(r*r-h*h);\n\n\t// sampling dependant computations\n\tvec2 q = vec2( length(p.xz), p.y );\n\tfloat s = max( (h-r)*q.x*q.x+w*w*(h+r-2.0*q.y), h*q.x-w*q.y );\n\treturn (s<0.0) ? length(q)-r :\n\t\t\t\t(q.x<w) ? h - q.y :\n\t\t\t\t\tlength(q-vec2(w,h));\n}\nfloat sdCutHollowSphere( vec3 p, float r, float h, float t )\n{\n\t// sampling independent computations (only depend on shape)\n\tfloat w = sqrt(r*r-h*h);\n\t\n\t// sampling dependant computations\n\tvec2 q = vec2( length(p.xz), p.y );\n\treturn ((h*q.x<w*q.y) ? length(q-vec2(w,h)) : \n\t\t\t\t\t\t\tabs(length(q)-r) ) - t;\n}\n\nfloat sdBox( vec3 p, vec3 b )\n{\n\tvec3 q = abs(p) - b*0.5;\n\treturn length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0);\n}\nfloat sdRoundBox( vec3 p, vec3 b, float r )\n{\n\tvec3 q = abs(p) - b*0.5;\n\treturn length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0) - r;\n}\n\n\nfloat sdBoxFrame( vec3 p, vec3 b, float e )\n{\n\t\tp = abs(p )-b*0.5;\n\tvec3 q = abs(p+e)-e;\n\treturn min(min(\n\t\tlength(max(vec3(p.x,q.y,q.z),0.0))+min(max(p.x,max(q.y,q.z)),0.0),\n\t\tlength(max(vec3(q.x,p.y,q.z),0.0))+min(max(q.x,max(p.y,q.z)),0.0)),\n\t\tlength(max(vec3(q.x,q.y,p.z),0.0))+min(max(q.x,max(q.y,p.z)),0.0));\n}\nfloat sdCapsule( vec3 p, vec3 a, vec3 b, float r )\n{\n\tvec3 pa = p - a, ba = b - a;\n\tfloat h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n\treturn length( pa - ba*h ) - r;\n}\nfloat sdVerticalCapsule( vec3 p, float h, float r )\n{\n\tp.y -= clamp( p.y, 0.0, h );\n\treturn length( p ) - r;\n}\nfloat sdCone( in vec3 p, in vec2 c, float h )\n{\n\t// c is the sin/cos of the angle, h is height\n\t// Alternatively pass q instead of (c,h),\n\t// which is the point at the base in 2D\n\tvec2 q = h*vec2(c.x/c.y,-1.0);\n\n\tvec2 w = vec2( length(p.xz), p.y );\n\tvec2 a = w - q*clamp( dot(w,q)/dot(q,q), 0.0, 1.0 );\n\tvec2 b = w - q*vec2( clamp( w.x/q.x, 0.0, 1.0 ), 1.0 );\n\tfloat k = sign( q.y );\n\tfloat d = min(dot( a, a ),dot(b, b));\n\tfloat s = max( k*(w.x*q.y-w.y*q.x),k*(w.y-q.y) );\n\treturn sqrt(d)*sign(s);\n}\nfloat sdConeWrapped(vec3 pos, float angle, float height){\n\treturn sdCone(pos, vec2(sin(angle), cos(angle)), height);\n}\nfloat sdRoundCone( vec3 p, float r1, float r2, float h )\n{\n\tfloat b = (r1-r2)/h;\n\tfloat a = sqrt(1.0-b*b);\n\n\tvec2 q = vec2( length(p.xz), p.y );\n\tfloat k = dot(q,vec2(-b,a));\n\tif( k<0.0 ) return length(q) - r1;\n\tif( k>a*h ) return length(q-vec2(0.0,h)) - r2;\n\treturn dot(q, vec2(a,b) ) - r1;\n}\nfloat sdOctogonPrism( in vec3 p, in float r, float h )\n{\n\tconst vec3 k = vec3(-0.9238795325, // sqrt(2+sqrt(2))/2 \n\t\t\t\t\t\t0.3826834323, // sqrt(2-sqrt(2))/2\n\t\t\t\t\t\t0.4142135623 ); // sqrt(2)-1 \n\t// reflections\n\tp = abs(p);\n\tp.xy -= 2.0*min(dot(vec2( k.x,k.y),p.xy),0.0)*vec2( k.x,k.y);\n\tp.xy -= 2.0*min(dot(vec2(-k.x,k.y),p.xy),0.0)*vec2(-k.x,k.y);\n\t// polygon side\n\tp.xy -= vec2(clamp(p.x, -k.z*r, k.z*r), r);\n\tvec2 d = vec2( length(p.xy)*sign(p.y), p.z-h );\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdHexPrism( vec3 p, vec2 h )\n{\n\tconst vec3 k = vec3(-0.8660254, 0.5, 0.57735);\n\tp = abs(p);\n\tp.xy -= 2.0*min(dot(k.xy, p.xy), 0.0)*k.xy;\n\tvec2 d = vec2(\n\t\tlength(p.xy-vec2(clamp(p.x,-k.z*h.x,k.z*h.x), h.x))*sign(p.y-h.x),\n\t\tp.z-h.y );\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdHorseshoe( in vec3 p, in float angle, in float r, in float le, vec2 w )\n{\n\tvec2 c = vec2(cos(angle),sin(angle));\n\tp.x = abs(p.x);\n\tfloat l = length(p.xy);\n\tp.xy = mat2(-c.x, c.y, \n\t\t\tc.y, c.x)*p.xy;\n\tp.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x),\n\t\t\t\t(p.x>0.0)?p.y:l );\n\tp.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0);\n\t\n\tvec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z);\n\tvec2 d = abs(q) - w;\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdTriPrism( vec3 p, vec2 h )\n{\n\tvec3 q = abs(p);\n\treturn max(q.z-h.y,max(q.x*0.866025+p.y*0.5,-p.y)-h.x*0.5);\n}\nfloat sdPyramid( vec3 p, float h)\n{\n\tfloat m2 = h*h + 0.25;\n\n\tp.xz = abs(p.xz);\n\tp.xz = (p.z>p.x) ? p.zx : p.xz;\n\tp.xz -= 0.5;\n\n\tvec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y);\n\n\tfloat s = max(-q.x,0.0);\n\tfloat t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 );\n\n\tfloat a = m2*(q.x+s)*(q.x+s) + q.y*q.y;\n\tfloat b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t);\n\n\tfloat d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b);\n\n\treturn sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));\n}\n\nfloat sdPlane( vec3 p, vec3 n, float h )\n{\n\t// n must be normalized\n\treturn dot(p,n) + h;\n}\n\nfloat sdTorus( vec3 p, vec2 t )\n{\n\tvec2 q = vec2(length(p.xz)-t.x,p.y);\n\treturn length(q)-t.y;\n}\nfloat sdCappedTorus(in vec3 p, in float an, in float ra, in float rb)\n{\n\tvec2 sc = vec2(sin(an),cos(an));\n\tp.x = abs(p.x);\n\tfloat k = (sc.y*p.x>sc.x*p.z) ? dot(p.xz,sc) : length(p.xz);\n\treturn sqrt( dot(p,p) + ra*ra - 2.0*ra*k ) - rb;\n}\nfloat sdLink( vec3 p, float le, float r1, float r2 )\n{\n vec3 q = vec3( p.x, max(abs(p.y)-le,0.0), p.z );\n return length(vec2(length(q.xy)-r1,q.z)) - r2;\n}\n// c is the sin/cos of the desired cone angle\nfloat sdSolidAngle(vec3 pos, vec2 c, float radius)\n{\n\tvec2 p = vec2( length(pos.xz), pos.y );\n\tfloat l = length(p) - radius;\n\tfloat m = length(p - c*clamp(dot(p,c),0.0,radius) );\n\treturn max(l,m*sign(c.y*p.x-c.x*p.y));\n}\nfloat sdSolidAngleWrapped(vec3 pos, float angle, float radius){\n\treturn sdSolidAngle(pos, vec2(sin(angle), cos(angle)), radius);\n}\nfloat sdTube( vec3 p, float r )\n{\n\treturn length(p.xz)-r;\n}\nfloat sdTubeCapped( vec3 p, float h, float r )\n{\n\tvec2 d = abs(vec2(length(p.xz),p.y)) - vec2(r,h);\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdOctahedron( vec3 p, float s)\n{\n p = abs(p);\n float m = p.x+p.y+p.z-s;\n vec3 q;\n if( 3.0*p.x < m ) q = p.xyz;\n else if( 3.0*p.y < m ) q = p.yzx;\n else if( 3.0*p.z < m ) q = p.zxy;\n else return m*0.57735027;\n \n float k = clamp(0.5*(q.z-q.y+s),0.0,s); \n return length(vec3(q.x,q.y-s+k,q.z-k)); \n}\nfloat udTriangle( vec3 p, vec3 a, vec3 b, vec3 c, float thickness )\n{\n\tvec3 ba = b - a; vec3 pa = p - a;\n\tvec3 cb = c - b; vec3 pb = p - b;\n\tvec3 ac = a - c; vec3 pc = p - c;\n\tvec3 nor = cross( ba, ac );\n\n\treturn - thickness + sqrt(\n\t\t(sign(dot(cross(ba,nor),pa)) +\n\t\tsign(dot(cross(cb,nor),pb)) +\n\t\tsign(dot(cross(ac,nor),pc))<2.0)\n\t\t?\n\t\tmin( min(\n\t\tdot2(ba*clamp(dot(ba,pa)/dot2(ba),0.0,1.0)-pa),\n\t\tdot2(cb*clamp(dot(cb,pb)/dot2(cb),0.0,1.0)-pb) ),\n\t\tdot2(ac*clamp(dot(ac,pc)/dot2(ac),0.0,1.0)-pc) )\n\t\t:\n\t\tdot(nor,pa)*dot(nor,pa)/dot2(nor) );\n}\nfloat udQuad( vec3 p, vec3 a, vec3 b, vec3 c, vec3 d, float thickness )\n{\n\tvec3 ba = b - a; vec3 pa = p - a;\n\tvec3 cb = c - b; vec3 pb = p - b;\n\tvec3 dc = d - c; vec3 pc = p - c;\n\tvec3 ad = a - d; vec3 pd = p - d;\n\tvec3 nor = cross( ba, ad );\n\n\treturn - thickness + sqrt(\n\t\t(sign(dot(cross(ba,nor),pa)) +\n\t\tsign(dot(cross(cb,nor),pb)) +\n\t\tsign(dot(cross(dc,nor),pc)) +\n\t\tsign(dot(cross(ad,nor),pd))<3.0)\n\t\t?\n\t\tmin( min( min(\n\t\tdot2(ba*clamp(dot(ba,pa)/dot2(ba),0.0,1.0)-pa),\n\t\tdot2(cb*clamp(dot(cb,pb)/dot2(cb),0.0,1.0)-pb) ),\n\t\tdot2(dc*clamp(dot(dc,pc)/dot2(dc),0.0,1.0)-pc) ),\n\t\tdot2(ad*clamp(dot(ad,pd)/dot2(ad),0.0,1.0)-pd) )\n\t\t:\n\t\tdot(nor,pa)*dot(nor,pa)/dot2(nor) );\n}\n\n/*\n*\n* SDF OPERATIONS\n*\n*/\nfloat SDFUnion( float d1, float d2 ) { return min(d1,d2); }\nfloat SDFSubtract( float d1, float d2 ) { return max(-d1,d2); }\nfloat SDFIntersect( float d1, float d2 ) { return max(d1,d2); }\n\nfloat SDFSmoothUnion( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 + 0.5*(d2-d1)/k, 0.0, 1.0 );\n\treturn mix( d2, d1, h ) - k*h*(1.0-h);\n}\n\nfloat SDFSmoothSubtract( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 - 0.5*(d2+d1)/k, 0.0, 1.0 );\n\treturn mix( d2, -d1, h ) + k*h*(1.0-h);\n}\n\nfloat SDFSmoothIntersect( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 - 0.5*(d2-d1)/k, 0.0, 1.0 );\n\treturn mix( d2, d1, h ) + k*h*(1.0-h);\n}\n\nvec4 SDFElongateFast( in vec3 p, in vec3 h )\n{\n\treturn vec4( p-clamp(p,-h,h), 0.0 );\n}\nvec4 SDFElongateSlow( in vec3 p, in vec3 h )\n{\n\tvec3 q = abs(p)-h;\n\treturn vec4( max(q,0.0), min(max(q.x,max(q.y,q.z)),0.0) );\n}\n\nfloat SDFOnion( in float sdf, in float thickness )\n{\n\treturn abs(sdf)-thickness;\n}\n\n// /geo1/MAT/rayMarchingBuilder1/checkers1\n// https://iquilezles.org/articles/checkerfiltering/\nfloat checkers(vec2 p) {\n\tvec2 s = sign(fract(p*.5)-.5);\n\treturn .5 - .5*s.x*s.y;\n}\nfloat checkersGrad( in vec2 p, in vec2 ddx, in vec2 ddy )\n{\n // filter kernel\n vec2 w = max(abs(ddx), abs(ddy)) + 0.01;\n // analytical integral (box filter)\n vec2 i = 2.0*(abs(fract((p-0.5*w)/2.0)-0.5)-abs(fract((p+0.5*w)/2.0)-0.5))/w;\n // xor pattern\n return 0.5 - 0.5*i.x*i.y;\n}\n\n\n// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\nconst int _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1 = 1;\n\n\n// https://stackoverflow.com/questions/23793698/how-to-implement-slerp-in-glsl-hlsl\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t)\n// {\n// \tfloat dotp = dot(normalize(p0), normalize(p1));\n// \tif ((dotp > 0.9999) || (dotp < -0.9999))\n// \t{\n// \t\tif (t<=0.5)\n// \t\t\treturn p0;\n// \t\treturn p1;\n// \t}\n// \tfloat theta = acos(dotp);\n// \tvec4 P = ((p0*sin((1.0-t)*theta) + p1*sin(t*theta)) / sin(theta));\n// \tP.w = 1.0;\n// \treturn P;\n// }\n\n// https://devcry.heiho.net/html/2017/20170521-slerp.html\n// float lerp(float a, float b, float t) {\n// \treturn (1.0 - t) * a + t * b;\n// }\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t){\n// \tvec4 qb = p1;\n\n// \t// cos(a) = dot product\n// \tfloat cos_a = p0.x * qb.x + p0.y * qb.y + p0.z * qb.z + p0.w * qb.w;\n// \tif (cos_a < 0.0f) {\n// \t\tcos_a = -cos_a;\n// \t\tqb = -qb;\n// \t}\n\n// \t// close to zero, cos(a) ~= 1\n// \t// do linear interpolation\n// \tif (cos_a > 0.999) {\n// \t\treturn vec4(\n// \t\t\tlerp(p0.x, qb.x, t),\n// \t\t\tlerp(p0.y, qb.y, t),\n// \t\t\tlerp(p0.z, qb.z, t),\n// \t\t\tlerp(p0.w, qb.w, t)\n// \t\t);\n// \t}\n\n// \tfloat alpha = acos(cos_a);\n// \treturn (p0 * sin(1.0 - t) + p1 * sin(t * alpha)) / sin(alpha);\n// }\n\n// https://stackoverflow.com/questions/62943083/interpolate-between-two-quaternions-the-long-way\nvec4 quatSlerp(vec4 q1, vec4 q2, float t){\n\tfloat angle = acos(dot(q1, q2));\n\tfloat denom = sin(angle);\n\t//check if denom is zero\n\treturn (q1*sin((1.0-t)*angle)+q2*sin(t*angle))/denom;\n}\n// TO CHECK:\n// this page https://www.reddit.com/r/opengl/comments/704la7/glsl_quaternion_library/\n// has a link to a potentially nice pdf:\n// http://web.mit.edu/2.998/www/QuaternionReport1.pdf\n\n// https://github.com/mattatz/ShibuyaCrowd/blob/master/source/shaders/common/quaternion.glsl\nvec4 quatMult(vec4 q1, vec4 q2)\n{\n\treturn vec4(\n\tq1.w * q2.x + q1.x * q2.w + q1.z * q2.y - q1.y * q2.z,\n\tq1.w * q2.y + q1.y * q2.w + q1.x * q2.z - q1.z * q2.x,\n\tq1.w * q2.z + q1.z * q2.w + q1.y * q2.x - q1.x * q2.y,\n\tq1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z\n\t);\n}\n// http://glmatrix.net/docs/quat.js.html#line97\n// let ax = a[0], ay = a[1], az = a[2], aw = a[3];\n\n// let bx = b[0], by = b[1], bz = b[2], bw = b[3];\n\n// out[0] = ax * bw + aw * bx + ay * bz - az * by;\n\n// out[1] = ay * bw + aw * by + az * bx - ax * bz;\n\n// out[2] = az * bw + aw * bz + ax * by - ay * bx;\n\n// out[3] = aw * bw - ax * bx - ay * by - az * bz;\n\n// return out\n\n\n\n// http://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/\nmat4 rotationMatrix(vec3 axis, float angle)\n{\n\taxis = normalize(axis);\n\tfloat s = sin(angle);\n\tfloat c = cos(angle);\n\tfloat oc = 1.0 - c;\n\n \treturn mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 0.0, 0.0, 0.0, 1.0);\n}\n\n// https://www.geeks3d.com/20141201/how-to-rotate-a-vertex-by-a-quaternion-in-glsl/\nvec4 quatFromAxisAngle(vec3 axis, float angle)\n{\n\tvec4 qr;\n\tfloat half_angle = (angle * 0.5); // * 3.14159 / 180.0;\n\tfloat sin_half_angle = sin(half_angle);\n\tqr.x = axis.x * sin_half_angle;\n\tqr.y = axis.y * sin_half_angle;\n\tqr.z = axis.z * sin_half_angle;\n\tqr.w = cos(half_angle);\n\treturn qr;\n}\nvec3 rotateWithAxisAngle(vec3 position, vec3 axis, float angle)\n{\n\tvec4 q = quatFromAxisAngle(axis, angle);\n\tvec3 v = position.xyz;\n\treturn v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);\n}\n// vec3 applyQuaternionToVector( vec4 q, vec3 v ){\n// \treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n// }\nvec3 rotateWithQuat( vec3 v, vec4 q )\n{\n\t// vec4 qv = multQuat( quat, vec4(vec, 0.0) );\n\t// return multQuat( qv, vec4(-quat.x, -quat.y, -quat.z, quat.w) ).xyz;\n\treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n}\n// https://github.com/glslify/glsl-look-at/blob/gh-pages/index.glsl\n// mat3 rotation_matrix(vec3 origin, vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target - origin);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n// mat3 rotation_matrix(vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n\nfloat vectorAngle(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 c1 = cross(start, dest);\n\t// We use the dot product of the cross with the Y axis.\n\t// This is a little arbitrary, but can still give a good sense of direction\n\tvec3 y_axis = vec3(0.0, 1.0, 0.0);\n\tfloat d1 = dot(c1, y_axis);\n\tfloat angle = acos(cosTheta) * sign(d1);\n\treturn angle;\n}\n\n// http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/#i-need-an-equivalent-of-glulookat-how-do-i-orient-an-object-towards-a-point-\nvec4 vectorAlign(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 axis;\n\n\t// if (cosTheta < -1 + 0.001f){\n\t// \t// special case when vectors in opposite directions:\n\t// \t// there is no ideal rotation axis\n\t// \t// So guess one; any will do as long as it's perpendicular to start\n\t// \taxis = cross(vec3(0.0f, 0.0f, 1.0f), start);\n\t// \tif (length2(axis) < 0.01 ) // bad luck, they were parallel, try again!\n\t// \t\taxis = cross(vec3(1.0f, 0.0f, 0.0f), start);\n\n\t// \taxis = normalize(axis);\n\t// \treturn gtx::quaternion::angleAxis(glm::radians(180.0f), axis);\n\t// }\n\tif(cosTheta > (1.0 - 0.0001) || cosTheta < (-1.0 + 0.0001) ){\n\t\taxis = normalize(cross(start, vec3(0.0, 1.0, 0.0)));\n\t\tif (length(axis) < 0.001 ){ // bad luck, they were parallel, try again!\n\t\t\taxis = normalize(cross(start, vec3(1.0, 0.0, 0.0)));\n\t\t}\n\t} else {\n\t\taxis = normalize(cross(start, dest));\n\t}\n\n\tfloat angle = acos(cosTheta);\n\n\treturn quatFromAxisAngle(axis, angle);\n}\nvec4 vectorAlignWithUp(vec3 start, vec3 dest, vec3 up){\n\tvec4 rot1 = vectorAlign(start, dest);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\t// vec3 right = normalize(cross(dest, up));\n\t// up = normalize(cross(right, dest));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(vec3(0.0, 1.0, 0.0), rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(up, newUp);\n\n\t// return rot1;\n\treturn rot2;\n\t// return multQuat(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\n// https://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\nfloat quatToAngle(vec4 q){\n\treturn 2.0 * acos(q.w);\n}\nvec3 quatToAxis(vec4 q){\n\treturn vec3(\n\t\tq.x / sqrt(1.0-q.w*q.w),\n\t\tq.y / sqrt(1.0-q.w*q.w),\n\t\tq.z / sqrt(1.0-q.w*q.w)\n\t);\n}\n\nvec4 align(vec3 dir, vec3 up){\n\tvec3 start_dir = vec3(0.0, 0.0, 1.0);\n\tvec3 start_up = vec3(0.0, 1.0, 0.0);\n\tvec4 rot1 = vectorAlign(start_dir, dir);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\tvec3 right = normalize(cross(dir, up));\n\tif(length(right)<0.001){\n\t\tright = vec3(1.0, 0.0, 0.0);\n\t}\n\tup = normalize(cross(right, dir));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(start_up, rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(normalize(newUp), up);\n\n\t// return rot1;\n\treturn quatMult(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\nstruct EnvMapProps {\n\tvec3 tint;\n\tfloat intensity;\n\tfloat roughness;\n\tfloat fresnel;\n\tfloat fresnelPower;\n};\nuniform sampler2D envMap;\nuniform float envMapIntensity;\nuniform float roughness;\n#ifdef ROTATE_ENV_MAP_Y\n\tuniform float envMapRotationY;\n#endif\nvec3 envMapSample(vec3 rayDir, float envMapRoughness){\n\t// http://www.pocketgl.com/reflections/\n\tvec3 env = vec3(0.);\n\t// vec2 uv = vec2( atan( -rayDir.z, -rayDir.x ) * RECIPROCAL_PI2 + 0.5, rayDir.y * 0.5 + 0.5 );\n\t// vec3 env = texture2D(map, uv).rgb;\n\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t#ifdef ROTATE_ENV_MAP_Y\n\t\t\trayDir = rotateWithAxisAngle(rayDir, vec3(0.,1.,0.), envMapRotationY);\n\t\t#endif\n\t\tenv = textureCubeUV(envMap, rayDir, envMapRoughness * roughness).rgb;\n\t#endif\n\treturn env;\n}\nvec3 envMapSampleWithFresnel(vec3 rayDir, EnvMapProps envMapProps, vec3 n, vec3 cameraPosition){\n\t// http://www.pocketgl.com/reflections/\n\tvec3 env = envMapSample(rayDir, envMapProps.roughness);\n\tfloat fresnel = pow(1.-dot(normalize(cameraPosition), n), envMapProps.fresnelPower);\n\tfloat fresnelFactor = (1.-envMapProps.fresnel) + envMapProps.fresnel*fresnel;\n\treturn env * envMapIntensity * envMapProps.tint * envMapProps.intensity * fresnelFactor;\n}\n\n\n\n\n\n\nSDFContext GetDist(vec3 p) {\n\tSDFContext sdfContext = SDFContext(0., 0, 0, 0, 0.);\n\n\t// start GetDist builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/SDFSphere3\n\tfloat v_POLY_SDFSphere3_float = sdSphere(p - vec3(-0.25, 0.0, 0.0), 0.2);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFSphere4\n\tfloat v_POLY_SDFSphere4_float = sdSphere(p - vec3(0.25, 0.0, 0.0), 0.2);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFPlane1\n\tfloat v_POLY_SDFPlane1_float = sdPlane(p-vec3(0.0, -0.2, 0.0), vec3(0.0, 1.0, 0.0), 0.0);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFUnion2\n\tfloat v_POLY_SDFUnion2_union = SDFSmoothUnion(v_POLY_SDFSphere3_float, v_POLY_SDFSphere4_float, 0.31);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFUnion3\n\tfloat v_POLY_SDFUnion3_union = SDFSmoothUnion(v_POLY_SDFUnion2_union, v_POLY_SDFPlane1_float, 0.31);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFContext1\n\tSDFContext v_POLY_SDFContext1_SDFContext = SDFContext(v_POLY_SDFUnion3_union, 0, _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1, _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1, 0.);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/output1\n\tsdfContext = v_POLY_SDFContext1_SDFContext;\n\n\n\n\t\n\n\treturn sdfContext;\n}\n\nSDFContext RayMarch(vec3 ro, vec3 rd, float side) {\n\tSDFContext dO = SDFContext(0.,0,0,0,0.);\n\n\t#pragma unroll_loop_start\n\tfor(int i=0; i<MAX_STEPS; i++) {\n\t\tvec3 p = ro + rd*dO.d;\n\t\tSDFContext sdfContext = GetDist(p);\n\t\tdO.d += sdfContext.d * side;\n\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\tdO.stepsCount += 1;\n\t\t#endif\n\t\tdO.matId = sdfContext.matId;\n\t\tdO.matId2 = sdfContext.matId2;\n\t\tdO.matBlend = sdfContext.matBlend;\n\t\tif(dO.d>MAX_DIST || abs(sdfContext.d)<SURF_DIST) break;\n\t}\n\t#pragma unroll_loop_end\n\n\treturn dO;\n}\n\nvec3 GetNormal(vec3 p) {\n\tSDFContext sdfContext = GetDist(p);\n\tvec2 e = vec2(NORMALS_BIAS, 0);\n\n\tvec3 n = sdfContext.d - vec3(\n\t\tGetDist(p-e.xyy).d,\n\t\tGetDist(p-e.yxy).d,\n\t\tGetDist(p-e.yyx).d);\n\n\treturn normalize(n);\n}\n// https://iquilezles.org/articles/rmshadows\nfloat calcSoftshadow( in vec3 ro, in vec3 rd, float mint, float maxt, float k, inout SDFContext sdfContext )\n{\n\tfloat res = 1.0;\n\tfloat ph = 1e20;\n\tfor( float t=mint; t<maxt; )\n\t{\n\t\tfloat h = GetDist(ro + rd*t).d;\n\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\tsdfContext.stepsCount += 1;\n\t\t#endif\n\t\tif( h<SURF_DIST )\n\t\t\treturn 0.0;\n\t\tfloat y = h*h/(2.0*ph);\n\t\tfloat d = sqrt(h*h-y*y);\n\t\tres = min( res, k*d/max(0.0,t-y) );\n\t\tph = h;\n\t\tt += h;\n\t}\n\treturn res;\n}\n\nvec3 GetLight(vec3 _p, vec3 _n, inout SDFContext sdfContext) {\n\tvec3 dif = vec3(0.,0.,0.);\n\t// GeometricContext geometry;\n\t// geometry.position = _p;\n\t// geometry.normal = _n;\n\t// geometry.viewDir = rayDir;\n\n\t// vec4 mvPosition = vec4( p, 1.0 );\n\t// mvPosition = modelViewMatrix * mvPosition;\n\t// vec3 vViewPosition = - mvPosition.xyz;\n\tvec3 pWorld = ( vModelMatrix * vec4( _p, 1.0 )).xyz;\n\tvec3 nWorld = transformDirection(_n, vModelMatrix);\n\t// geometry.position = (VViewMatrix * vec4( _p, 1.0 )).xyz;\n\tvec3 geometryPosition = (VViewMatrix * vec4(pWorld, 1.0 )).xyz;\n\t// geometry.normal = transformDirection(_n, VViewMatrix);\n\t// geometry.normal = inverseTransformDirection(transformDirection(_n, VViewMatrix), vInverseModelMatrix);\n\tvec3 geometryNormal = transformDirection(nWorld, VViewMatrix);\n\t\n\n\t#if NUM_SPOT_LIGHTS > 0 || NUM_DIR_LIGHTS > 0 || NUM_HEMI_LIGHTS > 0 || NUM_POINT_LIGHTS > 0 || NUM_RECT_AREA_LIGHTS > 0\n\n\t\tIncidentLight directLight;\n\t\tReflectedLight reflectedLight;\n\t\tvec3 lightPos, lightDir, worldLightDir, objectSpaceLightDir, lighDif, directDiffuse;\n\t\tfloat dotNL, lightDistance;\n\t\t#if NUM_SPOT_LIGHTS > 0\n\t\t\tSpotLightRayMarching spotLightRayMarching;\n\t\t\tSpotLight spotLight;\n\t\t\tfloat spotLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\t\t\t\tSpotLightShadow spotLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\t\t\tspotLightRayMarching = spotLightsRayMarching[ i ];\n\t\t\t\tspotLight = spotLights[ i ];\n\t\t\t\tgetSpotLightInfo( spotLight, geometryPosition, directLight );\n\n\t\t\t\t// #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t\t\t// \tspotLightShadow = spotLightShadows[ i ];\n\t\t\t\t// \tvec4 spotLightShadowCoord = spotLightMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t// \tdirectLight.color *= (directLight.visible && receiveShadow) ? getShadow(\n\t\t\t\t// \t\tspotShadowMap[ i ],\n\t\t\t\t// \t\tspotLightShadow.shadowMapSize,\n\t\t\t\t// \t\tspotLightShadow.shadowBias,\n\t\t\t\t// \t\tspotLightShadow.shadowRadius,\n\t\t\t\t// \t\tspotLightShadowCoord\n\t\t\t\t// \t) : 1.0;\n\t\t\t\t// #endif\n\n\t\t\t\tlightPos = spotLight.position;\n\t\t\t\tlightDir = normalize(lightPos-geometryPosition);\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tlightDistance = distance(geometryPosition,lightPos);\n\t\t\t\tspotLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < spotLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t: calcSoftshadow(\n\t\t\t\t\t\t_p,\n\t\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\t\tspotLightRayMarching.shadowBiasDistance,\n\t\t\t\t\t\tdistance(geometryPosition,lightPos),\n\t\t\t\t\t\t1./max(spotLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\t\tsdfContext\n\t\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * spotLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\t\t#if NUM_DIR_LIGHTS > 0\n\t\t\tDirectionalLightRayMarching directionalLightRayMarching;\n\t\t\tDirectionalLight directionalLight;\n\t\t\tfloat dirLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\t\t\t\tDirectionalLightShadow directionalLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\t\t\tdirectionalLightRayMarching = directionalLightsRayMarching[ i ];\n\t\t\t\tdirectionalLight = directionalLights[ i ];\n\t\t\t\t\n\t\t\t\tgetDirectionalLightInfo( directionalLight, directLight );\n\n\t\t\t\t// #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\t\t\t// \tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\t\t\t// \tvec4 dirLightShadowCoord = directionalShadowMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t// \tdirectLight.color *= (directLight.visible && receiveShadow) ? getShadow(\n\t\t\t\t// \t\tdirectionalShadowMap[ i ],\n\t\t\t\t// \t\tdirectionalLightShadow.shadowMapSize,\n\t\t\t\t// \t\tdirectionalLightShadow.shadowBias,\n\t\t\t\t// \t\tdirectionalLightShadow.shadowRadius,\n\t\t\t\t// \t\tdirLightShadowCoord\n\t\t\t\t// \t) : 1.0;\n\t\t\t\t// #endif\n\n\t\t\t\tlightDir = directionalLight.direction;\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tdirLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < directionalLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t:\n\t\t\t\t\tcalcSoftshadow(\n\t\t\t\t\t\t_p,\n\t\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\t\tdirectionalLightRayMarching.shadowBiasDistance,\n\t\t\t\t\t\tMAX_DIST,//distance(geometryPosition,lightPos),\n\t\t\t\t\t\t1./max(directionalLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\t\tsdfContext\n\t\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\t// lighDif = directLight.color * dotNL * dirLightSdfShadow;\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * dirLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\n\t\t#if ( NUM_HEMI_LIGHTS > 0 )\n\n\t\t\t#pragma unroll_loop_start\n\t\t\tHemisphereLight hemiLight;\n\t\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\t\themiLight = hemisphereLights[ i ];\n\t\t\t\tdif += getHemisphereLightIrradiance( hemiLight, geometryNormal ) * BRDF_Lambert( vec3(1.) );\n\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\n\t\t#endif\n\n\t\t#if NUM_POINT_LIGHTS > 0\n\t\t\tPointLightRayMarching pointLightRayMarching;\n\t\t\tPointLight pointLight;\n\t\t\tfloat pointLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\t\t\t\tPointLightShadow pointLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\t\t\tpointLightRayMarching = pointLightsRayMarching[ i ];\n\t\t\t\tpointLight = pointLights[ i ];\n\t\t\t\tgetPointLightInfo( pointLight, geometryPosition, directLight );\n\n\n\t\t\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\t\t\t\tpointLightShadow = pointLightShadows[ i ];\n\t\t\t\t\tvec4 pointLightShadowCoord = pointShadowMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t\tdirectLight.color *= (directLight.visible && receiveShadow) ? getPointShadow(\n\t\t\t\t\t\tpointShadowMap[ i ],\n\t\t\t\t\t\tpointLightShadow.shadowMapSize,\n\t\t\t\t\t\tpointLightShadow.shadowBias,\n\t\t\t\t\t\tpointLightShadow.shadowRadius,\n\t\t\t\t\t\tpointLightShadowCoord,\n\t\t\t\t\t\tpointLightShadow.shadowCameraNear,\n\t\t\t\t\t\tpointLightShadow.shadowCameraFar\n\t\t\t\t\t) : 1.0;\n\t\t\t\t#endif\n\n\t\t\t\tlightPos = pointLight.position;\n\t\t\t\tlightDir = normalize(lightPos-geometryPosition);\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tpointLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < pointLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t:\n\t\t\t\t\tcalcSoftshadow(\n\t\t\t\t\t_p,\n\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\tpointLightRayMarching.shadowBiasDistance,\n\t\t\t\t\tdistance(geometryPosition,lightPos),\n\t\t\t\t\t1./max(pointLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\tsdfContext\n\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * pointLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\n\t\t#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\n\t\t\tRectAreaLight rectAreaLight;\n\t\t\t// AreaLightRayMarching areaLightRayMarching;\n\t\t\tPhysicalMaterial material;\n\t\t\tmaterial.roughness = 1.;\n\t\t\tmaterial.specularColor = vec3(1.);\n\t\t\tmaterial.diffuseColor = vec3(1.);\n\n\t\t\tvec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( cameraPosition - geometryPosition );\n\t\t\tvec3 geometryClearcoatNormal = geometryNormal;\n\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\t\t\t// areaLightRayMarching = areaLightsRayMarching[ i ];\n\t\t\t\trectAreaLight = rectAreaLights[ i ];\n\t\t\t\t// rectAreaLight.position = areaLightRayMarching.worldPos;\n\n\t\t\t\tRE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t\tdif += reflectedLight.directDiffuse;\n\n\t\t#endif\n\t#endif\n\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\n\t#if defined( USE_LIGHT_PROBES )\n\n\t\tirradiance += getLightProbeIrradiance( lightProbe, geometryNormal );\n\n\t#endif\n\n\tdif += irradiance;\n\n\treturn dif;\n}\n\n\n\n\nvec3 applyMaterialWithoutRefraction(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(1.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n\nvec3 applyMaterialWithoutReflection(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(1.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n#ifdef RAYMARCHED_REFLECTIONS\nvec3 GetReflection(vec3 p, vec3 n, vec3 rayDir, float biasMult, float roughness, int reflectionDepth, inout SDFContext sdfContextMain){\n\tbool hitReflection = true;\n\tvec3 reflectedColor = vec3(0.);\n\t#pragma unroll_loop_start\n\tfor(int i=0; i < reflectionDepth; i++) {\n\t\tif(hitReflection){\n\t\t\trayDir = reflect(rayDir, n);\n\t\t\tp += n*SURF_DIST*biasMult;\n\t\t\tSDFContext sdfContext = RayMarch(p, rayDir, 1.);\n\t\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\t\tsdfContextMain.stepsCount += sdfContext.stepsCount;\n\t\t\t#endif\n\t\t\tif( sdfContext.d >= MAX_DIST){\n\t\t\t\thitReflection = false;\n\t\t\t\treflectedColor = envMapSample(rayDir, roughness);\n\t\t\t}\n\t\t\tif(hitReflection){\n\t\t\t\tp += rayDir * sdfContext.d;\n\t\t\t\tn = GetNormal(p);\n\t\t\t\tvec3 matCol = applyMaterialWithoutReflection(p, n, rayDir, sdfContext.matId, sdfContextMain);\n\t\t\t\treflectedColor += matCol;\n\t\t\t}\n\t\t}\n\t}\n\t#pragma unroll_loop_end\n\treturn reflectedColor;\n}\n#endif\n\n#ifdef RAYMARCHED_REFRACTIONS\n// xyz for color, w for distanceInsideMedium\nvec4 GetRefractedData(vec3 p, vec3 n, vec3 rayDir, float ior, float biasMult, float roughness, float refractionMaxDist, int refractionDepth, inout SDFContext sdfContextMain){\n\tbool hitRefraction = true;\n\tbool changeSide = true;\n\t#ifdef RAYMARCHED_REFRACTIONS_START_OUTSIDE_MEDIUM\n\tfloat side = -1.;\n\t#else\n\tfloat side = 1.;\n\t#endif\n\tfloat iorInverted = 1. / ior;\n\tvec3 refractedColor = vec3(0.);\n\tfloat distanceInsideMedium=0.;\n\tfloat totalRefractedDistance=0.;\n\n\t#pragma unroll_loop_start\n\tfor(int i=0; i < refractionDepth; i++) {\n\t\tif(hitRefraction){\n\t\t\tfloat currentIor = side<0. ? iorInverted : ior;\n\t\t\tvec3 rayDirPreRefract = rayDir;\n\t\t\trayDir = refract(rayDir, n, currentIor);\n\t\t\tchangeSide = dot(rayDir, rayDir)!=0.;\n\t\t\tif(changeSide == true) {\n\t\t\t\tp -= n*SURF_DIST*(2.+biasMult);\n\t\t\t} else {\n\t\t\t\tp += n*SURF_DIST*( biasMult);\n\t\t\t\trayDir = reflect(rayDirPreRefract, n);\n\t\t\t}\n\t\t\tSDFContext sdfContext = RayMarch(p, rayDir, side);\n\t\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\t\tsdfContextMain.stepsCount += sdfContext.stepsCount;\n\t\t\t#endif\n\t\t\ttotalRefractedDistance += sdfContext.d;\n\t\t\tif( abs(sdfContext.d) >= MAX_DIST || totalRefractedDistance > refractionMaxDist ){\n\t\t\t\thitRefraction = false;\n\t\t\t\trefractedColor = envMapSample(rayDir, roughness);\n\t\t\t}\n\t\t\tif(hitRefraction){\n\t\t\t\tp += rayDir * sdfContext.d;\n\t\t\t\tn = GetNormal(p) * side;\n\t\t\t\tvec3 matCol = applyMaterialWithoutRefraction(p, n, rayDir, sdfContext.matId, sdfContextMain);\n\t\t\t\trefractedColor = matCol;\n\n\t\t\t\t// same as: side < 0. ? abs(sdfContext.d) : 0.;\n\t\t\t\tdistanceInsideMedium += (side-1.)*-0.5*abs(sdfContext.d);\n\t\t\t\tif( changeSide ){\n\t\t\t\t\tside *= -1.;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#ifdef RAYMARCHED_REFRACTIONS_SAMPLE_ENV_MAP_ON_LAST\n\t\tif(i == refractionDepth-1){\n\t\t\trefractedColor = envMapSample(rayDir, roughness);\n\t\t}\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n\treturn vec4(refractedColor, distanceInsideMedium);\n}\nfloat refractionTint(float baseValue, float tint, float distanceInsideMedium, float absorption){\n\tfloat tintNegated = baseValue-tint;\n\tfloat t = tintNegated*( distanceInsideMedium*absorption );\n\treturn max(baseValue-t, 0.);\n}\nfloat applyRefractionAbsorption(float refractedDataColor, float baseValue, float tint, float distanceInsideMedium, float absorption){\n\treturn refractedDataColor*refractionTint(baseValue, tint, distanceInsideMedium, absorption);\n}\nvec3 applyRefractionAbsorption(vec3 refractedDataColor, vec3 baseValue, vec3 tint, float distanceInsideMedium, float absorption){\n\treturn vec3(\n\t\trefractedDataColor.r * refractionTint(baseValue.r, tint.r, distanceInsideMedium, absorption),\n\t\trefractedDataColor.g * refractionTint(baseValue.g, tint.g, distanceInsideMedium, absorption),\n\t\trefractedDataColor.b * refractionTint(baseValue.b, tint.b, distanceInsideMedium, absorption)\n\t);\n}\n\n#endif\n\nvec3 applyMaterial(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(0.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n\n\n\n\nvec4 applyShading(vec3 rayOrigin, vec3 rayDir, inout SDFContext sdfContext){\n\tvec3 p = rayOrigin + rayDir * sdfContext.d;\n\tvec3 n = GetNormal(p);\n\t\n\tvec3 col = applyMaterial(p, n, rayDir, sdfContext.matId, sdfContext);\n\tif(sdfContext.matBlend > 0.) {\n\t\t// blend material colors if needed\n\t\tvec3 col2 = applyMaterial(p, n, rayDir, sdfContext.matId2, sdfContext);\n\t\tcol = (1. - sdfContext.matBlend)*col + sdfContext.matBlend*col2;\n\t}\n\t\t\n\t// gamma\n\t//col = pow( col, vec3(0.4545) ); // this gamma leads to a different look than standard materials\n\treturn vec4(col, 1.);\n}\n\nvoid main()\t{\n\n\tvec3 rayDir = normalize(vPw - cameraPosition);\n\trayDir = transformDirection(rayDir, vInverseModelMatrix);\n\tvec3 rayOrigin = (vInverseModelMatrix * vec4( cameraPosition, 1.0 )).xyz;\n\n\tSDFContext sdfContext = RayMarch(rayOrigin, rayDir, 1.);\n\n\t#if defined( DEBUG_DEPTH )\n\t\tfloat normalizedDepth = 1.-(sdfContext.d - debugMinDepth ) / ( debugMaxDepth - debugMinDepth );\n\t\tnormalizedDepth = saturate(normalizedDepth); // clamp to [0,1]\n\t\tgl_FragColor = vec4(normalizedDepth);\n\t\treturn;\n\t#endif\n\t#if defined( SHADOW_DEPTH )\n\t\tfloat normalizedDepth = 1.-(sdfContext.d - debugMinDepth ) / ( debugMaxDepth - debugMinDepth );\n\t\t// float fragCoordZ = sdfContext.d / vHighPrecisionZW[1];\n\t\tfloat compoundedDepth = 0.5 * (normalizedDepth) + 0.5;\n\t\tfloat alpha = sdfContext.d < MAX_DIST ? 0.:1.;\n\t\tgl_FragColor = vec4( vec3(compoundedDepth), alpha );\n\t\t// normalizedDepth = 0.5*normalizedDepth+0.5;\n\t\t// gl_FragColor = packDepthToRGBA( normalizedDepth );\n\t\t// gl_FragColor = vec4(0.);\n\t\treturn;\n\t#endif\n\t#if defined( SHADOW_DISTANCE )\n\t\tfloat normalizedDepth = (sdfContext.d - shadowDistanceMin ) / ( shadowDistanceMax - shadowDistanceMin );\n\t\tnormalizedDepth = saturate(normalizedDepth); // clamp to [0,1]\n\t\tgl_FragColor = packDepthToRGBA( normalizedDepth );\n\t\treturn;\n\t#endif\n\n\tif( sdfContext.d < MAX_DIST ){\n\t\tgl_FragColor = applyShading(rayOrigin, rayDir, sdfContext);\n\t\t#if defined( TONE_MAPPING )\n\t\t\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n\t\t#endif\n\t\tgl_FragColor = linearToOutputTexel( gl_FragColor );\n\n\t\t#ifdef USE_FOG\n\t\t\tfloat vFogDepth = sdfContext.d;\n\t\t\t#ifdef FOG_EXP2\n\t\t\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );\n\t\t\t#else\n\t\t\t\tfloat fogFactor = smoothstep( fogNear, fogFar, vFogDepth );\n\t\t\t#endif\n\t\t\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n\t\t#endif\n\t\t#include <premultiplied_alpha_fragment>\n\t\t#include <dithering_fragment>\n\t} else {\n\t\tgl_FragColor = vec4(0.);\n\t}\n\n\t#if defined( DEBUG_STEPS_COUNT )\n\t\tfloat normalizedStepsCount = (float(sdfContext.stepsCount) - debugMinSteps ) / ( debugMaxSteps - debugMinSteps );\n\t\tgl_FragColor = vec4(normalizedStepsCount, 1.-normalizedStepsCount, 0., 1.);\n\t\treturn;\n\t#endif\n\t\n}","lights":true,"clipping":false},"onBeforeCompileDataJSONWithoutShaders":{"paramConfigs":[],"timeDependent":false,"resolutionDependent":false,"raymarchingLightsWorldCoordsDependent":true},"customMaterials":{"customDepthMaterial":{"material":{"metadata":{"version":4.6,"type":"Material","generator":"Material.toJSON"},"uuid":"/geo1/MAT/rayMarchingBuilder1-customDepthMaterial","type":"ShaderMaterial","name":"customDepthMaterial","blendColor":0,"alphaTest":0.5,"forceSinglePass":true,"fog":false,"glslVersion":null,"uniforms":{"diffuse":{"type":"c","value":16777215},"opacity":{"value":1},"map":{"value":null},"mapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"alphaMap":{"value":null},"alphaMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"alphaTest":{"value":0},"envMap":{"value":null},"flipEnvMap":{"value":-1},"reflectivity":{"value":1},"ior":{"value":1.5},"refractionRatio":{"value":0.98},"aoMap":{"value":null},"aoMapIntensity":{"value":1},"aoMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"lightMap":{"value":null},"lightMapIntensity":{"value":1},"lightMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"emissiveMap":{"value":null},"emissiveMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"bumpMap":{"value":null},"bumpMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"bumpScale":{"value":1},"normalMap":{"value":null},"normalMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"normalScale":{"type":"v2","value":[1,1]},"displacementMap":{"value":null},"displacementMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"displacementScale":{"value":1},"displacementBias":{"value":0},"roughnessMap":{"value":null},"roughnessMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"metalnessMap":{"value":null},"metalnessMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"fogDensity":{"value":0.00025},"fogNear":{"value":1},"fogFar":{"value":2000},"fogColor":{"type":"c","value":16777215},"ambientLightColor":{"value":[]},"lightProbe":{"value":[]},"directionalLights":{"value":[]},"directionalLightShadows":{"value":[]},"directionalShadowMap":{"value":[]},"directionalShadowMatrix":{"value":[]},"spotLights":{"value":[]},"spotLightShadows":{"value":[]},"spotLightMap":{"value":[]},"spotShadowMap":{"value":[]},"spotLightMatrix":{"value":[]},"pointLights":{"value":[]},"pointLightShadows":{"value":[]},"pointShadowMap":{"value":[]},"pointShadowMatrix":{"value":[]},"hemisphereLights":{"value":[]},"rectAreaLights":{"value":[]},"ltc_1":{"value":null},"ltc_2":{"value":null},"emissive":{"type":"c","value":0},"roughness":{"value":1},"metalness":{"value":0},"envMapIntensity":{"value":1},"MAX_STEPS":{"value":100},"MAX_DIST":{"value":100},"SURF_DIST":{"value":0.001},"NORMALS_BIAS":{"value":0.01},"SHADOW_BIAS":{"value":0},"debugMinSteps":{"value":0},"debugMaxSteps":{"value":128},"debugMinDepth":{"value":0},"debugMaxDepth":{"value":128},"shadowDistanceMin":{"value":0},"shadowDistanceMax":{"value":100},"shadowDepthMin":{"value":0},"shadowDepthMax":{"value":100},"envMapRotationY":{"value":0},"spotLightsRayMarching":{"value":[{"penumbra":0,"shadowBiasAngle":0.01,"shadowBiasDistance":0.1}]},"directionalLightsRayMarching":{"value":[]},"pointLightsRayMarching":{"value":[]}},"defines":{"SHADOW_DEPTH":1,"DEPTH_PACKING":3200},"vertexShader":"precision highp float;\nprecision highp int;\n\nvarying vec3 vPw;\nvarying mat4 vModelMatrix;\nvarying mat4 vInverseModelMatrix;\nvarying mat4 VViewMatrix;\n\n#include <common>\n\n// // for depth material\n// varying vec2 vHighPrecisionZW;\n\nvoid main()\t{\n\n\tvModelMatrix = modelMatrix;\n\tvInverseModelMatrix = inverse(modelMatrix);\n\tVViewMatrix = viewMatrix;\n\tvPw = (modelMatrix * vec4( position, 1.0 )).xyz;\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n\t// vHighPrecisionZW = gl_Position.zw;\n}","fragmentShader":"precision highp float;\nprecision highp int;\n\n// --- applyMaterial constants definition\nuniform int MAX_STEPS;\nuniform float MAX_DIST;\nuniform float SURF_DIST;\nuniform float NORMALS_BIAS;\nuniform float SHADOW_BIAS;\n#define ZERO 0\nuniform float debugMinSteps;\nuniform float debugMaxSteps;\nuniform float debugMinDepth;\nuniform float debugMaxDepth;\n\n#include <common>\n#include <packing>\n#include <lightmap_pars_fragment>\n#include <bsdfs>\n#include <cube_uv_reflection_fragment>\n#include <lights_pars_begin>\n#include <lights_physical_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <fog_pars_fragment>\n\n#if defined( SHADOW_DISTANCE )\n\tuniform float shadowDistanceMin;\n\tuniform float shadowDistanceMax;\n#endif \n#if defined( SHADOW_DEPTH )\n\tuniform float shadowDepthMin;\n\tuniform float shadowDepthMax;\n#endif\n\n// varying vec2 vHighPrecisionZW;\n\nvarying vec3 vPw;\nvarying mat4 vModelMatrix;\nvarying mat4 vInverseModelMatrix;\nvarying mat4 VViewMatrix;\n\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform SpotLightRayMarching spotLightsRayMarching[ NUM_SPOT_LIGHTS ];\n\t#if NUM_SPOT_LIGHT_COORDS > 0\n\n\t\tuniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];\n\n\t#endif\n#endif\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform DirectionalLightRayMarching directionalLightsRayMarching[ NUM_DIR_LIGHTS ];\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\n\t#endif\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform PointLightRayMarching pointLightsRayMarching[ NUM_POINT_LIGHTS ];\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\n\t#endif\n#endif\n\n\nstruct SDFContext {\n\tfloat d;\n\tint stepsCount;\n\tint matId;\n\tint matId2;\n\tfloat matBlend;\n};\n\nSDFContext DefaultSDFContext(){\n\treturn SDFContext( 0., 0, 0, 0, 0. );\n}\nint DefaultSDFMaterial(){\n\treturn 0;\n}\n\n// start raymarching builder define code\n\n\n\n// /geo1/MAT/rayMarchingBuilder1/SDFSphere3\nfloat dot2( in vec2 v ) { return dot(v,v); }\nfloat dot2( in vec3 v ) { return dot(v,v); }\nfloat ndot( in vec2 a, in vec2 b ) { return a.x*b.x - a.y*b.y; }\n// https://iquilezles.org/articles/distfunctions/\n\n\n/*\n*\n* SDF PRIMITIVES\n*\n*/\nfloat sdSphere( vec3 p, float s )\n{\n\treturn length(p)-s;\n}\nfloat sdCutSphere( vec3 p, float r, float h )\n{\n\t// sampling independent computations (only depend on shape)\n\tfloat w = sqrt(r*r-h*h);\n\n\t// sampling dependant computations\n\tvec2 q = vec2( length(p.xz), p.y );\n\tfloat s = max( (h-r)*q.x*q.x+w*w*(h+r-2.0*q.y), h*q.x-w*q.y );\n\treturn (s<0.0) ? length(q)-r :\n\t\t\t\t(q.x<w) ? h - q.y :\n\t\t\t\t\tlength(q-vec2(w,h));\n}\nfloat sdCutHollowSphere( vec3 p, float r, float h, float t )\n{\n\t// sampling independent computations (only depend on shape)\n\tfloat w = sqrt(r*r-h*h);\n\t\n\t// sampling dependant computations\n\tvec2 q = vec2( length(p.xz), p.y );\n\treturn ((h*q.x<w*q.y) ? length(q-vec2(w,h)) : \n\t\t\t\t\t\t\tabs(length(q)-r) ) - t;\n}\n\nfloat sdBox( vec3 p, vec3 b )\n{\n\tvec3 q = abs(p) - b*0.5;\n\treturn length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0);\n}\nfloat sdRoundBox( vec3 p, vec3 b, float r )\n{\n\tvec3 q = abs(p) - b*0.5;\n\treturn length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0) - r;\n}\n\n\nfloat sdBoxFrame( vec3 p, vec3 b, float e )\n{\n\t\tp = abs(p )-b*0.5;\n\tvec3 q = abs(p+e)-e;\n\treturn min(min(\n\t\tlength(max(vec3(p.x,q.y,q.z),0.0))+min(max(p.x,max(q.y,q.z)),0.0),\n\t\tlength(max(vec3(q.x,p.y,q.z),0.0))+min(max(q.x,max(p.y,q.z)),0.0)),\n\t\tlength(max(vec3(q.x,q.y,p.z),0.0))+min(max(q.x,max(q.y,p.z)),0.0));\n}\nfloat sdCapsule( vec3 p, vec3 a, vec3 b, float r )\n{\n\tvec3 pa = p - a, ba = b - a;\n\tfloat h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n\treturn length( pa - ba*h ) - r;\n}\nfloat sdVerticalCapsule( vec3 p, float h, float r )\n{\n\tp.y -= clamp( p.y, 0.0, h );\n\treturn length( p ) - r;\n}\nfloat sdCone( in vec3 p, in vec2 c, float h )\n{\n\t// c is the sin/cos of the angle, h is height\n\t// Alternatively pass q instead of (c,h),\n\t// which is the point at the base in 2D\n\tvec2 q = h*vec2(c.x/c.y,-1.0);\n\n\tvec2 w = vec2( length(p.xz), p.y );\n\tvec2 a = w - q*clamp( dot(w,q)/dot(q,q), 0.0, 1.0 );\n\tvec2 b = w - q*vec2( clamp( w.x/q.x, 0.0, 1.0 ), 1.0 );\n\tfloat k = sign( q.y );\n\tfloat d = min(dot( a, a ),dot(b, b));\n\tfloat s = max( k*(w.x*q.y-w.y*q.x),k*(w.y-q.y) );\n\treturn sqrt(d)*sign(s);\n}\nfloat sdConeWrapped(vec3 pos, float angle, float height){\n\treturn sdCone(pos, vec2(sin(angle), cos(angle)), height);\n}\nfloat sdRoundCone( vec3 p, float r1, float r2, float h )\n{\n\tfloat b = (r1-r2)/h;\n\tfloat a = sqrt(1.0-b*b);\n\n\tvec2 q = vec2( length(p.xz), p.y );\n\tfloat k = dot(q,vec2(-b,a));\n\tif( k<0.0 ) return length(q) - r1;\n\tif( k>a*h ) return length(q-vec2(0.0,h)) - r2;\n\treturn dot(q, vec2(a,b) ) - r1;\n}\nfloat sdOctogonPrism( in vec3 p, in float r, float h )\n{\n\tconst vec3 k = vec3(-0.9238795325, // sqrt(2+sqrt(2))/2 \n\t\t\t\t\t\t0.3826834323, // sqrt(2-sqrt(2))/2\n\t\t\t\t\t\t0.4142135623 ); // sqrt(2)-1 \n\t// reflections\n\tp = abs(p);\n\tp.xy -= 2.0*min(dot(vec2( k.x,k.y),p.xy),0.0)*vec2( k.x,k.y);\n\tp.xy -= 2.0*min(dot(vec2(-k.x,k.y),p.xy),0.0)*vec2(-k.x,k.y);\n\t// polygon side\n\tp.xy -= vec2(clamp(p.x, -k.z*r, k.z*r), r);\n\tvec2 d = vec2( length(p.xy)*sign(p.y), p.z-h );\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdHexPrism( vec3 p, vec2 h )\n{\n\tconst vec3 k = vec3(-0.8660254, 0.5, 0.57735);\n\tp = abs(p);\n\tp.xy -= 2.0*min(dot(k.xy, p.xy), 0.0)*k.xy;\n\tvec2 d = vec2(\n\t\tlength(p.xy-vec2(clamp(p.x,-k.z*h.x,k.z*h.x), h.x))*sign(p.y-h.x),\n\t\tp.z-h.y );\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdHorseshoe( in vec3 p, in float angle, in float r, in float le, vec2 w )\n{\n\tvec2 c = vec2(cos(angle),sin(angle));\n\tp.x = abs(p.x);\n\tfloat l = length(p.xy);\n\tp.xy = mat2(-c.x, c.y, \n\t\t\tc.y, c.x)*p.xy;\n\tp.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x),\n\t\t\t\t(p.x>0.0)?p.y:l );\n\tp.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0);\n\t\n\tvec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z);\n\tvec2 d = abs(q) - w;\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdTriPrism( vec3 p, vec2 h )\n{\n\tvec3 q = abs(p);\n\treturn max(q.z-h.y,max(q.x*0.866025+p.y*0.5,-p.y)-h.x*0.5);\n}\nfloat sdPyramid( vec3 p, float h)\n{\n\tfloat m2 = h*h + 0.25;\n\n\tp.xz = abs(p.xz);\n\tp.xz = (p.z>p.x) ? p.zx : p.xz;\n\tp.xz -= 0.5;\n\n\tvec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y);\n\n\tfloat s = max(-q.x,0.0);\n\tfloat t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 );\n\n\tfloat a = m2*(q.x+s)*(q.x+s) + q.y*q.y;\n\tfloat b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t);\n\n\tfloat d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b);\n\n\treturn sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));\n}\n\nfloat sdPlane( vec3 p, vec3 n, float h )\n{\n\t// n must be normalized\n\treturn dot(p,n) + h;\n}\n\nfloat sdTorus( vec3 p, vec2 t )\n{\n\tvec2 q = vec2(length(p.xz)-t.x,p.y);\n\treturn length(q)-t.y;\n}\nfloat sdCappedTorus(in vec3 p, in float an, in float ra, in float rb)\n{\n\tvec2 sc = vec2(sin(an),cos(an));\n\tp.x = abs(p.x);\n\tfloat k = (sc.y*p.x>sc.x*p.z) ? dot(p.xz,sc) : length(p.xz);\n\treturn sqrt( dot(p,p) + ra*ra - 2.0*ra*k ) - rb;\n}\nfloat sdLink( vec3 p, float le, float r1, float r2 )\n{\n vec3 q = vec3( p.x, max(abs(p.y)-le,0.0), p.z );\n return length(vec2(length(q.xy)-r1,q.z)) - r2;\n}\n// c is the sin/cos of the desired cone angle\nfloat sdSolidAngle(vec3 pos, vec2 c, float radius)\n{\n\tvec2 p = vec2( length(pos.xz), pos.y );\n\tfloat l = length(p) - radius;\n\tfloat m = length(p - c*clamp(dot(p,c),0.0,radius) );\n\treturn max(l,m*sign(c.y*p.x-c.x*p.y));\n}\nfloat sdSolidAngleWrapped(vec3 pos, float angle, float radius){\n\treturn sdSolidAngle(pos, vec2(sin(angle), cos(angle)), radius);\n}\nfloat sdTube( vec3 p, float r )\n{\n\treturn length(p.xz)-r;\n}\nfloat sdTubeCapped( vec3 p, float h, float r )\n{\n\tvec2 d = abs(vec2(length(p.xz),p.y)) - vec2(r,h);\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdOctahedron( vec3 p, float s)\n{\n p = abs(p);\n float m = p.x+p.y+p.z-s;\n vec3 q;\n if( 3.0*p.x < m ) q = p.xyz;\n else if( 3.0*p.y < m ) q = p.yzx;\n else if( 3.0*p.z < m ) q = p.zxy;\n else return m*0.57735027;\n \n float k = clamp(0.5*(q.z-q.y+s),0.0,s); \n return length(vec3(q.x,q.y-s+k,q.z-k)); \n}\nfloat udTriangle( vec3 p, vec3 a, vec3 b, vec3 c, float thickness )\n{\n\tvec3 ba = b - a; vec3 pa = p - a;\n\tvec3 cb = c - b; vec3 pb = p - b;\n\tvec3 ac = a - c; vec3 pc = p - c;\n\tvec3 nor = cross( ba, ac );\n\n\treturn - thickness + sqrt(\n\t\t(sign(dot(cross(ba,nor),pa)) +\n\t\tsign(dot(cross(cb,nor),pb)) +\n\t\tsign(dot(cross(ac,nor),pc))<2.0)\n\t\t?\n\t\tmin( min(\n\t\tdot2(ba*clamp(dot(ba,pa)/dot2(ba),0.0,1.0)-pa),\n\t\tdot2(cb*clamp(dot(cb,pb)/dot2(cb),0.0,1.0)-pb) ),\n\t\tdot2(ac*clamp(dot(ac,pc)/dot2(ac),0.0,1.0)-pc) )\n\t\t:\n\t\tdot(nor,pa)*dot(nor,pa)/dot2(nor) );\n}\nfloat udQuad( vec3 p, vec3 a, vec3 b, vec3 c, vec3 d, float thickness )\n{\n\tvec3 ba = b - a; vec3 pa = p - a;\n\tvec3 cb = c - b; vec3 pb = p - b;\n\tvec3 dc = d - c; vec3 pc = p - c;\n\tvec3 ad = a - d; vec3 pd = p - d;\n\tvec3 nor = cross( ba, ad );\n\n\treturn - thickness + sqrt(\n\t\t(sign(dot(cross(ba,nor),pa)) +\n\t\tsign(dot(cross(cb,nor),pb)) +\n\t\tsign(dot(cross(dc,nor),pc)) +\n\t\tsign(dot(cross(ad,nor),pd))<3.0)\n\t\t?\n\t\tmin( min( min(\n\t\tdot2(ba*clamp(dot(ba,pa)/dot2(ba),0.0,1.0)-pa),\n\t\tdot2(cb*clamp(dot(cb,pb)/dot2(cb),0.0,1.0)-pb) ),\n\t\tdot2(dc*clamp(dot(dc,pc)/dot2(dc),0.0,1.0)-pc) ),\n\t\tdot2(ad*clamp(dot(ad,pd)/dot2(ad),0.0,1.0)-pd) )\n\t\t:\n\t\tdot(nor,pa)*dot(nor,pa)/dot2(nor) );\n}\n\n/*\n*\n* SDF OPERATIONS\n*\n*/\nfloat SDFUnion( float d1, float d2 ) { return min(d1,d2); }\nfloat SDFSubtract( float d1, float d2 ) { return max(-d1,d2); }\nfloat SDFIntersect( float d1, float d2 ) { return max(d1,d2); }\n\nfloat SDFSmoothUnion( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 + 0.5*(d2-d1)/k, 0.0, 1.0 );\n\treturn mix( d2, d1, h ) - k*h*(1.0-h);\n}\n\nfloat SDFSmoothSubtract( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 - 0.5*(d2+d1)/k, 0.0, 1.0 );\n\treturn mix( d2, -d1, h ) + k*h*(1.0-h);\n}\n\nfloat SDFSmoothIntersect( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 - 0.5*(d2-d1)/k, 0.0, 1.0 );\n\treturn mix( d2, d1, h ) + k*h*(1.0-h);\n}\n\nvec4 SDFElongateFast( in vec3 p, in vec3 h )\n{\n\treturn vec4( p-clamp(p,-h,h), 0.0 );\n}\nvec4 SDFElongateSlow( in vec3 p, in vec3 h )\n{\n\tvec3 q = abs(p)-h;\n\treturn vec4( max(q,0.0), min(max(q.x,max(q.y,q.z)),0.0) );\n}\n\nfloat SDFOnion( in float sdf, in float thickness )\n{\n\treturn abs(sdf)-thickness;\n}\n\n// /geo1/MAT/rayMarchingBuilder1/checkers1\n// https://iquilezles.org/articles/checkerfiltering/\nfloat checkers(vec2 p) {\n\tvec2 s = sign(fract(p*.5)-.5);\n\treturn .5 - .5*s.x*s.y;\n}\nfloat checkersGrad( in vec2 p, in vec2 ddx, in vec2 ddy )\n{\n // filter kernel\n vec2 w = max(abs(ddx), abs(ddy)) + 0.01;\n // analytical integral (box filter)\n vec2 i = 2.0*(abs(fract((p-0.5*w)/2.0)-0.5)-abs(fract((p+0.5*w)/2.0)-0.5))/w;\n // xor pattern\n return 0.5 - 0.5*i.x*i.y;\n}\n\n\n// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\nconst int _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1 = 1;\n\n\n// https://stackoverflow.com/questions/23793698/how-to-implement-slerp-in-glsl-hlsl\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t)\n// {\n// \tfloat dotp = dot(normalize(p0), normalize(p1));\n// \tif ((dotp > 0.9999) || (dotp < -0.9999))\n// \t{\n// \t\tif (t<=0.5)\n// \t\t\treturn p0;\n// \t\treturn p1;\n// \t}\n// \tfloat theta = acos(dotp);\n// \tvec4 P = ((p0*sin((1.0-t)*theta) + p1*sin(t*theta)) / sin(theta));\n// \tP.w = 1.0;\n// \treturn P;\n// }\n\n// https://devcry.heiho.net/html/2017/20170521-slerp.html\n// float lerp(float a, float b, float t) {\n// \treturn (1.0 - t) * a + t * b;\n// }\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t){\n// \tvec4 qb = p1;\n\n// \t// cos(a) = dot product\n// \tfloat cos_a = p0.x * qb.x + p0.y * qb.y + p0.z * qb.z + p0.w * qb.w;\n// \tif (cos_a < 0.0f) {\n// \t\tcos_a = -cos_a;\n// \t\tqb = -qb;\n// \t}\n\n// \t// close to zero, cos(a) ~= 1\n// \t// do linear interpolation\n// \tif (cos_a > 0.999) {\n// \t\treturn vec4(\n// \t\t\tlerp(p0.x, qb.x, t),\n// \t\t\tlerp(p0.y, qb.y, t),\n// \t\t\tlerp(p0.z, qb.z, t),\n// \t\t\tlerp(p0.w, qb.w, t)\n// \t\t);\n// \t}\n\n// \tfloat alpha = acos(cos_a);\n// \treturn (p0 * sin(1.0 - t) + p1 * sin(t * alpha)) / sin(alpha);\n// }\n\n// https://stackoverflow.com/questions/62943083/interpolate-between-two-quaternions-the-long-way\nvec4 quatSlerp(vec4 q1, vec4 q2, float t){\n\tfloat angle = acos(dot(q1, q2));\n\tfloat denom = sin(angle);\n\t//check if denom is zero\n\treturn (q1*sin((1.0-t)*angle)+q2*sin(t*angle))/denom;\n}\n// TO CHECK:\n// this page https://www.reddit.com/r/opengl/comments/704la7/glsl_quaternion_library/\n// has a link to a potentially nice pdf:\n// http://web.mit.edu/2.998/www/QuaternionReport1.pdf\n\n// https://github.com/mattatz/ShibuyaCrowd/blob/master/source/shaders/common/quaternion.glsl\nvec4 quatMult(vec4 q1, vec4 q2)\n{\n\treturn vec4(\n\tq1.w * q2.x + q1.x * q2.w + q1.z * q2.y - q1.y * q2.z,\n\tq1.w * q2.y + q1.y * q2.w + q1.x * q2.z - q1.z * q2.x,\n\tq1.w * q2.z + q1.z * q2.w + q1.y * q2.x - q1.x * q2.y,\n\tq1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z\n\t);\n}\n// http://glmatrix.net/docs/quat.js.html#line97\n// let ax = a[0], ay = a[1], az = a[2], aw = a[3];\n\n// let bx = b[0], by = b[1], bz = b[2], bw = b[3];\n\n// out[0] = ax * bw + aw * bx + ay * bz - az * by;\n\n// out[1] = ay * bw + aw * by + az * bx - ax * bz;\n\n// out[2] = az * bw + aw * bz + ax * by - ay * bx;\n\n// out[3] = aw * bw - ax * bx - ay * by - az * bz;\n\n// return out\n\n\n\n// http://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/\nmat4 rotationMatrix(vec3 axis, float angle)\n{\n\taxis = normalize(axis);\n\tfloat s = sin(angle);\n\tfloat c = cos(angle);\n\tfloat oc = 1.0 - c;\n\n \treturn mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 0.0, 0.0, 0.0, 1.0);\n}\n\n// https://www.geeks3d.com/20141201/how-to-rotate-a-vertex-by-a-quaternion-in-glsl/\nvec4 quatFromAxisAngle(vec3 axis, float angle)\n{\n\tvec4 qr;\n\tfloat half_angle = (angle * 0.5); // * 3.14159 / 180.0;\n\tfloat sin_half_angle = sin(half_angle);\n\tqr.x = axis.x * sin_half_angle;\n\tqr.y = axis.y * sin_half_angle;\n\tqr.z = axis.z * sin_half_angle;\n\tqr.w = cos(half_angle);\n\treturn qr;\n}\nvec3 rotateWithAxisAngle(vec3 position, vec3 axis, float angle)\n{\n\tvec4 q = quatFromAxisAngle(axis, angle);\n\tvec3 v = position.xyz;\n\treturn v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);\n}\n// vec3 applyQuaternionToVector( vec4 q, vec3 v ){\n// \treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n// }\nvec3 rotateWithQuat( vec3 v, vec4 q )\n{\n\t// vec4 qv = multQuat( quat, vec4(vec, 0.0) );\n\t// return multQuat( qv, vec4(-quat.x, -quat.y, -quat.z, quat.w) ).xyz;\n\treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n}\n// https://github.com/glslify/glsl-look-at/blob/gh-pages/index.glsl\n// mat3 rotation_matrix(vec3 origin, vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target - origin);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n// mat3 rotation_matrix(vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n\nfloat vectorAngle(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 c1 = cross(start, dest);\n\t// We use the dot product of the cross with the Y axis.\n\t// This is a little arbitrary, but can still give a good sense of direction\n\tvec3 y_axis = vec3(0.0, 1.0, 0.0);\n\tfloat d1 = dot(c1, y_axis);\n\tfloat angle = acos(cosTheta) * sign(d1);\n\treturn angle;\n}\n\n// http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/#i-need-an-equivalent-of-glulookat-how-do-i-orient-an-object-towards-a-point-\nvec4 vectorAlign(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 axis;\n\n\t// if (cosTheta < -1 + 0.001f){\n\t// \t// special case when vectors in opposite directions:\n\t// \t// there is no ideal rotation axis\n\t// \t// So guess one; any will do as long as it's perpendicular to start\n\t// \taxis = cross(vec3(0.0f, 0.0f, 1.0f), start);\n\t// \tif (length2(axis) < 0.01 ) // bad luck, they were parallel, try again!\n\t// \t\taxis = cross(vec3(1.0f, 0.0f, 0.0f), start);\n\n\t// \taxis = normalize(axis);\n\t// \treturn gtx::quaternion::angleAxis(glm::radians(180.0f), axis);\n\t// }\n\tif(cosTheta > (1.0 - 0.0001) || cosTheta < (-1.0 + 0.0001) ){\n\t\taxis = normalize(cross(start, vec3(0.0, 1.0, 0.0)));\n\t\tif (length(axis) < 0.001 ){ // bad luck, they were parallel, try again!\n\t\t\taxis = normalize(cross(start, vec3(1.0, 0.0, 0.0)));\n\t\t}\n\t} else {\n\t\taxis = normalize(cross(start, dest));\n\t}\n\n\tfloat angle = acos(cosTheta);\n\n\treturn quatFromAxisAngle(axis, angle);\n}\nvec4 vectorAlignWithUp(vec3 start, vec3 dest, vec3 up){\n\tvec4 rot1 = vectorAlign(start, dest);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\t// vec3 right = normalize(cross(dest, up));\n\t// up = normalize(cross(right, dest));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(vec3(0.0, 1.0, 0.0), rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(up, newUp);\n\n\t// return rot1;\n\treturn rot2;\n\t// return multQuat(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\n// https://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\nfloat quatToAngle(vec4 q){\n\treturn 2.0 * acos(q.w);\n}\nvec3 quatToAxis(vec4 q){\n\treturn vec3(\n\t\tq.x / sqrt(1.0-q.w*q.w),\n\t\tq.y / sqrt(1.0-q.w*q.w),\n\t\tq.z / sqrt(1.0-q.w*q.w)\n\t);\n}\n\nvec4 align(vec3 dir, vec3 up){\n\tvec3 start_dir = vec3(0.0, 0.0, 1.0);\n\tvec3 start_up = vec3(0.0, 1.0, 0.0);\n\tvec4 rot1 = vectorAlign(start_dir, dir);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\tvec3 right = normalize(cross(dir, up));\n\tif(length(right)<0.001){\n\t\tright = vec3(1.0, 0.0, 0.0);\n\t}\n\tup = normalize(cross(right, dir));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(start_up, rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(normalize(newUp), up);\n\n\t// return rot1;\n\treturn quatMult(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\nstruct EnvMapProps {\n\tvec3 tint;\n\tfloat intensity;\n\tfloat roughness;\n\tfloat fresnel;\n\tfloat fresnelPower;\n};\nuniform sampler2D envMap;\nuniform float envMapIntensity;\nuniform float roughness;\n#ifdef ROTATE_ENV_MAP_Y\n\tuniform float envMapRotationY;\n#endif\nvec3 envMapSample(vec3 rayDir, float envMapRoughness){\n\t// http://www.pocketgl.com/reflections/\n\tvec3 env = vec3(0.);\n\t// vec2 uv = vec2( atan( -rayDir.z, -rayDir.x ) * RECIPROCAL_PI2 + 0.5, rayDir.y * 0.5 + 0.5 );\n\t// vec3 env = texture2D(map, uv).rgb;\n\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t#ifdef ROTATE_ENV_MAP_Y\n\t\t\trayDir = rotateWithAxisAngle(rayDir, vec3(0.,1.,0.), envMapRotationY);\n\t\t#endif\n\t\tenv = textureCubeUV(envMap, rayDir, envMapRoughness * roughness).rgb;\n\t#endif\n\treturn env;\n}\nvec3 envMapSampleWithFresnel(vec3 rayDir, EnvMapProps envMapProps, vec3 n, vec3 cameraPosition){\n\t// http://www.pocketgl.com/reflections/\n\tvec3 env = envMapSample(rayDir, envMapProps.roughness);\n\tfloat fresnel = pow(1.-dot(normalize(cameraPosition), n), envMapProps.fresnelPower);\n\tfloat fresnelFactor = (1.-envMapProps.fresnel) + envMapProps.fresnel*fresnel;\n\treturn env * envMapIntensity * envMapProps.tint * envMapProps.intensity * fresnelFactor;\n}\n\n\n\n\n\n\nSDFContext GetDist(vec3 p) {\n\tSDFContext sdfContext = SDFContext(0., 0, 0, 0, 0.);\n\n\t// start GetDist builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/SDFSphere3\n\tfloat v_POLY_SDFSphere3_float = sdSphere(p - vec3(-0.25, 0.0, 0.0), 0.2);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFSphere4\n\tfloat v_POLY_SDFSphere4_float = sdSphere(p - vec3(0.25, 0.0, 0.0), 0.2);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFPlane1\n\tfloat v_POLY_SDFPlane1_float = sdPlane(p-vec3(0.0, -0.2, 0.0), vec3(0.0, 1.0, 0.0), 0.0);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFUnion2\n\tfloat v_POLY_SDFUnion2_union = SDFSmoothUnion(v_POLY_SDFSphere3_float, v_POLY_SDFSphere4_float, 0.31);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFUnion3\n\tfloat v_POLY_SDFUnion3_union = SDFSmoothUnion(v_POLY_SDFUnion2_union, v_POLY_SDFPlane1_float, 0.31);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFContext1\n\tSDFContext v_POLY_SDFContext1_SDFContext = SDFContext(v_POLY_SDFUnion3_union, 0, _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1, _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1, 0.);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/output1\n\tsdfContext = v_POLY_SDFContext1_SDFContext;\n\n\n\n\t\n\n\treturn sdfContext;\n}\n\nSDFContext RayMarch(vec3 ro, vec3 rd, float side) {\n\tSDFContext dO = SDFContext(0.,0,0,0,0.);\n\n\t#pragma unroll_loop_start\n\tfor(int i=0; i<MAX_STEPS; i++) {\n\t\tvec3 p = ro + rd*dO.d;\n\t\tSDFContext sdfContext = GetDist(p);\n\t\tdO.d += sdfContext.d * side;\n\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\tdO.stepsCount += 1;\n\t\t#endif\n\t\tdO.matId = sdfContext.matId;\n\t\tdO.matId2 = sdfContext.matId2;\n\t\tdO.matBlend = sdfContext.matBlend;\n\t\tif(dO.d>MAX_DIST || abs(sdfContext.d)<SURF_DIST) break;\n\t}\n\t#pragma unroll_loop_end\n\n\treturn dO;\n}\n\nvec3 GetNormal(vec3 p) {\n\tSDFContext sdfContext = GetDist(p);\n\tvec2 e = vec2(NORMALS_BIAS, 0);\n\n\tvec3 n = sdfContext.d - vec3(\n\t\tGetDist(p-e.xyy).d,\n\t\tGetDist(p-e.yxy).d,\n\t\tGetDist(p-e.yyx).d);\n\n\treturn normalize(n);\n}\n// https://iquilezles.org/articles/rmshadows\nfloat calcSoftshadow( in vec3 ro, in vec3 rd, float mint, float maxt, float k, inout SDFContext sdfContext )\n{\n\tfloat res = 1.0;\n\tfloat ph = 1e20;\n\tfor( float t=mint; t<maxt; )\n\t{\n\t\tfloat h = GetDist(ro + rd*t).d;\n\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\tsdfContext.stepsCount += 1;\n\t\t#endif\n\t\tif( h<SURF_DIST )\n\t\t\treturn 0.0;\n\t\tfloat y = h*h/(2.0*ph);\n\t\tfloat d = sqrt(h*h-y*y);\n\t\tres = min( res, k*d/max(0.0,t-y) );\n\t\tph = h;\n\t\tt += h;\n\t}\n\treturn res;\n}\n\nvec3 GetLight(vec3 _p, vec3 _n, inout SDFContext sdfContext) {\n\tvec3 dif = vec3(0.,0.,0.);\n\t// GeometricContext geometry;\n\t// geometry.position = _p;\n\t// geometry.normal = _n;\n\t// geometry.viewDir = rayDir;\n\n\t// vec4 mvPosition = vec4( p, 1.0 );\n\t// mvPosition = modelViewMatrix * mvPosition;\n\t// vec3 vViewPosition = - mvPosition.xyz;\n\tvec3 pWorld = ( vModelMatrix * vec4( _p, 1.0 )).xyz;\n\tvec3 nWorld = transformDirection(_n, vModelMatrix);\n\t// geometry.position = (VViewMatrix * vec4( _p, 1.0 )).xyz;\n\tvec3 geometryPosition = (VViewMatrix * vec4(pWorld, 1.0 )).xyz;\n\t// geometry.normal = transformDirection(_n, VViewMatrix);\n\t// geometry.normal = inverseTransformDirection(transformDirection(_n, VViewMatrix), vInverseModelMatrix);\n\tvec3 geometryNormal = transformDirection(nWorld, VViewMatrix);\n\t\n\n\t#if NUM_SPOT_LIGHTS > 0 || NUM_DIR_LIGHTS > 0 || NUM_HEMI_LIGHTS > 0 || NUM_POINT_LIGHTS > 0 || NUM_RECT_AREA_LIGHTS > 0\n\n\t\tIncidentLight directLight;\n\t\tReflectedLight reflectedLight;\n\t\tvec3 lightPos, lightDir, worldLightDir, objectSpaceLightDir, lighDif, directDiffuse;\n\t\tfloat dotNL, lightDistance;\n\t\t#if NUM_SPOT_LIGHTS > 0\n\t\t\tSpotLightRayMarching spotLightRayMarching;\n\t\t\tSpotLight spotLight;\n\t\t\tfloat spotLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\t\t\t\tSpotLightShadow spotLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\t\t\tspotLightRayMarching = spotLightsRayMarching[ i ];\n\t\t\t\tspotLight = spotLights[ i ];\n\t\t\t\tgetSpotLightInfo( spotLight, geometryPosition, directLight );\n\n\t\t\t\t// #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t\t\t// \tspotLightShadow = spotLightShadows[ i ];\n\t\t\t\t// \tvec4 spotLightShadowCoord = spotLightMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t// \tdirectLight.color *= (directLight.visible && receiveShadow) ? getShadow(\n\t\t\t\t// \t\tspotShadowMap[ i ],\n\t\t\t\t// \t\tspotLightShadow.shadowMapSize,\n\t\t\t\t// \t\tspotLightShadow.shadowBias,\n\t\t\t\t// \t\tspotLightShadow.shadowRadius,\n\t\t\t\t// \t\tspotLightShadowCoord\n\t\t\t\t// \t) : 1.0;\n\t\t\t\t// #endif\n\n\t\t\t\tlightPos = spotLight.position;\n\t\t\t\tlightDir = normalize(lightPos-geometryPosition);\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tlightDistance = distance(geometryPosition,lightPos);\n\t\t\t\tspotLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < spotLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t: calcSoftshadow(\n\t\t\t\t\t\t_p,\n\t\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\t\tspotLightRayMarching.shadowBiasDistance,\n\t\t\t\t\t\tdistance(geometryPosition,lightPos),\n\t\t\t\t\t\t1./max(spotLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\t\tsdfContext\n\t\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * spotLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\t\t#if NUM_DIR_LIGHTS > 0\n\t\t\tDirectionalLightRayMarching directionalLightRayMarching;\n\t\t\tDirectionalLight directionalLight;\n\t\t\tfloat dirLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\t\t\t\tDirectionalLightShadow directionalLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\t\t\tdirectionalLightRayMarching = directionalLightsRayMarching[ i ];\n\t\t\t\tdirectionalLight = directionalLights[ i ];\n\t\t\t\t\n\t\t\t\tgetDirectionalLightInfo( directionalLight, directLight );\n\n\t\t\t\t// #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\t\t\t// \tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\t\t\t// \tvec4 dirLightShadowCoord = directionalShadowMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t// \tdirectLight.color *= (directLight.visible && receiveShadow) ? getShadow(\n\t\t\t\t// \t\tdirectionalShadowMap[ i ],\n\t\t\t\t// \t\tdirectionalLightShadow.shadowMapSize,\n\t\t\t\t// \t\tdirectionalLightShadow.shadowBias,\n\t\t\t\t// \t\tdirectionalLightShadow.shadowRadius,\n\t\t\t\t// \t\tdirLightShadowCoord\n\t\t\t\t// \t) : 1.0;\n\t\t\t\t// #endif\n\n\t\t\t\tlightDir = directionalLight.direction;\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tdirLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < directionalLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t:\n\t\t\t\t\tcalcSoftshadow(\n\t\t\t\t\t\t_p,\n\t\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\t\tdirectionalLightRayMarching.shadowBiasDistance,\n\t\t\t\t\t\tMAX_DIST,//distance(geometryPosition,lightPos),\n\t\t\t\t\t\t1./max(directionalLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\t\tsdfContext\n\t\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\t// lighDif = directLight.color * dotNL * dirLightSdfShadow;\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * dirLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\n\t\t#if ( NUM_HEMI_LIGHTS > 0 )\n\n\t\t\t#pragma unroll_loop_start\n\t\t\tHemisphereLight hemiLight;\n\t\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\t\themiLight = hemisphereLights[ i ];\n\t\t\t\tdif += getHemisphereLightIrradiance( hemiLight, geometryNormal ) * BRDF_Lambert( vec3(1.) );\n\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\n\t\t#endif\n\n\t\t#if NUM_POINT_LIGHTS > 0\n\t\t\tPointLightRayMarching pointLightRayMarching;\n\t\t\tPointLight pointLight;\n\t\t\tfloat pointLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\t\t\t\tPointLightShadow pointLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\t\t\tpointLightRayMarching = pointLightsRayMarching[ i ];\n\t\t\t\tpointLight = pointLights[ i ];\n\t\t\t\tgetPointLightInfo( pointLight, geometryPosition, directLight );\n\n\n\t\t\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\t\t\t\tpointLightShadow = pointLightShadows[ i ];\n\t\t\t\t\tvec4 pointLightShadowCoord = pointShadowMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t\tdirectLight.color *= (directLight.visible && receiveShadow) ? getPointShadow(\n\t\t\t\t\t\tpointShadowMap[ i ],\n\t\t\t\t\t\tpointLightShadow.shadowMapSize,\n\t\t\t\t\t\tpointLightShadow.shadowBias,\n\t\t\t\t\t\tpointLightShadow.shadowRadius,\n\t\t\t\t\t\tpointLightShadowCoord,\n\t\t\t\t\t\tpointLightShadow.shadowCameraNear,\n\t\t\t\t\t\tpointLightShadow.shadowCameraFar\n\t\t\t\t\t) : 1.0;\n\t\t\t\t#endif\n\n\t\t\t\tlightPos = pointLight.position;\n\t\t\t\tlightDir = normalize(lightPos-geometryPosition);\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tpointLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < pointLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t:\n\t\t\t\t\tcalcSoftshadow(\n\t\t\t\t\t_p,\n\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\tpointLightRayMarching.shadowBiasDistance,\n\t\t\t\t\tdistance(geometryPosition,lightPos),\n\t\t\t\t\t1./max(pointLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\tsdfContext\n\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * pointLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\n\t\t#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\n\t\t\tRectAreaLight rectAreaLight;\n\t\t\t// AreaLightRayMarching areaLightRayMarching;\n\t\t\tPhysicalMaterial material;\n\t\t\tmaterial.roughness = 1.;\n\t\t\tmaterial.specularColor = vec3(1.);\n\t\t\tmaterial.diffuseColor = vec3(1.);\n\n\t\t\tvec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( cameraPosition - geometryPosition );\n\t\t\tvec3 geometryClearcoatNormal = geometryNormal;\n\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\t\t\t// areaLightRayMarching = areaLightsRayMarching[ i ];\n\t\t\t\trectAreaLight = rectAreaLights[ i ];\n\t\t\t\t// rectAreaLight.position = areaLightRayMarching.worldPos;\n\n\t\t\t\tRE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t\tdif += reflectedLight.directDiffuse;\n\n\t\t#endif\n\t#endif\n\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\n\t#if defined( USE_LIGHT_PROBES )\n\n\t\tirradiance += getLightProbeIrradiance( lightProbe, geometryNormal );\n\n\t#endif\n\n\tdif += irradiance;\n\n\treturn dif;\n}\n\n\n\n\nvec3 applyMaterialWithoutRefraction(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(1.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n\nvec3 applyMaterialWithoutReflection(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(1.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n#ifdef RAYMARCHED_REFLECTIONS\nvec3 GetReflection(vec3 p, vec3 n, vec3 rayDir, float biasMult, float roughness, int reflectionDepth, inout SDFContext sdfContextMain){\n\tbool hitReflection = true;\n\tvec3 reflectedColor = vec3(0.);\n\t#pragma unroll_loop_start\n\tfor(int i=0; i < reflectionDepth; i++) {\n\t\tif(hitReflection){\n\t\t\trayDir = reflect(rayDir, n);\n\t\t\tp += n*SURF_DIST*biasMult;\n\t\t\tSDFContext sdfContext = RayMarch(p, rayDir, 1.);\n\t\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\t\tsdfContextMain.stepsCount += sdfContext.stepsCount;\n\t\t\t#endif\n\t\t\tif( sdfContext.d >= MAX_DIST){\n\t\t\t\thitReflection = false;\n\t\t\t\treflectedColor = envMapSample(rayDir, roughness);\n\t\t\t}\n\t\t\tif(hitReflection){\n\t\t\t\tp += rayDir * sdfContext.d;\n\t\t\t\tn = GetNormal(p);\n\t\t\t\tvec3 matCol = applyMaterialWithoutReflection(p, n, rayDir, sdfContext.matId, sdfContextMain);\n\t\t\t\treflectedColor += matCol;\n\t\t\t}\n\t\t}\n\t}\n\t#pragma unroll_loop_end\n\treturn reflectedColor;\n}\n#endif\n\n#ifdef RAYMARCHED_REFRACTIONS\n// xyz for color, w for distanceInsideMedium\nvec4 GetRefractedData(vec3 p, vec3 n, vec3 rayDir, float ior, float biasMult, float roughness, float refractionMaxDist, int refractionDepth, inout SDFContext sdfContextMain){\n\tbool hitRefraction = true;\n\tbool changeSide = true;\n\t#ifdef RAYMARCHED_REFRACTIONS_START_OUTSIDE_MEDIUM\n\tfloat side = -1.;\n\t#else\n\tfloat side = 1.;\n\t#endif\n\tfloat iorInverted = 1. / ior;\n\tvec3 refractedColor = vec3(0.);\n\tfloat distanceInsideMedium=0.;\n\tfloat totalRefractedDistance=0.;\n\n\t#pragma unroll_loop_start\n\tfor(int i=0; i < refractionDepth; i++) {\n\t\tif(hitRefraction){\n\t\t\tfloat currentIor = side<0. ? iorInverted : ior;\n\t\t\tvec3 rayDirPreRefract = rayDir;\n\t\t\trayDir = refract(rayDir, n, currentIor);\n\t\t\tchangeSide = dot(rayDir, rayDir)!=0.;\n\t\t\tif(changeSide == true) {\n\t\t\t\tp -= n*SURF_DIST*(2.+biasMult);\n\t\t\t} else {\n\t\t\t\tp += n*SURF_DIST*( biasMult);\n\t\t\t\trayDir = reflect(rayDirPreRefract, n);\n\t\t\t}\n\t\t\tSDFContext sdfContext = RayMarch(p, rayDir, side);\n\t\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\t\tsdfContextMain.stepsCount += sdfContext.stepsCount;\n\t\t\t#endif\n\t\t\ttotalRefractedDistance += sdfContext.d;\n\t\t\tif( abs(sdfContext.d) >= MAX_DIST || totalRefractedDistance > refractionMaxDist ){\n\t\t\t\thitRefraction = false;\n\t\t\t\trefractedColor = envMapSample(rayDir, roughness);\n\t\t\t}\n\t\t\tif(hitRefraction){\n\t\t\t\tp += rayDir * sdfContext.d;\n\t\t\t\tn = GetNormal(p) * side;\n\t\t\t\tvec3 matCol = applyMaterialWithoutRefraction(p, n, rayDir, sdfContext.matId, sdfContextMain);\n\t\t\t\trefractedColor = matCol;\n\n\t\t\t\t// same as: side < 0. ? abs(sdfContext.d) : 0.;\n\t\t\t\tdistanceInsideMedium += (side-1.)*-0.5*abs(sdfContext.d);\n\t\t\t\tif( changeSide ){\n\t\t\t\t\tside *= -1.;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#ifdef RAYMARCHED_REFRACTIONS_SAMPLE_ENV_MAP_ON_LAST\n\t\tif(i == refractionDepth-1){\n\t\t\trefractedColor = envMapSample(rayDir, roughness);\n\t\t}\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n\treturn vec4(refractedColor, distanceInsideMedium);\n}\nfloat refractionTint(float baseValue, float tint, float distanceInsideMedium, float absorption){\n\tfloat tintNegated = baseValue-tint;\n\tfloat t = tintNegated*( distanceInsideMedium*absorption );\n\treturn max(baseValue-t, 0.);\n}\nfloat applyRefractionAbsorption(float refractedDataColor, float baseValue, float tint, float distanceInsideMedium, float absorption){\n\treturn refractedDataColor*refractionTint(baseValue, tint, distanceInsideMedium, absorption);\n}\nvec3 applyRefractionAbsorption(vec3 refractedDataColor, vec3 baseValue, vec3 tint, float distanceInsideMedium, float absorption){\n\treturn vec3(\n\t\trefractedDataColor.r * refractionTint(baseValue.r, tint.r, distanceInsideMedium, absorption),\n\t\trefractedDataColor.g * refractionTint(baseValue.g, tint.g, distanceInsideMedium, absorption),\n\t\trefractedDataColor.b * refractionTint(baseValue.b, tint.b, distanceInsideMedium, absorption)\n\t);\n}\n\n#endif\n\nvec3 applyMaterial(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(0.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n\n\n\n\nvec4 applyShading(vec3 rayOrigin, vec3 rayDir, inout SDFContext sdfContext){\n\tvec3 p = rayOrigin + rayDir * sdfContext.d;\n\tvec3 n = GetNormal(p);\n\t\n\tvec3 col = applyMaterial(p, n, rayDir, sdfContext.matId, sdfContext);\n\tif(sdfContext.matBlend > 0.) {\n\t\t// blend material colors if needed\n\t\tvec3 col2 = applyMaterial(p, n, rayDir, sdfContext.matId2, sdfContext);\n\t\tcol = (1. - sdfContext.matBlend)*col + sdfContext.matBlend*col2;\n\t}\n\t\t\n\t// gamma\n\t//col = pow( col, vec3(0.4545) ); // this gamma leads to a different look than standard materials\n\treturn vec4(col, 1.);\n}\n\nvoid main()\t{\n\n\tvec3 rayDir = normalize(vPw - cameraPosition);\n\trayDir = transformDirection(rayDir, vInverseModelMatrix);\n\tvec3 rayOrigin = (vInverseModelMatrix * vec4( cameraPosition, 1.0 )).xyz;\n\n\tSDFContext sdfContext = RayMarch(rayOrigin, rayDir, 1.);\n\n\t#if defined( DEBUG_DEPTH )\n\t\tfloat normalizedDepth = 1.-(sdfContext.d - debugMinDepth ) / ( debugMaxDepth - debugMinDepth );\n\t\tnormalizedDepth = saturate(normalizedDepth); // clamp to [0,1]\n\t\tgl_FragColor = vec4(normalizedDepth);\n\t\treturn;\n\t#endif\n\t#if defined( SHADOW_DEPTH )\n\t\tfloat normalizedDepth = 1.-(sdfContext.d - debugMinDepth ) / ( debugMaxDepth - debugMinDepth );\n\t\t// float fragCoordZ = sdfContext.d / vHighPrecisionZW[1];\n\t\tfloat compoundedDepth = 0.5 * (normalizedDepth) + 0.5;\n\t\tfloat alpha = sdfContext.d < MAX_DIST ? 0.:1.;\n\t\tgl_FragColor = vec4( vec3(compoundedDepth), alpha );\n\t\t// normalizedDepth = 0.5*normalizedDepth+0.5;\n\t\t// gl_FragColor = packDepthToRGBA( normalizedDepth );\n\t\t// gl_FragColor = vec4(0.);\n\t\treturn;\n\t#endif\n\t#if defined( SHADOW_DISTANCE )\n\t\tfloat normalizedDepth = (sdfContext.d - shadowDistanceMin ) / ( shadowDistanceMax - shadowDistanceMin );\n\t\tnormalizedDepth = saturate(normalizedDepth); // clamp to [0,1]\n\t\tgl_FragColor = packDepthToRGBA( normalizedDepth );\n\t\treturn;\n\t#endif\n\n\tif( sdfContext.d < MAX_DIST ){\n\t\tgl_FragColor = applyShading(rayOrigin, rayDir, sdfContext);\n\t\t#if defined( TONE_MAPPING )\n\t\t\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n\t\t#endif\n\t\tgl_FragColor = linearToOutputTexel( gl_FragColor );\n\n\t\t#ifdef USE_FOG\n\t\t\tfloat vFogDepth = sdfContext.d;\n\t\t\t#ifdef FOG_EXP2\n\t\t\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );\n\t\t\t#else\n\t\t\t\tfloat fogFactor = smoothstep( fogNear, fogFar, vFogDepth );\n\t\t\t#endif\n\t\t\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n\t\t#endif\n\t\t#include <premultiplied_alpha_fragment>\n\t\t#include <dithering_fragment>\n\t} else {\n\t\tgl_FragColor = vec4(0.);\n\t}\n\n\t#if defined( DEBUG_STEPS_COUNT )\n\t\tfloat normalizedStepsCount = (float(sdfContext.stepsCount) - debugMinSteps ) / ( debugMaxSteps - debugMinSteps );\n\t\tgl_FragColor = vec4(normalizedStepsCount, 1.-normalizedStepsCount, 0., 1.);\n\t\treturn;\n\t#endif\n\t\n}","lights":false,"clipping":false,"depthPacking":3200},"onBeforeCompileDataJSONWithoutShaders":{"paramConfigs":[],"timeDependent":false,"resolutionDependent":false,"raymarchingLightsWorldCoordsDependent":true}},"customDistanceMaterial":{"material":{"metadata":{"version":4.6,"type":"Material","generator":"Material.toJSON"},"uuid":"/geo1/MAT/rayMarchingBuilder1-customDistanceMaterial","type":"ShaderMaterial","name":"customDistanceMaterial","blendColor":0,"alphaTest":0.5,"forceSinglePass":true,"fog":false,"glslVersion":null,"uniforms":{"diffuse":{"type":"c","value":16777215},"opacity":{"value":1},"map":{"value":null},"mapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"alphaMap":{"value":null},"alphaMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"alphaTest":{"value":0},"envMap":{"value":null},"flipEnvMap":{"value":-1},"reflectivity":{"value":1},"ior":{"value":1.5},"refractionRatio":{"value":0.98},"aoMap":{"value":null},"aoMapIntensity":{"value":1},"aoMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"lightMap":{"value":null},"lightMapIntensity":{"value":1},"lightMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"emissiveMap":{"value":null},"emissiveMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"bumpMap":{"value":null},"bumpMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"bumpScale":{"value":1},"normalMap":{"value":null},"normalMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"normalScale":{"type":"v2","value":[1,1]},"displacementMap":{"value":null},"displacementMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"displacementScale":{"value":1},"displacementBias":{"value":0},"roughnessMap":{"value":null},"roughnessMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"metalnessMap":{"value":null},"metalnessMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"fogDensity":{"value":0.00025},"fogNear":{"value":1},"fogFar":{"value":2000},"fogColor":{"type":"c","value":16777215},"ambientLightColor":{"value":[]},"lightProbe":{"value":[]},"directionalLights":{"value":[]},"directionalLightShadows":{"value":[]},"directionalShadowMap":{"value":[]},"directionalShadowMatrix":{"value":[]},"spotLights":{"value":[]},"spotLightShadows":{"value":[]},"spotLightMap":{"value":[]},"spotShadowMap":{"value":[]},"spotLightMatrix":{"value":[]},"pointLights":{"value":[]},"pointLightShadows":{"value":[]},"pointShadowMap":{"value":[]},"pointShadowMatrix":{"value":[]},"hemisphereLights":{"value":[]},"rectAreaLights":{"value":[]},"ltc_1":{"value":null},"ltc_2":{"value":null},"emissive":{"type":"c","value":0},"roughness":{"value":1},"metalness":{"value":0},"envMapIntensity":{"value":1},"MAX_STEPS":{"value":100},"MAX_DIST":{"value":100},"SURF_DIST":{"value":0.001},"NORMALS_BIAS":{"value":0.01},"SHADOW_BIAS":{"value":0},"debugMinSteps":{"value":0},"debugMaxSteps":{"value":128},"debugMinDepth":{"value":0},"debugMaxDepth":{"value":128},"shadowDistanceMin":{"value":0},"shadowDistanceMax":{"value":100},"shadowDepthMin":{"value":0},"shadowDepthMax":{"value":100},"envMapRotationY":{"value":0},"spotLightsRayMarching":{"value":[{"penumbra":0,"shadowBiasAngle":0.01,"shadowBiasDistance":0.1}]},"directionalLightsRayMarching":{"value":[]},"pointLightsRayMarching":{"value":[]}},"defines":{"SHADOW_DISTANCE":1},"vertexShader":"precision highp float;\nprecision highp int;\n\nvarying vec3 vPw;\nvarying mat4 vModelMatrix;\nvarying mat4 vInverseModelMatrix;\nvarying mat4 VViewMatrix;\n\n#include <common>\n\n// // for depth material\n// varying vec2 vHighPrecisionZW;\n\nvoid main()\t{\n\n\tvModelMatrix = modelMatrix;\n\tvInverseModelMatrix = inverse(modelMatrix);\n\tVViewMatrix = viewMatrix;\n\tvPw = (modelMatrix * vec4( position, 1.0 )).xyz;\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n\t// vHighPrecisionZW = gl_Position.zw;\n}","fragmentShader":"precision highp float;\nprecision highp int;\n\n// --- applyMaterial constants definition\nuniform int MAX_STEPS;\nuniform float MAX_DIST;\nuniform float SURF_DIST;\nuniform float NORMALS_BIAS;\nuniform float SHADOW_BIAS;\n#define ZERO 0\nuniform float debugMinSteps;\nuniform float debugMaxSteps;\nuniform float debugMinDepth;\nuniform float debugMaxDepth;\n\n#include <common>\n#include <packing>\n#include <lightmap_pars_fragment>\n#include <bsdfs>\n#include <cube_uv_reflection_fragment>\n#include <lights_pars_begin>\n#include <lights_physical_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <fog_pars_fragment>\n\n#if defined( SHADOW_DISTANCE )\n\tuniform float shadowDistanceMin;\n\tuniform float shadowDistanceMax;\n#endif \n#if defined( SHADOW_DEPTH )\n\tuniform float shadowDepthMin;\n\tuniform float shadowDepthMax;\n#endif\n\n// varying vec2 vHighPrecisionZW;\n\nvarying vec3 vPw;\nvarying mat4 vModelMatrix;\nvarying mat4 vInverseModelMatrix;\nvarying mat4 VViewMatrix;\n\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform SpotLightRayMarching spotLightsRayMarching[ NUM_SPOT_LIGHTS ];\n\t#if NUM_SPOT_LIGHT_COORDS > 0\n\n\t\tuniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];\n\n\t#endif\n#endif\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform DirectionalLightRayMarching directionalLightsRayMarching[ NUM_DIR_LIGHTS ];\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\n\t#endif\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform PointLightRayMarching pointLightsRayMarching[ NUM_POINT_LIGHTS ];\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\n\t#endif\n#endif\n\n\nstruct SDFContext {\n\tfloat d;\n\tint stepsCount;\n\tint matId;\n\tint matId2;\n\tfloat matBlend;\n};\n\nSDFContext DefaultSDFContext(){\n\treturn SDFContext( 0., 0, 0, 0, 0. );\n}\nint DefaultSDFMaterial(){\n\treturn 0;\n}\n\n// start raymarching builder define code\n\n\nSDFContext GetDist(vec3 p) {\n\tSDFContext sdfContext = SDFContext(0., 0, 0, 0, 0.);\n\n\t// start GetDist builder body code\n\t\n\n\treturn sdfContext;\n}\n\nSDFContext RayMarch(vec3 ro, vec3 rd, float side) {\n\tSDFContext dO = SDFContext(0.,0,0,0,0.);\n\n\t#pragma unroll_loop_start\n\tfor(int i=0; i<MAX_STEPS; i++) {\n\t\tvec3 p = ro + rd*dO.d;\n\t\tSDFContext sdfContext = GetDist(p);\n\t\tdO.d += sdfContext.d * side;\n\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\tdO.stepsCount += 1;\n\t\t#endif\n\t\tdO.matId = sdfContext.matId;\n\t\tdO.matId2 = sdfContext.matId2;\n\t\tdO.matBlend = sdfContext.matBlend;\n\t\tif(dO.d>MAX_DIST || abs(sdfContext.d)<SURF_DIST) break;\n\t}\n\t#pragma unroll_loop_end\n\n\treturn dO;\n}\n\nvec3 GetNormal(vec3 p) {\n\tSDFContext sdfContext = GetDist(p);\n\tvec2 e = vec2(NORMALS_BIAS, 0);\n\n\tvec3 n = sdfContext.d - vec3(\n\t\tGetDist(p-e.xyy).d,\n\t\tGetDist(p-e.yxy).d,\n\t\tGetDist(p-e.yyx).d);\n\n\treturn normalize(n);\n}\n// https://iquilezles.org/articles/rmshadows\nfloat calcSoftshadow( in vec3 ro, in vec3 rd, float mint, float maxt, float k, inout SDFContext sdfContext )\n{\n\tfloat res = 1.0;\n\tfloat ph = 1e20;\n\tfor( float t=mint; t<maxt; )\n\t{\n\t\tfloat h = GetDist(ro + rd*t).d;\n\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\tsdfContext.stepsCount += 1;\n\t\t#endif\n\t\tif( h<SURF_DIST )\n\t\t\treturn 0.0;\n\t\tfloat y = h*h/(2.0*ph);\n\t\tfloat d = sqrt(h*h-y*y);\n\t\tres = min( res, k*d/max(0.0,t-y) );\n\t\tph = h;\n\t\tt += h;\n\t}\n\treturn res;\n}\n\nvec3 GetLight(vec3 _p, vec3 _n, inout SDFContext sdfContext) {\n\tvec3 dif = vec3(0.,0.,0.);\n\t// GeometricContext geometry;\n\t// geometry.position = _p;\n\t// geometry.normal = _n;\n\t// geometry.viewDir = rayDir;\n\n\t// vec4 mvPosition = vec4( p, 1.0 );\n\t// mvPosition = modelViewMatrix * mvPosition;\n\t// vec3 vViewPosition = - mvPosition.xyz;\n\tvec3 pWorld = ( vModelMatrix * vec4( _p, 1.0 )).xyz;\n\tvec3 nWorld = transformDirection(_n, vModelMatrix);\n\t// geometry.position = (VViewMatrix * vec4( _p, 1.0 )).xyz;\n\tvec3 geometryPosition = (VViewMatrix * vec4(pWorld, 1.0 )).xyz;\n\t// geometry.normal = transformDirection(_n, VViewMatrix);\n\t// geometry.normal = inverseTransformDirection(transformDirection(_n, VViewMatrix), vInverseModelMatrix);\n\tvec3 geometryNormal = transformDirection(nWorld, VViewMatrix);\n\t\n\n\t#if NUM_SPOT_LIGHTS > 0 || NUM_DIR_LIGHTS > 0 || NUM_HEMI_LIGHTS > 0 || NUM_POINT_LIGHTS > 0 || NUM_RECT_AREA_LIGHTS > 0\n\n\t\tIncidentLight directLight;\n\t\tReflectedLight reflectedLight;\n\t\tvec3 lightPos, lightDir, worldLightDir, objectSpaceLightDir, lighDif, directDiffuse;\n\t\tfloat dotNL, lightDistance;\n\t\t#if NUM_SPOT_LIGHTS > 0\n\t\t\tSpotLightRayMarching spotLightRayMarching;\n\t\t\tSpotLight spotLight;\n\t\t\tfloat spotLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\t\t\t\tSpotLightShadow spotLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\t\t\tspotLightRayMarching = spotLightsRayMarching[ i ];\n\t\t\t\tspotLight = spotLights[ i ];\n\t\t\t\tgetSpotLightInfo( spotLight, geometryPosition, directLight );\n\n\t\t\t\t// #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t\t\t// \tspotLightShadow = spotLightShadows[ i ];\n\t\t\t\t// \tvec4 spotLightShadowCoord = spotLightMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t// \tdirectLight.color *= (directLight.visible && receiveShadow) ? getShadow(\n\t\t\t\t// \t\tspotShadowMap[ i ],\n\t\t\t\t// \t\tspotLightShadow.shadowMapSize,\n\t\t\t\t// \t\tspotLightShadow.shadowBias,\n\t\t\t\t// \t\tspotLightShadow.shadowRadius,\n\t\t\t\t// \t\tspotLightShadowCoord\n\t\t\t\t// \t) : 1.0;\n\t\t\t\t// #endif\n\n\t\t\t\tlightPos = spotLight.position;\n\t\t\t\tlightDir = normalize(lightPos-geometryPosition);\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tlightDistance = distance(geometryPosition,lightPos);\n\t\t\t\tspotLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < spotLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t: calcSoftshadow(\n\t\t\t\t\t\t_p,\n\t\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\t\tspotLightRayMarching.shadowBiasDistance,\n\t\t\t\t\t\tdistance(geometryPosition,lightPos),\n\t\t\t\t\t\t1./max(spotLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\t\tsdfContext\n\t\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * spotLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\t\t#if NUM_DIR_LIGHTS > 0\n\t\t\tDirectionalLightRayMarching directionalLightRayMarching;\n\t\t\tDirectionalLight directionalLight;\n\t\t\tfloat dirLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\t\t\t\tDirectionalLightShadow directionalLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\t\t\tdirectionalLightRayMarching = directionalLightsRayMarching[ i ];\n\t\t\t\tdirectionalLight = directionalLights[ i ];\n\t\t\t\t\n\t\t\t\tgetDirectionalLightInfo( directionalLight, directLight );\n\n\t\t\t\t// #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\t\t\t// \tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\t\t\t// \tvec4 dirLightShadowCoord = directionalShadowMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t// \tdirectLight.color *= (directLight.visible && receiveShadow) ? getShadow(\n\t\t\t\t// \t\tdirectionalShadowMap[ i ],\n\t\t\t\t// \t\tdirectionalLightShadow.shadowMapSize,\n\t\t\t\t// \t\tdirectionalLightShadow.shadowBias,\n\t\t\t\t// \t\tdirectionalLightShadow.shadowRadius,\n\t\t\t\t// \t\tdirLightShadowCoord\n\t\t\t\t// \t) : 1.0;\n\t\t\t\t// #endif\n\n\t\t\t\tlightDir = directionalLight.direction;\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tdirLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < directionalLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t:\n\t\t\t\t\tcalcSoftshadow(\n\t\t\t\t\t\t_p,\n\t\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\t\tdirectionalLightRayMarching.shadowBiasDistance,\n\t\t\t\t\t\tMAX_DIST,//distance(geometryPosition,lightPos),\n\t\t\t\t\t\t1./max(directionalLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\t\tsdfContext\n\t\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\t// lighDif = directLight.color * dotNL * dirLightSdfShadow;\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * dirLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\n\t\t#if ( NUM_HEMI_LIGHTS > 0 )\n\n\t\t\t#pragma unroll_loop_start\n\t\t\tHemisphereLight hemiLight;\n\t\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\t\themiLight = hemisphereLights[ i ];\n\t\t\t\tdif += getHemisphereLightIrradiance( hemiLight, geometryNormal ) * BRDF_Lambert( vec3(1.) );\n\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\n\t\t#endif\n\n\t\t#if NUM_POINT_LIGHTS > 0\n\t\t\tPointLightRayMarching pointLightRayMarching;\n\t\t\tPointLight pointLight;\n\t\t\tfloat pointLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\t\t\t\tPointLightShadow pointLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\t\t\tpointLightRayMarching = pointLightsRayMarching[ i ];\n\t\t\t\tpointLight = pointLights[ i ];\n\t\t\t\tgetPointLightInfo( pointLight, geometryPosition, directLight );\n\n\n\t\t\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\t\t\t\tpointLightShadow = pointLightShadows[ i ];\n\t\t\t\t\tvec4 pointLightShadowCoord = pointShadowMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t\tdirectLight.color *= (directLight.visible && receiveShadow) ? getPointShadow(\n\t\t\t\t\t\tpointShadowMap[ i ],\n\t\t\t\t\t\tpointLightShadow.shadowMapSize,\n\t\t\t\t\t\tpointLightShadow.shadowBias,\n\t\t\t\t\t\tpointLightShadow.shadowRadius,\n\t\t\t\t\t\tpointLightShadowCoord,\n\t\t\t\t\t\tpointLightShadow.shadowCameraNear,\n\t\t\t\t\t\tpointLightShadow.shadowCameraFar\n\t\t\t\t\t) : 1.0;\n\t\t\t\t#endif\n\n\t\t\t\tlightPos = pointLight.position;\n\t\t\t\tlightDir = normalize(lightPos-geometryPosition);\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tpointLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < pointLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t:\n\t\t\t\t\tcalcSoftshadow(\n\t\t\t\t\t_p,\n\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\tpointLightRayMarching.shadowBiasDistance,\n\t\t\t\t\tdistance(geometryPosition,lightPos),\n\t\t\t\t\t1./max(pointLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\tsdfContext\n\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * pointLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\n\t\t#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\n\t\t\tRectAreaLight rectAreaLight;\n\t\t\t// AreaLightRayMarching areaLightRayMarching;\n\t\t\tPhysicalMaterial material;\n\t\t\tmaterial.roughness = 1.;\n\t\t\tmaterial.specularColor = vec3(1.);\n\t\t\tmaterial.diffuseColor = vec3(1.);\n\n\t\t\tvec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( cameraPosition - geometryPosition );\n\t\t\tvec3 geometryClearcoatNormal = geometryNormal;\n\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\t\t\t// areaLightRayMarching = areaLightsRayMarching[ i ];\n\t\t\t\trectAreaLight = rectAreaLights[ i ];\n\t\t\t\t// rectAreaLight.position = areaLightRayMarching.worldPos;\n\n\t\t\t\tRE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t\tdif += reflectedLight.directDiffuse;\n\n\t\t#endif\n\t#endif\n\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\n\t#if defined( USE_LIGHT_PROBES )\n\n\t\tirradiance += getLightProbeIrradiance( lightProbe, geometryNormal );\n\n\t#endif\n\n\tdif += irradiance;\n\n\treturn dif;\n}\n\n\n\n// --- applyMaterial function definition\n\n\n\nvec4 applyShading(vec3 rayOrigin, vec3 rayDir, inout SDFContext sdfContext){\n\tvec3 p = rayOrigin + rayDir * sdfContext.d;\n\tvec3 n = GetNormal(p);\n\t\n\tvec3 col = applyMaterial(p, n, rayDir, sdfContext.matId, sdfContext);\n\tif(sdfContext.matBlend > 0.) {\n\t\t// blend material colors if needed\n\t\tvec3 col2 = applyMaterial(p, n, rayDir, sdfContext.matId2, sdfContext);\n\t\tcol = (1. - sdfContext.matBlend)*col + sdfContext.matBlend*col2;\n\t}\n\t\t\n\t// gamma\n\t//col = pow( col, vec3(0.4545) ); // this gamma leads to a different look than standard materials\n\treturn vec4(col, 1.);\n}\n\nvoid main()\t{\n\n\tvec3 rayDir = normalize(vPw - cameraPosition);\n\trayDir = transformDirection(rayDir, vInverseModelMatrix);\n\tvec3 rayOrigin = (vInverseModelMatrix * vec4( cameraPosition, 1.0 )).xyz;\n\n\tSDFContext sdfContext = RayMarch(rayOrigin, rayDir, 1.);\n\n\t#if defined( DEBUG_DEPTH )\n\t\tfloat normalizedDepth = 1.-(sdfContext.d - debugMinDepth ) / ( debugMaxDepth - debugMinDepth );\n\t\tnormalizedDepth = saturate(normalizedDepth); // clamp to [0,1]\n\t\tgl_FragColor = vec4(normalizedDepth);\n\t\treturn;\n\t#endif\n\t#if defined( SHADOW_DEPTH )\n\t\tfloat normalizedDepth = 1.-(sdfContext.d - debugMinDepth ) / ( debugMaxDepth - debugMinDepth );\n\t\t// float fragCoordZ = sdfContext.d / vHighPrecisionZW[1];\n\t\tfloat compoundedDepth = 0.5 * (normalizedDepth) + 0.5;\n\t\tfloat alpha = sdfContext.d < MAX_DIST ? 0.:1.;\n\t\tgl_FragColor = vec4( vec3(compoundedDepth), alpha );\n\t\t// normalizedDepth = 0.5*normalizedDepth+0.5;\n\t\t// gl_FragColor = packDepthToRGBA( normalizedDepth );\n\t\t// gl_FragColor = vec4(0.);\n\t\treturn;\n\t#endif\n\t#if defined( SHADOW_DISTANCE )\n\t\tfloat normalizedDepth = (sdfContext.d - shadowDistanceMin ) / ( shadowDistanceMax - shadowDistanceMin );\n\t\tnormalizedDepth = saturate(normalizedDepth); // clamp to [0,1]\n\t\tgl_FragColor = packDepthToRGBA( normalizedDepth );\n\t\treturn;\n\t#endif\n\n\tif( sdfContext.d < MAX_DIST ){\n\t\tgl_FragColor = applyShading(rayOrigin, rayDir, sdfContext);\n\t\t#if defined( TONE_MAPPING )\n\t\t\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n\t\t#endif\n\t\tgl_FragColor = linearToOutputTexel( gl_FragColor );\n\n\t\t#ifdef USE_FOG\n\t\t\tfloat vFogDepth = sdfContext.d;\n\t\t\t#ifdef FOG_EXP2\n\t\t\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );\n\t\t\t#else\n\t\t\t\tfloat fogFactor = smoothstep( fogNear, fogFar, vFogDepth );\n\t\t\t#endif\n\t\t\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n\t\t#endif\n\t\t#include <premultiplied_alpha_fragment>\n\t\t#include <dithering_fragment>\n\t} else {\n\t\tgl_FragColor = vec4(0.);\n\t}\n\n\t#if defined( DEBUG_STEPS_COUNT )\n\t\tfloat normalizedStepsCount = (float(sdfContext.stepsCount) - debugMinSteps ) / ( debugMaxSteps - debugMinSteps );\n\t\tgl_FragColor = vec4(normalizedStepsCount, 1.-normalizedStepsCount, 0., 1.);\n\t\treturn;\n\t#endif\n\t\n}","lights":false,"clipping":false},"onBeforeCompileDataJSONWithoutShaders":{"paramConfigs":[],"timeDependent":false,"resolutionDependent":false,"raymarchingLightsWorldCoordsDependent":true}}}}}}}},"params":{"CADLinearTolerance":{"overriden_options":{"callback":"{}"}},"CADAngularTolerance":{"overriden_options":{"callback":"{}"}},"CADCurveAbscissa":{"overriden_options":{"callback":"{}"}},"CADCurveTolerance":{"overriden_options":{"callback":"{}"}},"CADDisplayEdges":{"overriden_options":{"callback":"{}"}},"CADEdgesColor":{"overriden_options":{"callback":"{}"}},"CADDisplayMeshes":{"overriden_options":{"callback":"{}"}},"CADMeshesColor":{"overriden_options":{"callback":"{}"}},"CADWireframe":{"overriden_options":{"callback":"{}"}},"CSGFacetAngle":{"overriden_options":{"callback":"{}"}},"CSGLinesColor":{"overriden_options":{"callback":"{}"}},"CSGMeshesColor":{"overriden_options":{"callback":"{}"}},"CSGWireframe":{"overriden_options":{"callback":"{}"}},"QUADTriangles":{"overriden_options":{"callback":"{}"}},"QUADWireframe":{"overriden_options":{"callback":"{}"}},"TetScale":{"overriden_options":{"callback":"{}"}},"TetDisplayLines":{"overriden_options":{"callback":"{}"}},"TetDisplaySharedFaces":{"overriden_options":{"callback":"{}"}},"TetDisplayPoints":{"overriden_options":{"callback":"{}"}},"TetDisplayCenter":{"overriden_options":{"callback":"{}"}},"TetDisplaySphere":{"overriden_options":{"callback":"{}"}}},"flags":{"display":true}},"COP":{"type":"copNetwork","nodes":{"envMap":{"type":"envMap","inputs":["imageEnv"]},"imageEnv":{"type":"imageEXR","params":{"tminFilter":true,"tmagFilter":true,"tanisotropy":true,"useRendererMaxAnisotropy":true}},"image1":{"type":"image"}}},"lights":{"type":"geo","nodes":{"hemisphereLight1":{"type":"hemisphereLight","params":{"intensity":0.52}},"spotLight1":{"type":"spotLight","params":{"decay":0.1,"distance":10,"castShadow":1}},"polarTransform1":{"type":"polarTransform","params":{"center":[0,0.7,0],"latitude":25.2,"depth":3},"inputs":["spotLight1"]},"merge1":{"type":"merge","inputs":["hemisphereLight1","polarTransform1"],"flags":{"display":true}}},"params":{"CADLinearTolerance":{"overriden_options":{"callback":"{}"}},"CADAngularTolerance":{"overriden_options":{"callback":"{}"}},"CADCurveAbscissa":{"overriden_options":{"callback":"{}"}},"CADCurveTolerance":{"overriden_options":{"callback":"{}"}},"CADDisplayEdges":{"overriden_options":{"callback":"{}"}},"CADEdgesColor":{"overriden_options":{"callback":"{}"}},"CADDisplayMeshes":{"overriden_options":{"callback":"{}"}},"CADMeshesColor":{"overriden_options":{"callback":"{}"}},"CADWireframe":{"overriden_options":{"callback":"{}"}},"CSGFacetAngle":{"overriden_options":{"callback":"{}"}},"CSGLinesColor":{"overriden_options":{"callback":"{}"}},"CSGMeshesColor":{"overriden_options":{"callback":"{}"}},"CSGWireframe":{"overriden_options":{"callback":"{}"}},"QUADTriangles":{"overriden_options":{"callback":"{}"}},"QUADWireframe":{"overriden_options":{"callback":"{}"}},"TetScale":{"overriden_options":{"callback":"{}"}},"TetDisplayLines":{"overriden_options":{"callback":"{}"}},"TetDisplaySharedFaces":{"overriden_options":{"callback":"{}"}},"TetDisplayPoints":{"overriden_options":{"callback":"{}"}},"TetDisplayCenter":{"overriden_options":{"callback":"{}"}},"TetDisplaySphere":{"overriden_options":{"callback":"{}"}}},"flags":{"display":true}},"cameras":{"type":"geo","nodes":{"perspectiveCamera1":{"type":"perspectiveCamera","params":{"position":[3.3,3.3,3.3]}},"cameraControls1":{"type":"cameraControls","nodes":{"cameraOrbitControls1":{"type":"cameraOrbitControls","params":{"target":[0.09340836732398616,0.09450322255654031,-0.15671710041291376]}}},"params":{"node":"cameraOrbitControls1"},"inputs":["perspectiveCamera1"],"flags":{"display":true}}},"params":{"CADLinearTolerance":{"overriden_options":{"callback":"{}"}},"CADAngularTolerance":{"overriden_options":{"callback":"{}"}},"CADCurveAbscissa":{"overriden_options":{"callback":"{}"}},"CADCurveTolerance":{"overriden_options":{"callback":"{}"}},"CADDisplayEdges":{"overriden_options":{"callback":"{}"}},"CADEdgesColor":{"overriden_options":{"callback":"{}"}},"CADDisplayMeshes":{"overriden_options":{"callback":"{}"}},"CADMeshesColor":{"overriden_options":{"callback":"{}"}},"CADWireframe":{"overriden_options":{"callback":"{}"}},"CSGFacetAngle":{"overriden_options":{"callback":"{}"}},"CSGLinesColor":{"overriden_options":{"callback":"{}"}},"CSGMeshesColor":{"overriden_options":{"callback":"{}"}},"CSGWireframe":{"overriden_options":{"callback":"{}"}},"QUADTriangles":{"overriden_options":{"callback":"{}"}},"QUADWireframe":{"overriden_options":{"callback":"{}"}},"TetScale":{"overriden_options":{"callback":"{}"}},"TetDisplayLines":{"overriden_options":{"callback":"{}"}},"TetDisplaySharedFaces":{"overriden_options":{"callback":"{}"}},"TetDisplayPoints":{"overriden_options":{"callback":"{}"}},"TetDisplayCenter":{"overriden_options":{"callback":"{}"}},"TetDisplaySphere":{"overriden_options":{"callback":"{}"}}},"flags":{"display":true}}},"params":{"mainCameraPath":"/cameras/cameras:sopGroup/perspectiveCamera1"}},"ui":{"nodes":{"geo1":{"pos":[-50,-350],"selection":["MAT"],"nodes":{"box1":{"pos":[-100,100]},"material1":{"pos":[-100,250]},"MAT":{"pos":[-300,250],"selection":["rayMarchingBuilder1"],"nodes":{"rayMarchingBuilder1":{"pos":[-50,0],"nodes":{"globals1":{"pos":[-1300,-100]},"output1":{"pos":[300,0]},"SDFContext1":{"pos":[100,0]},"SDFMaterial1":{"pos":[-400,400]},"SDFSphere1":{"pos":[-700,-200]},"SDFSphere2":{"pos":[-700,0]},"SDFUnion1":{"pos":[-500,-100]},"floatToVec3_1":{"pos":[-900,0]},"cos1":{"pos":[-1100,0]},"constant1":{"pos":[-600,400]},"SDFSphere3":{"pos":[-400,-350]},"SDFSphere4":{"pos":[-450,50]},"SDFUnion2":{"pos":[-250,-150]},"SDFPlane1":{"pos":[-250,150]},"SDFUnion3":{"pos":[-100,0]},"grid1":{"pos":[-650,550]},"checkers1":{"pos":[-800,800]},"mix1":{"pos":[-600,650]},"constant2":{"pos":[-850,500]},"constant3":{"pos":[-850,650]},"globals2":{"pos":[-1150,800]},"vec3ToFloat1":{"pos":[-1050,800]},"floatToVec2_1":{"pos":[-950,800]}}}}}}},"COP":{"pos":[-300,-50],"selection":["image1"],"nodes":{"envMap":{"pos":[50,250]},"imageEnv":{"pos":[50,100]},"image1":{"pos":[-200,100]}}},"lights":{"pos":[-50,-250],"selection":["hemisphereLight1"],"nodes":{"hemisphereLight1":{"pos":[50,-50]},"spotLight1":{"pos":[300,-50]},"polarTransform1":{"pos":[300,150]},"merge1":{"pos":[100,300]}}},"cameras":{"pos":[-50,-150],"nodes":{"perspectiveCamera1":{"pos":[0,-50]},"cameraControls1":{"pos":[0,150],"nodes":{"cameraOrbitControls1":{"pos":[0,0]}}}}}}},"shaders":{"/geo1/MAT/rayMarchingBuilder1":{"vertex":"precision highp float;\nprecision highp int;\n\nvarying vec3 vPw;\nvarying mat4 vModelMatrix;\nvarying mat4 vInverseModelMatrix;\nvarying mat4 VViewMatrix;\n\n#include <common>\n\n// // for depth material\n// varying vec2 vHighPrecisionZW;\n\nvoid main()\t{\n\n\tvModelMatrix = modelMatrix;\n\tvInverseModelMatrix = inverse(modelMatrix);\n\tVViewMatrix = viewMatrix;\n\tvPw = (modelMatrix * vec4( position, 1.0 )).xyz;\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n\t// vHighPrecisionZW = gl_Position.zw;\n}","fragment":"precision highp float;\nprecision highp int;\n\n// --- applyMaterial constants definition\nuniform int MAX_STEPS;\nuniform float MAX_DIST;\nuniform float SURF_DIST;\nuniform float NORMALS_BIAS;\nuniform float SHADOW_BIAS;\n#define ZERO 0\nuniform float debugMinSteps;\nuniform float debugMaxSteps;\nuniform float debugMinDepth;\nuniform float debugMaxDepth;\n\n#include <common>\n#include <packing>\n#include <lightmap_pars_fragment>\n#include <bsdfs>\n#include <cube_uv_reflection_fragment>\n#include <lights_pars_begin>\n#include <lights_physical_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <fog_pars_fragment>\n\n#if defined( SHADOW_DISTANCE )\n\tuniform float shadowDistanceMin;\n\tuniform float shadowDistanceMax;\n#endif \n#if defined( SHADOW_DEPTH )\n\tuniform float shadowDepthMin;\n\tuniform float shadowDepthMax;\n#endif\n\n// varying vec2 vHighPrecisionZW;\n\nvarying vec3 vPw;\nvarying mat4 vModelMatrix;\nvarying mat4 vInverseModelMatrix;\nvarying mat4 VViewMatrix;\n\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform SpotLightRayMarching spotLightsRayMarching[ NUM_SPOT_LIGHTS ];\n\t#if NUM_SPOT_LIGHT_COORDS > 0\n\n\t\tuniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];\n\n\t#endif\n#endif\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform DirectionalLightRayMarching directionalLightsRayMarching[ NUM_DIR_LIGHTS ];\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\n\t#endif\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform PointLightRayMarching pointLightsRayMarching[ NUM_POINT_LIGHTS ];\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\n\t#endif\n#endif\n\n\nstruct SDFContext {\n\tfloat d;\n\tint stepsCount;\n\tint matId;\n\tint matId2;\n\tfloat matBlend;\n};\n\nSDFContext DefaultSDFContext(){\n\treturn SDFContext( 0., 0, 0, 0, 0. );\n}\nint DefaultSDFMaterial(){\n\treturn 0;\n}\n\n// start raymarching builder define code\n\n\n\n// /geo1/MAT/rayMarchingBuilder1/SDFSphere3\nfloat dot2( in vec2 v ) { return dot(v,v); }\nfloat dot2( in vec3 v ) { return dot(v,v); }\nfloat ndot( in vec2 a, in vec2 b ) { return a.x*b.x - a.y*b.y; }\n// https://iquilezles.org/articles/distfunctions/\n\n\n/*\n*\n* SDF PRIMITIVES\n*\n*/\nfloat sdSphere( vec3 p, float s )\n{\n\treturn length(p)-s;\n}\nfloat sdCutSphere( vec3 p, float r, float h )\n{\n\t// sampling independent computations (only depend on shape)\n\tfloat w = sqrt(r*r-h*h);\n\n\t// sampling dependant computations\n\tvec2 q = vec2( length(p.xz), p.y );\n\tfloat s = max( (h-r)*q.x*q.x+w*w*(h+r-2.0*q.y), h*q.x-w*q.y );\n\treturn (s<0.0) ? length(q)-r :\n\t\t\t\t(q.x<w) ? h - q.y :\n\t\t\t\t\tlength(q-vec2(w,h));\n}\nfloat sdCutHollowSphere( vec3 p, float r, float h, float t )\n{\n\t// sampling independent computations (only depend on shape)\n\tfloat w = sqrt(r*r-h*h);\n\t\n\t// sampling dependant computations\n\tvec2 q = vec2( length(p.xz), p.y );\n\treturn ((h*q.x<w*q.y) ? length(q-vec2(w,h)) : \n\t\t\t\t\t\t\tabs(length(q)-r) ) - t;\n}\n\nfloat sdBox( vec3 p, vec3 b )\n{\n\tvec3 q = abs(p) - b*0.5;\n\treturn length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0);\n}\nfloat sdRoundBox( vec3 p, vec3 b, float r )\n{\n\tvec3 q = abs(p) - b*0.5;\n\treturn length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0) - r;\n}\n\n\nfloat sdBoxFrame( vec3 p, vec3 b, float e )\n{\n\t\tp = abs(p )-b*0.5;\n\tvec3 q = abs(p+e)-e;\n\treturn min(min(\n\t\tlength(max(vec3(p.x,q.y,q.z),0.0))+min(max(p.x,max(q.y,q.z)),0.0),\n\t\tlength(max(vec3(q.x,p.y,q.z),0.0))+min(max(q.x,max(p.y,q.z)),0.0)),\n\t\tlength(max(vec3(q.x,q.y,p.z),0.0))+min(max(q.x,max(q.y,p.z)),0.0));\n}\nfloat sdCapsule( vec3 p, vec3 a, vec3 b, float r )\n{\n\tvec3 pa = p - a, ba = b - a;\n\tfloat h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n\treturn length( pa - ba*h ) - r;\n}\nfloat sdVerticalCapsule( vec3 p, float h, float r )\n{\n\tp.y -= clamp( p.y, 0.0, h );\n\treturn length( p ) - r;\n}\nfloat sdCone( in vec3 p, in vec2 c, float h )\n{\n\t// c is the sin/cos of the angle, h is height\n\t// Alternatively pass q instead of (c,h),\n\t// which is the point at the base in 2D\n\tvec2 q = h*vec2(c.x/c.y,-1.0);\n\n\tvec2 w = vec2( length(p.xz), p.y );\n\tvec2 a = w - q*clamp( dot(w,q)/dot(q,q), 0.0, 1.0 );\n\tvec2 b = w - q*vec2( clamp( w.x/q.x, 0.0, 1.0 ), 1.0 );\n\tfloat k = sign( q.y );\n\tfloat d = min(dot( a, a ),dot(b, b));\n\tfloat s = max( k*(w.x*q.y-w.y*q.x),k*(w.y-q.y) );\n\treturn sqrt(d)*sign(s);\n}\nfloat sdConeWrapped(vec3 pos, float angle, float height){\n\treturn sdCone(pos, vec2(sin(angle), cos(angle)), height);\n}\nfloat sdRoundCone( vec3 p, float r1, float r2, float h )\n{\n\tfloat b = (r1-r2)/h;\n\tfloat a = sqrt(1.0-b*b);\n\n\tvec2 q = vec2( length(p.xz), p.y );\n\tfloat k = dot(q,vec2(-b,a));\n\tif( k<0.0 ) return length(q) - r1;\n\tif( k>a*h ) return length(q-vec2(0.0,h)) - r2;\n\treturn dot(q, vec2(a,b) ) - r1;\n}\nfloat sdOctogonPrism( in vec3 p, in float r, float h )\n{\n\tconst vec3 k = vec3(-0.9238795325, // sqrt(2+sqrt(2))/2 \n\t\t\t\t\t\t0.3826834323, // sqrt(2-sqrt(2))/2\n\t\t\t\t\t\t0.4142135623 ); // sqrt(2)-1 \n\t// reflections\n\tp = abs(p);\n\tp.xy -= 2.0*min(dot(vec2( k.x,k.y),p.xy),0.0)*vec2( k.x,k.y);\n\tp.xy -= 2.0*min(dot(vec2(-k.x,k.y),p.xy),0.0)*vec2(-k.x,k.y);\n\t// polygon side\n\tp.xy -= vec2(clamp(p.x, -k.z*r, k.z*r), r);\n\tvec2 d = vec2( length(p.xy)*sign(p.y), p.z-h );\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdHexPrism( vec3 p, vec2 h )\n{\n\tconst vec3 k = vec3(-0.8660254, 0.5, 0.57735);\n\tp = abs(p);\n\tp.xy -= 2.0*min(dot(k.xy, p.xy), 0.0)*k.xy;\n\tvec2 d = vec2(\n\t\tlength(p.xy-vec2(clamp(p.x,-k.z*h.x,k.z*h.x), h.x))*sign(p.y-h.x),\n\t\tp.z-h.y );\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdHorseshoe( in vec3 p, in float angle, in float r, in float le, vec2 w )\n{\n\tvec2 c = vec2(cos(angle),sin(angle));\n\tp.x = abs(p.x);\n\tfloat l = length(p.xy);\n\tp.xy = mat2(-c.x, c.y, \n\t\t\tc.y, c.x)*p.xy;\n\tp.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x),\n\t\t\t\t(p.x>0.0)?p.y:l );\n\tp.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0);\n\t\n\tvec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z);\n\tvec2 d = abs(q) - w;\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdTriPrism( vec3 p, vec2 h )\n{\n\tvec3 q = abs(p);\n\treturn max(q.z-h.y,max(q.x*0.866025+p.y*0.5,-p.y)-h.x*0.5);\n}\nfloat sdPyramid( vec3 p, float h)\n{\n\tfloat m2 = h*h + 0.25;\n\n\tp.xz = abs(p.xz);\n\tp.xz = (p.z>p.x) ? p.zx : p.xz;\n\tp.xz -= 0.5;\n\n\tvec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y);\n\n\tfloat s = max(-q.x,0.0);\n\tfloat t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 );\n\n\tfloat a = m2*(q.x+s)*(q.x+s) + q.y*q.y;\n\tfloat b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t);\n\n\tfloat d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b);\n\n\treturn sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));\n}\n\nfloat sdPlane( vec3 p, vec3 n, float h )\n{\n\t// n must be normalized\n\treturn dot(p,n) + h;\n}\n\nfloat sdTorus( vec3 p, vec2 t )\n{\n\tvec2 q = vec2(length(p.xz)-t.x,p.y);\n\treturn length(q)-t.y;\n}\nfloat sdCappedTorus(in vec3 p, in float an, in float ra, in float rb)\n{\n\tvec2 sc = vec2(sin(an),cos(an));\n\tp.x = abs(p.x);\n\tfloat k = (sc.y*p.x>sc.x*p.z) ? dot(p.xz,sc) : length(p.xz);\n\treturn sqrt( dot(p,p) + ra*ra - 2.0*ra*k ) - rb;\n}\nfloat sdLink( vec3 p, float le, float r1, float r2 )\n{\n vec3 q = vec3( p.x, max(abs(p.y)-le,0.0), p.z );\n return length(vec2(length(q.xy)-r1,q.z)) - r2;\n}\n// c is the sin/cos of the desired cone angle\nfloat sdSolidAngle(vec3 pos, vec2 c, float radius)\n{\n\tvec2 p = vec2( length(pos.xz), pos.y );\n\tfloat l = length(p) - radius;\n\tfloat m = length(p - c*clamp(dot(p,c),0.0,radius) );\n\treturn max(l,m*sign(c.y*p.x-c.x*p.y));\n}\nfloat sdSolidAngleWrapped(vec3 pos, float angle, float radius){\n\treturn sdSolidAngle(pos, vec2(sin(angle), cos(angle)), radius);\n}\nfloat sdTube( vec3 p, float r )\n{\n\treturn length(p.xz)-r;\n}\nfloat sdTubeCapped( vec3 p, float h, float r )\n{\n\tvec2 d = abs(vec2(length(p.xz),p.y)) - vec2(r,h);\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdOctahedron( vec3 p, float s)\n{\n p = abs(p);\n float m = p.x+p.y+p.z-s;\n vec3 q;\n if( 3.0*p.x < m ) q = p.xyz;\n else if( 3.0*p.y < m ) q = p.yzx;\n else if( 3.0*p.z < m ) q = p.zxy;\n else return m*0.57735027;\n \n float k = clamp(0.5*(q.z-q.y+s),0.0,s); \n return length(vec3(q.x,q.y-s+k,q.z-k)); \n}\nfloat udTriangle( vec3 p, vec3 a, vec3 b, vec3 c, float thickness )\n{\n\tvec3 ba = b - a; vec3 pa = p - a;\n\tvec3 cb = c - b; vec3 pb = p - b;\n\tvec3 ac = a - c; vec3 pc = p - c;\n\tvec3 nor = cross( ba, ac );\n\n\treturn - thickness + sqrt(\n\t\t(sign(dot(cross(ba,nor),pa)) +\n\t\tsign(dot(cross(cb,nor),pb)) +\n\t\tsign(dot(cross(ac,nor),pc))<2.0)\n\t\t?\n\t\tmin( min(\n\t\tdot2(ba*clamp(dot(ba,pa)/dot2(ba),0.0,1.0)-pa),\n\t\tdot2(cb*clamp(dot(cb,pb)/dot2(cb),0.0,1.0)-pb) ),\n\t\tdot2(ac*clamp(dot(ac,pc)/dot2(ac),0.0,1.0)-pc) )\n\t\t:\n\t\tdot(nor,pa)*dot(nor,pa)/dot2(nor) );\n}\nfloat udQuad( vec3 p, vec3 a, vec3 b, vec3 c, vec3 d, float thickness )\n{\n\tvec3 ba = b - a; vec3 pa = p - a;\n\tvec3 cb = c - b; vec3 pb = p - b;\n\tvec3 dc = d - c; vec3 pc = p - c;\n\tvec3 ad = a - d; vec3 pd = p - d;\n\tvec3 nor = cross( ba, ad );\n\n\treturn - thickness + sqrt(\n\t\t(sign(dot(cross(ba,nor),pa)) +\n\t\tsign(dot(cross(cb,nor),pb)) +\n\t\tsign(dot(cross(dc,nor),pc)) +\n\t\tsign(dot(cross(ad,nor),pd))<3.0)\n\t\t?\n\t\tmin( min( min(\n\t\tdot2(ba*clamp(dot(ba,pa)/dot2(ba),0.0,1.0)-pa),\n\t\tdot2(cb*clamp(dot(cb,pb)/dot2(cb),0.0,1.0)-pb) ),\n\t\tdot2(dc*clamp(dot(dc,pc)/dot2(dc),0.0,1.0)-pc) ),\n\t\tdot2(ad*clamp(dot(ad,pd)/dot2(ad),0.0,1.0)-pd) )\n\t\t:\n\t\tdot(nor,pa)*dot(nor,pa)/dot2(nor) );\n}\n\n/*\n*\n* SDF OPERATIONS\n*\n*/\nfloat SDFUnion( float d1, float d2 ) { return min(d1,d2); }\nfloat SDFSubtract( float d1, float d2 ) { return max(-d1,d2); }\nfloat SDFIntersect( float d1, float d2 ) { return max(d1,d2); }\n\nfloat SDFSmoothUnion( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 + 0.5*(d2-d1)/k, 0.0, 1.0 );\n\treturn mix( d2, d1, h ) - k*h*(1.0-h);\n}\n\nfloat SDFSmoothSubtract( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 - 0.5*(d2+d1)/k, 0.0, 1.0 );\n\treturn mix( d2, -d1, h ) + k*h*(1.0-h);\n}\n\nfloat SDFSmoothIntersect( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 - 0.5*(d2-d1)/k, 0.0, 1.0 );\n\treturn mix( d2, d1, h ) + k*h*(1.0-h);\n}\n\nvec4 SDFElongateFast( in vec3 p, in vec3 h )\n{\n\treturn vec4( p-clamp(p,-h,h), 0.0 );\n}\nvec4 SDFElongateSlow( in vec3 p, in vec3 h )\n{\n\tvec3 q = abs(p)-h;\n\treturn vec4( max(q,0.0), min(max(q.x,max(q.y,q.z)),0.0) );\n}\n\nfloat SDFOnion( in float sdf, in float thickness )\n{\n\treturn abs(sdf)-thickness;\n}\n\n// /geo1/MAT/rayMarchingBuilder1/checkers1\n// https://iquilezles.org/articles/checkerfiltering/\nfloat checkers(vec2 p) {\n\tvec2 s = sign(fract(p*.5)-.5);\n\treturn .5 - .5*s.x*s.y;\n}\nfloat checkersGrad( in vec2 p, in vec2 ddx, in vec2 ddy )\n{\n // filter kernel\n vec2 w = max(abs(ddx), abs(ddy)) + 0.01;\n // analytical integral (box filter)\n vec2 i = 2.0*(abs(fract((p-0.5*w)/2.0)-0.5)-abs(fract((p+0.5*w)/2.0)-0.5))/w;\n // xor pattern\n return 0.5 - 0.5*i.x*i.y;\n}\n\n\n// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\nconst int _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1 = 1;\n\n\n// https://stackoverflow.com/questions/23793698/how-to-implement-slerp-in-glsl-hlsl\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t)\n// {\n// \tfloat dotp = dot(normalize(p0), normalize(p1));\n// \tif ((dotp > 0.9999) || (dotp < -0.9999))\n// \t{\n// \t\tif (t<=0.5)\n// \t\t\treturn p0;\n// \t\treturn p1;\n// \t}\n// \tfloat theta = acos(dotp);\n// \tvec4 P = ((p0*sin((1.0-t)*theta) + p1*sin(t*theta)) / sin(theta));\n// \tP.w = 1.0;\n// \treturn P;\n// }\n\n// https://devcry.heiho.net/html/2017/20170521-slerp.html\n// float lerp(float a, float b, float t) {\n// \treturn (1.0 - t) * a + t * b;\n// }\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t){\n// \tvec4 qb = p1;\n\n// \t// cos(a) = dot product\n// \tfloat cos_a = p0.x * qb.x + p0.y * qb.y + p0.z * qb.z + p0.w * qb.w;\n// \tif (cos_a < 0.0f) {\n// \t\tcos_a = -cos_a;\n// \t\tqb = -qb;\n// \t}\n\n// \t// close to zero, cos(a) ~= 1\n// \t// do linear interpolation\n// \tif (cos_a > 0.999) {\n// \t\treturn vec4(\n// \t\t\tlerp(p0.x, qb.x, t),\n// \t\t\tlerp(p0.y, qb.y, t),\n// \t\t\tlerp(p0.z, qb.z, t),\n// \t\t\tlerp(p0.w, qb.w, t)\n// \t\t);\n// \t}\n\n// \tfloat alpha = acos(cos_a);\n// \treturn (p0 * sin(1.0 - t) + p1 * sin(t * alpha)) / sin(alpha);\n// }\n\n// https://stackoverflow.com/questions/62943083/interpolate-between-two-quaternions-the-long-way\nvec4 quatSlerp(vec4 q1, vec4 q2, float t){\n\tfloat angle = acos(dot(q1, q2));\n\tfloat denom = sin(angle);\n\t//check if denom is zero\n\treturn (q1*sin((1.0-t)*angle)+q2*sin(t*angle))/denom;\n}\n// TO CHECK:\n// this page https://www.reddit.com/r/opengl/comments/704la7/glsl_quaternion_library/\n// has a link to a potentially nice pdf:\n// http://web.mit.edu/2.998/www/QuaternionReport1.pdf\n\n// https://github.com/mattatz/ShibuyaCrowd/blob/master/source/shaders/common/quaternion.glsl\nvec4 quatMult(vec4 q1, vec4 q2)\n{\n\treturn vec4(\n\tq1.w * q2.x + q1.x * q2.w + q1.z * q2.y - q1.y * q2.z,\n\tq1.w * q2.y + q1.y * q2.w + q1.x * q2.z - q1.z * q2.x,\n\tq1.w * q2.z + q1.z * q2.w + q1.y * q2.x - q1.x * q2.y,\n\tq1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z\n\t);\n}\n// http://glmatrix.net/docs/quat.js.html#line97\n// let ax = a[0], ay = a[1], az = a[2], aw = a[3];\n\n// let bx = b[0], by = b[1], bz = b[2], bw = b[3];\n\n// out[0] = ax * bw + aw * bx + ay * bz - az * by;\n\n// out[1] = ay * bw + aw * by + az * bx - ax * bz;\n\n// out[2] = az * bw + aw * bz + ax * by - ay * bx;\n\n// out[3] = aw * bw - ax * bx - ay * by - az * bz;\n\n// return out\n\n\n\n// http://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/\nmat4 rotationMatrix(vec3 axis, float angle)\n{\n\taxis = normalize(axis);\n\tfloat s = sin(angle);\n\tfloat c = cos(angle);\n\tfloat oc = 1.0 - c;\n\n \treturn mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 0.0, 0.0, 0.0, 1.0);\n}\n\n// https://www.geeks3d.com/20141201/how-to-rotate-a-vertex-by-a-quaternion-in-glsl/\nvec4 quatFromAxisAngle(vec3 axis, float angle)\n{\n\tvec4 qr;\n\tfloat half_angle = (angle * 0.5); // * 3.14159 / 180.0;\n\tfloat sin_half_angle = sin(half_angle);\n\tqr.x = axis.x * sin_half_angle;\n\tqr.y = axis.y * sin_half_angle;\n\tqr.z = axis.z * sin_half_angle;\n\tqr.w = cos(half_angle);\n\treturn qr;\n}\nvec3 rotateWithAxisAngle(vec3 position, vec3 axis, float angle)\n{\n\tvec4 q = quatFromAxisAngle(axis, angle);\n\tvec3 v = position.xyz;\n\treturn v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);\n}\n// vec3 applyQuaternionToVector( vec4 q, vec3 v ){\n// \treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n// }\nvec3 rotateWithQuat( vec3 v, vec4 q )\n{\n\t// vec4 qv = multQuat( quat, vec4(vec, 0.0) );\n\t// return multQuat( qv, vec4(-quat.x, -quat.y, -quat.z, quat.w) ).xyz;\n\treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n}\n// https://github.com/glslify/glsl-look-at/blob/gh-pages/index.glsl\n// mat3 rotation_matrix(vec3 origin, vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target - origin);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n// mat3 rotation_matrix(vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n\nfloat vectorAngle(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 c1 = cross(start, dest);\n\t// We use the dot product of the cross with the Y axis.\n\t// This is a little arbitrary, but can still give a good sense of direction\n\tvec3 y_axis = vec3(0.0, 1.0, 0.0);\n\tfloat d1 = dot(c1, y_axis);\n\tfloat angle = acos(cosTheta) * sign(d1);\n\treturn angle;\n}\n\n// http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/#i-need-an-equivalent-of-glulookat-how-do-i-orient-an-object-towards-a-point-\nvec4 vectorAlign(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 axis;\n\n\t// if (cosTheta < -1 + 0.001f){\n\t// \t// special case when vectors in opposite directions:\n\t// \t// there is no ideal rotation axis\n\t// \t// So guess one; any will do as long as it's perpendicular to start\n\t// \taxis = cross(vec3(0.0f, 0.0f, 1.0f), start);\n\t// \tif (length2(axis) < 0.01 ) // bad luck, they were parallel, try again!\n\t// \t\taxis = cross(vec3(1.0f, 0.0f, 0.0f), start);\n\n\t// \taxis = normalize(axis);\n\t// \treturn gtx::quaternion::angleAxis(glm::radians(180.0f), axis);\n\t// }\n\tif(cosTheta > (1.0 - 0.0001) || cosTheta < (-1.0 + 0.0001) ){\n\t\taxis = normalize(cross(start, vec3(0.0, 1.0, 0.0)));\n\t\tif (length(axis) < 0.001 ){ // bad luck, they were parallel, try again!\n\t\t\taxis = normalize(cross(start, vec3(1.0, 0.0, 0.0)));\n\t\t}\n\t} else {\n\t\taxis = normalize(cross(start, dest));\n\t}\n\n\tfloat angle = acos(cosTheta);\n\n\treturn quatFromAxisAngle(axis, angle);\n}\nvec4 vectorAlignWithUp(vec3 start, vec3 dest, vec3 up){\n\tvec4 rot1 = vectorAlign(start, dest);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\t// vec3 right = normalize(cross(dest, up));\n\t// up = normalize(cross(right, dest));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(vec3(0.0, 1.0, 0.0), rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(up, newUp);\n\n\t// return rot1;\n\treturn rot2;\n\t// return multQuat(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\n// https://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\nfloat quatToAngle(vec4 q){\n\treturn 2.0 * acos(q.w);\n}\nvec3 quatToAxis(vec4 q){\n\treturn vec3(\n\t\tq.x / sqrt(1.0-q.w*q.w),\n\t\tq.y / sqrt(1.0-q.w*q.w),\n\t\tq.z / sqrt(1.0-q.w*q.w)\n\t);\n}\n\nvec4 align(vec3 dir, vec3 up){\n\tvec3 start_dir = vec3(0.0, 0.0, 1.0);\n\tvec3 start_up = vec3(0.0, 1.0, 0.0);\n\tvec4 rot1 = vectorAlign(start_dir, dir);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\tvec3 right = normalize(cross(dir, up));\n\tif(length(right)<0.001){\n\t\tright = vec3(1.0, 0.0, 0.0);\n\t}\n\tup = normalize(cross(right, dir));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(start_up, rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(normalize(newUp), up);\n\n\t// return rot1;\n\treturn quatMult(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\nstruct EnvMapProps {\n\tvec3 tint;\n\tfloat intensity;\n\tfloat roughness;\n\tfloat fresnel;\n\tfloat fresnelPower;\n};\nuniform sampler2D envMap;\nuniform float envMapIntensity;\nuniform float roughness;\n#ifdef ROTATE_ENV_MAP_Y\n\tuniform float envMapRotationY;\n#endif\nvec3 envMapSample(vec3 rayDir, float envMapRoughness){\n\t// http://www.pocketgl.com/reflections/\n\tvec3 env = vec3(0.);\n\t// vec2 uv = vec2( atan( -rayDir.z, -rayDir.x ) * RECIPROCAL_PI2 + 0.5, rayDir.y * 0.5 + 0.5 );\n\t// vec3 env = texture2D(map, uv).rgb;\n\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t#ifdef ROTATE_ENV_MAP_Y\n\t\t\trayDir = rotateWithAxisAngle(rayDir, vec3(0.,1.,0.), envMapRotationY);\n\t\t#endif\n\t\tenv = textureCubeUV(envMap, rayDir, envMapRoughness * roughness).rgb;\n\t#endif\n\treturn env;\n}\nvec3 envMapSampleWithFresnel(vec3 rayDir, EnvMapProps envMapProps, vec3 n, vec3 cameraPosition){\n\t// http://www.pocketgl.com/reflections/\n\tvec3 env = envMapSample(rayDir, envMapProps.roughness);\n\tfloat fresnel = pow(1.-dot(normalize(cameraPosition), n), envMapProps.fresnelPower);\n\tfloat fresnelFactor = (1.-envMapProps.fresnel) + envMapProps.fresnel*fresnel;\n\treturn env * envMapIntensity * envMapProps.tint * envMapProps.intensity * fresnelFactor;\n}\n\n\n\n\n\n\nSDFContext GetDist(vec3 p) {\n\tSDFContext sdfContext = SDFContext(0., 0, 0, 0, 0.);\n\n\t// start GetDist builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/SDFSphere3\n\tfloat v_POLY_SDFSphere3_float = sdSphere(p - vec3(-0.25, 0.0, 0.0), 0.2);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFSphere4\n\tfloat v_POLY_SDFSphere4_float = sdSphere(p - vec3(0.25, 0.0, 0.0), 0.2);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFPlane1\n\tfloat v_POLY_SDFPlane1_float = sdPlane(p-vec3(0.0, -0.2, 0.0), vec3(0.0, 1.0, 0.0), 0.0);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFUnion2\n\tfloat v_POLY_SDFUnion2_union = SDFSmoothUnion(v_POLY_SDFSphere3_float, v_POLY_SDFSphere4_float, 0.31);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFUnion3\n\tfloat v_POLY_SDFUnion3_union = SDFSmoothUnion(v_POLY_SDFUnion2_union, v_POLY_SDFPlane1_float, 0.31);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFContext1\n\tSDFContext v_POLY_SDFContext1_SDFContext = SDFContext(v_POLY_SDFUnion3_union, 0, _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1, _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1, 0.);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/output1\n\tsdfContext = v_POLY_SDFContext1_SDFContext;\n\n\n\n\t\n\n\treturn sdfContext;\n}\n\nSDFContext RayMarch(vec3 ro, vec3 rd, float side) {\n\tSDFContext dO = SDFContext(0.,0,0,0,0.);\n\n\t#pragma unroll_loop_start\n\tfor(int i=0; i<MAX_STEPS; i++) {\n\t\tvec3 p = ro + rd*dO.d;\n\t\tSDFContext sdfContext = GetDist(p);\n\t\tdO.d += sdfContext.d * side;\n\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\tdO.stepsCount += 1;\n\t\t#endif\n\t\tdO.matId = sdfContext.matId;\n\t\tdO.matId2 = sdfContext.matId2;\n\t\tdO.matBlend = sdfContext.matBlend;\n\t\tif(dO.d>MAX_DIST || abs(sdfContext.d)<SURF_DIST) break;\n\t}\n\t#pragma unroll_loop_end\n\n\treturn dO;\n}\n\nvec3 GetNormal(vec3 p) {\n\tSDFContext sdfContext = GetDist(p);\n\tvec2 e = vec2(NORMALS_BIAS, 0);\n\n\tvec3 n = sdfContext.d - vec3(\n\t\tGetDist(p-e.xyy).d,\n\t\tGetDist(p-e.yxy).d,\n\t\tGetDist(p-e.yyx).d);\n\n\treturn normalize(n);\n}\n// https://iquilezles.org/articles/rmshadows\nfloat calcSoftshadow( in vec3 ro, in vec3 rd, float mint, float maxt, float k, inout SDFContext sdfContext )\n{\n\tfloat res = 1.0;\n\tfloat ph = 1e20;\n\tfor( float t=mint; t<maxt; )\n\t{\n\t\tfloat h = GetDist(ro + rd*t).d;\n\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\tsdfContext.stepsCount += 1;\n\t\t#endif\n\t\tif( h<SURF_DIST )\n\t\t\treturn 0.0;\n\t\tfloat y = h*h/(2.0*ph);\n\t\tfloat d = sqrt(h*h-y*y);\n\t\tres = min( res, k*d/max(0.0,t-y) );\n\t\tph = h;\n\t\tt += h;\n\t}\n\treturn res;\n}\n\nvec3 GetLight(vec3 _p, vec3 _n, inout SDFContext sdfContext) {\n\tvec3 dif = vec3(0.,0.,0.);\n\t// GeometricContext geometry;\n\t// geometry.position = _p;\n\t// geometry.normal = _n;\n\t// geometry.viewDir = rayDir;\n\n\t// vec4 mvPosition = vec4( p, 1.0 );\n\t// mvPosition = modelViewMatrix * mvPosition;\n\t// vec3 vViewPosition = - mvPosition.xyz;\n\tvec3 pWorld = ( vModelMatrix * vec4( _p, 1.0 )).xyz;\n\tvec3 nWorld = transformDirection(_n, vModelMatrix);\n\t// geometry.position = (VViewMatrix * vec4( _p, 1.0 )).xyz;\n\tvec3 geometryPosition = (VViewMatrix * vec4(pWorld, 1.0 )).xyz;\n\t// geometry.normal = transformDirection(_n, VViewMatrix);\n\t// geometry.normal = inverseTransformDirection(transformDirection(_n, VViewMatrix), vInverseModelMatrix);\n\tvec3 geometryNormal = transformDirection(nWorld, VViewMatrix);\n\t\n\n\t#if NUM_SPOT_LIGHTS > 0 || NUM_DIR_LIGHTS > 0 || NUM_HEMI_LIGHTS > 0 || NUM_POINT_LIGHTS > 0 || NUM_RECT_AREA_LIGHTS > 0\n\n\t\tIncidentLight directLight;\n\t\tReflectedLight reflectedLight;\n\t\tvec3 lightPos, lightDir, worldLightDir, objectSpaceLightDir, lighDif, directDiffuse;\n\t\tfloat dotNL, lightDistance;\n\t\t#if NUM_SPOT_LIGHTS > 0\n\t\t\tSpotLightRayMarching spotLightRayMarching;\n\t\t\tSpotLight spotLight;\n\t\t\tfloat spotLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\t\t\t\tSpotLightShadow spotLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\t\t\tspotLightRayMarching = spotLightsRayMarching[ i ];\n\t\t\t\tspotLight = spotLights[ i ];\n\t\t\t\tgetSpotLightInfo( spotLight, geometryPosition, directLight );\n\n\t\t\t\t// #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t\t\t// \tspotLightShadow = spotLightShadows[ i ];\n\t\t\t\t// \tvec4 spotLightShadowCoord = spotLightMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t// \tdirectLight.color *= (directLight.visible && receiveShadow) ? getShadow(\n\t\t\t\t// \t\tspotShadowMap[ i ],\n\t\t\t\t// \t\tspotLightShadow.shadowMapSize,\n\t\t\t\t// \t\tspotLightShadow.shadowBias,\n\t\t\t\t// \t\tspotLightShadow.shadowRadius,\n\t\t\t\t// \t\tspotLightShadowCoord\n\t\t\t\t// \t) : 1.0;\n\t\t\t\t// #endif\n\n\t\t\t\tlightPos = spotLight.position;\n\t\t\t\tlightDir = normalize(lightPos-geometryPosition);\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tlightDistance = distance(geometryPosition,lightPos);\n\t\t\t\tspotLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < spotLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t: calcSoftshadow(\n\t\t\t\t\t\t_p,\n\t\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\t\tspotLightRayMarching.shadowBiasDistance,\n\t\t\t\t\t\tdistance(geometryPosition,lightPos),\n\t\t\t\t\t\t1./max(spotLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\t\tsdfContext\n\t\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * spotLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\t\t#if NUM_DIR_LIGHTS > 0\n\t\t\tDirectionalLightRayMarching directionalLightRayMarching;\n\t\t\tDirectionalLight directionalLight;\n\t\t\tfloat dirLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\t\t\t\tDirectionalLightShadow directionalLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\t\t\tdirectionalLightRayMarching = directionalLightsRayMarching[ i ];\n\t\t\t\tdirectionalLight = directionalLights[ i ];\n\t\t\t\t\n\t\t\t\tgetDirectionalLightInfo( directionalLight, directLight );\n\n\t\t\t\t// #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\t\t\t// \tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\t\t\t// \tvec4 dirLightShadowCoord = directionalShadowMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t// \tdirectLight.color *= (directLight.visible && receiveShadow) ? getShadow(\n\t\t\t\t// \t\tdirectionalShadowMap[ i ],\n\t\t\t\t// \t\tdirectionalLightShadow.shadowMapSize,\n\t\t\t\t// \t\tdirectionalLightShadow.shadowBias,\n\t\t\t\t// \t\tdirectionalLightShadow.shadowRadius,\n\t\t\t\t// \t\tdirLightShadowCoord\n\t\t\t\t// \t) : 1.0;\n\t\t\t\t// #endif\n\n\t\t\t\tlightDir = directionalLight.direction;\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tdirLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < directionalLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t:\n\t\t\t\t\tcalcSoftshadow(\n\t\t\t\t\t\t_p,\n\t\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\t\tdirectionalLightRayMarching.shadowBiasDistance,\n\t\t\t\t\t\tMAX_DIST,//distance(geometryPosition,lightPos),\n\t\t\t\t\t\t1./max(directionalLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\t\tsdfContext\n\t\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\t// lighDif = directLight.color * dotNL * dirLightSdfShadow;\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * dirLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\n\t\t#if ( NUM_HEMI_LIGHTS > 0 )\n\n\t\t\t#pragma unroll_loop_start\n\t\t\tHemisphereLight hemiLight;\n\t\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\t\themiLight = hemisphereLights[ i ];\n\t\t\t\tdif += getHemisphereLightIrradiance( hemiLight, geometryNormal ) * BRDF_Lambert( vec3(1.) );\n\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\n\t\t#endif\n\n\t\t#if NUM_POINT_LIGHTS > 0\n\t\t\tPointLightRayMarching pointLightRayMarching;\n\t\t\tPointLight pointLight;\n\t\t\tfloat pointLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\t\t\t\tPointLightShadow pointLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\t\t\tpointLightRayMarching = pointLightsRayMarching[ i ];\n\t\t\t\tpointLight = pointLights[ i ];\n\t\t\t\tgetPointLightInfo( pointLight, geometryPosition, directLight );\n\n\n\t\t\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\t\t\t\tpointLightShadow = pointLightShadows[ i ];\n\t\t\t\t\tvec4 pointLightShadowCoord = pointShadowMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t\tdirectLight.color *= (directLight.visible && receiveShadow) ? getPointShadow(\n\t\t\t\t\t\tpointShadowMap[ i ],\n\t\t\t\t\t\tpointLightShadow.shadowMapSize,\n\t\t\t\t\t\tpointLightShadow.shadowBias,\n\t\t\t\t\t\tpointLightShadow.shadowRadius,\n\t\t\t\t\t\tpointLightShadowCoord,\n\t\t\t\t\t\tpointLightShadow.shadowCameraNear,\n\t\t\t\t\t\tpointLightShadow.shadowCameraFar\n\t\t\t\t\t) : 1.0;\n\t\t\t\t#endif\n\n\t\t\t\tlightPos = pointLight.position;\n\t\t\t\tlightDir = normalize(lightPos-geometryPosition);\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tpointLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < pointLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t:\n\t\t\t\t\tcalcSoftshadow(\n\t\t\t\t\t_p,\n\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\tpointLightRayMarching.shadowBiasDistance,\n\t\t\t\t\tdistance(geometryPosition,lightPos),\n\t\t\t\t\t1./max(pointLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\tsdfContext\n\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * pointLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\n\t\t#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\n\t\t\tRectAreaLight rectAreaLight;\n\t\t\t// AreaLightRayMarching areaLightRayMarching;\n\t\t\tPhysicalMaterial material;\n\t\t\tmaterial.roughness = 1.;\n\t\t\tmaterial.specularColor = vec3(1.);\n\t\t\tmaterial.diffuseColor = vec3(1.);\n\n\t\t\tvec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( cameraPosition - geometryPosition );\n\t\t\tvec3 geometryClearcoatNormal = geometryNormal;\n\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\t\t\t// areaLightRayMarching = areaLightsRayMarching[ i ];\n\t\t\t\trectAreaLight = rectAreaLights[ i ];\n\t\t\t\t// rectAreaLight.position = areaLightRayMarching.worldPos;\n\n\t\t\t\tRE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t\tdif += reflectedLight.directDiffuse;\n\n\t\t#endif\n\t#endif\n\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\n\t#if defined( USE_LIGHT_PROBES )\n\n\t\tirradiance += getLightProbeIrradiance( lightProbe, geometryNormal );\n\n\t#endif\n\n\tdif += irradiance;\n\n\treturn dif;\n}\n\n\n\n\nvec3 applyMaterialWithoutRefraction(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(1.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n\nvec3 applyMaterialWithoutReflection(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(1.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n#ifdef RAYMARCHED_REFLECTIONS\nvec3 GetReflection(vec3 p, vec3 n, vec3 rayDir, float biasMult, float roughness, int reflectionDepth, inout SDFContext sdfContextMain){\n\tbool hitReflection = true;\n\tvec3 reflectedColor = vec3(0.);\n\t#pragma unroll_loop_start\n\tfor(int i=0; i < reflectionDepth; i++) {\n\t\tif(hitReflection){\n\t\t\trayDir = reflect(rayDir, n);\n\t\t\tp += n*SURF_DIST*biasMult;\n\t\t\tSDFContext sdfContext = RayMarch(p, rayDir, 1.);\n\t\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\t\tsdfContextMain.stepsCount += sdfContext.stepsCount;\n\t\t\t#endif\n\t\t\tif( sdfContext.d >= MAX_DIST){\n\t\t\t\thitReflection = false;\n\t\t\t\treflectedColor = envMapSample(rayDir, roughness);\n\t\t\t}\n\t\t\tif(hitReflection){\n\t\t\t\tp += rayDir * sdfContext.d;\n\t\t\t\tn = GetNormal(p);\n\t\t\t\tvec3 matCol = applyMaterialWithoutReflection(p, n, rayDir, sdfContext.matId, sdfContextMain);\n\t\t\t\treflectedColor += matCol;\n\t\t\t}\n\t\t}\n\t}\n\t#pragma unroll_loop_end\n\treturn reflectedColor;\n}\n#endif\n\n#ifdef RAYMARCHED_REFRACTIONS\n// xyz for color, w for distanceInsideMedium\nvec4 GetRefractedData(vec3 p, vec3 n, vec3 rayDir, float ior, float biasMult, float roughness, float refractionMaxDist, int refractionDepth, inout SDFContext sdfContextMain){\n\tbool hitRefraction = true;\n\tbool changeSide = true;\n\t#ifdef RAYMARCHED_REFRACTIONS_START_OUTSIDE_MEDIUM\n\tfloat side = -1.;\n\t#else\n\tfloat side = 1.;\n\t#endif\n\tfloat iorInverted = 1. / ior;\n\tvec3 refractedColor = vec3(0.);\n\tfloat distanceInsideMedium=0.;\n\tfloat totalRefractedDistance=0.;\n\n\t#pragma unroll_loop_start\n\tfor(int i=0; i < refractionDepth; i++) {\n\t\tif(hitRefraction){\n\t\t\tfloat currentIor = side<0. ? iorInverted : ior;\n\t\t\tvec3 rayDirPreRefract = rayDir;\n\t\t\trayDir = refract(rayDir, n, currentIor);\n\t\t\tchangeSide = dot(rayDir, rayDir)!=0.;\n\t\t\tif(changeSide == true) {\n\t\t\t\tp -= n*SURF_DIST*(2.+biasMult);\n\t\t\t} else {\n\t\t\t\tp += n*SURF_DIST*( biasMult);\n\t\t\t\trayDir = reflect(rayDirPreRefract, n);\n\t\t\t}\n\t\t\tSDFContext sdfContext = RayMarch(p, rayDir, side);\n\t\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\t\tsdfContextMain.stepsCount += sdfContext.stepsCount;\n\t\t\t#endif\n\t\t\ttotalRefractedDistance += sdfContext.d;\n\t\t\tif( abs(sdfContext.d) >= MAX_DIST || totalRefractedDistance > refractionMaxDist ){\n\t\t\t\thitRefraction = false;\n\t\t\t\trefractedColor = envMapSample(rayDir, roughness);\n\t\t\t}\n\t\t\tif(hitRefraction){\n\t\t\t\tp += rayDir * sdfContext.d;\n\t\t\t\tn = GetNormal(p) * side;\n\t\t\t\tvec3 matCol = applyMaterialWithoutRefraction(p, n, rayDir, sdfContext.matId, sdfContextMain);\n\t\t\t\trefractedColor = matCol;\n\n\t\t\t\t// same as: side < 0. ? abs(sdfContext.d) : 0.;\n\t\t\t\tdistanceInsideMedium += (side-1.)*-0.5*abs(sdfContext.d);\n\t\t\t\tif( changeSide ){\n\t\t\t\t\tside *= -1.;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#ifdef RAYMARCHED_REFRACTIONS_SAMPLE_ENV_MAP_ON_LAST\n\t\tif(i == refractionDepth-1){\n\t\t\trefractedColor = envMapSample(rayDir, roughness);\n\t\t}\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n\treturn vec4(refractedColor, distanceInsideMedium);\n}\nfloat refractionTint(float baseValue, float tint, float distanceInsideMedium, float absorption){\n\tfloat tintNegated = baseValue-tint;\n\tfloat t = tintNegated*( distanceInsideMedium*absorption );\n\treturn max(baseValue-t, 0.);\n}\nfloat applyRefractionAbsorption(float refractedDataColor, float baseValue, float tint, float distanceInsideMedium, float absorption){\n\treturn refractedDataColor*refractionTint(baseValue, tint, distanceInsideMedium, absorption);\n}\nvec3 applyRefractionAbsorption(vec3 refractedDataColor, vec3 baseValue, vec3 tint, float distanceInsideMedium, float absorption){\n\treturn vec3(\n\t\trefractedDataColor.r * refractionTint(baseValue.r, tint.r, distanceInsideMedium, absorption),\n\t\trefractedDataColor.g * refractionTint(baseValue.g, tint.g, distanceInsideMedium, absorption),\n\t\trefractedDataColor.b * refractionTint(baseValue.b, tint.b, distanceInsideMedium, absorption)\n\t);\n}\n\n#endif\n\nvec3 applyMaterial(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(0.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n\n\n\n\nvec4 applyShading(vec3 rayOrigin, vec3 rayDir, inout SDFContext sdfContext){\n\tvec3 p = rayOrigin + rayDir * sdfContext.d;\n\tvec3 n = GetNormal(p);\n\t\n\tvec3 col = applyMaterial(p, n, rayDir, sdfContext.matId, sdfContext);\n\tif(sdfContext.matBlend > 0.) {\n\t\t// blend material colors if needed\n\t\tvec3 col2 = applyMaterial(p, n, rayDir, sdfContext.matId2, sdfContext);\n\t\tcol = (1. - sdfContext.matBlend)*col + sdfContext.matBlend*col2;\n\t}\n\t\t\n\t// gamma\n\t//col = pow( col, vec3(0.4545) ); // this gamma leads to a different look than standard materials\n\treturn vec4(col, 1.);\n}\n\nvoid main()\t{\n\n\tvec3 rayDir = normalize(vPw - cameraPosition);\n\trayDir = transformDirection(rayDir, vInverseModelMatrix);\n\tvec3 rayOrigin = (vInverseModelMatrix * vec4( cameraPosition, 1.0 )).xyz;\n\n\tSDFContext sdfContext = RayMarch(rayOrigin, rayDir, 1.);\n\n\t#if defined( DEBUG_DEPTH )\n\t\tfloat normalizedDepth = 1.-(sdfContext.d - debugMinDepth ) / ( debugMaxDepth - debugMinDepth );\n\t\tnormalizedDepth = saturate(normalizedDepth); // clamp to [0,1]\n\t\tgl_FragColor = vec4(normalizedDepth);\n\t\treturn;\n\t#endif\n\t#if defined( SHADOW_DEPTH )\n\t\tfloat normalizedDepth = 1.-(sdfContext.d - debugMinDepth ) / ( debugMaxDepth - debugMinDepth );\n\t\t// float fragCoordZ = sdfContext.d / vHighPrecisionZW[1];\n\t\tfloat compoundedDepth = 0.5 * (normalizedDepth) + 0.5;\n\t\tfloat alpha = sdfContext.d < MAX_DIST ? 0.:1.;\n\t\tgl_FragColor = vec4( vec3(compoundedDepth), alpha );\n\t\t// normalizedDepth = 0.5*normalizedDepth+0.5;\n\t\t// gl_FragColor = packDepthToRGBA( normalizedDepth );\n\t\t// gl_FragColor = vec4(0.);\n\t\treturn;\n\t#endif\n\t#if defined( SHADOW_DISTANCE )\n\t\tfloat normalizedDepth = (sdfContext.d - shadowDistanceMin ) / ( shadowDistanceMax - shadowDistanceMin );\n\t\tnormalizedDepth = saturate(normalizedDepth); // clamp to [0,1]\n\t\tgl_FragColor = packDepthToRGBA( normalizedDepth );\n\t\treturn;\n\t#endif\n\n\tif( sdfContext.d < MAX_DIST ){\n\t\tgl_FragColor = applyShading(rayOrigin, rayDir, sdfContext);\n\t\t#if defined( TONE_MAPPING )\n\t\t\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n\t\t#endif\n\t\tgl_FragColor = linearToOutputTexel( gl_FragColor );\n\n\t\t#ifdef USE_FOG\n\t\t\tfloat vFogDepth = sdfContext.d;\n\t\t\t#ifdef FOG_EXP2\n\t\t\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );\n\t\t\t#else\n\t\t\t\tfloat fogFactor = smoothstep( fogNear, fogFar, vFogDepth );\n\t\t\t#endif\n\t\t\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n\t\t#endif\n\t\t#include <premultiplied_alpha_fragment>\n\t\t#include <dithering_fragment>\n\t} else {\n\t\tgl_FragColor = vec4(0.);\n\t}\n\n\t#if defined( DEBUG_STEPS_COUNT )\n\t\tfloat normalizedStepsCount = (float(sdfContext.stepsCount) - debugMinSteps ) / ( debugMaxSteps - debugMinSteps );\n\t\tgl_FragColor = vec4(normalizedStepsCount, 1.-normalizedStepsCount, 0., 1.);\n\t\treturn;\n\t#endif\n\t\n}","customDepthMaterial.vertex":"precision highp float;\nprecision highp int;\n\nvarying vec3 vPw;\nvarying mat4 vModelMatrix;\nvarying mat4 vInverseModelMatrix;\nvarying mat4 VViewMatrix;\n\n#include <common>\n\n// // for depth material\n// varying vec2 vHighPrecisionZW;\n\nvoid main()\t{\n\n\tvModelMatrix = modelMatrix;\n\tvInverseModelMatrix = inverse(modelMatrix);\n\tVViewMatrix = viewMatrix;\n\tvPw = (modelMatrix * vec4( position, 1.0 )).xyz;\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n\t// vHighPrecisionZW = gl_Position.zw;\n}","customDepthMaterial.fragment":"precision highp float;\nprecision highp int;\n\n// --- applyMaterial constants definition\nuniform int MAX_STEPS;\nuniform float MAX_DIST;\nuniform float SURF_DIST;\nuniform float NORMALS_BIAS;\nuniform float SHADOW_BIAS;\n#define ZERO 0\nuniform float debugMinSteps;\nuniform float debugMaxSteps;\nuniform float debugMinDepth;\nuniform float debugMaxDepth;\n\n#include <common>\n#include <packing>\n#include <lightmap_pars_fragment>\n#include <bsdfs>\n#include <cube_uv_reflection_fragment>\n#include <lights_pars_begin>\n#include <lights_physical_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <fog_pars_fragment>\n\n#if defined( SHADOW_DISTANCE )\n\tuniform float shadowDistanceMin;\n\tuniform float shadowDistanceMax;\n#endif \n#if defined( SHADOW_DEPTH )\n\tuniform float shadowDepthMin;\n\tuniform float shadowDepthMax;\n#endif\n\n// varying vec2 vHighPrecisionZW;\n\nvarying vec3 vPw;\nvarying mat4 vModelMatrix;\nvarying mat4 vInverseModelMatrix;\nvarying mat4 VViewMatrix;\n\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform SpotLightRayMarching spotLightsRayMarching[ NUM_SPOT_LIGHTS ];\n\t#if NUM_SPOT_LIGHT_COORDS > 0\n\n\t\tuniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];\n\n\t#endif\n#endif\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform DirectionalLightRayMarching directionalLightsRayMarching[ NUM_DIR_LIGHTS ];\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\n\t#endif\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform PointLightRayMarching pointLightsRayMarching[ NUM_POINT_LIGHTS ];\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\n\t#endif\n#endif\n\n\nstruct SDFContext {\n\tfloat d;\n\tint stepsCount;\n\tint matId;\n\tint matId2;\n\tfloat matBlend;\n};\n\nSDFContext DefaultSDFContext(){\n\treturn SDFContext( 0., 0, 0, 0, 0. );\n}\nint DefaultSDFMaterial(){\n\treturn 0;\n}\n\n// start raymarching builder define code\n\n\n\n// /geo1/MAT/rayMarchingBuilder1/SDFSphere3\nfloat dot2( in vec2 v ) { return dot(v,v); }\nfloat dot2( in vec3 v ) { return dot(v,v); }\nfloat ndot( in vec2 a, in vec2 b ) { return a.x*b.x - a.y*b.y; }\n// https://iquilezles.org/articles/distfunctions/\n\n\n/*\n*\n* SDF PRIMITIVES\n*\n*/\nfloat sdSphere( vec3 p, float s )\n{\n\treturn length(p)-s;\n}\nfloat sdCutSphere( vec3 p, float r, float h )\n{\n\t// sampling independent computations (only depend on shape)\n\tfloat w = sqrt(r*r-h*h);\n\n\t// sampling dependant computations\n\tvec2 q = vec2( length(p.xz), p.y );\n\tfloat s = max( (h-r)*q.x*q.x+w*w*(h+r-2.0*q.y), h*q.x-w*q.y );\n\treturn (s<0.0) ? length(q)-r :\n\t\t\t\t(q.x<w) ? h - q.y :\n\t\t\t\t\tlength(q-vec2(w,h));\n}\nfloat sdCutHollowSphere( vec3 p, float r, float h, float t )\n{\n\t// sampling independent computations (only depend on shape)\n\tfloat w = sqrt(r*r-h*h);\n\t\n\t// sampling dependant computations\n\tvec2 q = vec2( length(p.xz), p.y );\n\treturn ((h*q.x<w*q.y) ? length(q-vec2(w,h)) : \n\t\t\t\t\t\t\tabs(length(q)-r) ) - t;\n}\n\nfloat sdBox( vec3 p, vec3 b )\n{\n\tvec3 q = abs(p) - b*0.5;\n\treturn length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0);\n}\nfloat sdRoundBox( vec3 p, vec3 b, float r )\n{\n\tvec3 q = abs(p) - b*0.5;\n\treturn length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0) - r;\n}\n\n\nfloat sdBoxFrame( vec3 p, vec3 b, float e )\n{\n\t\tp = abs(p )-b*0.5;\n\tvec3 q = abs(p+e)-e;\n\treturn min(min(\n\t\tlength(max(vec3(p.x,q.y,q.z),0.0))+min(max(p.x,max(q.y,q.z)),0.0),\n\t\tlength(max(vec3(q.x,p.y,q.z),0.0))+min(max(q.x,max(p.y,q.z)),0.0)),\n\t\tlength(max(vec3(q.x,q.y,p.z),0.0))+min(max(q.x,max(q.y,p.z)),0.0));\n}\nfloat sdCapsule( vec3 p, vec3 a, vec3 b, float r )\n{\n\tvec3 pa = p - a, ba = b - a;\n\tfloat h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n\treturn length( pa - ba*h ) - r;\n}\nfloat sdVerticalCapsule( vec3 p, float h, float r )\n{\n\tp.y -= clamp( p.y, 0.0, h );\n\treturn length( p ) - r;\n}\nfloat sdCone( in vec3 p, in vec2 c, float h )\n{\n\t// c is the sin/cos of the angle, h is height\n\t// Alternatively pass q instead of (c,h),\n\t// which is the point at the base in 2D\n\tvec2 q = h*vec2(c.x/c.y,-1.0);\n\n\tvec2 w = vec2( length(p.xz), p.y );\n\tvec2 a = w - q*clamp( dot(w,q)/dot(q,q), 0.0, 1.0 );\n\tvec2 b = w - q*vec2( clamp( w.x/q.x, 0.0, 1.0 ), 1.0 );\n\tfloat k = sign( q.y );\n\tfloat d = min(dot( a, a ),dot(b, b));\n\tfloat s = max( k*(w.x*q.y-w.y*q.x),k*(w.y-q.y) );\n\treturn sqrt(d)*sign(s);\n}\nfloat sdConeWrapped(vec3 pos, float angle, float height){\n\treturn sdCone(pos, vec2(sin(angle), cos(angle)), height);\n}\nfloat sdRoundCone( vec3 p, float r1, float r2, float h )\n{\n\tfloat b = (r1-r2)/h;\n\tfloat a = sqrt(1.0-b*b);\n\n\tvec2 q = vec2( length(p.xz), p.y );\n\tfloat k = dot(q,vec2(-b,a));\n\tif( k<0.0 ) return length(q) - r1;\n\tif( k>a*h ) return length(q-vec2(0.0,h)) - r2;\n\treturn dot(q, vec2(a,b) ) - r1;\n}\nfloat sdOctogonPrism( in vec3 p, in float r, float h )\n{\n\tconst vec3 k = vec3(-0.9238795325, // sqrt(2+sqrt(2))/2 \n\t\t\t\t\t\t0.3826834323, // sqrt(2-sqrt(2))/2\n\t\t\t\t\t\t0.4142135623 ); // sqrt(2)-1 \n\t// reflections\n\tp = abs(p);\n\tp.xy -= 2.0*min(dot(vec2( k.x,k.y),p.xy),0.0)*vec2( k.x,k.y);\n\tp.xy -= 2.0*min(dot(vec2(-k.x,k.y),p.xy),0.0)*vec2(-k.x,k.y);\n\t// polygon side\n\tp.xy -= vec2(clamp(p.x, -k.z*r, k.z*r), r);\n\tvec2 d = vec2( length(p.xy)*sign(p.y), p.z-h );\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdHexPrism( vec3 p, vec2 h )\n{\n\tconst vec3 k = vec3(-0.8660254, 0.5, 0.57735);\n\tp = abs(p);\n\tp.xy -= 2.0*min(dot(k.xy, p.xy), 0.0)*k.xy;\n\tvec2 d = vec2(\n\t\tlength(p.xy-vec2(clamp(p.x,-k.z*h.x,k.z*h.x), h.x))*sign(p.y-h.x),\n\t\tp.z-h.y );\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdHorseshoe( in vec3 p, in float angle, in float r, in float le, vec2 w )\n{\n\tvec2 c = vec2(cos(angle),sin(angle));\n\tp.x = abs(p.x);\n\tfloat l = length(p.xy);\n\tp.xy = mat2(-c.x, c.y, \n\t\t\tc.y, c.x)*p.xy;\n\tp.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x),\n\t\t\t\t(p.x>0.0)?p.y:l );\n\tp.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0);\n\t\n\tvec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z);\n\tvec2 d = abs(q) - w;\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdTriPrism( vec3 p, vec2 h )\n{\n\tvec3 q = abs(p);\n\treturn max(q.z-h.y,max(q.x*0.866025+p.y*0.5,-p.y)-h.x*0.5);\n}\nfloat sdPyramid( vec3 p, float h)\n{\n\tfloat m2 = h*h + 0.25;\n\n\tp.xz = abs(p.xz);\n\tp.xz = (p.z>p.x) ? p.zx : p.xz;\n\tp.xz -= 0.5;\n\n\tvec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y);\n\n\tfloat s = max(-q.x,0.0);\n\tfloat t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 );\n\n\tfloat a = m2*(q.x+s)*(q.x+s) + q.y*q.y;\n\tfloat b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t);\n\n\tfloat d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b);\n\n\treturn sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));\n}\n\nfloat sdPlane( vec3 p, vec3 n, float h )\n{\n\t// n must be normalized\n\treturn dot(p,n) + h;\n}\n\nfloat sdTorus( vec3 p, vec2 t )\n{\n\tvec2 q = vec2(length(p.xz)-t.x,p.y);\n\treturn length(q)-t.y;\n}\nfloat sdCappedTorus(in vec3 p, in float an, in float ra, in float rb)\n{\n\tvec2 sc = vec2(sin(an),cos(an));\n\tp.x = abs(p.x);\n\tfloat k = (sc.y*p.x>sc.x*p.z) ? dot(p.xz,sc) : length(p.xz);\n\treturn sqrt( dot(p,p) + ra*ra - 2.0*ra*k ) - rb;\n}\nfloat sdLink( vec3 p, float le, float r1, float r2 )\n{\n vec3 q = vec3( p.x, max(abs(p.y)-le,0.0), p.z );\n return length(vec2(length(q.xy)-r1,q.z)) - r2;\n}\n// c is the sin/cos of the desired cone angle\nfloat sdSolidAngle(vec3 pos, vec2 c, float radius)\n{\n\tvec2 p = vec2( length(pos.xz), pos.y );\n\tfloat l = length(p) - radius;\n\tfloat m = length(p - c*clamp(dot(p,c),0.0,radius) );\n\treturn max(l,m*sign(c.y*p.x-c.x*p.y));\n}\nfloat sdSolidAngleWrapped(vec3 pos, float angle, float radius){\n\treturn sdSolidAngle(pos, vec2(sin(angle), cos(angle)), radius);\n}\nfloat sdTube( vec3 p, float r )\n{\n\treturn length(p.xz)-r;\n}\nfloat sdTubeCapped( vec3 p, float h, float r )\n{\n\tvec2 d = abs(vec2(length(p.xz),p.y)) - vec2(r,h);\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdOctahedron( vec3 p, float s)\n{\n p = abs(p);\n float m = p.x+p.y+p.z-s;\n vec3 q;\n if( 3.0*p.x < m ) q = p.xyz;\n else if( 3.0*p.y < m ) q = p.yzx;\n else if( 3.0*p.z < m ) q = p.zxy;\n else return m*0.57735027;\n \n float k = clamp(0.5*(q.z-q.y+s),0.0,s); \n return length(vec3(q.x,q.y-s+k,q.z-k)); \n}\nfloat udTriangle( vec3 p, vec3 a, vec3 b, vec3 c, float thickness )\n{\n\tvec3 ba = b - a; vec3 pa = p - a;\n\tvec3 cb = c - b; vec3 pb = p - b;\n\tvec3 ac = a - c; vec3 pc = p - c;\n\tvec3 nor = cross( ba, ac );\n\n\treturn - thickness + sqrt(\n\t\t(sign(dot(cross(ba,nor),pa)) +\n\t\tsign(dot(cross(cb,nor),pb)) +\n\t\tsign(dot(cross(ac,nor),pc))<2.0)\n\t\t?\n\t\tmin( min(\n\t\tdot2(ba*clamp(dot(ba,pa)/dot2(ba),0.0,1.0)-pa),\n\t\tdot2(cb*clamp(dot(cb,pb)/dot2(cb),0.0,1.0)-pb) ),\n\t\tdot2(ac*clamp(dot(ac,pc)/dot2(ac),0.0,1.0)-pc) )\n\t\t:\n\t\tdot(nor,pa)*dot(nor,pa)/dot2(nor) );\n}\nfloat udQuad( vec3 p, vec3 a, vec3 b, vec3 c, vec3 d, float thickness )\n{\n\tvec3 ba = b - a; vec3 pa = p - a;\n\tvec3 cb = c - b; vec3 pb = p - b;\n\tvec3 dc = d - c; vec3 pc = p - c;\n\tvec3 ad = a - d; vec3 pd = p - d;\n\tvec3 nor = cross( ba, ad );\n\n\treturn - thickness + sqrt(\n\t\t(sign(dot(cross(ba,nor),pa)) +\n\t\tsign(dot(cross(cb,nor),pb)) +\n\t\tsign(dot(cross(dc,nor),pc)) +\n\t\tsign(dot(cross(ad,nor),pd))<3.0)\n\t\t?\n\t\tmin( min( min(\n\t\tdot2(ba*clamp(dot(ba,pa)/dot2(ba),0.0,1.0)-pa),\n\t\tdot2(cb*clamp(dot(cb,pb)/dot2(cb),0.0,1.0)-pb) ),\n\t\tdot2(dc*clamp(dot(dc,pc)/dot2(dc),0.0,1.0)-pc) ),\n\t\tdot2(ad*clamp(dot(ad,pd)/dot2(ad),0.0,1.0)-pd) )\n\t\t:\n\t\tdot(nor,pa)*dot(nor,pa)/dot2(nor) );\n}\n\n/*\n*\n* SDF OPERATIONS\n*\n*/\nfloat SDFUnion( float d1, float d2 ) { return min(d1,d2); }\nfloat SDFSubtract( float d1, float d2 ) { return max(-d1,d2); }\nfloat SDFIntersect( float d1, float d2 ) { return max(d1,d2); }\n\nfloat SDFSmoothUnion( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 + 0.5*(d2-d1)/k, 0.0, 1.0 );\n\treturn mix( d2, d1, h ) - k*h*(1.0-h);\n}\n\nfloat SDFSmoothSubtract( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 - 0.5*(d2+d1)/k, 0.0, 1.0 );\n\treturn mix( d2, -d1, h ) + k*h*(1.0-h);\n}\n\nfloat SDFSmoothIntersect( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 - 0.5*(d2-d1)/k, 0.0, 1.0 );\n\treturn mix( d2, d1, h ) + k*h*(1.0-h);\n}\n\nvec4 SDFElongateFast( in vec3 p, in vec3 h )\n{\n\treturn vec4( p-clamp(p,-h,h), 0.0 );\n}\nvec4 SDFElongateSlow( in vec3 p, in vec3 h )\n{\n\tvec3 q = abs(p)-h;\n\treturn vec4( max(q,0.0), min(max(q.x,max(q.y,q.z)),0.0) );\n}\n\nfloat SDFOnion( in float sdf, in float thickness )\n{\n\treturn abs(sdf)-thickness;\n}\n\n// /geo1/MAT/rayMarchingBuilder1/checkers1\n// https://iquilezles.org/articles/checkerfiltering/\nfloat checkers(vec2 p) {\n\tvec2 s = sign(fract(p*.5)-.5);\n\treturn .5 - .5*s.x*s.y;\n}\nfloat checkersGrad( in vec2 p, in vec2 ddx, in vec2 ddy )\n{\n // filter kernel\n vec2 w = max(abs(ddx), abs(ddy)) + 0.01;\n // analytical integral (box filter)\n vec2 i = 2.0*(abs(fract((p-0.5*w)/2.0)-0.5)-abs(fract((p+0.5*w)/2.0)-0.5))/w;\n // xor pattern\n return 0.5 - 0.5*i.x*i.y;\n}\n\n\n// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\nconst int _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1 = 1;\n\n\n// https://stackoverflow.com/questions/23793698/how-to-implement-slerp-in-glsl-hlsl\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t)\n// {\n// \tfloat dotp = dot(normalize(p0), normalize(p1));\n// \tif ((dotp > 0.9999) || (dotp < -0.9999))\n// \t{\n// \t\tif (t<=0.5)\n// \t\t\treturn p0;\n// \t\treturn p1;\n// \t}\n// \tfloat theta = acos(dotp);\n// \tvec4 P = ((p0*sin((1.0-t)*theta) + p1*sin(t*theta)) / sin(theta));\n// \tP.w = 1.0;\n// \treturn P;\n// }\n\n// https://devcry.heiho.net/html/2017/20170521-slerp.html\n// float lerp(float a, float b, float t) {\n// \treturn (1.0 - t) * a + t * b;\n// }\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t){\n// \tvec4 qb = p1;\n\n// \t// cos(a) = dot product\n// \tfloat cos_a = p0.x * qb.x + p0.y * qb.y + p0.z * qb.z + p0.w * qb.w;\n// \tif (cos_a < 0.0f) {\n// \t\tcos_a = -cos_a;\n// \t\tqb = -qb;\n// \t}\n\n// \t// close to zero, cos(a) ~= 1\n// \t// do linear interpolation\n// \tif (cos_a > 0.999) {\n// \t\treturn vec4(\n// \t\t\tlerp(p0.x, qb.x, t),\n// \t\t\tlerp(p0.y, qb.y, t),\n// \t\t\tlerp(p0.z, qb.z, t),\n// \t\t\tlerp(p0.w, qb.w, t)\n// \t\t);\n// \t}\n\n// \tfloat alpha = acos(cos_a);\n// \treturn (p0 * sin(1.0 - t) + p1 * sin(t * alpha)) / sin(alpha);\n// }\n\n// https://stackoverflow.com/questions/62943083/interpolate-between-two-quaternions-the-long-way\nvec4 quatSlerp(vec4 q1, vec4 q2, float t){\n\tfloat angle = acos(dot(q1, q2));\n\tfloat denom = sin(angle);\n\t//check if denom is zero\n\treturn (q1*sin((1.0-t)*angle)+q2*sin(t*angle))/denom;\n}\n// TO CHECK:\n// this page https://www.reddit.com/r/opengl/comments/704la7/glsl_quaternion_library/\n// has a link to a potentially nice pdf:\n// http://web.mit.edu/2.998/www/QuaternionReport1.pdf\n\n// https://github.com/mattatz/ShibuyaCrowd/blob/master/source/shaders/common/quaternion.glsl\nvec4 quatMult(vec4 q1, vec4 q2)\n{\n\treturn vec4(\n\tq1.w * q2.x + q1.x * q2.w + q1.z * q2.y - q1.y * q2.z,\n\tq1.w * q2.y + q1.y * q2.w + q1.x * q2.z - q1.z * q2.x,\n\tq1.w * q2.z + q1.z * q2.w + q1.y * q2.x - q1.x * q2.y,\n\tq1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z\n\t);\n}\n// http://glmatrix.net/docs/quat.js.html#line97\n// let ax = a[0], ay = a[1], az = a[2], aw = a[3];\n\n// let bx = b[0], by = b[1], bz = b[2], bw = b[3];\n\n// out[0] = ax * bw + aw * bx + ay * bz - az * by;\n\n// out[1] = ay * bw + aw * by + az * bx - ax * bz;\n\n// out[2] = az * bw + aw * bz + ax * by - ay * bx;\n\n// out[3] = aw * bw - ax * bx - ay * by - az * bz;\n\n// return out\n\n\n\n// http://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/\nmat4 rotationMatrix(vec3 axis, float angle)\n{\n\taxis = normalize(axis);\n\tfloat s = sin(angle);\n\tfloat c = cos(angle);\n\tfloat oc = 1.0 - c;\n\n \treturn mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 0.0, 0.0, 0.0, 1.0);\n}\n\n// https://www.geeks3d.com/20141201/how-to-rotate-a-vertex-by-a-quaternion-in-glsl/\nvec4 quatFromAxisAngle(vec3 axis, float angle)\n{\n\tvec4 qr;\n\tfloat half_angle = (angle * 0.5); // * 3.14159 / 180.0;\n\tfloat sin_half_angle = sin(half_angle);\n\tqr.x = axis.x * sin_half_angle;\n\tqr.y = axis.y * sin_half_angle;\n\tqr.z = axis.z * sin_half_angle;\n\tqr.w = cos(half_angle);\n\treturn qr;\n}\nvec3 rotateWithAxisAngle(vec3 position, vec3 axis, float angle)\n{\n\tvec4 q = quatFromAxisAngle(axis, angle);\n\tvec3 v = position.xyz;\n\treturn v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);\n}\n// vec3 applyQuaternionToVector( vec4 q, vec3 v ){\n// \treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n// }\nvec3 rotateWithQuat( vec3 v, vec4 q )\n{\n\t// vec4 qv = multQuat( quat, vec4(vec, 0.0) );\n\t// return multQuat( qv, vec4(-quat.x, -quat.y, -quat.z, quat.w) ).xyz;\n\treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n}\n// https://github.com/glslify/glsl-look-at/blob/gh-pages/index.glsl\n// mat3 rotation_matrix(vec3 origin, vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target - origin);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n// mat3 rotation_matrix(vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n\nfloat vectorAngle(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 c1 = cross(start, dest);\n\t// We use the dot product of the cross with the Y axis.\n\t// This is a little arbitrary, but can still give a good sense of direction\n\tvec3 y_axis = vec3(0.0, 1.0, 0.0);\n\tfloat d1 = dot(c1, y_axis);\n\tfloat angle = acos(cosTheta) * sign(d1);\n\treturn angle;\n}\n\n// http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/#i-need-an-equivalent-of-glulookat-how-do-i-orient-an-object-towards-a-point-\nvec4 vectorAlign(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 axis;\n\n\t// if (cosTheta < -1 + 0.001f){\n\t// \t// special case when vectors in opposite directions:\n\t// \t// there is no ideal rotation axis\n\t// \t// So guess one; any will do as long as it's perpendicular to start\n\t// \taxis = cross(vec3(0.0f, 0.0f, 1.0f), start);\n\t// \tif (length2(axis) < 0.01 ) // bad luck, they were parallel, try again!\n\t// \t\taxis = cross(vec3(1.0f, 0.0f, 0.0f), start);\n\n\t// \taxis = normalize(axis);\n\t// \treturn gtx::quaternion::angleAxis(glm::radians(180.0f), axis);\n\t// }\n\tif(cosTheta > (1.0 - 0.0001) || cosTheta < (-1.0 + 0.0001) ){\n\t\taxis = normalize(cross(start, vec3(0.0, 1.0, 0.0)));\n\t\tif (length(axis) < 0.001 ){ // bad luck, they were parallel, try again!\n\t\t\taxis = normalize(cross(start, vec3(1.0, 0.0, 0.0)));\n\t\t}\n\t} else {\n\t\taxis = normalize(cross(start, dest));\n\t}\n\n\tfloat angle = acos(cosTheta);\n\n\treturn quatFromAxisAngle(axis, angle);\n}\nvec4 vectorAlignWithUp(vec3 start, vec3 dest, vec3 up){\n\tvec4 rot1 = vectorAlign(start, dest);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\t// vec3 right = normalize(cross(dest, up));\n\t// up = normalize(cross(right, dest));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(vec3(0.0, 1.0, 0.0), rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(up, newUp);\n\n\t// return rot1;\n\treturn rot2;\n\t// return multQuat(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\n// https://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\nfloat quatToAngle(vec4 q){\n\treturn 2.0 * acos(q.w);\n}\nvec3 quatToAxis(vec4 q){\n\treturn vec3(\n\t\tq.x / sqrt(1.0-q.w*q.w),\n\t\tq.y / sqrt(1.0-q.w*q.w),\n\t\tq.z / sqrt(1.0-q.w*q.w)\n\t);\n}\n\nvec4 align(vec3 dir, vec3 up){\n\tvec3 start_dir = vec3(0.0, 0.0, 1.0);\n\tvec3 start_up = vec3(0.0, 1.0, 0.0);\n\tvec4 rot1 = vectorAlign(start_dir, dir);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\tvec3 right = normalize(cross(dir, up));\n\tif(length(right)<0.001){\n\t\tright = vec3(1.0, 0.0, 0.0);\n\t}\n\tup = normalize(cross(right, dir));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(start_up, rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(normalize(newUp), up);\n\n\t// return rot1;\n\treturn quatMult(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\nstruct EnvMapProps {\n\tvec3 tint;\n\tfloat intensity;\n\tfloat roughness;\n\tfloat fresnel;\n\tfloat fresnelPower;\n};\nuniform sampler2D envMap;\nuniform float envMapIntensity;\nuniform float roughness;\n#ifdef ROTATE_ENV_MAP_Y\n\tuniform float envMapRotationY;\n#endif\nvec3 envMapSample(vec3 rayDir, float envMapRoughness){\n\t// http://www.pocketgl.com/reflections/\n\tvec3 env = vec3(0.);\n\t// vec2 uv = vec2( atan( -rayDir.z, -rayDir.x ) * RECIPROCAL_PI2 + 0.5, rayDir.y * 0.5 + 0.5 );\n\t// vec3 env = texture2D(map, uv).rgb;\n\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t#ifdef ROTATE_ENV_MAP_Y\n\t\t\trayDir = rotateWithAxisAngle(rayDir, vec3(0.,1.,0.), envMapRotationY);\n\t\t#endif\n\t\tenv = textureCubeUV(envMap, rayDir, envMapRoughness * roughness).rgb;\n\t#endif\n\treturn env;\n}\nvec3 envMapSampleWithFresnel(vec3 rayDir, EnvMapProps envMapProps, vec3 n, vec3 cameraPosition){\n\t// http://www.pocketgl.com/reflections/\n\tvec3 env = envMapSample(rayDir, envMapProps.roughness);\n\tfloat fresnel = pow(1.-dot(normalize(cameraPosition), n), envMapProps.fresnelPower);\n\tfloat fresnelFactor = (1.-envMapProps.fresnel) + envMapProps.fresnel*fresnel;\n\treturn env * envMapIntensity * envMapProps.tint * envMapProps.intensity * fresnelFactor;\n}\n\n\n\n\n\n\nSDFContext GetDist(vec3 p) {\n\tSDFContext sdfContext = SDFContext(0., 0, 0, 0, 0.);\n\n\t// start GetDist builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/SDFSphere3\n\tfloat v_POLY_SDFSphere3_float = sdSphere(p - vec3(-0.25, 0.0, 0.0), 0.2);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFSphere4\n\tfloat v_POLY_SDFSphere4_float = sdSphere(p - vec3(0.25, 0.0, 0.0), 0.2);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFPlane1\n\tfloat v_POLY_SDFPlane1_float = sdPlane(p-vec3(0.0, -0.2, 0.0), vec3(0.0, 1.0, 0.0), 0.0);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFUnion2\n\tfloat v_POLY_SDFUnion2_union = SDFSmoothUnion(v_POLY_SDFSphere3_float, v_POLY_SDFSphere4_float, 0.31);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFUnion3\n\tfloat v_POLY_SDFUnion3_union = SDFSmoothUnion(v_POLY_SDFUnion2_union, v_POLY_SDFPlane1_float, 0.31);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFContext1\n\tSDFContext v_POLY_SDFContext1_SDFContext = SDFContext(v_POLY_SDFUnion3_union, 0, _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1, _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1, 0.);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/output1\n\tsdfContext = v_POLY_SDFContext1_SDFContext;\n\n\n\n\t\n\n\treturn sdfContext;\n}\n\nSDFContext RayMarch(vec3 ro, vec3 rd, float side) {\n\tSDFContext dO = SDFContext(0.,0,0,0,0.);\n\n\t#pragma unroll_loop_start\n\tfor(int i=0; i<MAX_STEPS; i++) {\n\t\tvec3 p = ro + rd*dO.d;\n\t\tSDFContext sdfContext = GetDist(p);\n\t\tdO.d += sdfContext.d * side;\n\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\tdO.stepsCount += 1;\n\t\t#endif\n\t\tdO.matId = sdfContext.matId;\n\t\tdO.matId2 = sdfContext.matId2;\n\t\tdO.matBlend = sdfContext.matBlend;\n\t\tif(dO.d>MAX_DIST || abs(sdfContext.d)<SURF_DIST) break;\n\t}\n\t#pragma unroll_loop_end\n\n\treturn dO;\n}\n\nvec3 GetNormal(vec3 p) {\n\tSDFContext sdfContext = GetDist(p);\n\tvec2 e = vec2(NORMALS_BIAS, 0);\n\n\tvec3 n = sdfContext.d - vec3(\n\t\tGetDist(p-e.xyy).d,\n\t\tGetDist(p-e.yxy).d,\n\t\tGetDist(p-e.yyx).d);\n\n\treturn normalize(n);\n}\n// https://iquilezles.org/articles/rmshadows\nfloat calcSoftshadow( in vec3 ro, in vec3 rd, float mint, float maxt, float k, inout SDFContext sdfContext )\n{\n\tfloat res = 1.0;\n\tfloat ph = 1e20;\n\tfor( float t=mint; t<maxt; )\n\t{\n\t\tfloat h = GetDist(ro + rd*t).d;\n\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\tsdfContext.stepsCount += 1;\n\t\t#endif\n\t\tif( h<SURF_DIST )\n\t\t\treturn 0.0;\n\t\tfloat y = h*h/(2.0*ph);\n\t\tfloat d = sqrt(h*h-y*y);\n\t\tres = min( res, k*d/max(0.0,t-y) );\n\t\tph = h;\n\t\tt += h;\n\t}\n\treturn res;\n}\n\nvec3 GetLight(vec3 _p, vec3 _n, inout SDFContext sdfContext) {\n\tvec3 dif = vec3(0.,0.,0.);\n\t// GeometricContext geometry;\n\t// geometry.position = _p;\n\t// geometry.normal = _n;\n\t// geometry.viewDir = rayDir;\n\n\t// vec4 mvPosition = vec4( p, 1.0 );\n\t// mvPosition = modelViewMatrix * mvPosition;\n\t// vec3 vViewPosition = - mvPosition.xyz;\n\tvec3 pWorld = ( vModelMatrix * vec4( _p, 1.0 )).xyz;\n\tvec3 nWorld = transformDirection(_n, vModelMatrix);\n\t// geometry.position = (VViewMatrix * vec4( _p, 1.0 )).xyz;\n\tvec3 geometryPosition = (VViewMatrix * vec4(pWorld, 1.0 )).xyz;\n\t// geometry.normal = transformDirection(_n, VViewMatrix);\n\t// geometry.normal = inverseTransformDirection(transformDirection(_n, VViewMatrix), vInverseModelMatrix);\n\tvec3 geometryNormal = transformDirection(nWorld, VViewMatrix);\n\t\n\n\t#if NUM_SPOT_LIGHTS > 0 || NUM_DIR_LIGHTS > 0 || NUM_HEMI_LIGHTS > 0 || NUM_POINT_LIGHTS > 0 || NUM_RECT_AREA_LIGHTS > 0\n\n\t\tIncidentLight directLight;\n\t\tReflectedLight reflectedLight;\n\t\tvec3 lightPos, lightDir, worldLightDir, objectSpaceLightDir, lighDif, directDiffuse;\n\t\tfloat dotNL, lightDistance;\n\t\t#if NUM_SPOT_LIGHTS > 0\n\t\t\tSpotLightRayMarching spotLightRayMarching;\n\t\t\tSpotLight spotLight;\n\t\t\tfloat spotLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\t\t\t\tSpotLightShadow spotLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\t\t\tspotLightRayMarching = spotLightsRayMarching[ i ];\n\t\t\t\tspotLight = spotLights[ i ];\n\t\t\t\tgetSpotLightInfo( spotLight, geometryPosition, directLight );\n\n\t\t\t\t// #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t\t\t// \tspotLightShadow = spotLightShadows[ i ];\n\t\t\t\t// \tvec4 spotLightShadowCoord = spotLightMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t// \tdirectLight.color *= (directLight.visible && receiveShadow) ? getShadow(\n\t\t\t\t// \t\tspotShadowMap[ i ],\n\t\t\t\t// \t\tspotLightShadow.shadowMapSize,\n\t\t\t\t// \t\tspotLightShadow.shadowBias,\n\t\t\t\t// \t\tspotLightShadow.shadowRadius,\n\t\t\t\t// \t\tspotLightShadowCoord\n\t\t\t\t// \t) : 1.0;\n\t\t\t\t// #endif\n\n\t\t\t\tlightPos = spotLight.position;\n\t\t\t\tlightDir = normalize(lightPos-geometryPosition);\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tlightDistance = distance(geometryPosition,lightPos);\n\t\t\t\tspotLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < spotLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t: calcSoftshadow(\n\t\t\t\t\t\t_p,\n\t\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\t\tspotLightRayMarching.shadowBiasDistance,\n\t\t\t\t\t\tdistance(geometryPosition,lightPos),\n\t\t\t\t\t\t1./max(spotLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\t\tsdfContext\n\t\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * spotLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\t\t#if NUM_DIR_LIGHTS > 0\n\t\t\tDirectionalLightRayMarching directionalLightRayMarching;\n\t\t\tDirectionalLight directionalLight;\n\t\t\tfloat dirLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\t\t\t\tDirectionalLightShadow directionalLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\t\t\tdirectionalLightRayMarching = directionalLightsRayMarching[ i ];\n\t\t\t\tdirectionalLight = directionalLights[ i ];\n\t\t\t\t\n\t\t\t\tgetDirectionalLightInfo( directionalLight, directLight );\n\n\t\t\t\t// #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\t\t\t// \tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\t\t\t// \tvec4 dirLightShadowCoord = directionalShadowMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t// \tdirectLight.color *= (directLight.visible && receiveShadow) ? getShadow(\n\t\t\t\t// \t\tdirectionalShadowMap[ i ],\n\t\t\t\t// \t\tdirectionalLightShadow.shadowMapSize,\n\t\t\t\t// \t\tdirectionalLightShadow.shadowBias,\n\t\t\t\t// \t\tdirectionalLightShadow.shadowRadius,\n\t\t\t\t// \t\tdirLightShadowCoord\n\t\t\t\t// \t) : 1.0;\n\t\t\t\t// #endif\n\n\t\t\t\tlightDir = directionalLight.direction;\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tdirLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < directionalLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t:\n\t\t\t\t\tcalcSoftshadow(\n\t\t\t\t\t\t_p,\n\t\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\t\tdirectionalLightRayMarching.shadowBiasDistance,\n\t\t\t\t\t\tMAX_DIST,//distance(geometryPosition,lightPos),\n\t\t\t\t\t\t1./max(directionalLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\t\tsdfContext\n\t\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\t// lighDif = directLight.color * dotNL * dirLightSdfShadow;\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * dirLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\n\t\t#if ( NUM_HEMI_LIGHTS > 0 )\n\n\t\t\t#pragma unroll_loop_start\n\t\t\tHemisphereLight hemiLight;\n\t\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\t\themiLight = hemisphereLights[ i ];\n\t\t\t\tdif += getHemisphereLightIrradiance( hemiLight, geometryNormal ) * BRDF_Lambert( vec3(1.) );\n\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\n\t\t#endif\n\n\t\t#if NUM_POINT_LIGHTS > 0\n\t\t\tPointLightRayMarching pointLightRayMarching;\n\t\t\tPointLight pointLight;\n\t\t\tfloat pointLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\t\t\t\tPointLightShadow pointLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\t\t\tpointLightRayMarching = pointLightsRayMarching[ i ];\n\t\t\t\tpointLight = pointLights[ i ];\n\t\t\t\tgetPointLightInfo( pointLight, geometryPosition, directLight );\n\n\n\t\t\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\t\t\t\tpointLightShadow = pointLightShadows[ i ];\n\t\t\t\t\tvec4 pointLightShadowCoord = pointShadowMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t\tdirectLight.color *= (directLight.visible && receiveShadow) ? getPointShadow(\n\t\t\t\t\t\tpointShadowMap[ i ],\n\t\t\t\t\t\tpointLightShadow.shadowMapSize,\n\t\t\t\t\t\tpointLightShadow.shadowBias,\n\t\t\t\t\t\tpointLightShadow.shadowRadius,\n\t\t\t\t\t\tpointLightShadowCoord,\n\t\t\t\t\t\tpointLightShadow.shadowCameraNear,\n\t\t\t\t\t\tpointLightShadow.shadowCameraFar\n\t\t\t\t\t) : 1.0;\n\t\t\t\t#endif\n\n\t\t\t\tlightPos = pointLight.position;\n\t\t\t\tlightDir = normalize(lightPos-geometryPosition);\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tpointLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < pointLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t:\n\t\t\t\t\tcalcSoftshadow(\n\t\t\t\t\t_p,\n\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\tpointLightRayMarching.shadowBiasDistance,\n\t\t\t\t\tdistance(geometryPosition,lightPos),\n\t\t\t\t\t1./max(pointLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\tsdfContext\n\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * pointLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\n\t\t#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\n\t\t\tRectAreaLight rectAreaLight;\n\t\t\t// AreaLightRayMarching areaLightRayMarching;\n\t\t\tPhysicalMaterial material;\n\t\t\tmaterial.roughness = 1.;\n\t\t\tmaterial.specularColor = vec3(1.);\n\t\t\tmaterial.diffuseColor = vec3(1.);\n\n\t\t\tvec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( cameraPosition - geometryPosition );\n\t\t\tvec3 geometryClearcoatNormal = geometryNormal;\n\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\t\t\t// areaLightRayMarching = areaLightsRayMarching[ i ];\n\t\t\t\trectAreaLight = rectAreaLights[ i ];\n\t\t\t\t// rectAreaLight.position = areaLightRayMarching.worldPos;\n\n\t\t\t\tRE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t\tdif += reflectedLight.directDiffuse;\n\n\t\t#endif\n\t#endif\n\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\n\t#if defined( USE_LIGHT_PROBES )\n\n\t\tirradiance += getLightProbeIrradiance( lightProbe, geometryNormal );\n\n\t#endif\n\n\tdif += irradiance;\n\n\treturn dif;\n}\n\n\n\n\nvec3 applyMaterialWithoutRefraction(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(1.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n\nvec3 applyMaterialWithoutReflection(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(1.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n#ifdef RAYMARCHED_REFLECTIONS\nvec3 GetReflection(vec3 p, vec3 n, vec3 rayDir, float biasMult, float roughness, int reflectionDepth, inout SDFContext sdfContextMain){\n\tbool hitReflection = true;\n\tvec3 reflectedColor = vec3(0.);\n\t#pragma unroll_loop_start\n\tfor(int i=0; i < reflectionDepth; i++) {\n\t\tif(hitReflection){\n\t\t\trayDir = reflect(rayDir, n);\n\t\t\tp += n*SURF_DIST*biasMult;\n\t\t\tSDFContext sdfContext = RayMarch(p, rayDir, 1.);\n\t\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\t\tsdfContextMain.stepsCount += sdfContext.stepsCount;\n\t\t\t#endif\n\t\t\tif( sdfContext.d >= MAX_DIST){\n\t\t\t\thitReflection = false;\n\t\t\t\treflectedColor = envMapSample(rayDir, roughness);\n\t\t\t}\n\t\t\tif(hitReflection){\n\t\t\t\tp += rayDir * sdfContext.d;\n\t\t\t\tn = GetNormal(p);\n\t\t\t\tvec3 matCol = applyMaterialWithoutReflection(p, n, rayDir, sdfContext.matId, sdfContextMain);\n\t\t\t\treflectedColor += matCol;\n\t\t\t}\n\t\t}\n\t}\n\t#pragma unroll_loop_end\n\treturn reflectedColor;\n}\n#endif\n\n#ifdef RAYMARCHED_REFRACTIONS\n// xyz for color, w for distanceInsideMedium\nvec4 GetRefractedData(vec3 p, vec3 n, vec3 rayDir, float ior, float biasMult, float roughness, float refractionMaxDist, int refractionDepth, inout SDFContext sdfContextMain){\n\tbool hitRefraction = true;\n\tbool changeSide = true;\n\t#ifdef RAYMARCHED_REFRACTIONS_START_OUTSIDE_MEDIUM\n\tfloat side = -1.;\n\t#else\n\tfloat side = 1.;\n\t#endif\n\tfloat iorInverted = 1. / ior;\n\tvec3 refractedColor = vec3(0.);\n\tfloat distanceInsideMedium=0.;\n\tfloat totalRefractedDistance=0.;\n\n\t#pragma unroll_loop_start\n\tfor(int i=0; i < refractionDepth; i++) {\n\t\tif(hitRefraction){\n\t\t\tfloat currentIor = side<0. ? iorInverted : ior;\n\t\t\tvec3 rayDirPreRefract = rayDir;\n\t\t\trayDir = refract(rayDir, n, currentIor);\n\t\t\tchangeSide = dot(rayDir, rayDir)!=0.;\n\t\t\tif(changeSide == true) {\n\t\t\t\tp -= n*SURF_DIST*(2.+biasMult);\n\t\t\t} else {\n\t\t\t\tp += n*SURF_DIST*( biasMult);\n\t\t\t\trayDir = reflect(rayDirPreRefract, n);\n\t\t\t}\n\t\t\tSDFContext sdfContext = RayMarch(p, rayDir, side);\n\t\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\t\tsdfContextMain.stepsCount += sdfContext.stepsCount;\n\t\t\t#endif\n\t\t\ttotalRefractedDistance += sdfContext.d;\n\t\t\tif( abs(sdfContext.d) >= MAX_DIST || totalRefractedDistance > refractionMaxDist ){\n\t\t\t\thitRefraction = false;\n\t\t\t\trefractedColor = envMapSample(rayDir, roughness);\n\t\t\t}\n\t\t\tif(hitRefraction){\n\t\t\t\tp += rayDir * sdfContext.d;\n\t\t\t\tn = GetNormal(p) * side;\n\t\t\t\tvec3 matCol = applyMaterialWithoutRefraction(p, n, rayDir, sdfContext.matId, sdfContextMain);\n\t\t\t\trefractedColor = matCol;\n\n\t\t\t\t// same as: side < 0. ? abs(sdfContext.d) : 0.;\n\t\t\t\tdistanceInsideMedium += (side-1.)*-0.5*abs(sdfContext.d);\n\t\t\t\tif( changeSide ){\n\t\t\t\t\tside *= -1.;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#ifdef RAYMARCHED_REFRACTIONS_SAMPLE_ENV_MAP_ON_LAST\n\t\tif(i == refractionDepth-1){\n\t\t\trefractedColor = envMapSample(rayDir, roughness);\n\t\t}\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n\treturn vec4(refractedColor, distanceInsideMedium);\n}\nfloat refractionTint(float baseValue, float tint, float distanceInsideMedium, float absorption){\n\tfloat tintNegated = baseValue-tint;\n\tfloat t = tintNegated*( distanceInsideMedium*absorption );\n\treturn max(baseValue-t, 0.);\n}\nfloat applyRefractionAbsorption(float refractedDataColor, float baseValue, float tint, float distanceInsideMedium, float absorption){\n\treturn refractedDataColor*refractionTint(baseValue, tint, distanceInsideMedium, absorption);\n}\nvec3 applyRefractionAbsorption(vec3 refractedDataColor, vec3 baseValue, vec3 tint, float distanceInsideMedium, float absorption){\n\treturn vec3(\n\t\trefractedDataColor.r * refractionTint(baseValue.r, tint.r, distanceInsideMedium, absorption),\n\t\trefractedDataColor.g * refractionTint(baseValue.g, tint.g, distanceInsideMedium, absorption),\n\t\trefractedDataColor.b * refractionTint(baseValue.b, tint.b, distanceInsideMedium, absorption)\n\t);\n}\n\n#endif\n\nvec3 applyMaterial(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(0.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n\n\n\n\nvec4 applyShading(vec3 rayOrigin, vec3 rayDir, inout SDFContext sdfContext){\n\tvec3 p = rayOrigin + rayDir * sdfContext.d;\n\tvec3 n = GetNormal(p);\n\t\n\tvec3 col = applyMaterial(p, n, rayDir, sdfContext.matId, sdfContext);\n\tif(sdfContext.matBlend > 0.) {\n\t\t// blend material colors if needed\n\t\tvec3 col2 = applyMaterial(p, n, rayDir, sdfContext.matId2, sdfContext);\n\t\tcol = (1. - sdfContext.matBlend)*col + sdfContext.matBlend*col2;\n\t}\n\t\t\n\t// gamma\n\t//col = pow( col, vec3(0.4545) ); // this gamma leads to a different look than standard materials\n\treturn vec4(col, 1.);\n}\n\nvoid main()\t{\n\n\tvec3 rayDir = normalize(vPw - cameraPosition);\n\trayDir = transformDirection(rayDir, vInverseModelMatrix);\n\tvec3 rayOrigin = (vInverseModelMatrix * vec4( cameraPosition, 1.0 )).xyz;\n\n\tSDFContext sdfContext = RayMarch(rayOrigin, rayDir, 1.);\n\n\t#if defined( DEBUG_DEPTH )\n\t\tfloat normalizedDepth = 1.-(sdfContext.d - debugMinDepth ) / ( debugMaxDepth - debugMinDepth );\n\t\tnormalizedDepth = saturate(normalizedDepth); // clamp to [0,1]\n\t\tgl_FragColor = vec4(normalizedDepth);\n\t\treturn;\n\t#endif\n\t#if defined( SHADOW_DEPTH )\n\t\tfloat normalizedDepth = 1.-(sdfContext.d - debugMinDepth ) / ( debugMaxDepth - debugMinDepth );\n\t\t// float fragCoordZ = sdfContext.d / vHighPrecisionZW[1];\n\t\tfloat compoundedDepth = 0.5 * (normalizedDepth) + 0.5;\n\t\tfloat alpha = sdfContext.d < MAX_DIST ? 0.:1.;\n\t\tgl_FragColor = vec4( vec3(compoundedDepth), alpha );\n\t\t// normalizedDepth = 0.5*normalizedDepth+0.5;\n\t\t// gl_FragColor = packDepthToRGBA( normalizedDepth );\n\t\t// gl_FragColor = vec4(0.);\n\t\treturn;\n\t#endif\n\t#if defined( SHADOW_DISTANCE )\n\t\tfloat normalizedDepth = (sdfContext.d - shadowDistanceMin ) / ( shadowDistanceMax - shadowDistanceMin );\n\t\tnormalizedDepth = saturate(normalizedDepth); // clamp to [0,1]\n\t\tgl_FragColor = packDepthToRGBA( normalizedDepth );\n\t\treturn;\n\t#endif\n\n\tif( sdfContext.d < MAX_DIST ){\n\t\tgl_FragColor = applyShading(rayOrigin, rayDir, sdfContext);\n\t\t#if defined( TONE_MAPPING )\n\t\t\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n\t\t#endif\n\t\tgl_FragColor = linearToOutputTexel( gl_FragColor );\n\n\t\t#ifdef USE_FOG\n\t\t\tfloat vFogDepth = sdfContext.d;\n\t\t\t#ifdef FOG_EXP2\n\t\t\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );\n\t\t\t#else\n\t\t\t\tfloat fogFactor = smoothstep( fogNear, fogFar, vFogDepth );\n\t\t\t#endif\n\t\t\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n\t\t#endif\n\t\t#include <premultiplied_alpha_fragment>\n\t\t#include <dithering_fragment>\n\t} else {\n\t\tgl_FragColor = vec4(0.);\n\t}\n\n\t#if defined( DEBUG_STEPS_COUNT )\n\t\tfloat normalizedStepsCount = (float(sdfContext.stepsCount) - debugMinSteps ) / ( debugMaxSteps - debugMinSteps );\n\t\tgl_FragColor = vec4(normalizedStepsCount, 1.-normalizedStepsCount, 0., 1.);\n\t\treturn;\n\t#endif\n\t\n}","customDistanceMaterial.vertex":"precision highp float;\nprecision highp int;\n\nvarying vec3 vPw;\nvarying mat4 vModelMatrix;\nvarying mat4 vInverseModelMatrix;\nvarying mat4 VViewMatrix;\n\n#include <common>\n\n// // for depth material\n// varying vec2 vHighPrecisionZW;\n\nvoid main()\t{\n\n\tvModelMatrix = modelMatrix;\n\tvInverseModelMatrix = inverse(modelMatrix);\n\tVViewMatrix = viewMatrix;\n\tvPw = (modelMatrix * vec4( position, 1.0 )).xyz;\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n\t// vHighPrecisionZW = gl_Position.zw;\n}","customDistanceMaterial.fragment":"precision highp float;\nprecision highp int;\n\n// --- applyMaterial constants definition\nuniform int MAX_STEPS;\nuniform float MAX_DIST;\nuniform float SURF_DIST;\nuniform float NORMALS_BIAS;\nuniform float SHADOW_BIAS;\n#define ZERO 0\nuniform float debugMinSteps;\nuniform float debugMaxSteps;\nuniform float debugMinDepth;\nuniform float debugMaxDepth;\n\n#include <common>\n#include <packing>\n#include <lightmap_pars_fragment>\n#include <bsdfs>\n#include <cube_uv_reflection_fragment>\n#include <lights_pars_begin>\n#include <lights_physical_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <fog_pars_fragment>\n\n#if defined( SHADOW_DISTANCE )\n\tuniform float shadowDistanceMin;\n\tuniform float shadowDistanceMax;\n#endif \n#if defined( SHADOW_DEPTH )\n\tuniform float shadowDepthMin;\n\tuniform float shadowDepthMax;\n#endif\n\n// varying vec2 vHighPrecisionZW;\n\nvarying vec3 vPw;\nvarying mat4 vModelMatrix;\nvarying mat4 vInverseModelMatrix;\nvarying mat4 VViewMatrix;\n\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform SpotLightRayMarching spotLightsRayMarching[ NUM_SPOT_LIGHTS ];\n\t#if NUM_SPOT_LIGHT_COORDS > 0\n\n\t\tuniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];\n\n\t#endif\n#endif\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform DirectionalLightRayMarching directionalLightsRayMarching[ NUM_DIR_LIGHTS ];\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\n\t#endif\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform PointLightRayMarching pointLightsRayMarching[ NUM_POINT_LIGHTS ];\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\n\t#endif\n#endif\n\n\nstruct SDFContext {\n\tfloat d;\n\tint stepsCount;\n\tint matId;\n\tint matId2;\n\tfloat matBlend;\n};\n\nSDFContext DefaultSDFContext(){\n\treturn SDFContext( 0., 0, 0, 0, 0. );\n}\nint DefaultSDFMaterial(){\n\treturn 0;\n}\n\n// start raymarching builder define code\n\n\n\n// /geo1/MAT/rayMarchingBuilder1/SDFSphere3\nfloat dot2( in vec2 v ) { return dot(v,v); }\nfloat dot2( in vec3 v ) { return dot(v,v); }\nfloat ndot( in vec2 a, in vec2 b ) { return a.x*b.x - a.y*b.y; }\n// https://iquilezles.org/articles/distfunctions/\n\n\n/*\n*\n* SDF PRIMITIVES\n*\n*/\nfloat sdSphere( vec3 p, float s )\n{\n\treturn length(p)-s;\n}\nfloat sdCutSphere( vec3 p, float r, float h )\n{\n\t// sampling independent computations (only depend on shape)\n\tfloat w = sqrt(r*r-h*h);\n\n\t// sampling dependant computations\n\tvec2 q = vec2( length(p.xz), p.y );\n\tfloat s = max( (h-r)*q.x*q.x+w*w*(h+r-2.0*q.y), h*q.x-w*q.y );\n\treturn (s<0.0) ? length(q)-r :\n\t\t\t\t(q.x<w) ? h - q.y :\n\t\t\t\t\tlength(q-vec2(w,h));\n}\nfloat sdCutHollowSphere( vec3 p, float r, float h, float t )\n{\n\t// sampling independent computations (only depend on shape)\n\tfloat w = sqrt(r*r-h*h);\n\t\n\t// sampling dependant computations\n\tvec2 q = vec2( length(p.xz), p.y );\n\treturn ((h*q.x<w*q.y) ? length(q-vec2(w,h)) : \n\t\t\t\t\t\t\tabs(length(q)-r) ) - t;\n}\n\nfloat sdBox( vec3 p, vec3 b )\n{\n\tvec3 q = abs(p) - b*0.5;\n\treturn length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0);\n}\nfloat sdRoundBox( vec3 p, vec3 b, float r )\n{\n\tvec3 q = abs(p) - b*0.5;\n\treturn length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0) - r;\n}\n\n\nfloat sdBoxFrame( vec3 p, vec3 b, float e )\n{\n\t\tp = abs(p )-b*0.5;\n\tvec3 q = abs(p+e)-e;\n\treturn min(min(\n\t\tlength(max(vec3(p.x,q.y,q.z),0.0))+min(max(p.x,max(q.y,q.z)),0.0),\n\t\tlength(max(vec3(q.x,p.y,q.z),0.0))+min(max(q.x,max(p.y,q.z)),0.0)),\n\t\tlength(max(vec3(q.x,q.y,p.z),0.0))+min(max(q.x,max(q.y,p.z)),0.0));\n}\nfloat sdCapsule( vec3 p, vec3 a, vec3 b, float r )\n{\n\tvec3 pa = p - a, ba = b - a;\n\tfloat h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n\treturn length( pa - ba*h ) - r;\n}\nfloat sdVerticalCapsule( vec3 p, float h, float r )\n{\n\tp.y -= clamp( p.y, 0.0, h );\n\treturn length( p ) - r;\n}\nfloat sdCone( in vec3 p, in vec2 c, float h )\n{\n\t// c is the sin/cos of the angle, h is height\n\t// Alternatively pass q instead of (c,h),\n\t// which is the point at the base in 2D\n\tvec2 q = h*vec2(c.x/c.y,-1.0);\n\n\tvec2 w = vec2( length(p.xz), p.y );\n\tvec2 a = w - q*clamp( dot(w,q)/dot(q,q), 0.0, 1.0 );\n\tvec2 b = w - q*vec2( clamp( w.x/q.x, 0.0, 1.0 ), 1.0 );\n\tfloat k = sign( q.y );\n\tfloat d = min(dot( a, a ),dot(b, b));\n\tfloat s = max( k*(w.x*q.y-w.y*q.x),k*(w.y-q.y) );\n\treturn sqrt(d)*sign(s);\n}\nfloat sdConeWrapped(vec3 pos, float angle, float height){\n\treturn sdCone(pos, vec2(sin(angle), cos(angle)), height);\n}\nfloat sdRoundCone( vec3 p, float r1, float r2, float h )\n{\n\tfloat b = (r1-r2)/h;\n\tfloat a = sqrt(1.0-b*b);\n\n\tvec2 q = vec2( length(p.xz), p.y );\n\tfloat k = dot(q,vec2(-b,a));\n\tif( k<0.0 ) return length(q) - r1;\n\tif( k>a*h ) return length(q-vec2(0.0,h)) - r2;\n\treturn dot(q, vec2(a,b) ) - r1;\n}\nfloat sdOctogonPrism( in vec3 p, in float r, float h )\n{\n\tconst vec3 k = vec3(-0.9238795325, // sqrt(2+sqrt(2))/2 \n\t\t\t\t\t\t0.3826834323, // sqrt(2-sqrt(2))/2\n\t\t\t\t\t\t0.4142135623 ); // sqrt(2)-1 \n\t// reflections\n\tp = abs(p);\n\tp.xy -= 2.0*min(dot(vec2( k.x,k.y),p.xy),0.0)*vec2( k.x,k.y);\n\tp.xy -= 2.0*min(dot(vec2(-k.x,k.y),p.xy),0.0)*vec2(-k.x,k.y);\n\t// polygon side\n\tp.xy -= vec2(clamp(p.x, -k.z*r, k.z*r), r);\n\tvec2 d = vec2( length(p.xy)*sign(p.y), p.z-h );\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdHexPrism( vec3 p, vec2 h )\n{\n\tconst vec3 k = vec3(-0.8660254, 0.5, 0.57735);\n\tp = abs(p);\n\tp.xy -= 2.0*min(dot(k.xy, p.xy), 0.0)*k.xy;\n\tvec2 d = vec2(\n\t\tlength(p.xy-vec2(clamp(p.x,-k.z*h.x,k.z*h.x), h.x))*sign(p.y-h.x),\n\t\tp.z-h.y );\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdHorseshoe( in vec3 p, in float angle, in float r, in float le, vec2 w )\n{\n\tvec2 c = vec2(cos(angle),sin(angle));\n\tp.x = abs(p.x);\n\tfloat l = length(p.xy);\n\tp.xy = mat2(-c.x, c.y, \n\t\t\tc.y, c.x)*p.xy;\n\tp.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x),\n\t\t\t\t(p.x>0.0)?p.y:l );\n\tp.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0);\n\t\n\tvec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z);\n\tvec2 d = abs(q) - w;\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdTriPrism( vec3 p, vec2 h )\n{\n\tvec3 q = abs(p);\n\treturn max(q.z-h.y,max(q.x*0.866025+p.y*0.5,-p.y)-h.x*0.5);\n}\nfloat sdPyramid( vec3 p, float h)\n{\n\tfloat m2 = h*h + 0.25;\n\n\tp.xz = abs(p.xz);\n\tp.xz = (p.z>p.x) ? p.zx : p.xz;\n\tp.xz -= 0.5;\n\n\tvec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y);\n\n\tfloat s = max(-q.x,0.0);\n\tfloat t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 );\n\n\tfloat a = m2*(q.x+s)*(q.x+s) + q.y*q.y;\n\tfloat b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t);\n\n\tfloat d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b);\n\n\treturn sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));\n}\n\nfloat sdPlane( vec3 p, vec3 n, float h )\n{\n\t// n must be normalized\n\treturn dot(p,n) + h;\n}\n\nfloat sdTorus( vec3 p, vec2 t )\n{\n\tvec2 q = vec2(length(p.xz)-t.x,p.y);\n\treturn length(q)-t.y;\n}\nfloat sdCappedTorus(in vec3 p, in float an, in float ra, in float rb)\n{\n\tvec2 sc = vec2(sin(an),cos(an));\n\tp.x = abs(p.x);\n\tfloat k = (sc.y*p.x>sc.x*p.z) ? dot(p.xz,sc) : length(p.xz);\n\treturn sqrt( dot(p,p) + ra*ra - 2.0*ra*k ) - rb;\n}\nfloat sdLink( vec3 p, float le, float r1, float r2 )\n{\n vec3 q = vec3( p.x, max(abs(p.y)-le,0.0), p.z );\n return length(vec2(length(q.xy)-r1,q.z)) - r2;\n}\n// c is the sin/cos of the desired cone angle\nfloat sdSolidAngle(vec3 pos, vec2 c, float radius)\n{\n\tvec2 p = vec2( length(pos.xz), pos.y );\n\tfloat l = length(p) - radius;\n\tfloat m = length(p - c*clamp(dot(p,c),0.0,radius) );\n\treturn max(l,m*sign(c.y*p.x-c.x*p.y));\n}\nfloat sdSolidAngleWrapped(vec3 pos, float angle, float radius){\n\treturn sdSolidAngle(pos, vec2(sin(angle), cos(angle)), radius);\n}\nfloat sdTube( vec3 p, float r )\n{\n\treturn length(p.xz)-r;\n}\nfloat sdTubeCapped( vec3 p, float h, float r )\n{\n\tvec2 d = abs(vec2(length(p.xz),p.y)) - vec2(r,h);\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdOctahedron( vec3 p, float s)\n{\n p = abs(p);\n float m = p.x+p.y+p.z-s;\n vec3 q;\n if( 3.0*p.x < m ) q = p.xyz;\n else if( 3.0*p.y < m ) q = p.yzx;\n else if( 3.0*p.z < m ) q = p.zxy;\n else return m*0.57735027;\n \n float k = clamp(0.5*(q.z-q.y+s),0.0,s); \n return length(vec3(q.x,q.y-s+k,q.z-k)); \n}\nfloat udTriangle( vec3 p, vec3 a, vec3 b, vec3 c, float thickness )\n{\n\tvec3 ba = b - a; vec3 pa = p - a;\n\tvec3 cb = c - b; vec3 pb = p - b;\n\tvec3 ac = a - c; vec3 pc = p - c;\n\tvec3 nor = cross( ba, ac );\n\n\treturn - thickness + sqrt(\n\t\t(sign(dot(cross(ba,nor),pa)) +\n\t\tsign(dot(cross(cb,nor),pb)) +\n\t\tsign(dot(cross(ac,nor),pc))<2.0)\n\t\t?\n\t\tmin( min(\n\t\tdot2(ba*clamp(dot(ba,pa)/dot2(ba),0.0,1.0)-pa),\n\t\tdot2(cb*clamp(dot(cb,pb)/dot2(cb),0.0,1.0)-pb) ),\n\t\tdot2(ac*clamp(dot(ac,pc)/dot2(ac),0.0,1.0)-pc) )\n\t\t:\n\t\tdot(nor,pa)*dot(nor,pa)/dot2(nor) );\n}\nfloat udQuad( vec3 p, vec3 a, vec3 b, vec3 c, vec3 d, float thickness )\n{\n\tvec3 ba = b - a; vec3 pa = p - a;\n\tvec3 cb = c - b; vec3 pb = p - b;\n\tvec3 dc = d - c; vec3 pc = p - c;\n\tvec3 ad = a - d; vec3 pd = p - d;\n\tvec3 nor = cross( ba, ad );\n\n\treturn - thickness + sqrt(\n\t\t(sign(dot(cross(ba,nor),pa)) +\n\t\tsign(dot(cross(cb,nor),pb)) +\n\t\tsign(dot(cross(dc,nor),pc)) +\n\t\tsign(dot(cross(ad,nor),pd))<3.0)\n\t\t?\n\t\tmin( min( min(\n\t\tdot2(ba*clamp(dot(ba,pa)/dot2(ba),0.0,1.0)-pa),\n\t\tdot2(cb*clamp(dot(cb,pb)/dot2(cb),0.0,1.0)-pb) ),\n\t\tdot2(dc*clamp(dot(dc,pc)/dot2(dc),0.0,1.0)-pc) ),\n\t\tdot2(ad*clamp(dot(ad,pd)/dot2(ad),0.0,1.0)-pd) )\n\t\t:\n\t\tdot(nor,pa)*dot(nor,pa)/dot2(nor) );\n}\n\n/*\n*\n* SDF OPERATIONS\n*\n*/\nfloat SDFUnion( float d1, float d2 ) { return min(d1,d2); }\nfloat SDFSubtract( float d1, float d2 ) { return max(-d1,d2); }\nfloat SDFIntersect( float d1, float d2 ) { return max(d1,d2); }\n\nfloat SDFSmoothUnion( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 + 0.5*(d2-d1)/k, 0.0, 1.0 );\n\treturn mix( d2, d1, h ) - k*h*(1.0-h);\n}\n\nfloat SDFSmoothSubtract( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 - 0.5*(d2+d1)/k, 0.0, 1.0 );\n\treturn mix( d2, -d1, h ) + k*h*(1.0-h);\n}\n\nfloat SDFSmoothIntersect( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 - 0.5*(d2-d1)/k, 0.0, 1.0 );\n\treturn mix( d2, d1, h ) + k*h*(1.0-h);\n}\n\nvec4 SDFElongateFast( in vec3 p, in vec3 h )\n{\n\treturn vec4( p-clamp(p,-h,h), 0.0 );\n}\nvec4 SDFElongateSlow( in vec3 p, in vec3 h )\n{\n\tvec3 q = abs(p)-h;\n\treturn vec4( max(q,0.0), min(max(q.x,max(q.y,q.z)),0.0) );\n}\n\nfloat SDFOnion( in float sdf, in float thickness )\n{\n\treturn abs(sdf)-thickness;\n}\n\n// /geo1/MAT/rayMarchingBuilder1/checkers1\n// https://iquilezles.org/articles/checkerfiltering/\nfloat checkers(vec2 p) {\n\tvec2 s = sign(fract(p*.5)-.5);\n\treturn .5 - .5*s.x*s.y;\n}\nfloat checkersGrad( in vec2 p, in vec2 ddx, in vec2 ddy )\n{\n // filter kernel\n vec2 w = max(abs(ddx), abs(ddy)) + 0.01;\n // analytical integral (box filter)\n vec2 i = 2.0*(abs(fract((p-0.5*w)/2.0)-0.5)-abs(fract((p+0.5*w)/2.0)-0.5))/w;\n // xor pattern\n return 0.5 - 0.5*i.x*i.y;\n}\n\n\n// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\nconst int _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1 = 1;\n\n\n// https://stackoverflow.com/questions/23793698/how-to-implement-slerp-in-glsl-hlsl\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t)\n// {\n// \tfloat dotp = dot(normalize(p0), normalize(p1));\n// \tif ((dotp > 0.9999) || (dotp < -0.9999))\n// \t{\n// \t\tif (t<=0.5)\n// \t\t\treturn p0;\n// \t\treturn p1;\n// \t}\n// \tfloat theta = acos(dotp);\n// \tvec4 P = ((p0*sin((1.0-t)*theta) + p1*sin(t*theta)) / sin(theta));\n// \tP.w = 1.0;\n// \treturn P;\n// }\n\n// https://devcry.heiho.net/html/2017/20170521-slerp.html\n// float lerp(float a, float b, float t) {\n// \treturn (1.0 - t) * a + t * b;\n// }\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t){\n// \tvec4 qb = p1;\n\n// \t// cos(a) = dot product\n// \tfloat cos_a = p0.x * qb.x + p0.y * qb.y + p0.z * qb.z + p0.w * qb.w;\n// \tif (cos_a < 0.0f) {\n// \t\tcos_a = -cos_a;\n// \t\tqb = -qb;\n// \t}\n\n// \t// close to zero, cos(a) ~= 1\n// \t// do linear interpolation\n// \tif (cos_a > 0.999) {\n// \t\treturn vec4(\n// \t\t\tlerp(p0.x, qb.x, t),\n// \t\t\tlerp(p0.y, qb.y, t),\n// \t\t\tlerp(p0.z, qb.z, t),\n// \t\t\tlerp(p0.w, qb.w, t)\n// \t\t);\n// \t}\n\n// \tfloat alpha = acos(cos_a);\n// \treturn (p0 * sin(1.0 - t) + p1 * sin(t * alpha)) / sin(alpha);\n// }\n\n// https://stackoverflow.com/questions/62943083/interpolate-between-two-quaternions-the-long-way\nvec4 quatSlerp(vec4 q1, vec4 q2, float t){\n\tfloat angle = acos(dot(q1, q2));\n\tfloat denom = sin(angle);\n\t//check if denom is zero\n\treturn (q1*sin((1.0-t)*angle)+q2*sin(t*angle))/denom;\n}\n// TO CHECK:\n// this page https://www.reddit.com/r/opengl/comments/704la7/glsl_quaternion_library/\n// has a link to a potentially nice pdf:\n// http://web.mit.edu/2.998/www/QuaternionReport1.pdf\n\n// https://github.com/mattatz/ShibuyaCrowd/blob/master/source/shaders/common/quaternion.glsl\nvec4 quatMult(vec4 q1, vec4 q2)\n{\n\treturn vec4(\n\tq1.w * q2.x + q1.x * q2.w + q1.z * q2.y - q1.y * q2.z,\n\tq1.w * q2.y + q1.y * q2.w + q1.x * q2.z - q1.z * q2.x,\n\tq1.w * q2.z + q1.z * q2.w + q1.y * q2.x - q1.x * q2.y,\n\tq1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z\n\t);\n}\n// http://glmatrix.net/docs/quat.js.html#line97\n// let ax = a[0], ay = a[1], az = a[2], aw = a[3];\n\n// let bx = b[0], by = b[1], bz = b[2], bw = b[3];\n\n// out[0] = ax * bw + aw * bx + ay * bz - az * by;\n\n// out[1] = ay * bw + aw * by + az * bx - ax * bz;\n\n// out[2] = az * bw + aw * bz + ax * by - ay * bx;\n\n// out[3] = aw * bw - ax * bx - ay * by - az * bz;\n\n// return out\n\n\n\n// http://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/\nmat4 rotationMatrix(vec3 axis, float angle)\n{\n\taxis = normalize(axis);\n\tfloat s = sin(angle);\n\tfloat c = cos(angle);\n\tfloat oc = 1.0 - c;\n\n \treturn mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 0.0, 0.0, 0.0, 1.0);\n}\n\n// https://www.geeks3d.com/20141201/how-to-rotate-a-vertex-by-a-quaternion-in-glsl/\nvec4 quatFromAxisAngle(vec3 axis, float angle)\n{\n\tvec4 qr;\n\tfloat half_angle = (angle * 0.5); // * 3.14159 / 180.0;\n\tfloat sin_half_angle = sin(half_angle);\n\tqr.x = axis.x * sin_half_angle;\n\tqr.y = axis.y * sin_half_angle;\n\tqr.z = axis.z * sin_half_angle;\n\tqr.w = cos(half_angle);\n\treturn qr;\n}\nvec3 rotateWithAxisAngle(vec3 position, vec3 axis, float angle)\n{\n\tvec4 q = quatFromAxisAngle(axis, angle);\n\tvec3 v = position.xyz;\n\treturn v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);\n}\n// vec3 applyQuaternionToVector( vec4 q, vec3 v ){\n// \treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n// }\nvec3 rotateWithQuat( vec3 v, vec4 q )\n{\n\t// vec4 qv = multQuat( quat, vec4(vec, 0.0) );\n\t// return multQuat( qv, vec4(-quat.x, -quat.y, -quat.z, quat.w) ).xyz;\n\treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n}\n// https://github.com/glslify/glsl-look-at/blob/gh-pages/index.glsl\n// mat3 rotation_matrix(vec3 origin, vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target - origin);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n// mat3 rotation_matrix(vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n\nfloat vectorAngle(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 c1 = cross(start, dest);\n\t// We use the dot product of the cross with the Y axis.\n\t// This is a little arbitrary, but can still give a good sense of direction\n\tvec3 y_axis = vec3(0.0, 1.0, 0.0);\n\tfloat d1 = dot(c1, y_axis);\n\tfloat angle = acos(cosTheta) * sign(d1);\n\treturn angle;\n}\n\n// http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/#i-need-an-equivalent-of-glulookat-how-do-i-orient-an-object-towards-a-point-\nvec4 vectorAlign(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 axis;\n\n\t// if (cosTheta < -1 + 0.001f){\n\t// \t// special case when vectors in opposite directions:\n\t// \t// there is no ideal rotation axis\n\t// \t// So guess one; any will do as long as it's perpendicular to start\n\t// \taxis = cross(vec3(0.0f, 0.0f, 1.0f), start);\n\t// \tif (length2(axis) < 0.01 ) // bad luck, they were parallel, try again!\n\t// \t\taxis = cross(vec3(1.0f, 0.0f, 0.0f), start);\n\n\t// \taxis = normalize(axis);\n\t// \treturn gtx::quaternion::angleAxis(glm::radians(180.0f), axis);\n\t// }\n\tif(cosTheta > (1.0 - 0.0001) || cosTheta < (-1.0 + 0.0001) ){\n\t\taxis = normalize(cross(start, vec3(0.0, 1.0, 0.0)));\n\t\tif (length(axis) < 0.001 ){ // bad luck, they were parallel, try again!\n\t\t\taxis = normalize(cross(start, vec3(1.0, 0.0, 0.0)));\n\t\t}\n\t} else {\n\t\taxis = normalize(cross(start, dest));\n\t}\n\n\tfloat angle = acos(cosTheta);\n\n\treturn quatFromAxisAngle(axis, angle);\n}\nvec4 vectorAlignWithUp(vec3 start, vec3 dest, vec3 up){\n\tvec4 rot1 = vectorAlign(start, dest);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\t// vec3 right = normalize(cross(dest, up));\n\t// up = normalize(cross(right, dest));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(vec3(0.0, 1.0, 0.0), rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(up, newUp);\n\n\t// return rot1;\n\treturn rot2;\n\t// return multQuat(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\n// https://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\nfloat quatToAngle(vec4 q){\n\treturn 2.0 * acos(q.w);\n}\nvec3 quatToAxis(vec4 q){\n\treturn vec3(\n\t\tq.x / sqrt(1.0-q.w*q.w),\n\t\tq.y / sqrt(1.0-q.w*q.w),\n\t\tq.z / sqrt(1.0-q.w*q.w)\n\t);\n}\n\nvec4 align(vec3 dir, vec3 up){\n\tvec3 start_dir = vec3(0.0, 0.0, 1.0);\n\tvec3 start_up = vec3(0.0, 1.0, 0.0);\n\tvec4 rot1 = vectorAlign(start_dir, dir);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\tvec3 right = normalize(cross(dir, up));\n\tif(length(right)<0.001){\n\t\tright = vec3(1.0, 0.0, 0.0);\n\t}\n\tup = normalize(cross(right, dir));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(start_up, rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(normalize(newUp), up);\n\n\t// return rot1;\n\treturn quatMult(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\nstruct EnvMapProps {\n\tvec3 tint;\n\tfloat intensity;\n\tfloat roughness;\n\tfloat fresnel;\n\tfloat fresnelPower;\n};\nuniform sampler2D envMap;\nuniform float envMapIntensity;\nuniform float roughness;\n#ifdef ROTATE_ENV_MAP_Y\n\tuniform float envMapRotationY;\n#endif\nvec3 envMapSample(vec3 rayDir, float envMapRoughness){\n\t// http://www.pocketgl.com/reflections/\n\tvec3 env = vec3(0.);\n\t// vec2 uv = vec2( atan( -rayDir.z, -rayDir.x ) * RECIPROCAL_PI2 + 0.5, rayDir.y * 0.5 + 0.5 );\n\t// vec3 env = texture2D(map, uv).rgb;\n\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t#ifdef ROTATE_ENV_MAP_Y\n\t\t\trayDir = rotateWithAxisAngle(rayDir, vec3(0.,1.,0.), envMapRotationY);\n\t\t#endif\n\t\tenv = textureCubeUV(envMap, rayDir, envMapRoughness * roughness).rgb;\n\t#endif\n\treturn env;\n}\nvec3 envMapSampleWithFresnel(vec3 rayDir, EnvMapProps envMapProps, vec3 n, vec3 cameraPosition){\n\t// http://www.pocketgl.com/reflections/\n\tvec3 env = envMapSample(rayDir, envMapProps.roughness);\n\tfloat fresnel = pow(1.-dot(normalize(cameraPosition), n), envMapProps.fresnelPower);\n\tfloat fresnelFactor = (1.-envMapProps.fresnel) + envMapProps.fresnel*fresnel;\n\treturn env * envMapIntensity * envMapProps.tint * envMapProps.intensity * fresnelFactor;\n}\n\n\n\n\n\n\nSDFContext GetDist(vec3 p) {\n\tSDFContext sdfContext = SDFContext(0., 0, 0, 0, 0.);\n\n\t// start GetDist builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/SDFSphere3\n\tfloat v_POLY_SDFSphere3_float = sdSphere(p - vec3(-0.25, 0.0, 0.0), 0.2);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFSphere4\n\tfloat v_POLY_SDFSphere4_float = sdSphere(p - vec3(0.25, 0.0, 0.0), 0.2);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFPlane1\n\tfloat v_POLY_SDFPlane1_float = sdPlane(p-vec3(0.0, -0.2, 0.0), vec3(0.0, 1.0, 0.0), 0.0);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFUnion2\n\tfloat v_POLY_SDFUnion2_union = SDFSmoothUnion(v_POLY_SDFSphere3_float, v_POLY_SDFSphere4_float, 0.31);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFUnion3\n\tfloat v_POLY_SDFUnion3_union = SDFSmoothUnion(v_POLY_SDFUnion2_union, v_POLY_SDFPlane1_float, 0.31);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFContext1\n\tSDFContext v_POLY_SDFContext1_SDFContext = SDFContext(v_POLY_SDFUnion3_union, 0, _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1, _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1, 0.);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/output1\n\tsdfContext = v_POLY_SDFContext1_SDFContext;\n\n\n\n\t\n\n\treturn sdfContext;\n}\n\nSDFContext RayMarch(vec3 ro, vec3 rd, float side) {\n\tSDFContext dO = SDFContext(0.,0,0,0,0.);\n\n\t#pragma unroll_loop_start\n\tfor(int i=0; i<MAX_STEPS; i++) {\n\t\tvec3 p = ro + rd*dO.d;\n\t\tSDFContext sdfContext = GetDist(p);\n\t\tdO.d += sdfContext.d * side;\n\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\tdO.stepsCount += 1;\n\t\t#endif\n\t\tdO.matId = sdfContext.matId;\n\t\tdO.matId2 = sdfContext.matId2;\n\t\tdO.matBlend = sdfContext.matBlend;\n\t\tif(dO.d>MAX_DIST || abs(sdfContext.d)<SURF_DIST) break;\n\t}\n\t#pragma unroll_loop_end\n\n\treturn dO;\n}\n\nvec3 GetNormal(vec3 p) {\n\tSDFContext sdfContext = GetDist(p);\n\tvec2 e = vec2(NORMALS_BIAS, 0);\n\n\tvec3 n = sdfContext.d - vec3(\n\t\tGetDist(p-e.xyy).d,\n\t\tGetDist(p-e.yxy).d,\n\t\tGetDist(p-e.yyx).d);\n\n\treturn normalize(n);\n}\n// https://iquilezles.org/articles/rmshadows\nfloat calcSoftshadow( in vec3 ro, in vec3 rd, float mint, float maxt, float k, inout SDFContext sdfContext )\n{\n\tfloat res = 1.0;\n\tfloat ph = 1e20;\n\tfor( float t=mint; t<maxt; )\n\t{\n\t\tfloat h = GetDist(ro + rd*t).d;\n\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\tsdfContext.stepsCount += 1;\n\t\t#endif\n\t\tif( h<SURF_DIST )\n\t\t\treturn 0.0;\n\t\tfloat y = h*h/(2.0*ph);\n\t\tfloat d = sqrt(h*h-y*y);\n\t\tres = min( res, k*d/max(0.0,t-y) );\n\t\tph = h;\n\t\tt += h;\n\t}\n\treturn res;\n}\n\nvec3 GetLight(vec3 _p, vec3 _n, inout SDFContext sdfContext) {\n\tvec3 dif = vec3(0.,0.,0.);\n\t// GeometricContext geometry;\n\t// geometry.position = _p;\n\t// geometry.normal = _n;\n\t// geometry.viewDir = rayDir;\n\n\t// vec4 mvPosition = vec4( p, 1.0 );\n\t// mvPosition = modelViewMatrix * mvPosition;\n\t// vec3 vViewPosition = - mvPosition.xyz;\n\tvec3 pWorld = ( vModelMatrix * vec4( _p, 1.0 )).xyz;\n\tvec3 nWorld = transformDirection(_n, vModelMatrix);\n\t// geometry.position = (VViewMatrix * vec4( _p, 1.0 )).xyz;\n\tvec3 geometryPosition = (VViewMatrix * vec4(pWorld, 1.0 )).xyz;\n\t// geometry.normal = transformDirection(_n, VViewMatrix);\n\t// geometry.normal = inverseTransformDirection(transformDirection(_n, VViewMatrix), vInverseModelMatrix);\n\tvec3 geometryNormal = transformDirection(nWorld, VViewMatrix);\n\t\n\n\t#if NUM_SPOT_LIGHTS > 0 || NUM_DIR_LIGHTS > 0 || NUM_HEMI_LIGHTS > 0 || NUM_POINT_LIGHTS > 0 || NUM_RECT_AREA_LIGHTS > 0\n\n\t\tIncidentLight directLight;\n\t\tReflectedLight reflectedLight;\n\t\tvec3 lightPos, lightDir, worldLightDir, objectSpaceLightDir, lighDif, directDiffuse;\n\t\tfloat dotNL, lightDistance;\n\t\t#if NUM_SPOT_LIGHTS > 0\n\t\t\tSpotLightRayMarching spotLightRayMarching;\n\t\t\tSpotLight spotLight;\n\t\t\tfloat spotLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\t\t\t\tSpotLightShadow spotLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\t\t\tspotLightRayMarching = spotLightsRayMarching[ i ];\n\t\t\t\tspotLight = spotLights[ i ];\n\t\t\t\tgetSpotLightInfo( spotLight, geometryPosition, directLight );\n\n\t\t\t\t// #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t\t\t// \tspotLightShadow = spotLightShadows[ i ];\n\t\t\t\t// \tvec4 spotLightShadowCoord = spotLightMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t// \tdirectLight.color *= (directLight.visible && receiveShadow) ? getShadow(\n\t\t\t\t// \t\tspotShadowMap[ i ],\n\t\t\t\t// \t\tspotLightShadow.shadowMapSize,\n\t\t\t\t// \t\tspotLightShadow.shadowBias,\n\t\t\t\t// \t\tspotLightShadow.shadowRadius,\n\t\t\t\t// \t\tspotLightShadowCoord\n\t\t\t\t// \t) : 1.0;\n\t\t\t\t// #endif\n\n\t\t\t\tlightPos = spotLight.position;\n\t\t\t\tlightDir = normalize(lightPos-geometryPosition);\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tlightDistance = distance(geometryPosition,lightPos);\n\t\t\t\tspotLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < spotLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t: calcSoftshadow(\n\t\t\t\t\t\t_p,\n\t\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\t\tspotLightRayMarching.shadowBiasDistance,\n\t\t\t\t\t\tdistance(geometryPosition,lightPos),\n\t\t\t\t\t\t1./max(spotLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\t\tsdfContext\n\t\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * spotLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\t\t#if NUM_DIR_LIGHTS > 0\n\t\t\tDirectionalLightRayMarching directionalLightRayMarching;\n\t\t\tDirectionalLight directionalLight;\n\t\t\tfloat dirLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\t\t\t\tDirectionalLightShadow directionalLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\t\t\tdirectionalLightRayMarching = directionalLightsRayMarching[ i ];\n\t\t\t\tdirectionalLight = directionalLights[ i ];\n\t\t\t\t\n\t\t\t\tgetDirectionalLightInfo( directionalLight, directLight );\n\n\t\t\t\t// #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\t\t\t// \tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\t\t\t// \tvec4 dirLightShadowCoord = directionalShadowMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t// \tdirectLight.color *= (directLight.visible && receiveShadow) ? getShadow(\n\t\t\t\t// \t\tdirectionalShadowMap[ i ],\n\t\t\t\t// \t\tdirectionalLightShadow.shadowMapSize,\n\t\t\t\t// \t\tdirectionalLightShadow.shadowBias,\n\t\t\t\t// \t\tdirectionalLightShadow.shadowRadius,\n\t\t\t\t// \t\tdirLightShadowCoord\n\t\t\t\t// \t) : 1.0;\n\t\t\t\t// #endif\n\n\t\t\t\tlightDir = directionalLight.direction;\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tdirLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < directionalLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t:\n\t\t\t\t\tcalcSoftshadow(\n\t\t\t\t\t\t_p,\n\t\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\t\tdirectionalLightRayMarching.shadowBiasDistance,\n\t\t\t\t\t\tMAX_DIST,//distance(geometryPosition,lightPos),\n\t\t\t\t\t\t1./max(directionalLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\t\tsdfContext\n\t\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\t// lighDif = directLight.color * dotNL * dirLightSdfShadow;\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * dirLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\n\t\t#if ( NUM_HEMI_LIGHTS > 0 )\n\n\t\t\t#pragma unroll_loop_start\n\t\t\tHemisphereLight hemiLight;\n\t\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\t\themiLight = hemisphereLights[ i ];\n\t\t\t\tdif += getHemisphereLightIrradiance( hemiLight, geometryNormal ) * BRDF_Lambert( vec3(1.) );\n\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\n\t\t#endif\n\n\t\t#if NUM_POINT_LIGHTS > 0\n\t\t\tPointLightRayMarching pointLightRayMarching;\n\t\t\tPointLight pointLight;\n\t\t\tfloat pointLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\t\t\t\tPointLightShadow pointLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\t\t\tpointLightRayMarching = pointLightsRayMarching[ i ];\n\t\t\t\tpointLight = pointLights[ i ];\n\t\t\t\tgetPointLightInfo( pointLight, geometryPosition, directLight );\n\n\n\t\t\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\t\t\t\tpointLightShadow = pointLightShadows[ i ];\n\t\t\t\t\tvec4 pointLightShadowCoord = pointShadowMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t\tdirectLight.color *= (directLight.visible && receiveShadow) ? getPointShadow(\n\t\t\t\t\t\tpointShadowMap[ i ],\n\t\t\t\t\t\tpointLightShadow.shadowMapSize,\n\t\t\t\t\t\tpointLightShadow.shadowBias,\n\t\t\t\t\t\tpointLightShadow.shadowRadius,\n\t\t\t\t\t\tpointLightShadowCoord,\n\t\t\t\t\t\tpointLightShadow.shadowCameraNear,\n\t\t\t\t\t\tpointLightShadow.shadowCameraFar\n\t\t\t\t\t) : 1.0;\n\t\t\t\t#endif\n\n\t\t\t\tlightPos = pointLight.position;\n\t\t\t\tlightDir = normalize(lightPos-geometryPosition);\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tpointLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < pointLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t:\n\t\t\t\t\tcalcSoftshadow(\n\t\t\t\t\t_p,\n\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\tpointLightRayMarching.shadowBiasDistance,\n\t\t\t\t\tdistance(geometryPosition,lightPos),\n\t\t\t\t\t1./max(pointLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\tsdfContext\n\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * pointLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\n\t\t#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\n\t\t\tRectAreaLight rectAreaLight;\n\t\t\t// AreaLightRayMarching areaLightRayMarching;\n\t\t\tPhysicalMaterial material;\n\t\t\tmaterial.roughness = 1.;\n\t\t\tmaterial.specularColor = vec3(1.);\n\t\t\tmaterial.diffuseColor = vec3(1.);\n\n\t\t\tvec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( cameraPosition - geometryPosition );\n\t\t\tvec3 geometryClearcoatNormal = geometryNormal;\n\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\t\t\t// areaLightRayMarching = areaLightsRayMarching[ i ];\n\t\t\t\trectAreaLight = rectAreaLights[ i ];\n\t\t\t\t// rectAreaLight.position = areaLightRayMarching.worldPos;\n\n\t\t\t\tRE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t\tdif += reflectedLight.directDiffuse;\n\n\t\t#endif\n\t#endif\n\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\n\t#if defined( USE_LIGHT_PROBES )\n\n\t\tirradiance += getLightProbeIrradiance( lightProbe, geometryNormal );\n\n\t#endif\n\n\tdif += irradiance;\n\n\treturn dif;\n}\n\n\n\n\nvec3 applyMaterialWithoutRefraction(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(1.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n\nvec3 applyMaterialWithoutReflection(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(1.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n#ifdef RAYMARCHED_REFLECTIONS\nvec3 GetReflection(vec3 p, vec3 n, vec3 rayDir, float biasMult, float roughness, int reflectionDepth, inout SDFContext sdfContextMain){\n\tbool hitReflection = true;\n\tvec3 reflectedColor = vec3(0.);\n\t#pragma unroll_loop_start\n\tfor(int i=0; i < reflectionDepth; i++) {\n\t\tif(hitReflection){\n\t\t\trayDir = reflect(rayDir, n);\n\t\t\tp += n*SURF_DIST*biasMult;\n\t\t\tSDFContext sdfContext = RayMarch(p, rayDir, 1.);\n\t\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\t\tsdfContextMain.stepsCount += sdfContext.stepsCount;\n\t\t\t#endif\n\t\t\tif( sdfContext.d >= MAX_DIST){\n\t\t\t\thitReflection = false;\n\t\t\t\treflectedColor = envMapSample(rayDir, roughness);\n\t\t\t}\n\t\t\tif(hitReflection){\n\t\t\t\tp += rayDir * sdfContext.d;\n\t\t\t\tn = GetNormal(p);\n\t\t\t\tvec3 matCol = applyMaterialWithoutReflection(p, n, rayDir, sdfContext.matId, sdfContextMain);\n\t\t\t\treflectedColor += matCol;\n\t\t\t}\n\t\t}\n\t}\n\t#pragma unroll_loop_end\n\treturn reflectedColor;\n}\n#endif\n\n#ifdef RAYMARCHED_REFRACTIONS\n// xyz for color, w for distanceInsideMedium\nvec4 GetRefractedData(vec3 p, vec3 n, vec3 rayDir, float ior, float biasMult, float roughness, float refractionMaxDist, int refractionDepth, inout SDFContext sdfContextMain){\n\tbool hitRefraction = true;\n\tbool changeSide = true;\n\t#ifdef RAYMARCHED_REFRACTIONS_START_OUTSIDE_MEDIUM\n\tfloat side = -1.;\n\t#else\n\tfloat side = 1.;\n\t#endif\n\tfloat iorInverted = 1. / ior;\n\tvec3 refractedColor = vec3(0.);\n\tfloat distanceInsideMedium=0.;\n\tfloat totalRefractedDistance=0.;\n\n\t#pragma unroll_loop_start\n\tfor(int i=0; i < refractionDepth; i++) {\n\t\tif(hitRefraction){\n\t\t\tfloat currentIor = side<0. ? iorInverted : ior;\n\t\t\tvec3 rayDirPreRefract = rayDir;\n\t\t\trayDir = refract(rayDir, n, currentIor);\n\t\t\tchangeSide = dot(rayDir, rayDir)!=0.;\n\t\t\tif(changeSide == true) {\n\t\t\t\tp -= n*SURF_DIST*(2.+biasMult);\n\t\t\t} else {\n\t\t\t\tp += n*SURF_DIST*( biasMult);\n\t\t\t\trayDir = reflect(rayDirPreRefract, n);\n\t\t\t}\n\t\t\tSDFContext sdfContext = RayMarch(p, rayDir, side);\n\t\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\t\tsdfContextMain.stepsCount += sdfContext.stepsCount;\n\t\t\t#endif\n\t\t\ttotalRefractedDistance += sdfContext.d;\n\t\t\tif( abs(sdfContext.d) >= MAX_DIST || totalRefractedDistance > refractionMaxDist ){\n\t\t\t\thitRefraction = false;\n\t\t\t\trefractedColor = envMapSample(rayDir, roughness);\n\t\t\t}\n\t\t\tif(hitRefraction){\n\t\t\t\tp += rayDir * sdfContext.d;\n\t\t\t\tn = GetNormal(p) * side;\n\t\t\t\tvec3 matCol = applyMaterialWithoutRefraction(p, n, rayDir, sdfContext.matId, sdfContextMain);\n\t\t\t\trefractedColor = matCol;\n\n\t\t\t\t// same as: side < 0. ? abs(sdfContext.d) : 0.;\n\t\t\t\tdistanceInsideMedium += (side-1.)*-0.5*abs(sdfContext.d);\n\t\t\t\tif( changeSide ){\n\t\t\t\t\tside *= -1.;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#ifdef RAYMARCHED_REFRACTIONS_SAMPLE_ENV_MAP_ON_LAST\n\t\tif(i == refractionDepth-1){\n\t\t\trefractedColor = envMapSample(rayDir, roughness);\n\t\t}\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n\treturn vec4(refractedColor, distanceInsideMedium);\n}\nfloat refractionTint(float baseValue, float tint, float distanceInsideMedium, float absorption){\n\tfloat tintNegated = baseValue-tint;\n\tfloat t = tintNegated*( distanceInsideMedium*absorption );\n\treturn max(baseValue-t, 0.);\n}\nfloat applyRefractionAbsorption(float refractedDataColor, float baseValue, float tint, float distanceInsideMedium, float absorption){\n\treturn refractedDataColor*refractionTint(baseValue, tint, distanceInsideMedium, absorption);\n}\nvec3 applyRefractionAbsorption(vec3 refractedDataColor, vec3 baseValue, vec3 tint, float distanceInsideMedium, float absorption){\n\treturn vec3(\n\t\trefractedDataColor.r * refractionTint(baseValue.r, tint.r, distanceInsideMedium, absorption),\n\t\trefractedDataColor.g * refractionTint(baseValue.g, tint.g, distanceInsideMedium, absorption),\n\t\trefractedDataColor.b * refractionTint(baseValue.b, tint.b, distanceInsideMedium, absorption)\n\t);\n}\n\n#endif\n\nvec3 applyMaterial(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(0.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n\n\n\n\nvec4 applyShading(vec3 rayOrigin, vec3 rayDir, inout SDFContext sdfContext){\n\tvec3 p = rayOrigin + rayDir * sdfContext.d;\n\tvec3 n = GetNormal(p);\n\t\n\tvec3 col = applyMaterial(p, n, rayDir, sdfContext.matId, sdfContext);\n\tif(sdfContext.matBlend > 0.) {\n\t\t// blend material colors if needed\n\t\tvec3 col2 = applyMaterial(p, n, rayDir, sdfContext.matId2, sdfContext);\n\t\tcol = (1. - sdfContext.matBlend)*col + sdfContext.matBlend*col2;\n\t}\n\t\t\n\t// gamma\n\t//col = pow( col, vec3(0.4545) ); // this gamma leads to a different look than standard materials\n\treturn vec4(col, 1.);\n}\n\nvoid main()\t{\n\n\tvec3 rayDir = normalize(vPw - cameraPosition);\n\trayDir = transformDirection(rayDir, vInverseModelMatrix);\n\tvec3 rayOrigin = (vInverseModelMatrix * vec4( cameraPosition, 1.0 )).xyz;\n\n\tSDFContext sdfContext = RayMarch(rayOrigin, rayDir, 1.);\n\n\t#if defined( DEBUG_DEPTH )\n\t\tfloat normalizedDepth = 1.-(sdfContext.d - debugMinDepth ) / ( debugMaxDepth - debugMinDepth );\n\t\tnormalizedDepth = saturate(normalizedDepth); // clamp to [0,1]\n\t\tgl_FragColor = vec4(normalizedDepth);\n\t\treturn;\n\t#endif\n\t#if defined( SHADOW_DEPTH )\n\t\tfloat normalizedDepth = 1.-(sdfContext.d - debugMinDepth ) / ( debugMaxDepth - debugMinDepth );\n\t\t// float fragCoordZ = sdfContext.d / vHighPrecisionZW[1];\n\t\tfloat compoundedDepth = 0.5 * (normalizedDepth) + 0.5;\n\t\tfloat alpha = sdfContext.d < MAX_DIST ? 0.:1.;\n\t\tgl_FragColor = vec4( vec3(compoundedDepth), alpha );\n\t\t// normalizedDepth = 0.5*normalizedDepth+0.5;\n\t\t// gl_FragColor = packDepthToRGBA( normalizedDepth );\n\t\t// gl_FragColor = vec4(0.);\n\t\treturn;\n\t#endif\n\t#if defined( SHADOW_DISTANCE )\n\t\tfloat normalizedDepth = (sdfContext.d - shadowDistanceMin ) / ( shadowDistanceMax - shadowDistanceMin );\n\t\tnormalizedDepth = saturate(normalizedDepth); // clamp to [0,1]\n\t\tgl_FragColor = packDepthToRGBA( normalizedDepth );\n\t\treturn;\n\t#endif\n\n\tif( sdfContext.d < MAX_DIST ){\n\t\tgl_FragColor = applyShading(rayOrigin, rayDir, sdfContext);\n\t\t#if defined( TONE_MAPPING )\n\t\t\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n\t\t#endif\n\t\tgl_FragColor = linearToOutputTexel( gl_FragColor );\n\n\t\t#ifdef USE_FOG\n\t\t\tfloat vFogDepth = sdfContext.d;\n\t\t\t#ifdef FOG_EXP2\n\t\t\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );\n\t\t\t#else\n\t\t\t\tfloat fogFactor = smoothstep( fogNear, fogFar, vFogDepth );\n\t\t\t#endif\n\t\t\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n\t\t#endif\n\t\t#include <premultiplied_alpha_fragment>\n\t\t#include <dithering_fragment>\n\t} else {\n\t\tgl_FragColor = vec4(0.);\n\t}\n\n\t#if defined( DEBUG_STEPS_COUNT )\n\t\tfloat normalizedStepsCount = (float(sdfContext.stepsCount) - debugMinSteps ) / ( debugMaxSteps - debugMinSteps );\n\t\tgl_FragColor = vec4(normalizedStepsCount, 1.-normalizedStepsCount, 0., 1.);\n\t\treturn;\n\t#endif\n\t\n}"}},"jsFunctionBodies":{}}
Code editor
{"multiple_panel":{"split_ratio":0.66,"split_panel0":{"split_ratio":0.5,"split_panel0":{"split_ratio":0.5543217692883486,"split_panel0":{"panelTypes":["viewer"],"currentPanelIndex":0,"panel_data":{"camera":"/cameras/cameras:sopGroup/perspectiveCamera1","isViewerInitLayoutData":true,"linkIndex":1,"overlayedNetwork":{"allowed":false,"displayed":false}}},"split_panel1":{"panelTypes":["params"],"currentPanelIndex":0,"panel_data":{"active_folder":331,"linkIndex":1}},"split_mode":"vertical"},"split_panel1":{"panelTypes":["network","params","viewer"],"currentPanelIndex":0,"panel_data":{"camera":{"position":{"x":309.23864388044683,"y":-248.3325657959398},"zoom":0.5720000000000005},"history":{"2":{"position":{"x":111.45858092111928,"y":211.41919762987428},"zoom":1.0222221069335933},"36":{"position":{"x":164.5,"y":-211.5},"zoom":1.8350000000000004},"325":{"position":{"x":50,"y":0},"zoom":0.8490000000000008},"328":{"position":{"x":309.23864388044683,"y":-248.3325657959398},"zoom":0.5720000000000005},"1049":{"position":{"x":0,"y":0},"zoom":2},"1129":{"position":{"x":129.98560442179834,"y":-52.624173335152435},"zoom":0.6820000000000005}},"paramsDisplayed":false,"linkIndex":1}},"split_mode":"horizontal"},"split_panel1":{"panelTypes":["codePreview"],"currentPanelIndex":0,"panel_data":{"linkIndex":1}},"split_mode":"horizontal"},"currentNodes":["/geo1/MAT/rayMarchingBuilder1","/","/","/","/","/","/","/"],"navigationHistory":{"nodePaths":{"1":["/","/geo1","/geo1/MAT","/geo1/MAT/rayMarchingBuilder1","/geo1/MAT","/geo1","/geo1/MAT","/geo1/MAT/rayMarchingBuilder1","/geo1/MAT","/geo1","/","/geo1","/geo1/MAT","/geo1/MAT/rayMarchingBuilder1"],"2":["/"],"3":["/"],"4":["/"],"5":["/"],"6":["/"],"7":["/"],"8":["/"]},"index":{"1":13,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0}},"fullscreenPanelId":null,"saveOptions":{"checkRemoteAssetsUse":true,"minimizeFilesCount":false},"paramsModal":[]}
Used nodes
cop/envMap;cop/image;cop/imageEXR;event/cameraOrbitControls;mat/rayMarchingBuilder;obj/copNetwork;obj/geo;sop/box;sop/cameraControls;sop/hemisphereLight;sop/material;sop/materialsNetwork;sop/merge;sop/perspectiveCamera;sop/polarTransform;sop/spotLight
Used operations
Used modules
Used assemblers
GL_RAYMARCHING
Used integrations
[]
Used assets
Nodes map
{"/geo1":"obj/geo","/geo1/box1":"sop/box","/geo1/material1":"sop/material","/geo1/MAT":"sop/materialsNetwork","/geo1/MAT/rayMarchingBuilder1":"mat/rayMarchingBuilder","/COP":"obj/copNetwork","/COP/envMap":"cop/envMap","/COP/imageEnv":"cop/imageEXR","/COP/image1":"cop/image","/lights":"obj/geo","/lights/hemisphereLight1":"sop/hemisphereLight","/lights/spotLight1":"sop/spotLight","/lights/polarTransform1":"sop/polarTransform","/lights/merge1":"sop/merge","/cameras":"obj/geo","/cameras/perspectiveCamera1":"sop/perspectiveCamera","/cameras/cameraControls1":"sop/cameraControls","/cameras/cameraControls1/cameraOrbitControls1":"event/cameraOrbitControls"}
Js version
Editor version
Engine version
Name
*
Code
{"properties":{"frame":0,"maxFrame":600,"maxFrameLocked":false,"realtimeState":true,"mainCameraPath":"/cameras/cameras:sopGroup/perspectiveCamera1","versions":{"polygonjs":"1.5.82"}},"root":{"type":"root","nodes":{"geo1":{"type":"geo","nodes":{"box1":{"type":"box","params":{"sizes":[3,1,3]}},"material1":{"type":"material","params":{"material":"../MAT/rayMarchingBuilder1"},"inputs":["box1"],"flags":{"display":true}},"MAT":{"type":"materialsNetwork","nodes":{"rayMarchingBuilder1":{"type":"rayMarchingBuilder","nodes":{"globals1":{"type":"globals"},"output1":{"type":"output","inputs":[{"index":0,"inputName":"SDFContext","node":"SDFContext1","output":"SDFContext"}]},"SDFContext1":{"type":"SDFContext","params":{"sdf":{"type":"float","default_value":0,"options":{"spare":true,"editable":false,"computeOnDirty":true,"dependentOnFoundParam":false}},"material":{"type":"string","default_value":"DefaultSDFMaterial()","options":{"spare":true,"editable":false,"computeOnDirty":true,"dependentOnFoundParam":false},"overriden_options":{}}},"inputs":[{"index":0,"inputName":"sdf","node":"SDFUnion3","output":"union"},{"index":1,"inputName":"material","node":"SDFMaterial1","output":"SDFMaterial"}],"connection_points":{"in":[{"name":"sdf","type":"float"},{"name":"material","type":"SDFMaterial"}],"out":[{"name":"SDFContext","type":"SDFContext"}]}},"SDFMaterial1":{"type":"SDFMaterial","params":{"color":{"overriden_options":{}},"diffuse":{"overriden_options":{}},"emissive":{"overriden_options":{}},"envMapTint":{"overriden_options":{}},"envMapIntensity":{"overriden_options":{}},"envMapRoughness":{"overriden_options":{}},"envMapFresnel":{"overriden_options":{}},"envMapFresnelPower":{"overriden_options":{}},"reflectionTint":{"overriden_options":{}},"reflectivity":{"overriden_options":{}},"reflectionBiasMult":{"overriden_options":{}},"refractionTint":{"overriden_options":{}},"ior":{"overriden_options":{}},"iorOffset":{"overriden_options":{}},"transmission":{"overriden_options":{}},"absorption":{"overriden_options":{}},"refractionMaxDist":{"overriden_options":{}},"refractionBiasMult":{"overriden_options":{}}},"inputs":[{"index":0,"inputName":"color","node":"mix1","output":"mix"}]},"SDFSphere1":{"type":"SDFSphere","params":{"position":{"overriden_options":{}},"center":{"raw_input":[-0.1,0,0],"overriden_options":{}},"radius":{"raw_input":0.2,"overriden_options":{}}},"inputs":[{"index":0,"inputName":"position","node":"globals1","output":"position"}]},"SDFSphere2":{"type":"SDFSphere","params":{"position":{"overriden_options":{}},"center":{"raw_input":[0.1,0,0],"overriden_options":{}},"radius":{"raw_input":0.2,"overriden_options":{}}},"inputs":[{"index":0,"inputName":"position","node":"globals1","output":"position"},{"index":1,"inputName":"center","node":"floatToVec3_1","output":"vec3"}]},"SDFUnion1":{"type":"SDFUnion","params":{"sdf0":{"type":"float","default_value":0,"options":{"spare":true,"editable":false,"computeOnDirty":true,"dependentOnFoundParam":false}},"sdf1":{"type":"float","default_value":0,"options":{"spare":true,"editable":false,"computeOnDirty":true,"dependentOnFoundParam":false}},"smoothFactor":{"type":"float","default_value":0,"options":{"spare":true,"editable":true,"computeOnDirty":true,"dependentOnFoundParam":false},"raw_input":0.3},"matBlendDist":{"type":"float","default_value":0,"options":{"spare":true,"editable":true,"computeOnDirty":true,"dependentOnFoundParam":false}}},"inputs":[{"index":0,"inputName":"sdf0","node":"SDFSphere1","output":"float"},{"index":1,"inputName":"sdf1","node":"SDFSphere2","output":"float"}],"connection_points":{"in":[{"name":"sdf0","type":"float"},{"name":"sdf1","type":"float"},{"name":"smoothFactor","type":"float"},{"name":"matBlendDist","type":"float"}],"out":[{"name":"union","type":"float"}]}},"floatToVec3_1":{"type":"floatToVec3","params":{"x":{"overriden_options":{}},"y":{"overriden_options":{}},"z":{"overriden_options":{}}},"inputs":[{"index":0,"inputName":"x","node":"cos1","output":"val"}]},"cos1":{"type":"cos","params":{"radians":{"type":"float","default_value":0,"options":{"spare":true,"editable":false,"computeOnDirty":true,"dependentOnFoundParam":false}}},"inputs":[{"index":0,"inputName":"radians","node":"globals1","output":"time"}],"connection_points":{"in":[{"name":"radians","type":"float"}],"out":[{"name":"val","type":"float"}]}},"constant1":{"type":"constant","params":{"type":4,"color":[1,1,1],"asColor":1},"connection_points":{"in":[],"out":[{"name":"val","type":"vec3"}]}},"SDFSphere3":{"type":"SDFSphere","params":{"center":[-0.25,0,0],"radius":0.2}},"SDFSphere4":{"type":"SDFSphere","params":{"center":[0.25,0,0],"radius":0.2}},"SDFUnion2":{"type":"SDFUnion","params":{"sdf0":{"type":"float","default_value":0,"options":{"spare":true,"editable":false,"computeOnDirty":true,"dependentOnFoundParam":false}},"sdf1":{"type":"float","default_value":0,"options":{"spare":true,"editable":false,"computeOnDirty":true,"dependentOnFoundParam":false}},"smoothFactor":{"type":"float","default_value":0,"options":{"spare":true,"editable":true,"computeOnDirty":true,"dependentOnFoundParam":false},"raw_input":0.31},"matBlendDist":{"type":"float","default_value":0,"options":{"spare":true,"editable":true,"computeOnDirty":true,"dependentOnFoundParam":false}}},"inputs":[{"index":0,"inputName":"sdf0","node":"SDFSphere3","output":"float"},{"index":1,"inputName":"sdf1","node":"SDFSphere4","output":"float"}],"connection_points":{"in":[{"name":"sdf0","type":"float"},{"name":"sdf1","type":"float"},{"name":"smoothFactor","type":"float"},{"name":"matBlendDist","type":"float"}],"out":[{"name":"union","type":"float"}]}},"SDFPlane1":{"type":"SDFPlane","params":{"center":[0,-0.2,0]}},"SDFUnion3":{"type":"SDFUnion","params":{"sdf0":{"type":"float","default_value":0,"options":{"spare":true,"editable":false,"computeOnDirty":true,"dependentOnFoundParam":false}},"sdf1":{"type":"float","default_value":0,"options":{"spare":true,"editable":false,"computeOnDirty":true,"dependentOnFoundParam":false}},"smoothFactor":{"type":"float","default_value":0,"options":{"spare":true,"editable":true,"computeOnDirty":true,"dependentOnFoundParam":false},"raw_input":0.31},"matBlendDist":{"type":"float","default_value":0,"options":{"spare":true,"editable":true,"computeOnDirty":true,"dependentOnFoundParam":false}}},"inputs":[{"index":0,"inputName":"sdf0","node":"SDFUnion2","output":"union"},{"index":1,"inputName":"sdf1","node":"SDFPlane1","output":"float"}],"connection_points":{"in":[{"name":"sdf0","type":"float"},{"name":"sdf1","type":"float"},{"name":"smoothFactor","type":"float"},{"name":"matBlendDist","type":"float"}],"out":[{"name":"union","type":"float"}]}},"grid1":{"type":"grid"},"checkers1":{"type":"checkers","params":{"uv":{"overriden_options":{}},"freq":{"overriden_options":{}},"freqMult":{"raw_input":1.8,"overriden_options":{}}},"inputs":[{"index":0,"inputName":"uv","node":"floatToVec2_1","output":"vec2"}]},"mix1":{"type":"mix","params":{"value0":{"type":"vector3","default_value":[0,0,0],"options":{"spare":true,"editable":false,"computeOnDirty":true,"dependentOnFoundParam":false}},"value1":{"type":"vector3","default_value":[0,0,0],"options":{"spare":true,"editable":false,"computeOnDirty":true,"dependentOnFoundParam":false},"overriden_options":{}},"blend":{"type":"float","default_value":0.5,"options":{"spare":true,"editable":false,"computeOnDirty":true,"dependentOnFoundParam":false}}},"inputs":[{"index":0,"inputName":"value0","node":"constant2","output":"val"},{"index":1,"inputName":"value1","node":"constant3","output":"val"},{"index":2,"inputName":"blend","node":"checkers1","output":"checker"}],"connection_points":{"in":[{"name":"value0","type":"vec3"},{"name":"value1","type":"vec3"},{"name":"blend","type":"float"}],"out":[{"name":"mix","type":"vec3"}]}},"constant2":{"type":"constant","params":{"type":4,"color":[0.04091519690055698,0.19806931954941637,0.5271151256969157],"asColor":1},"connection_points":{"in":[],"out":[{"name":"val","type":"vec3"}]}},"constant3":{"type":"constant","params":{"type":4,"color":[0.3049873140591091,0.4452011945063733,0.623960391667596],"asColor":true},"connection_points":{"in":[],"out":[{"name":"val","type":"vec3"}]}},"globals2":{"type":"globals"},"vec3ToFloat1":{"type":"vec3ToFloat","params":{"vec":{"overriden_options":{}}},"inputs":[{"index":0,"inputName":"vec","node":"globals2","output":"position"}]},"floatToVec2_1":{"type":"floatToVec2","params":{"x":{"overriden_options":{}},"y":{"overriden_options":{}}},"inputs":[{"index":0,"inputName":"x","node":"vec3ToFloat1","output":"x"},{"index":1,"inputName":"y","node":"vec3ToFloat1","output":"z"}]}},"persisted_config":{"material":{"metadata":{"version":4.6,"type":"Material","generator":"Material.toJSON"},"uuid":"/geo1/MAT/rayMarchingBuilder1-main","type":"ShaderMaterial","side":1,"transparent":true,"blendColor":0,"alphaTest":0.5,"forceSinglePass":true,"fog":false,"glslVersion":null,"uniforms":{"diffuse":{"type":"c","value":16777215},"opacity":{"value":1},"map":{"value":null},"mapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"alphaMap":{"value":null},"alphaMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"alphaTest":{"value":0},"envMap":{"value":null},"flipEnvMap":{"value":-1},"reflectivity":{"value":1},"ior":{"value":1.5},"refractionRatio":{"value":0.98},"aoMap":{"value":null},"aoMapIntensity":{"value":1},"aoMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"lightMap":{"value":null},"lightMapIntensity":{"value":1},"lightMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"emissiveMap":{"value":null},"emissiveMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"bumpMap":{"value":null},"bumpMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"bumpScale":{"value":1},"normalMap":{"value":null},"normalMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"normalScale":{"type":"v2","value":[1,1]},"displacementMap":{"value":null},"displacementMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"displacementScale":{"value":1},"displacementBias":{"value":0},"roughnessMap":{"value":null},"roughnessMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"metalnessMap":{"value":null},"metalnessMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"fogDensity":{"value":0.00025},"fogNear":{"value":1},"fogFar":{"value":2000},"fogColor":{"type":"c","value":16777215},"ambientLightColor":{"value":[0,0,0]},"lightProbe":{"value":[{"x":0,"y":0,"z":0},{"x":0,"y":0,"z":0},{"x":0,"y":0,"z":0},{"x":0,"y":0,"z":0},{"x":0,"y":0,"z":0},{"x":0,"y":0,"z":0},{"x":0,"y":0,"z":0},{"x":0,"y":0,"z":0},{"x":0,"y":0,"z":0}]},"directionalLights":{"value":[]},"directionalLightShadows":{"value":[]},"directionalShadowMap":{"value":[]},"directionalShadowMatrix":{"value":[]},"spotLights":{"value":[{"position":{"x":-1.2852502799192873,"y":1.1507848233748126,"z":1.4267067456548526},"direction":{"x":-0.3770858317507352,"y":0.19704278327897823,"z":0.9049753682009969},"color":16777215,"distance":10,"coneCos":0.7071067811865476,"penumbraCos":0.7604059656000309,"decay":0.1}]},"spotLightShadows":{"value":[{"shadowBias":0.0001,"shadowNormalBias":0,"shadowRadius":0,"shadowMapSize":{"x":1024,"y":1024}}]},"spotLightMap":{"value":[]},"spotShadowMap":{"value":[{"metadata":{"version":4.6,"type":"Texture","generator":"Texture.toJSON"},"uuid":"56085f82-7703-480c-978a-0582ef73ad79","name":"spotLight1.shadowMap","image":"84de04b9-f175-4938-a796-84924082b48a","mapping":300,"channel":0,"repeat":[1,1],"offset":[0,0],"center":[0,0],"rotation":0,"wrap":[1001,1001],"format":1023,"internalFormat":null,"type":1009,"colorSpace":"","minFilter":1003,"magFilter":1003,"anisotropy":1,"flipY":false,"generateMipmaps":false,"premultiplyAlpha":false,"unpackAlignment":4}]},"spotLightMatrix":{"value":[{"elements":[0.5000000000000001,0,0,0,-0.21288964578253625,0.23952388045047365,-0.4300800924899722,-0.4257792915650725,-0.4524135262330098,-0.6653031720155461,-0.913966719662646,-0.9048270524660196,1.6540227520477755,1.3373332836846683,3.24045000413692,3.308045504095551]}]},"pointLights":{"value":[]},"pointLightShadows":{"value":[]},"pointShadowMap":{"value":[]},"pointShadowMatrix":{"value":[]},"hemisphereLights":{"value":[{"direction":{"x":1.3877787807814457e-17,"y":0.9655392056456817,"z":0.26025764611458757},"skyColor":12566463,"groundColor":0}]},"rectAreaLights":{"value":[]},"ltc_1":{"value":null},"ltc_2":{"value":null},"emissive":{"type":"c","value":0},"roughness":{"value":1},"metalness":{"value":0},"envMapIntensity":{"value":1},"MAX_STEPS":{"value":100},"MAX_DIST":{"value":100},"SURF_DIST":{"value":0.001},"NORMALS_BIAS":{"value":0.01},"SHADOW_BIAS":{"value":0},"debugMinSteps":{"value":0},"debugMaxSteps":{"value":128},"debugMinDepth":{"value":0},"debugMaxDepth":{"value":128},"shadowDistanceMin":{"value":0},"shadowDistanceMax":{"value":100},"shadowDepthMin":{"value":0},"shadowDepthMax":{"value":100},"envMapRotationY":{"value":0},"spotLightsRayMarching":{"value":[{"penumbra":0,"shadowBiasAngle":0.01,"shadowBiasDistance":0.1}]},"directionalLightsRayMarching":{"value":[]},"pointLightsRayMarching":{"value":[]}},"defines":{"ENVMAP_TYPE_CUBE_UV":0,"CUBEUV_TEXEL_WIDTH":"0.1","CUBEUV_TEXEL_HEIGHT":"0.1","CUBEUV_MAX_MIP":"1.0","ROTATE_ENV_MAP_Y":0},"vertexShader":"precision highp float;\nprecision highp int;\n\nvarying vec3 vPw;\nvarying mat4 vModelMatrix;\nvarying mat4 vInverseModelMatrix;\nvarying mat4 VViewMatrix;\n\n#include <common>\n\n// // for depth material\n// varying vec2 vHighPrecisionZW;\n\nvoid main()\t{\n\n\tvModelMatrix = modelMatrix;\n\tvInverseModelMatrix = inverse(modelMatrix);\n\tVViewMatrix = viewMatrix;\n\tvPw = (modelMatrix * vec4( position, 1.0 )).xyz;\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n\t// vHighPrecisionZW = gl_Position.zw;\n}","fragmentShader":"precision highp float;\nprecision highp int;\n\n// --- applyMaterial constants definition\nuniform int MAX_STEPS;\nuniform float MAX_DIST;\nuniform float SURF_DIST;\nuniform float NORMALS_BIAS;\nuniform float SHADOW_BIAS;\n#define ZERO 0\nuniform float debugMinSteps;\nuniform float debugMaxSteps;\nuniform float debugMinDepth;\nuniform float debugMaxDepth;\n\n#include <common>\n#include <packing>\n#include <lightmap_pars_fragment>\n#include <bsdfs>\n#include <cube_uv_reflection_fragment>\n#include <lights_pars_begin>\n#include <lights_physical_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <fog_pars_fragment>\n\n#if defined( SHADOW_DISTANCE )\n\tuniform float shadowDistanceMin;\n\tuniform float shadowDistanceMax;\n#endif \n#if defined( SHADOW_DEPTH )\n\tuniform float shadowDepthMin;\n\tuniform float shadowDepthMax;\n#endif\n\n// varying vec2 vHighPrecisionZW;\n\nvarying vec3 vPw;\nvarying mat4 vModelMatrix;\nvarying mat4 vInverseModelMatrix;\nvarying mat4 VViewMatrix;\n\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform SpotLightRayMarching spotLightsRayMarching[ NUM_SPOT_LIGHTS ];\n\t#if NUM_SPOT_LIGHT_COORDS > 0\n\n\t\tuniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];\n\n\t#endif\n#endif\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform DirectionalLightRayMarching directionalLightsRayMarching[ NUM_DIR_LIGHTS ];\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\n\t#endif\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform PointLightRayMarching pointLightsRayMarching[ NUM_POINT_LIGHTS ];\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\n\t#endif\n#endif\n\n\nstruct SDFContext {\n\tfloat d;\n\tint stepsCount;\n\tint matId;\n\tint matId2;\n\tfloat matBlend;\n};\n\nSDFContext DefaultSDFContext(){\n\treturn SDFContext( 0., 0, 0, 0, 0. );\n}\nint DefaultSDFMaterial(){\n\treturn 0;\n}\n\n// start raymarching builder define code\n\n\n\n// /geo1/MAT/rayMarchingBuilder1/SDFSphere3\nfloat dot2( in vec2 v ) { return dot(v,v); }\nfloat dot2( in vec3 v ) { return dot(v,v); }\nfloat ndot( in vec2 a, in vec2 b ) { return a.x*b.x - a.y*b.y; }\n// https://iquilezles.org/articles/distfunctions/\n\n\n/*\n*\n* SDF PRIMITIVES\n*\n*/\nfloat sdSphere( vec3 p, float s )\n{\n\treturn length(p)-s;\n}\nfloat sdCutSphere( vec3 p, float r, float h )\n{\n\t// sampling independent computations (only depend on shape)\n\tfloat w = sqrt(r*r-h*h);\n\n\t// sampling dependant computations\n\tvec2 q = vec2( length(p.xz), p.y );\n\tfloat s = max( (h-r)*q.x*q.x+w*w*(h+r-2.0*q.y), h*q.x-w*q.y );\n\treturn (s<0.0) ? length(q)-r :\n\t\t\t\t(q.x<w) ? h - q.y :\n\t\t\t\t\tlength(q-vec2(w,h));\n}\nfloat sdCutHollowSphere( vec3 p, float r, float h, float t )\n{\n\t// sampling independent computations (only depend on shape)\n\tfloat w = sqrt(r*r-h*h);\n\t\n\t// sampling dependant computations\n\tvec2 q = vec2( length(p.xz), p.y );\n\treturn ((h*q.x<w*q.y) ? length(q-vec2(w,h)) : \n\t\t\t\t\t\t\tabs(length(q)-r) ) - t;\n}\n\nfloat sdBox( vec3 p, vec3 b )\n{\n\tvec3 q = abs(p) - b*0.5;\n\treturn length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0);\n}\nfloat sdRoundBox( vec3 p, vec3 b, float r )\n{\n\tvec3 q = abs(p) - b*0.5;\n\treturn length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0) - r;\n}\n\n\nfloat sdBoxFrame( vec3 p, vec3 b, float e )\n{\n\t\tp = abs(p )-b*0.5;\n\tvec3 q = abs(p+e)-e;\n\treturn min(min(\n\t\tlength(max(vec3(p.x,q.y,q.z),0.0))+min(max(p.x,max(q.y,q.z)),0.0),\n\t\tlength(max(vec3(q.x,p.y,q.z),0.0))+min(max(q.x,max(p.y,q.z)),0.0)),\n\t\tlength(max(vec3(q.x,q.y,p.z),0.0))+min(max(q.x,max(q.y,p.z)),0.0));\n}\nfloat sdCapsule( vec3 p, vec3 a, vec3 b, float r )\n{\n\tvec3 pa = p - a, ba = b - a;\n\tfloat h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n\treturn length( pa - ba*h ) - r;\n}\nfloat sdVerticalCapsule( vec3 p, float h, float r )\n{\n\tp.y -= clamp( p.y, 0.0, h );\n\treturn length( p ) - r;\n}\nfloat sdCone( in vec3 p, in vec2 c, float h )\n{\n\t// c is the sin/cos of the angle, h is height\n\t// Alternatively pass q instead of (c,h),\n\t// which is the point at the base in 2D\n\tvec2 q = h*vec2(c.x/c.y,-1.0);\n\n\tvec2 w = vec2( length(p.xz), p.y );\n\tvec2 a = w - q*clamp( dot(w,q)/dot(q,q), 0.0, 1.0 );\n\tvec2 b = w - q*vec2( clamp( w.x/q.x, 0.0, 1.0 ), 1.0 );\n\tfloat k = sign( q.y );\n\tfloat d = min(dot( a, a ),dot(b, b));\n\tfloat s = max( k*(w.x*q.y-w.y*q.x),k*(w.y-q.y) );\n\treturn sqrt(d)*sign(s);\n}\nfloat sdConeWrapped(vec3 pos, float angle, float height){\n\treturn sdCone(pos, vec2(sin(angle), cos(angle)), height);\n}\nfloat sdRoundCone( vec3 p, float r1, float r2, float h )\n{\n\tfloat b = (r1-r2)/h;\n\tfloat a = sqrt(1.0-b*b);\n\n\tvec2 q = vec2( length(p.xz), p.y );\n\tfloat k = dot(q,vec2(-b,a));\n\tif( k<0.0 ) return length(q) - r1;\n\tif( k>a*h ) return length(q-vec2(0.0,h)) - r2;\n\treturn dot(q, vec2(a,b) ) - r1;\n}\nfloat sdOctogonPrism( in vec3 p, in float r, float h )\n{\n\tconst vec3 k = vec3(-0.9238795325, // sqrt(2+sqrt(2))/2 \n\t\t\t\t\t\t0.3826834323, // sqrt(2-sqrt(2))/2\n\t\t\t\t\t\t0.4142135623 ); // sqrt(2)-1 \n\t// reflections\n\tp = abs(p);\n\tp.xy -= 2.0*min(dot(vec2( k.x,k.y),p.xy),0.0)*vec2( k.x,k.y);\n\tp.xy -= 2.0*min(dot(vec2(-k.x,k.y),p.xy),0.0)*vec2(-k.x,k.y);\n\t// polygon side\n\tp.xy -= vec2(clamp(p.x, -k.z*r, k.z*r), r);\n\tvec2 d = vec2( length(p.xy)*sign(p.y), p.z-h );\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdHexPrism( vec3 p, vec2 h )\n{\n\tconst vec3 k = vec3(-0.8660254, 0.5, 0.57735);\n\tp = abs(p);\n\tp.xy -= 2.0*min(dot(k.xy, p.xy), 0.0)*k.xy;\n\tvec2 d = vec2(\n\t\tlength(p.xy-vec2(clamp(p.x,-k.z*h.x,k.z*h.x), h.x))*sign(p.y-h.x),\n\t\tp.z-h.y );\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdHorseshoe( in vec3 p, in float angle, in float r, in float le, vec2 w )\n{\n\tvec2 c = vec2(cos(angle),sin(angle));\n\tp.x = abs(p.x);\n\tfloat l = length(p.xy);\n\tp.xy = mat2(-c.x, c.y, \n\t\t\tc.y, c.x)*p.xy;\n\tp.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x),\n\t\t\t\t(p.x>0.0)?p.y:l );\n\tp.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0);\n\t\n\tvec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z);\n\tvec2 d = abs(q) - w;\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdTriPrism( vec3 p, vec2 h )\n{\n\tvec3 q = abs(p);\n\treturn max(q.z-h.y,max(q.x*0.866025+p.y*0.5,-p.y)-h.x*0.5);\n}\nfloat sdPyramid( vec3 p, float h)\n{\n\tfloat m2 = h*h + 0.25;\n\n\tp.xz = abs(p.xz);\n\tp.xz = (p.z>p.x) ? p.zx : p.xz;\n\tp.xz -= 0.5;\n\n\tvec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y);\n\n\tfloat s = max(-q.x,0.0);\n\tfloat t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 );\n\n\tfloat a = m2*(q.x+s)*(q.x+s) + q.y*q.y;\n\tfloat b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t);\n\n\tfloat d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b);\n\n\treturn sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));\n}\n\nfloat sdPlane( vec3 p, vec3 n, float h )\n{\n\t// n must be normalized\n\treturn dot(p,n) + h;\n}\n\nfloat sdTorus( vec3 p, vec2 t )\n{\n\tvec2 q = vec2(length(p.xz)-t.x,p.y);\n\treturn length(q)-t.y;\n}\nfloat sdCappedTorus(in vec3 p, in float an, in float ra, in float rb)\n{\n\tvec2 sc = vec2(sin(an),cos(an));\n\tp.x = abs(p.x);\n\tfloat k = (sc.y*p.x>sc.x*p.z) ? dot(p.xz,sc) : length(p.xz);\n\treturn sqrt( dot(p,p) + ra*ra - 2.0*ra*k ) - rb;\n}\nfloat sdLink( vec3 p, float le, float r1, float r2 )\n{\n vec3 q = vec3( p.x, max(abs(p.y)-le,0.0), p.z );\n return length(vec2(length(q.xy)-r1,q.z)) - r2;\n}\n// c is the sin/cos of the desired cone angle\nfloat sdSolidAngle(vec3 pos, vec2 c, float radius)\n{\n\tvec2 p = vec2( length(pos.xz), pos.y );\n\tfloat l = length(p) - radius;\n\tfloat m = length(p - c*clamp(dot(p,c),0.0,radius) );\n\treturn max(l,m*sign(c.y*p.x-c.x*p.y));\n}\nfloat sdSolidAngleWrapped(vec3 pos, float angle, float radius){\n\treturn sdSolidAngle(pos, vec2(sin(angle), cos(angle)), radius);\n}\nfloat sdTube( vec3 p, float r )\n{\n\treturn length(p.xz)-r;\n}\nfloat sdTubeCapped( vec3 p, float h, float r )\n{\n\tvec2 d = abs(vec2(length(p.xz),p.y)) - vec2(r,h);\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdOctahedron( vec3 p, float s)\n{\n p = abs(p);\n float m = p.x+p.y+p.z-s;\n vec3 q;\n if( 3.0*p.x < m ) q = p.xyz;\n else if( 3.0*p.y < m ) q = p.yzx;\n else if( 3.0*p.z < m ) q = p.zxy;\n else return m*0.57735027;\n \n float k = clamp(0.5*(q.z-q.y+s),0.0,s); \n return length(vec3(q.x,q.y-s+k,q.z-k)); \n}\nfloat udTriangle( vec3 p, vec3 a, vec3 b, vec3 c, float thickness )\n{\n\tvec3 ba = b - a; vec3 pa = p - a;\n\tvec3 cb = c - b; vec3 pb = p - b;\n\tvec3 ac = a - c; vec3 pc = p - c;\n\tvec3 nor = cross( ba, ac );\n\n\treturn - thickness + sqrt(\n\t\t(sign(dot(cross(ba,nor),pa)) +\n\t\tsign(dot(cross(cb,nor),pb)) +\n\t\tsign(dot(cross(ac,nor),pc))<2.0)\n\t\t?\n\t\tmin( min(\n\t\tdot2(ba*clamp(dot(ba,pa)/dot2(ba),0.0,1.0)-pa),\n\t\tdot2(cb*clamp(dot(cb,pb)/dot2(cb),0.0,1.0)-pb) ),\n\t\tdot2(ac*clamp(dot(ac,pc)/dot2(ac),0.0,1.0)-pc) )\n\t\t:\n\t\tdot(nor,pa)*dot(nor,pa)/dot2(nor) );\n}\nfloat udQuad( vec3 p, vec3 a, vec3 b, vec3 c, vec3 d, float thickness )\n{\n\tvec3 ba = b - a; vec3 pa = p - a;\n\tvec3 cb = c - b; vec3 pb = p - b;\n\tvec3 dc = d - c; vec3 pc = p - c;\n\tvec3 ad = a - d; vec3 pd = p - d;\n\tvec3 nor = cross( ba, ad );\n\n\treturn - thickness + sqrt(\n\t\t(sign(dot(cross(ba,nor),pa)) +\n\t\tsign(dot(cross(cb,nor),pb)) +\n\t\tsign(dot(cross(dc,nor),pc)) +\n\t\tsign(dot(cross(ad,nor),pd))<3.0)\n\t\t?\n\t\tmin( min( min(\n\t\tdot2(ba*clamp(dot(ba,pa)/dot2(ba),0.0,1.0)-pa),\n\t\tdot2(cb*clamp(dot(cb,pb)/dot2(cb),0.0,1.0)-pb) ),\n\t\tdot2(dc*clamp(dot(dc,pc)/dot2(dc),0.0,1.0)-pc) ),\n\t\tdot2(ad*clamp(dot(ad,pd)/dot2(ad),0.0,1.0)-pd) )\n\t\t:\n\t\tdot(nor,pa)*dot(nor,pa)/dot2(nor) );\n}\n\n/*\n*\n* SDF OPERATIONS\n*\n*/\nfloat SDFUnion( float d1, float d2 ) { return min(d1,d2); }\nfloat SDFSubtract( float d1, float d2 ) { return max(-d1,d2); }\nfloat SDFIntersect( float d1, float d2 ) { return max(d1,d2); }\n\nfloat SDFSmoothUnion( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 + 0.5*(d2-d1)/k, 0.0, 1.0 );\n\treturn mix( d2, d1, h ) - k*h*(1.0-h);\n}\n\nfloat SDFSmoothSubtract( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 - 0.5*(d2+d1)/k, 0.0, 1.0 );\n\treturn mix( d2, -d1, h ) + k*h*(1.0-h);\n}\n\nfloat SDFSmoothIntersect( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 - 0.5*(d2-d1)/k, 0.0, 1.0 );\n\treturn mix( d2, d1, h ) + k*h*(1.0-h);\n}\n\nvec4 SDFElongateFast( in vec3 p, in vec3 h )\n{\n\treturn vec4( p-clamp(p,-h,h), 0.0 );\n}\nvec4 SDFElongateSlow( in vec3 p, in vec3 h )\n{\n\tvec3 q = abs(p)-h;\n\treturn vec4( max(q,0.0), min(max(q.x,max(q.y,q.z)),0.0) );\n}\n\nfloat SDFOnion( in float sdf, in float thickness )\n{\n\treturn abs(sdf)-thickness;\n}\n\n// /geo1/MAT/rayMarchingBuilder1/checkers1\n// https://iquilezles.org/articles/checkerfiltering/\nfloat checkers(vec2 p) {\n\tvec2 s = sign(fract(p*.5)-.5);\n\treturn .5 - .5*s.x*s.y;\n}\nfloat checkersGrad( in vec2 p, in vec2 ddx, in vec2 ddy )\n{\n // filter kernel\n vec2 w = max(abs(ddx), abs(ddy)) + 0.01;\n // analytical integral (box filter)\n vec2 i = 2.0*(abs(fract((p-0.5*w)/2.0)-0.5)-abs(fract((p+0.5*w)/2.0)-0.5))/w;\n // xor pattern\n return 0.5 - 0.5*i.x*i.y;\n}\n\n\n// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\nconst int _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1 = 1;\n\n\n// https://stackoverflow.com/questions/23793698/how-to-implement-slerp-in-glsl-hlsl\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t)\n// {\n// \tfloat dotp = dot(normalize(p0), normalize(p1));\n// \tif ((dotp > 0.9999) || (dotp < -0.9999))\n// \t{\n// \t\tif (t<=0.5)\n// \t\t\treturn p0;\n// \t\treturn p1;\n// \t}\n// \tfloat theta = acos(dotp);\n// \tvec4 P = ((p0*sin((1.0-t)*theta) + p1*sin(t*theta)) / sin(theta));\n// \tP.w = 1.0;\n// \treturn P;\n// }\n\n// https://devcry.heiho.net/html/2017/20170521-slerp.html\n// float lerp(float a, float b, float t) {\n// \treturn (1.0 - t) * a + t * b;\n// }\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t){\n// \tvec4 qb = p1;\n\n// \t// cos(a) = dot product\n// \tfloat cos_a = p0.x * qb.x + p0.y * qb.y + p0.z * qb.z + p0.w * qb.w;\n// \tif (cos_a < 0.0f) {\n// \t\tcos_a = -cos_a;\n// \t\tqb = -qb;\n// \t}\n\n// \t// close to zero, cos(a) ~= 1\n// \t// do linear interpolation\n// \tif (cos_a > 0.999) {\n// \t\treturn vec4(\n// \t\t\tlerp(p0.x, qb.x, t),\n// \t\t\tlerp(p0.y, qb.y, t),\n// \t\t\tlerp(p0.z, qb.z, t),\n// \t\t\tlerp(p0.w, qb.w, t)\n// \t\t);\n// \t}\n\n// \tfloat alpha = acos(cos_a);\n// \treturn (p0 * sin(1.0 - t) + p1 * sin(t * alpha)) / sin(alpha);\n// }\n\n// https://stackoverflow.com/questions/62943083/interpolate-between-two-quaternions-the-long-way\nvec4 quatSlerp(vec4 q1, vec4 q2, float t){\n\tfloat angle = acos(dot(q1, q2));\n\tfloat denom = sin(angle);\n\t//check if denom is zero\n\treturn (q1*sin((1.0-t)*angle)+q2*sin(t*angle))/denom;\n}\n// TO CHECK:\n// this page https://www.reddit.com/r/opengl/comments/704la7/glsl_quaternion_library/\n// has a link to a potentially nice pdf:\n// http://web.mit.edu/2.998/www/QuaternionReport1.pdf\n\n// https://github.com/mattatz/ShibuyaCrowd/blob/master/source/shaders/common/quaternion.glsl\nvec4 quatMult(vec4 q1, vec4 q2)\n{\n\treturn vec4(\n\tq1.w * q2.x + q1.x * q2.w + q1.z * q2.y - q1.y * q2.z,\n\tq1.w * q2.y + q1.y * q2.w + q1.x * q2.z - q1.z * q2.x,\n\tq1.w * q2.z + q1.z * q2.w + q1.y * q2.x - q1.x * q2.y,\n\tq1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z\n\t);\n}\n// http://glmatrix.net/docs/quat.js.html#line97\n// let ax = a[0], ay = a[1], az = a[2], aw = a[3];\n\n// let bx = b[0], by = b[1], bz = b[2], bw = b[3];\n\n// out[0] = ax * bw + aw * bx + ay * bz - az * by;\n\n// out[1] = ay * bw + aw * by + az * bx - ax * bz;\n\n// out[2] = az * bw + aw * bz + ax * by - ay * bx;\n\n// out[3] = aw * bw - ax * bx - ay * by - az * bz;\n\n// return out\n\n\n\n// http://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/\nmat4 rotationMatrix(vec3 axis, float angle)\n{\n\taxis = normalize(axis);\n\tfloat s = sin(angle);\n\tfloat c = cos(angle);\n\tfloat oc = 1.0 - c;\n\n \treturn mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 0.0, 0.0, 0.0, 1.0);\n}\n\n// https://www.geeks3d.com/20141201/how-to-rotate-a-vertex-by-a-quaternion-in-glsl/\nvec4 quatFromAxisAngle(vec3 axis, float angle)\n{\n\tvec4 qr;\n\tfloat half_angle = (angle * 0.5); // * 3.14159 / 180.0;\n\tfloat sin_half_angle = sin(half_angle);\n\tqr.x = axis.x * sin_half_angle;\n\tqr.y = axis.y * sin_half_angle;\n\tqr.z = axis.z * sin_half_angle;\n\tqr.w = cos(half_angle);\n\treturn qr;\n}\nvec3 rotateWithAxisAngle(vec3 position, vec3 axis, float angle)\n{\n\tvec4 q = quatFromAxisAngle(axis, angle);\n\tvec3 v = position.xyz;\n\treturn v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);\n}\n// vec3 applyQuaternionToVector( vec4 q, vec3 v ){\n// \treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n// }\nvec3 rotateWithQuat( vec3 v, vec4 q )\n{\n\t// vec4 qv = multQuat( quat, vec4(vec, 0.0) );\n\t// return multQuat( qv, vec4(-quat.x, -quat.y, -quat.z, quat.w) ).xyz;\n\treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n}\n// https://github.com/glslify/glsl-look-at/blob/gh-pages/index.glsl\n// mat3 rotation_matrix(vec3 origin, vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target - origin);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n// mat3 rotation_matrix(vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n\nfloat vectorAngle(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 c1 = cross(start, dest);\n\t// We use the dot product of the cross with the Y axis.\n\t// This is a little arbitrary, but can still give a good sense of direction\n\tvec3 y_axis = vec3(0.0, 1.0, 0.0);\n\tfloat d1 = dot(c1, y_axis);\n\tfloat angle = acos(cosTheta) * sign(d1);\n\treturn angle;\n}\n\n// http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/#i-need-an-equivalent-of-glulookat-how-do-i-orient-an-object-towards-a-point-\nvec4 vectorAlign(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 axis;\n\n\t// if (cosTheta < -1 + 0.001f){\n\t// \t// special case when vectors in opposite directions:\n\t// \t// there is no ideal rotation axis\n\t// \t// So guess one; any will do as long as it's perpendicular to start\n\t// \taxis = cross(vec3(0.0f, 0.0f, 1.0f), start);\n\t// \tif (length2(axis) < 0.01 ) // bad luck, they were parallel, try again!\n\t// \t\taxis = cross(vec3(1.0f, 0.0f, 0.0f), start);\n\n\t// \taxis = normalize(axis);\n\t// \treturn gtx::quaternion::angleAxis(glm::radians(180.0f), axis);\n\t// }\n\tif(cosTheta > (1.0 - 0.0001) || cosTheta < (-1.0 + 0.0001) ){\n\t\taxis = normalize(cross(start, vec3(0.0, 1.0, 0.0)));\n\t\tif (length(axis) < 0.001 ){ // bad luck, they were parallel, try again!\n\t\t\taxis = normalize(cross(start, vec3(1.0, 0.0, 0.0)));\n\t\t}\n\t} else {\n\t\taxis = normalize(cross(start, dest));\n\t}\n\n\tfloat angle = acos(cosTheta);\n\n\treturn quatFromAxisAngle(axis, angle);\n}\nvec4 vectorAlignWithUp(vec3 start, vec3 dest, vec3 up){\n\tvec4 rot1 = vectorAlign(start, dest);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\t// vec3 right = normalize(cross(dest, up));\n\t// up = normalize(cross(right, dest));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(vec3(0.0, 1.0, 0.0), rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(up, newUp);\n\n\t// return rot1;\n\treturn rot2;\n\t// return multQuat(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\n// https://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\nfloat quatToAngle(vec4 q){\n\treturn 2.0 * acos(q.w);\n}\nvec3 quatToAxis(vec4 q){\n\treturn vec3(\n\t\tq.x / sqrt(1.0-q.w*q.w),\n\t\tq.y / sqrt(1.0-q.w*q.w),\n\t\tq.z / sqrt(1.0-q.w*q.w)\n\t);\n}\n\nvec4 align(vec3 dir, vec3 up){\n\tvec3 start_dir = vec3(0.0, 0.0, 1.0);\n\tvec3 start_up = vec3(0.0, 1.0, 0.0);\n\tvec4 rot1 = vectorAlign(start_dir, dir);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\tvec3 right = normalize(cross(dir, up));\n\tif(length(right)<0.001){\n\t\tright = vec3(1.0, 0.0, 0.0);\n\t}\n\tup = normalize(cross(right, dir));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(start_up, rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(normalize(newUp), up);\n\n\t// return rot1;\n\treturn quatMult(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\nstruct EnvMapProps {\n\tvec3 tint;\n\tfloat intensity;\n\tfloat roughness;\n\tfloat fresnel;\n\tfloat fresnelPower;\n};\nuniform sampler2D envMap;\nuniform float envMapIntensity;\nuniform float roughness;\n#ifdef ROTATE_ENV_MAP_Y\n\tuniform float envMapRotationY;\n#endif\nvec3 envMapSample(vec3 rayDir, float envMapRoughness){\n\t// http://www.pocketgl.com/reflections/\n\tvec3 env = vec3(0.);\n\t// vec2 uv = vec2( atan( -rayDir.z, -rayDir.x ) * RECIPROCAL_PI2 + 0.5, rayDir.y * 0.5 + 0.5 );\n\t// vec3 env = texture2D(map, uv).rgb;\n\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t#ifdef ROTATE_ENV_MAP_Y\n\t\t\trayDir = rotateWithAxisAngle(rayDir, vec3(0.,1.,0.), envMapRotationY);\n\t\t#endif\n\t\tenv = textureCubeUV(envMap, rayDir, envMapRoughness * roughness).rgb;\n\t#endif\n\treturn env;\n}\nvec3 envMapSampleWithFresnel(vec3 rayDir, EnvMapProps envMapProps, vec3 n, vec3 cameraPosition){\n\t// http://www.pocketgl.com/reflections/\n\tvec3 env = envMapSample(rayDir, envMapProps.roughness);\n\tfloat fresnel = pow(1.-dot(normalize(cameraPosition), n), envMapProps.fresnelPower);\n\tfloat fresnelFactor = (1.-envMapProps.fresnel) + envMapProps.fresnel*fresnel;\n\treturn env * envMapIntensity * envMapProps.tint * envMapProps.intensity * fresnelFactor;\n}\n\n\n\n\n\n\nSDFContext GetDist(vec3 p) {\n\tSDFContext sdfContext = SDFContext(0., 0, 0, 0, 0.);\n\n\t// start GetDist builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/SDFSphere3\n\tfloat v_POLY_SDFSphere3_float = sdSphere(p - vec3(-0.25, 0.0, 0.0), 0.2);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFSphere4\n\tfloat v_POLY_SDFSphere4_float = sdSphere(p - vec3(0.25, 0.0, 0.0), 0.2);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFPlane1\n\tfloat v_POLY_SDFPlane1_float = sdPlane(p-vec3(0.0, -0.2, 0.0), vec3(0.0, 1.0, 0.0), 0.0);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFUnion2\n\tfloat v_POLY_SDFUnion2_union = SDFSmoothUnion(v_POLY_SDFSphere3_float, v_POLY_SDFSphere4_float, 0.31);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFUnion3\n\tfloat v_POLY_SDFUnion3_union = SDFSmoothUnion(v_POLY_SDFUnion2_union, v_POLY_SDFPlane1_float, 0.31);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFContext1\n\tSDFContext v_POLY_SDFContext1_SDFContext = SDFContext(v_POLY_SDFUnion3_union, 0, _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1, _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1, 0.);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/output1\n\tsdfContext = v_POLY_SDFContext1_SDFContext;\n\n\n\n\t\n\n\treturn sdfContext;\n}\n\nSDFContext RayMarch(vec3 ro, vec3 rd, float side) {\n\tSDFContext dO = SDFContext(0.,0,0,0,0.);\n\n\t#pragma unroll_loop_start\n\tfor(int i=0; i<MAX_STEPS; i++) {\n\t\tvec3 p = ro + rd*dO.d;\n\t\tSDFContext sdfContext = GetDist(p);\n\t\tdO.d += sdfContext.d * side;\n\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\tdO.stepsCount += 1;\n\t\t#endif\n\t\tdO.matId = sdfContext.matId;\n\t\tdO.matId2 = sdfContext.matId2;\n\t\tdO.matBlend = sdfContext.matBlend;\n\t\tif(dO.d>MAX_DIST || abs(sdfContext.d)<SURF_DIST) break;\n\t}\n\t#pragma unroll_loop_end\n\n\treturn dO;\n}\n\nvec3 GetNormal(vec3 p) {\n\tSDFContext sdfContext = GetDist(p);\n\tvec2 e = vec2(NORMALS_BIAS, 0);\n\n\tvec3 n = sdfContext.d - vec3(\n\t\tGetDist(p-e.xyy).d,\n\t\tGetDist(p-e.yxy).d,\n\t\tGetDist(p-e.yyx).d);\n\n\treturn normalize(n);\n}\n// https://iquilezles.org/articles/rmshadows\nfloat calcSoftshadow( in vec3 ro, in vec3 rd, float mint, float maxt, float k, inout SDFContext sdfContext )\n{\n\tfloat res = 1.0;\n\tfloat ph = 1e20;\n\tfor( float t=mint; t<maxt; )\n\t{\n\t\tfloat h = GetDist(ro + rd*t).d;\n\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\tsdfContext.stepsCount += 1;\n\t\t#endif\n\t\tif( h<SURF_DIST )\n\t\t\treturn 0.0;\n\t\tfloat y = h*h/(2.0*ph);\n\t\tfloat d = sqrt(h*h-y*y);\n\t\tres = min( res, k*d/max(0.0,t-y) );\n\t\tph = h;\n\t\tt += h;\n\t}\n\treturn res;\n}\n\nvec3 GetLight(vec3 _p, vec3 _n, inout SDFContext sdfContext) {\n\tvec3 dif = vec3(0.,0.,0.);\n\t// GeometricContext geometry;\n\t// geometry.position = _p;\n\t// geometry.normal = _n;\n\t// geometry.viewDir = rayDir;\n\n\t// vec4 mvPosition = vec4( p, 1.0 );\n\t// mvPosition = modelViewMatrix * mvPosition;\n\t// vec3 vViewPosition = - mvPosition.xyz;\n\tvec3 pWorld = ( vModelMatrix * vec4( _p, 1.0 )).xyz;\n\tvec3 nWorld = transformDirection(_n, vModelMatrix);\n\t// geometry.position = (VViewMatrix * vec4( _p, 1.0 )).xyz;\n\tvec3 geometryPosition = (VViewMatrix * vec4(pWorld, 1.0 )).xyz;\n\t// geometry.normal = transformDirection(_n, VViewMatrix);\n\t// geometry.normal = inverseTransformDirection(transformDirection(_n, VViewMatrix), vInverseModelMatrix);\n\tvec3 geometryNormal = transformDirection(nWorld, VViewMatrix);\n\t\n\n\t#if NUM_SPOT_LIGHTS > 0 || NUM_DIR_LIGHTS > 0 || NUM_HEMI_LIGHTS > 0 || NUM_POINT_LIGHTS > 0 || NUM_RECT_AREA_LIGHTS > 0\n\n\t\tIncidentLight directLight;\n\t\tReflectedLight reflectedLight;\n\t\tvec3 lightPos, lightDir, worldLightDir, objectSpaceLightDir, lighDif, directDiffuse;\n\t\tfloat dotNL, lightDistance;\n\t\t#if NUM_SPOT_LIGHTS > 0\n\t\t\tSpotLightRayMarching spotLightRayMarching;\n\t\t\tSpotLight spotLight;\n\t\t\tfloat spotLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\t\t\t\tSpotLightShadow spotLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\t\t\tspotLightRayMarching = spotLightsRayMarching[ i ];\n\t\t\t\tspotLight = spotLights[ i ];\n\t\t\t\tgetSpotLightInfo( spotLight, geometryPosition, directLight );\n\n\t\t\t\t// #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t\t\t// \tspotLightShadow = spotLightShadows[ i ];\n\t\t\t\t// \tvec4 spotLightShadowCoord = spotLightMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t// \tdirectLight.color *= (directLight.visible && receiveShadow) ? getShadow(\n\t\t\t\t// \t\tspotShadowMap[ i ],\n\t\t\t\t// \t\tspotLightShadow.shadowMapSize,\n\t\t\t\t// \t\tspotLightShadow.shadowBias,\n\t\t\t\t// \t\tspotLightShadow.shadowRadius,\n\t\t\t\t// \t\tspotLightShadowCoord\n\t\t\t\t// \t) : 1.0;\n\t\t\t\t// #endif\n\n\t\t\t\tlightPos = spotLight.position;\n\t\t\t\tlightDir = normalize(lightPos-geometryPosition);\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tlightDistance = distance(geometryPosition,lightPos);\n\t\t\t\tspotLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < spotLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t: calcSoftshadow(\n\t\t\t\t\t\t_p,\n\t\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\t\tspotLightRayMarching.shadowBiasDistance,\n\t\t\t\t\t\tdistance(geometryPosition,lightPos),\n\t\t\t\t\t\t1./max(spotLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\t\tsdfContext\n\t\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * spotLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\t\t#if NUM_DIR_LIGHTS > 0\n\t\t\tDirectionalLightRayMarching directionalLightRayMarching;\n\t\t\tDirectionalLight directionalLight;\n\t\t\tfloat dirLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\t\t\t\tDirectionalLightShadow directionalLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\t\t\tdirectionalLightRayMarching = directionalLightsRayMarching[ i ];\n\t\t\t\tdirectionalLight = directionalLights[ i ];\n\t\t\t\t\n\t\t\t\tgetDirectionalLightInfo( directionalLight, directLight );\n\n\t\t\t\t// #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\t\t\t// \tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\t\t\t// \tvec4 dirLightShadowCoord = directionalShadowMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t// \tdirectLight.color *= (directLight.visible && receiveShadow) ? getShadow(\n\t\t\t\t// \t\tdirectionalShadowMap[ i ],\n\t\t\t\t// \t\tdirectionalLightShadow.shadowMapSize,\n\t\t\t\t// \t\tdirectionalLightShadow.shadowBias,\n\t\t\t\t// \t\tdirectionalLightShadow.shadowRadius,\n\t\t\t\t// \t\tdirLightShadowCoord\n\t\t\t\t// \t) : 1.0;\n\t\t\t\t// #endif\n\n\t\t\t\tlightDir = directionalLight.direction;\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tdirLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < directionalLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t:\n\t\t\t\t\tcalcSoftshadow(\n\t\t\t\t\t\t_p,\n\t\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\t\tdirectionalLightRayMarching.shadowBiasDistance,\n\t\t\t\t\t\tMAX_DIST,//distance(geometryPosition,lightPos),\n\t\t\t\t\t\t1./max(directionalLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\t\tsdfContext\n\t\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\t// lighDif = directLight.color * dotNL * dirLightSdfShadow;\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * dirLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\n\t\t#if ( NUM_HEMI_LIGHTS > 0 )\n\n\t\t\t#pragma unroll_loop_start\n\t\t\tHemisphereLight hemiLight;\n\t\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\t\themiLight = hemisphereLights[ i ];\n\t\t\t\tdif += getHemisphereLightIrradiance( hemiLight, geometryNormal ) * BRDF_Lambert( vec3(1.) );\n\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\n\t\t#endif\n\n\t\t#if NUM_POINT_LIGHTS > 0\n\t\t\tPointLightRayMarching pointLightRayMarching;\n\t\t\tPointLight pointLight;\n\t\t\tfloat pointLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\t\t\t\tPointLightShadow pointLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\t\t\tpointLightRayMarching = pointLightsRayMarching[ i ];\n\t\t\t\tpointLight = pointLights[ i ];\n\t\t\t\tgetPointLightInfo( pointLight, geometryPosition, directLight );\n\n\n\t\t\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\t\t\t\tpointLightShadow = pointLightShadows[ i ];\n\t\t\t\t\tvec4 pointLightShadowCoord = pointShadowMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t\tdirectLight.color *= (directLight.visible && receiveShadow) ? getPointShadow(\n\t\t\t\t\t\tpointShadowMap[ i ],\n\t\t\t\t\t\tpointLightShadow.shadowMapSize,\n\t\t\t\t\t\tpointLightShadow.shadowBias,\n\t\t\t\t\t\tpointLightShadow.shadowRadius,\n\t\t\t\t\t\tpointLightShadowCoord,\n\t\t\t\t\t\tpointLightShadow.shadowCameraNear,\n\t\t\t\t\t\tpointLightShadow.shadowCameraFar\n\t\t\t\t\t) : 1.0;\n\t\t\t\t#endif\n\n\t\t\t\tlightPos = pointLight.position;\n\t\t\t\tlightDir = normalize(lightPos-geometryPosition);\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tpointLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < pointLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t:\n\t\t\t\t\tcalcSoftshadow(\n\t\t\t\t\t_p,\n\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\tpointLightRayMarching.shadowBiasDistance,\n\t\t\t\t\tdistance(geometryPosition,lightPos),\n\t\t\t\t\t1./max(pointLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\tsdfContext\n\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * pointLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\n\t\t#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\n\t\t\tRectAreaLight rectAreaLight;\n\t\t\t// AreaLightRayMarching areaLightRayMarching;\n\t\t\tPhysicalMaterial material;\n\t\t\tmaterial.roughness = 1.;\n\t\t\tmaterial.specularColor = vec3(1.);\n\t\t\tmaterial.diffuseColor = vec3(1.);\n\n\t\t\tvec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( cameraPosition - geometryPosition );\n\t\t\tvec3 geometryClearcoatNormal = geometryNormal;\n\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\t\t\t// areaLightRayMarching = areaLightsRayMarching[ i ];\n\t\t\t\trectAreaLight = rectAreaLights[ i ];\n\t\t\t\t// rectAreaLight.position = areaLightRayMarching.worldPos;\n\n\t\t\t\tRE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t\tdif += reflectedLight.directDiffuse;\n\n\t\t#endif\n\t#endif\n\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\n\t#if defined( USE_LIGHT_PROBES )\n\n\t\tirradiance += getLightProbeIrradiance( lightProbe, geometryNormal );\n\n\t#endif\n\n\tdif += irradiance;\n\n\treturn dif;\n}\n\n\n\n\nvec3 applyMaterialWithoutRefraction(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(1.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n\nvec3 applyMaterialWithoutReflection(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(1.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n#ifdef RAYMARCHED_REFLECTIONS\nvec3 GetReflection(vec3 p, vec3 n, vec3 rayDir, float biasMult, float roughness, int reflectionDepth, inout SDFContext sdfContextMain){\n\tbool hitReflection = true;\n\tvec3 reflectedColor = vec3(0.);\n\t#pragma unroll_loop_start\n\tfor(int i=0; i < reflectionDepth; i++) {\n\t\tif(hitReflection){\n\t\t\trayDir = reflect(rayDir, n);\n\t\t\tp += n*SURF_DIST*biasMult;\n\t\t\tSDFContext sdfContext = RayMarch(p, rayDir, 1.);\n\t\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\t\tsdfContextMain.stepsCount += sdfContext.stepsCount;\n\t\t\t#endif\n\t\t\tif( sdfContext.d >= MAX_DIST){\n\t\t\t\thitReflection = false;\n\t\t\t\treflectedColor = envMapSample(rayDir, roughness);\n\t\t\t}\n\t\t\tif(hitReflection){\n\t\t\t\tp += rayDir * sdfContext.d;\n\t\t\t\tn = GetNormal(p);\n\t\t\t\tvec3 matCol = applyMaterialWithoutReflection(p, n, rayDir, sdfContext.matId, sdfContextMain);\n\t\t\t\treflectedColor += matCol;\n\t\t\t}\n\t\t}\n\t}\n\t#pragma unroll_loop_end\n\treturn reflectedColor;\n}\n#endif\n\n#ifdef RAYMARCHED_REFRACTIONS\n// xyz for color, w for distanceInsideMedium\nvec4 GetRefractedData(vec3 p, vec3 n, vec3 rayDir, float ior, float biasMult, float roughness, float refractionMaxDist, int refractionDepth, inout SDFContext sdfContextMain){\n\tbool hitRefraction = true;\n\tbool changeSide = true;\n\t#ifdef RAYMARCHED_REFRACTIONS_START_OUTSIDE_MEDIUM\n\tfloat side = -1.;\n\t#else\n\tfloat side = 1.;\n\t#endif\n\tfloat iorInverted = 1. / ior;\n\tvec3 refractedColor = vec3(0.);\n\tfloat distanceInsideMedium=0.;\n\tfloat totalRefractedDistance=0.;\n\n\t#pragma unroll_loop_start\n\tfor(int i=0; i < refractionDepth; i++) {\n\t\tif(hitRefraction){\n\t\t\tfloat currentIor = side<0. ? iorInverted : ior;\n\t\t\tvec3 rayDirPreRefract = rayDir;\n\t\t\trayDir = refract(rayDir, n, currentIor);\n\t\t\tchangeSide = dot(rayDir, rayDir)!=0.;\n\t\t\tif(changeSide == true) {\n\t\t\t\tp -= n*SURF_DIST*(2.+biasMult);\n\t\t\t} else {\n\t\t\t\tp += n*SURF_DIST*( biasMult);\n\t\t\t\trayDir = reflect(rayDirPreRefract, n);\n\t\t\t}\n\t\t\tSDFContext sdfContext = RayMarch(p, rayDir, side);\n\t\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\t\tsdfContextMain.stepsCount += sdfContext.stepsCount;\n\t\t\t#endif\n\t\t\ttotalRefractedDistance += sdfContext.d;\n\t\t\tif( abs(sdfContext.d) >= MAX_DIST || totalRefractedDistance > refractionMaxDist ){\n\t\t\t\thitRefraction = false;\n\t\t\t\trefractedColor = envMapSample(rayDir, roughness);\n\t\t\t}\n\t\t\tif(hitRefraction){\n\t\t\t\tp += rayDir * sdfContext.d;\n\t\t\t\tn = GetNormal(p) * side;\n\t\t\t\tvec3 matCol = applyMaterialWithoutRefraction(p, n, rayDir, sdfContext.matId, sdfContextMain);\n\t\t\t\trefractedColor = matCol;\n\n\t\t\t\t// same as: side < 0. ? abs(sdfContext.d) : 0.;\n\t\t\t\tdistanceInsideMedium += (side-1.)*-0.5*abs(sdfContext.d);\n\t\t\t\tif( changeSide ){\n\t\t\t\t\tside *= -1.;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#ifdef RAYMARCHED_REFRACTIONS_SAMPLE_ENV_MAP_ON_LAST\n\t\tif(i == refractionDepth-1){\n\t\t\trefractedColor = envMapSample(rayDir, roughness);\n\t\t}\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n\treturn vec4(refractedColor, distanceInsideMedium);\n}\nfloat refractionTint(float baseValue, float tint, float distanceInsideMedium, float absorption){\n\tfloat tintNegated = baseValue-tint;\n\tfloat t = tintNegated*( distanceInsideMedium*absorption );\n\treturn max(baseValue-t, 0.);\n}\nfloat applyRefractionAbsorption(float refractedDataColor, float baseValue, float tint, float distanceInsideMedium, float absorption){\n\treturn refractedDataColor*refractionTint(baseValue, tint, distanceInsideMedium, absorption);\n}\nvec3 applyRefractionAbsorption(vec3 refractedDataColor, vec3 baseValue, vec3 tint, float distanceInsideMedium, float absorption){\n\treturn vec3(\n\t\trefractedDataColor.r * refractionTint(baseValue.r, tint.r, distanceInsideMedium, absorption),\n\t\trefractedDataColor.g * refractionTint(baseValue.g, tint.g, distanceInsideMedium, absorption),\n\t\trefractedDataColor.b * refractionTint(baseValue.b, tint.b, distanceInsideMedium, absorption)\n\t);\n}\n\n#endif\n\nvec3 applyMaterial(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(0.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n\n\n\n\nvec4 applyShading(vec3 rayOrigin, vec3 rayDir, inout SDFContext sdfContext){\n\tvec3 p = rayOrigin + rayDir * sdfContext.d;\n\tvec3 n = GetNormal(p);\n\t\n\tvec3 col = applyMaterial(p, n, rayDir, sdfContext.matId, sdfContext);\n\tif(sdfContext.matBlend > 0.) {\n\t\t// blend material colors if needed\n\t\tvec3 col2 = applyMaterial(p, n, rayDir, sdfContext.matId2, sdfContext);\n\t\tcol = (1. - sdfContext.matBlend)*col + sdfContext.matBlend*col2;\n\t}\n\t\t\n\t// gamma\n\t//col = pow( col, vec3(0.4545) ); // this gamma leads to a different look than standard materials\n\treturn vec4(col, 1.);\n}\n\nvoid main()\t{\n\n\tvec3 rayDir = normalize(vPw - cameraPosition);\n\trayDir = transformDirection(rayDir, vInverseModelMatrix);\n\tvec3 rayOrigin = (vInverseModelMatrix * vec4( cameraPosition, 1.0 )).xyz;\n\n\tSDFContext sdfContext = RayMarch(rayOrigin, rayDir, 1.);\n\n\t#if defined( DEBUG_DEPTH )\n\t\tfloat normalizedDepth = 1.-(sdfContext.d - debugMinDepth ) / ( debugMaxDepth - debugMinDepth );\n\t\tnormalizedDepth = saturate(normalizedDepth); // clamp to [0,1]\n\t\tgl_FragColor = vec4(normalizedDepth);\n\t\treturn;\n\t#endif\n\t#if defined( SHADOW_DEPTH )\n\t\tfloat normalizedDepth = 1.-(sdfContext.d - debugMinDepth ) / ( debugMaxDepth - debugMinDepth );\n\t\t// float fragCoordZ = sdfContext.d / vHighPrecisionZW[1];\n\t\tfloat compoundedDepth = 0.5 * (normalizedDepth) + 0.5;\n\t\tfloat alpha = sdfContext.d < MAX_DIST ? 0.:1.;\n\t\tgl_FragColor = vec4( vec3(compoundedDepth), alpha );\n\t\t// normalizedDepth = 0.5*normalizedDepth+0.5;\n\t\t// gl_FragColor = packDepthToRGBA( normalizedDepth );\n\t\t// gl_FragColor = vec4(0.);\n\t\treturn;\n\t#endif\n\t#if defined( SHADOW_DISTANCE )\n\t\tfloat normalizedDepth = (sdfContext.d - shadowDistanceMin ) / ( shadowDistanceMax - shadowDistanceMin );\n\t\tnormalizedDepth = saturate(normalizedDepth); // clamp to [0,1]\n\t\tgl_FragColor = packDepthToRGBA( normalizedDepth );\n\t\treturn;\n\t#endif\n\n\tif( sdfContext.d < MAX_DIST ){\n\t\tgl_FragColor = applyShading(rayOrigin, rayDir, sdfContext);\n\t\t#if defined( TONE_MAPPING )\n\t\t\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n\t\t#endif\n\t\tgl_FragColor = linearToOutputTexel( gl_FragColor );\n\n\t\t#ifdef USE_FOG\n\t\t\tfloat vFogDepth = sdfContext.d;\n\t\t\t#ifdef FOG_EXP2\n\t\t\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );\n\t\t\t#else\n\t\t\t\tfloat fogFactor = smoothstep( fogNear, fogFar, vFogDepth );\n\t\t\t#endif\n\t\t\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n\t\t#endif\n\t\t#include <premultiplied_alpha_fragment>\n\t\t#include <dithering_fragment>\n\t} else {\n\t\tgl_FragColor = vec4(0.);\n\t}\n\n\t#if defined( DEBUG_STEPS_COUNT )\n\t\tfloat normalizedStepsCount = (float(sdfContext.stepsCount) - debugMinSteps ) / ( debugMaxSteps - debugMinSteps );\n\t\tgl_FragColor = vec4(normalizedStepsCount, 1.-normalizedStepsCount, 0., 1.);\n\t\treturn;\n\t#endif\n\t\n}","lights":true,"clipping":false},"onBeforeCompileDataJSONWithoutShaders":{"paramConfigs":[],"timeDependent":false,"resolutionDependent":false,"raymarchingLightsWorldCoordsDependent":true},"customMaterials":{"customDepthMaterial":{"material":{"metadata":{"version":4.6,"type":"Material","generator":"Material.toJSON"},"uuid":"/geo1/MAT/rayMarchingBuilder1-customDepthMaterial","type":"ShaderMaterial","name":"customDepthMaterial","blendColor":0,"alphaTest":0.5,"forceSinglePass":true,"fog":false,"glslVersion":null,"uniforms":{"diffuse":{"type":"c","value":16777215},"opacity":{"value":1},"map":{"value":null},"mapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"alphaMap":{"value":null},"alphaMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"alphaTest":{"value":0},"envMap":{"value":null},"flipEnvMap":{"value":-1},"reflectivity":{"value":1},"ior":{"value":1.5},"refractionRatio":{"value":0.98},"aoMap":{"value":null},"aoMapIntensity":{"value":1},"aoMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"lightMap":{"value":null},"lightMapIntensity":{"value":1},"lightMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"emissiveMap":{"value":null},"emissiveMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"bumpMap":{"value":null},"bumpMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"bumpScale":{"value":1},"normalMap":{"value":null},"normalMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"normalScale":{"type":"v2","value":[1,1]},"displacementMap":{"value":null},"displacementMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"displacementScale":{"value":1},"displacementBias":{"value":0},"roughnessMap":{"value":null},"roughnessMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"metalnessMap":{"value":null},"metalnessMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"fogDensity":{"value":0.00025},"fogNear":{"value":1},"fogFar":{"value":2000},"fogColor":{"type":"c","value":16777215},"ambientLightColor":{"value":[]},"lightProbe":{"value":[]},"directionalLights":{"value":[]},"directionalLightShadows":{"value":[]},"directionalShadowMap":{"value":[]},"directionalShadowMatrix":{"value":[]},"spotLights":{"value":[]},"spotLightShadows":{"value":[]},"spotLightMap":{"value":[]},"spotShadowMap":{"value":[]},"spotLightMatrix":{"value":[]},"pointLights":{"value":[]},"pointLightShadows":{"value":[]},"pointShadowMap":{"value":[]},"pointShadowMatrix":{"value":[]},"hemisphereLights":{"value":[]},"rectAreaLights":{"value":[]},"ltc_1":{"value":null},"ltc_2":{"value":null},"emissive":{"type":"c","value":0},"roughness":{"value":1},"metalness":{"value":0},"envMapIntensity":{"value":1},"MAX_STEPS":{"value":100},"MAX_DIST":{"value":100},"SURF_DIST":{"value":0.001},"NORMALS_BIAS":{"value":0.01},"SHADOW_BIAS":{"value":0},"debugMinSteps":{"value":0},"debugMaxSteps":{"value":128},"debugMinDepth":{"value":0},"debugMaxDepth":{"value":128},"shadowDistanceMin":{"value":0},"shadowDistanceMax":{"value":100},"shadowDepthMin":{"value":0},"shadowDepthMax":{"value":100},"envMapRotationY":{"value":0},"spotLightsRayMarching":{"value":[{"penumbra":0,"shadowBiasAngle":0.01,"shadowBiasDistance":0.1}]},"directionalLightsRayMarching":{"value":[]},"pointLightsRayMarching":{"value":[]}},"defines":{"SHADOW_DEPTH":1,"DEPTH_PACKING":3200},"vertexShader":"precision highp float;\nprecision highp int;\n\nvarying vec3 vPw;\nvarying mat4 vModelMatrix;\nvarying mat4 vInverseModelMatrix;\nvarying mat4 VViewMatrix;\n\n#include <common>\n\n// // for depth material\n// varying vec2 vHighPrecisionZW;\n\nvoid main()\t{\n\n\tvModelMatrix = modelMatrix;\n\tvInverseModelMatrix = inverse(modelMatrix);\n\tVViewMatrix = viewMatrix;\n\tvPw = (modelMatrix * vec4( position, 1.0 )).xyz;\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n\t// vHighPrecisionZW = gl_Position.zw;\n}","fragmentShader":"precision highp float;\nprecision highp int;\n\n// --- applyMaterial constants definition\nuniform int MAX_STEPS;\nuniform float MAX_DIST;\nuniform float SURF_DIST;\nuniform float NORMALS_BIAS;\nuniform float SHADOW_BIAS;\n#define ZERO 0\nuniform float debugMinSteps;\nuniform float debugMaxSteps;\nuniform float debugMinDepth;\nuniform float debugMaxDepth;\n\n#include <common>\n#include <packing>\n#include <lightmap_pars_fragment>\n#include <bsdfs>\n#include <cube_uv_reflection_fragment>\n#include <lights_pars_begin>\n#include <lights_physical_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <fog_pars_fragment>\n\n#if defined( SHADOW_DISTANCE )\n\tuniform float shadowDistanceMin;\n\tuniform float shadowDistanceMax;\n#endif \n#if defined( SHADOW_DEPTH )\n\tuniform float shadowDepthMin;\n\tuniform float shadowDepthMax;\n#endif\n\n// varying vec2 vHighPrecisionZW;\n\nvarying vec3 vPw;\nvarying mat4 vModelMatrix;\nvarying mat4 vInverseModelMatrix;\nvarying mat4 VViewMatrix;\n\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform SpotLightRayMarching spotLightsRayMarching[ NUM_SPOT_LIGHTS ];\n\t#if NUM_SPOT_LIGHT_COORDS > 0\n\n\t\tuniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];\n\n\t#endif\n#endif\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform DirectionalLightRayMarching directionalLightsRayMarching[ NUM_DIR_LIGHTS ];\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\n\t#endif\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform PointLightRayMarching pointLightsRayMarching[ NUM_POINT_LIGHTS ];\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\n\t#endif\n#endif\n\n\nstruct SDFContext {\n\tfloat d;\n\tint stepsCount;\n\tint matId;\n\tint matId2;\n\tfloat matBlend;\n};\n\nSDFContext DefaultSDFContext(){\n\treturn SDFContext( 0., 0, 0, 0, 0. );\n}\nint DefaultSDFMaterial(){\n\treturn 0;\n}\n\n// start raymarching builder define code\n\n\n\n// /geo1/MAT/rayMarchingBuilder1/SDFSphere3\nfloat dot2( in vec2 v ) { return dot(v,v); }\nfloat dot2( in vec3 v ) { return dot(v,v); }\nfloat ndot( in vec2 a, in vec2 b ) { return a.x*b.x - a.y*b.y; }\n// https://iquilezles.org/articles/distfunctions/\n\n\n/*\n*\n* SDF PRIMITIVES\n*\n*/\nfloat sdSphere( vec3 p, float s )\n{\n\treturn length(p)-s;\n}\nfloat sdCutSphere( vec3 p, float r, float h )\n{\n\t// sampling independent computations (only depend on shape)\n\tfloat w = sqrt(r*r-h*h);\n\n\t// sampling dependant computations\n\tvec2 q = vec2( length(p.xz), p.y );\n\tfloat s = max( (h-r)*q.x*q.x+w*w*(h+r-2.0*q.y), h*q.x-w*q.y );\n\treturn (s<0.0) ? length(q)-r :\n\t\t\t\t(q.x<w) ? h - q.y :\n\t\t\t\t\tlength(q-vec2(w,h));\n}\nfloat sdCutHollowSphere( vec3 p, float r, float h, float t )\n{\n\t// sampling independent computations (only depend on shape)\n\tfloat w = sqrt(r*r-h*h);\n\t\n\t// sampling dependant computations\n\tvec2 q = vec2( length(p.xz), p.y );\n\treturn ((h*q.x<w*q.y) ? length(q-vec2(w,h)) : \n\t\t\t\t\t\t\tabs(length(q)-r) ) - t;\n}\n\nfloat sdBox( vec3 p, vec3 b )\n{\n\tvec3 q = abs(p) - b*0.5;\n\treturn length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0);\n}\nfloat sdRoundBox( vec3 p, vec3 b, float r )\n{\n\tvec3 q = abs(p) - b*0.5;\n\treturn length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0) - r;\n}\n\n\nfloat sdBoxFrame( vec3 p, vec3 b, float e )\n{\n\t\tp = abs(p )-b*0.5;\n\tvec3 q = abs(p+e)-e;\n\treturn min(min(\n\t\tlength(max(vec3(p.x,q.y,q.z),0.0))+min(max(p.x,max(q.y,q.z)),0.0),\n\t\tlength(max(vec3(q.x,p.y,q.z),0.0))+min(max(q.x,max(p.y,q.z)),0.0)),\n\t\tlength(max(vec3(q.x,q.y,p.z),0.0))+min(max(q.x,max(q.y,p.z)),0.0));\n}\nfloat sdCapsule( vec3 p, vec3 a, vec3 b, float r )\n{\n\tvec3 pa = p - a, ba = b - a;\n\tfloat h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n\treturn length( pa - ba*h ) - r;\n}\nfloat sdVerticalCapsule( vec3 p, float h, float r )\n{\n\tp.y -= clamp( p.y, 0.0, h );\n\treturn length( p ) - r;\n}\nfloat sdCone( in vec3 p, in vec2 c, float h )\n{\n\t// c is the sin/cos of the angle, h is height\n\t// Alternatively pass q instead of (c,h),\n\t// which is the point at the base in 2D\n\tvec2 q = h*vec2(c.x/c.y,-1.0);\n\n\tvec2 w = vec2( length(p.xz), p.y );\n\tvec2 a = w - q*clamp( dot(w,q)/dot(q,q), 0.0, 1.0 );\n\tvec2 b = w - q*vec2( clamp( w.x/q.x, 0.0, 1.0 ), 1.0 );\n\tfloat k = sign( q.y );\n\tfloat d = min(dot( a, a ),dot(b, b));\n\tfloat s = max( k*(w.x*q.y-w.y*q.x),k*(w.y-q.y) );\n\treturn sqrt(d)*sign(s);\n}\nfloat sdConeWrapped(vec3 pos, float angle, float height){\n\treturn sdCone(pos, vec2(sin(angle), cos(angle)), height);\n}\nfloat sdRoundCone( vec3 p, float r1, float r2, float h )\n{\n\tfloat b = (r1-r2)/h;\n\tfloat a = sqrt(1.0-b*b);\n\n\tvec2 q = vec2( length(p.xz), p.y );\n\tfloat k = dot(q,vec2(-b,a));\n\tif( k<0.0 ) return length(q) - r1;\n\tif( k>a*h ) return length(q-vec2(0.0,h)) - r2;\n\treturn dot(q, vec2(a,b) ) - r1;\n}\nfloat sdOctogonPrism( in vec3 p, in float r, float h )\n{\n\tconst vec3 k = vec3(-0.9238795325, // sqrt(2+sqrt(2))/2 \n\t\t\t\t\t\t0.3826834323, // sqrt(2-sqrt(2))/2\n\t\t\t\t\t\t0.4142135623 ); // sqrt(2)-1 \n\t// reflections\n\tp = abs(p);\n\tp.xy -= 2.0*min(dot(vec2( k.x,k.y),p.xy),0.0)*vec2( k.x,k.y);\n\tp.xy -= 2.0*min(dot(vec2(-k.x,k.y),p.xy),0.0)*vec2(-k.x,k.y);\n\t// polygon side\n\tp.xy -= vec2(clamp(p.x, -k.z*r, k.z*r), r);\n\tvec2 d = vec2( length(p.xy)*sign(p.y), p.z-h );\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdHexPrism( vec3 p, vec2 h )\n{\n\tconst vec3 k = vec3(-0.8660254, 0.5, 0.57735);\n\tp = abs(p);\n\tp.xy -= 2.0*min(dot(k.xy, p.xy), 0.0)*k.xy;\n\tvec2 d = vec2(\n\t\tlength(p.xy-vec2(clamp(p.x,-k.z*h.x,k.z*h.x), h.x))*sign(p.y-h.x),\n\t\tp.z-h.y );\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdHorseshoe( in vec3 p, in float angle, in float r, in float le, vec2 w )\n{\n\tvec2 c = vec2(cos(angle),sin(angle));\n\tp.x = abs(p.x);\n\tfloat l = length(p.xy);\n\tp.xy = mat2(-c.x, c.y, \n\t\t\tc.y, c.x)*p.xy;\n\tp.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x),\n\t\t\t\t(p.x>0.0)?p.y:l );\n\tp.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0);\n\t\n\tvec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z);\n\tvec2 d = abs(q) - w;\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdTriPrism( vec3 p, vec2 h )\n{\n\tvec3 q = abs(p);\n\treturn max(q.z-h.y,max(q.x*0.866025+p.y*0.5,-p.y)-h.x*0.5);\n}\nfloat sdPyramid( vec3 p, float h)\n{\n\tfloat m2 = h*h + 0.25;\n\n\tp.xz = abs(p.xz);\n\tp.xz = (p.z>p.x) ? p.zx : p.xz;\n\tp.xz -= 0.5;\n\n\tvec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y);\n\n\tfloat s = max(-q.x,0.0);\n\tfloat t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 );\n\n\tfloat a = m2*(q.x+s)*(q.x+s) + q.y*q.y;\n\tfloat b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t);\n\n\tfloat d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b);\n\n\treturn sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));\n}\n\nfloat sdPlane( vec3 p, vec3 n, float h )\n{\n\t// n must be normalized\n\treturn dot(p,n) + h;\n}\n\nfloat sdTorus( vec3 p, vec2 t )\n{\n\tvec2 q = vec2(length(p.xz)-t.x,p.y);\n\treturn length(q)-t.y;\n}\nfloat sdCappedTorus(in vec3 p, in float an, in float ra, in float rb)\n{\n\tvec2 sc = vec2(sin(an),cos(an));\n\tp.x = abs(p.x);\n\tfloat k = (sc.y*p.x>sc.x*p.z) ? dot(p.xz,sc) : length(p.xz);\n\treturn sqrt( dot(p,p) + ra*ra - 2.0*ra*k ) - rb;\n}\nfloat sdLink( vec3 p, float le, float r1, float r2 )\n{\n vec3 q = vec3( p.x, max(abs(p.y)-le,0.0), p.z );\n return length(vec2(length(q.xy)-r1,q.z)) - r2;\n}\n// c is the sin/cos of the desired cone angle\nfloat sdSolidAngle(vec3 pos, vec2 c, float radius)\n{\n\tvec2 p = vec2( length(pos.xz), pos.y );\n\tfloat l = length(p) - radius;\n\tfloat m = length(p - c*clamp(dot(p,c),0.0,radius) );\n\treturn max(l,m*sign(c.y*p.x-c.x*p.y));\n}\nfloat sdSolidAngleWrapped(vec3 pos, float angle, float radius){\n\treturn sdSolidAngle(pos, vec2(sin(angle), cos(angle)), radius);\n}\nfloat sdTube( vec3 p, float r )\n{\n\treturn length(p.xz)-r;\n}\nfloat sdTubeCapped( vec3 p, float h, float r )\n{\n\tvec2 d = abs(vec2(length(p.xz),p.y)) - vec2(r,h);\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdOctahedron( vec3 p, float s)\n{\n p = abs(p);\n float m = p.x+p.y+p.z-s;\n vec3 q;\n if( 3.0*p.x < m ) q = p.xyz;\n else if( 3.0*p.y < m ) q = p.yzx;\n else if( 3.0*p.z < m ) q = p.zxy;\n else return m*0.57735027;\n \n float k = clamp(0.5*(q.z-q.y+s),0.0,s); \n return length(vec3(q.x,q.y-s+k,q.z-k)); \n}\nfloat udTriangle( vec3 p, vec3 a, vec3 b, vec3 c, float thickness )\n{\n\tvec3 ba = b - a; vec3 pa = p - a;\n\tvec3 cb = c - b; vec3 pb = p - b;\n\tvec3 ac = a - c; vec3 pc = p - c;\n\tvec3 nor = cross( ba, ac );\n\n\treturn - thickness + sqrt(\n\t\t(sign(dot(cross(ba,nor),pa)) +\n\t\tsign(dot(cross(cb,nor),pb)) +\n\t\tsign(dot(cross(ac,nor),pc))<2.0)\n\t\t?\n\t\tmin( min(\n\t\tdot2(ba*clamp(dot(ba,pa)/dot2(ba),0.0,1.0)-pa),\n\t\tdot2(cb*clamp(dot(cb,pb)/dot2(cb),0.0,1.0)-pb) ),\n\t\tdot2(ac*clamp(dot(ac,pc)/dot2(ac),0.0,1.0)-pc) )\n\t\t:\n\t\tdot(nor,pa)*dot(nor,pa)/dot2(nor) );\n}\nfloat udQuad( vec3 p, vec3 a, vec3 b, vec3 c, vec3 d, float thickness )\n{\n\tvec3 ba = b - a; vec3 pa = p - a;\n\tvec3 cb = c - b; vec3 pb = p - b;\n\tvec3 dc = d - c; vec3 pc = p - c;\n\tvec3 ad = a - d; vec3 pd = p - d;\n\tvec3 nor = cross( ba, ad );\n\n\treturn - thickness + sqrt(\n\t\t(sign(dot(cross(ba,nor),pa)) +\n\t\tsign(dot(cross(cb,nor),pb)) +\n\t\tsign(dot(cross(dc,nor),pc)) +\n\t\tsign(dot(cross(ad,nor),pd))<3.0)\n\t\t?\n\t\tmin( min( min(\n\t\tdot2(ba*clamp(dot(ba,pa)/dot2(ba),0.0,1.0)-pa),\n\t\tdot2(cb*clamp(dot(cb,pb)/dot2(cb),0.0,1.0)-pb) ),\n\t\tdot2(dc*clamp(dot(dc,pc)/dot2(dc),0.0,1.0)-pc) ),\n\t\tdot2(ad*clamp(dot(ad,pd)/dot2(ad),0.0,1.0)-pd) )\n\t\t:\n\t\tdot(nor,pa)*dot(nor,pa)/dot2(nor) );\n}\n\n/*\n*\n* SDF OPERATIONS\n*\n*/\nfloat SDFUnion( float d1, float d2 ) { return min(d1,d2); }\nfloat SDFSubtract( float d1, float d2 ) { return max(-d1,d2); }\nfloat SDFIntersect( float d1, float d2 ) { return max(d1,d2); }\n\nfloat SDFSmoothUnion( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 + 0.5*(d2-d1)/k, 0.0, 1.0 );\n\treturn mix( d2, d1, h ) - k*h*(1.0-h);\n}\n\nfloat SDFSmoothSubtract( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 - 0.5*(d2+d1)/k, 0.0, 1.0 );\n\treturn mix( d2, -d1, h ) + k*h*(1.0-h);\n}\n\nfloat SDFSmoothIntersect( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 - 0.5*(d2-d1)/k, 0.0, 1.0 );\n\treturn mix( d2, d1, h ) + k*h*(1.0-h);\n}\n\nvec4 SDFElongateFast( in vec3 p, in vec3 h )\n{\n\treturn vec4( p-clamp(p,-h,h), 0.0 );\n}\nvec4 SDFElongateSlow( in vec3 p, in vec3 h )\n{\n\tvec3 q = abs(p)-h;\n\treturn vec4( max(q,0.0), min(max(q.x,max(q.y,q.z)),0.0) );\n}\n\nfloat SDFOnion( in float sdf, in float thickness )\n{\n\treturn abs(sdf)-thickness;\n}\n\n// /geo1/MAT/rayMarchingBuilder1/checkers1\n// https://iquilezles.org/articles/checkerfiltering/\nfloat checkers(vec2 p) {\n\tvec2 s = sign(fract(p*.5)-.5);\n\treturn .5 - .5*s.x*s.y;\n}\nfloat checkersGrad( in vec2 p, in vec2 ddx, in vec2 ddy )\n{\n // filter kernel\n vec2 w = max(abs(ddx), abs(ddy)) + 0.01;\n // analytical integral (box filter)\n vec2 i = 2.0*(abs(fract((p-0.5*w)/2.0)-0.5)-abs(fract((p+0.5*w)/2.0)-0.5))/w;\n // xor pattern\n return 0.5 - 0.5*i.x*i.y;\n}\n\n\n// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\nconst int _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1 = 1;\n\n\n// https://stackoverflow.com/questions/23793698/how-to-implement-slerp-in-glsl-hlsl\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t)\n// {\n// \tfloat dotp = dot(normalize(p0), normalize(p1));\n// \tif ((dotp > 0.9999) || (dotp < -0.9999))\n// \t{\n// \t\tif (t<=0.5)\n// \t\t\treturn p0;\n// \t\treturn p1;\n// \t}\n// \tfloat theta = acos(dotp);\n// \tvec4 P = ((p0*sin((1.0-t)*theta) + p1*sin(t*theta)) / sin(theta));\n// \tP.w = 1.0;\n// \treturn P;\n// }\n\n// https://devcry.heiho.net/html/2017/20170521-slerp.html\n// float lerp(float a, float b, float t) {\n// \treturn (1.0 - t) * a + t * b;\n// }\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t){\n// \tvec4 qb = p1;\n\n// \t// cos(a) = dot product\n// \tfloat cos_a = p0.x * qb.x + p0.y * qb.y + p0.z * qb.z + p0.w * qb.w;\n// \tif (cos_a < 0.0f) {\n// \t\tcos_a = -cos_a;\n// \t\tqb = -qb;\n// \t}\n\n// \t// close to zero, cos(a) ~= 1\n// \t// do linear interpolation\n// \tif (cos_a > 0.999) {\n// \t\treturn vec4(\n// \t\t\tlerp(p0.x, qb.x, t),\n// \t\t\tlerp(p0.y, qb.y, t),\n// \t\t\tlerp(p0.z, qb.z, t),\n// \t\t\tlerp(p0.w, qb.w, t)\n// \t\t);\n// \t}\n\n// \tfloat alpha = acos(cos_a);\n// \treturn (p0 * sin(1.0 - t) + p1 * sin(t * alpha)) / sin(alpha);\n// }\n\n// https://stackoverflow.com/questions/62943083/interpolate-between-two-quaternions-the-long-way\nvec4 quatSlerp(vec4 q1, vec4 q2, float t){\n\tfloat angle = acos(dot(q1, q2));\n\tfloat denom = sin(angle);\n\t//check if denom is zero\n\treturn (q1*sin((1.0-t)*angle)+q2*sin(t*angle))/denom;\n}\n// TO CHECK:\n// this page https://www.reddit.com/r/opengl/comments/704la7/glsl_quaternion_library/\n// has a link to a potentially nice pdf:\n// http://web.mit.edu/2.998/www/QuaternionReport1.pdf\n\n// https://github.com/mattatz/ShibuyaCrowd/blob/master/source/shaders/common/quaternion.glsl\nvec4 quatMult(vec4 q1, vec4 q2)\n{\n\treturn vec4(\n\tq1.w * q2.x + q1.x * q2.w + q1.z * q2.y - q1.y * q2.z,\n\tq1.w * q2.y + q1.y * q2.w + q1.x * q2.z - q1.z * q2.x,\n\tq1.w * q2.z + q1.z * q2.w + q1.y * q2.x - q1.x * q2.y,\n\tq1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z\n\t);\n}\n// http://glmatrix.net/docs/quat.js.html#line97\n// let ax = a[0], ay = a[1], az = a[2], aw = a[3];\n\n// let bx = b[0], by = b[1], bz = b[2], bw = b[3];\n\n// out[0] = ax * bw + aw * bx + ay * bz - az * by;\n\n// out[1] = ay * bw + aw * by + az * bx - ax * bz;\n\n// out[2] = az * bw + aw * bz + ax * by - ay * bx;\n\n// out[3] = aw * bw - ax * bx - ay * by - az * bz;\n\n// return out\n\n\n\n// http://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/\nmat4 rotationMatrix(vec3 axis, float angle)\n{\n\taxis = normalize(axis);\n\tfloat s = sin(angle);\n\tfloat c = cos(angle);\n\tfloat oc = 1.0 - c;\n\n \treturn mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 0.0, 0.0, 0.0, 1.0);\n}\n\n// https://www.geeks3d.com/20141201/how-to-rotate-a-vertex-by-a-quaternion-in-glsl/\nvec4 quatFromAxisAngle(vec3 axis, float angle)\n{\n\tvec4 qr;\n\tfloat half_angle = (angle * 0.5); // * 3.14159 / 180.0;\n\tfloat sin_half_angle = sin(half_angle);\n\tqr.x = axis.x * sin_half_angle;\n\tqr.y = axis.y * sin_half_angle;\n\tqr.z = axis.z * sin_half_angle;\n\tqr.w = cos(half_angle);\n\treturn qr;\n}\nvec3 rotateWithAxisAngle(vec3 position, vec3 axis, float angle)\n{\n\tvec4 q = quatFromAxisAngle(axis, angle);\n\tvec3 v = position.xyz;\n\treturn v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);\n}\n// vec3 applyQuaternionToVector( vec4 q, vec3 v ){\n// \treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n// }\nvec3 rotateWithQuat( vec3 v, vec4 q )\n{\n\t// vec4 qv = multQuat( quat, vec4(vec, 0.0) );\n\t// return multQuat( qv, vec4(-quat.x, -quat.y, -quat.z, quat.w) ).xyz;\n\treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n}\n// https://github.com/glslify/glsl-look-at/blob/gh-pages/index.glsl\n// mat3 rotation_matrix(vec3 origin, vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target - origin);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n// mat3 rotation_matrix(vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n\nfloat vectorAngle(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 c1 = cross(start, dest);\n\t// We use the dot product of the cross with the Y axis.\n\t// This is a little arbitrary, but can still give a good sense of direction\n\tvec3 y_axis = vec3(0.0, 1.0, 0.0);\n\tfloat d1 = dot(c1, y_axis);\n\tfloat angle = acos(cosTheta) * sign(d1);\n\treturn angle;\n}\n\n// http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/#i-need-an-equivalent-of-glulookat-how-do-i-orient-an-object-towards-a-point-\nvec4 vectorAlign(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 axis;\n\n\t// if (cosTheta < -1 + 0.001f){\n\t// \t// special case when vectors in opposite directions:\n\t// \t// there is no ideal rotation axis\n\t// \t// So guess one; any will do as long as it's perpendicular to start\n\t// \taxis = cross(vec3(0.0f, 0.0f, 1.0f), start);\n\t// \tif (length2(axis) < 0.01 ) // bad luck, they were parallel, try again!\n\t// \t\taxis = cross(vec3(1.0f, 0.0f, 0.0f), start);\n\n\t// \taxis = normalize(axis);\n\t// \treturn gtx::quaternion::angleAxis(glm::radians(180.0f), axis);\n\t// }\n\tif(cosTheta > (1.0 - 0.0001) || cosTheta < (-1.0 + 0.0001) ){\n\t\taxis = normalize(cross(start, vec3(0.0, 1.0, 0.0)));\n\t\tif (length(axis) < 0.001 ){ // bad luck, they were parallel, try again!\n\t\t\taxis = normalize(cross(start, vec3(1.0, 0.0, 0.0)));\n\t\t}\n\t} else {\n\t\taxis = normalize(cross(start, dest));\n\t}\n\n\tfloat angle = acos(cosTheta);\n\n\treturn quatFromAxisAngle(axis, angle);\n}\nvec4 vectorAlignWithUp(vec3 start, vec3 dest, vec3 up){\n\tvec4 rot1 = vectorAlign(start, dest);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\t// vec3 right = normalize(cross(dest, up));\n\t// up = normalize(cross(right, dest));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(vec3(0.0, 1.0, 0.0), rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(up, newUp);\n\n\t// return rot1;\n\treturn rot2;\n\t// return multQuat(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\n// https://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\nfloat quatToAngle(vec4 q){\n\treturn 2.0 * acos(q.w);\n}\nvec3 quatToAxis(vec4 q){\n\treturn vec3(\n\t\tq.x / sqrt(1.0-q.w*q.w),\n\t\tq.y / sqrt(1.0-q.w*q.w),\n\t\tq.z / sqrt(1.0-q.w*q.w)\n\t);\n}\n\nvec4 align(vec3 dir, vec3 up){\n\tvec3 start_dir = vec3(0.0, 0.0, 1.0);\n\tvec3 start_up = vec3(0.0, 1.0, 0.0);\n\tvec4 rot1 = vectorAlign(start_dir, dir);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\tvec3 right = normalize(cross(dir, up));\n\tif(length(right)<0.001){\n\t\tright = vec3(1.0, 0.0, 0.0);\n\t}\n\tup = normalize(cross(right, dir));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(start_up, rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(normalize(newUp), up);\n\n\t// return rot1;\n\treturn quatMult(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\nstruct EnvMapProps {\n\tvec3 tint;\n\tfloat intensity;\n\tfloat roughness;\n\tfloat fresnel;\n\tfloat fresnelPower;\n};\nuniform sampler2D envMap;\nuniform float envMapIntensity;\nuniform float roughness;\n#ifdef ROTATE_ENV_MAP_Y\n\tuniform float envMapRotationY;\n#endif\nvec3 envMapSample(vec3 rayDir, float envMapRoughness){\n\t// http://www.pocketgl.com/reflections/\n\tvec3 env = vec3(0.);\n\t// vec2 uv = vec2( atan( -rayDir.z, -rayDir.x ) * RECIPROCAL_PI2 + 0.5, rayDir.y * 0.5 + 0.5 );\n\t// vec3 env = texture2D(map, uv).rgb;\n\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t#ifdef ROTATE_ENV_MAP_Y\n\t\t\trayDir = rotateWithAxisAngle(rayDir, vec3(0.,1.,0.), envMapRotationY);\n\t\t#endif\n\t\tenv = textureCubeUV(envMap, rayDir, envMapRoughness * roughness).rgb;\n\t#endif\n\treturn env;\n}\nvec3 envMapSampleWithFresnel(vec3 rayDir, EnvMapProps envMapProps, vec3 n, vec3 cameraPosition){\n\t// http://www.pocketgl.com/reflections/\n\tvec3 env = envMapSample(rayDir, envMapProps.roughness);\n\tfloat fresnel = pow(1.-dot(normalize(cameraPosition), n), envMapProps.fresnelPower);\n\tfloat fresnelFactor = (1.-envMapProps.fresnel) + envMapProps.fresnel*fresnel;\n\treturn env * envMapIntensity * envMapProps.tint * envMapProps.intensity * fresnelFactor;\n}\n\n\n\n\n\n\nSDFContext GetDist(vec3 p) {\n\tSDFContext sdfContext = SDFContext(0., 0, 0, 0, 0.);\n\n\t// start GetDist builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/SDFSphere3\n\tfloat v_POLY_SDFSphere3_float = sdSphere(p - vec3(-0.25, 0.0, 0.0), 0.2);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFSphere4\n\tfloat v_POLY_SDFSphere4_float = sdSphere(p - vec3(0.25, 0.0, 0.0), 0.2);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFPlane1\n\tfloat v_POLY_SDFPlane1_float = sdPlane(p-vec3(0.0, -0.2, 0.0), vec3(0.0, 1.0, 0.0), 0.0);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFUnion2\n\tfloat v_POLY_SDFUnion2_union = SDFSmoothUnion(v_POLY_SDFSphere3_float, v_POLY_SDFSphere4_float, 0.31);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFUnion3\n\tfloat v_POLY_SDFUnion3_union = SDFSmoothUnion(v_POLY_SDFUnion2_union, v_POLY_SDFPlane1_float, 0.31);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFContext1\n\tSDFContext v_POLY_SDFContext1_SDFContext = SDFContext(v_POLY_SDFUnion3_union, 0, _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1, _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1, 0.);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/output1\n\tsdfContext = v_POLY_SDFContext1_SDFContext;\n\n\n\n\t\n\n\treturn sdfContext;\n}\n\nSDFContext RayMarch(vec3 ro, vec3 rd, float side) {\n\tSDFContext dO = SDFContext(0.,0,0,0,0.);\n\n\t#pragma unroll_loop_start\n\tfor(int i=0; i<MAX_STEPS; i++) {\n\t\tvec3 p = ro + rd*dO.d;\n\t\tSDFContext sdfContext = GetDist(p);\n\t\tdO.d += sdfContext.d * side;\n\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\tdO.stepsCount += 1;\n\t\t#endif\n\t\tdO.matId = sdfContext.matId;\n\t\tdO.matId2 = sdfContext.matId2;\n\t\tdO.matBlend = sdfContext.matBlend;\n\t\tif(dO.d>MAX_DIST || abs(sdfContext.d)<SURF_DIST) break;\n\t}\n\t#pragma unroll_loop_end\n\n\treturn dO;\n}\n\nvec3 GetNormal(vec3 p) {\n\tSDFContext sdfContext = GetDist(p);\n\tvec2 e = vec2(NORMALS_BIAS, 0);\n\n\tvec3 n = sdfContext.d - vec3(\n\t\tGetDist(p-e.xyy).d,\n\t\tGetDist(p-e.yxy).d,\n\t\tGetDist(p-e.yyx).d);\n\n\treturn normalize(n);\n}\n// https://iquilezles.org/articles/rmshadows\nfloat calcSoftshadow( in vec3 ro, in vec3 rd, float mint, float maxt, float k, inout SDFContext sdfContext )\n{\n\tfloat res = 1.0;\n\tfloat ph = 1e20;\n\tfor( float t=mint; t<maxt; )\n\t{\n\t\tfloat h = GetDist(ro + rd*t).d;\n\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\tsdfContext.stepsCount += 1;\n\t\t#endif\n\t\tif( h<SURF_DIST )\n\t\t\treturn 0.0;\n\t\tfloat y = h*h/(2.0*ph);\n\t\tfloat d = sqrt(h*h-y*y);\n\t\tres = min( res, k*d/max(0.0,t-y) );\n\t\tph = h;\n\t\tt += h;\n\t}\n\treturn res;\n}\n\nvec3 GetLight(vec3 _p, vec3 _n, inout SDFContext sdfContext) {\n\tvec3 dif = vec3(0.,0.,0.);\n\t// GeometricContext geometry;\n\t// geometry.position = _p;\n\t// geometry.normal = _n;\n\t// geometry.viewDir = rayDir;\n\n\t// vec4 mvPosition = vec4( p, 1.0 );\n\t// mvPosition = modelViewMatrix * mvPosition;\n\t// vec3 vViewPosition = - mvPosition.xyz;\n\tvec3 pWorld = ( vModelMatrix * vec4( _p, 1.0 )).xyz;\n\tvec3 nWorld = transformDirection(_n, vModelMatrix);\n\t// geometry.position = (VViewMatrix * vec4( _p, 1.0 )).xyz;\n\tvec3 geometryPosition = (VViewMatrix * vec4(pWorld, 1.0 )).xyz;\n\t// geometry.normal = transformDirection(_n, VViewMatrix);\n\t// geometry.normal = inverseTransformDirection(transformDirection(_n, VViewMatrix), vInverseModelMatrix);\n\tvec3 geometryNormal = transformDirection(nWorld, VViewMatrix);\n\t\n\n\t#if NUM_SPOT_LIGHTS > 0 || NUM_DIR_LIGHTS > 0 || NUM_HEMI_LIGHTS > 0 || NUM_POINT_LIGHTS > 0 || NUM_RECT_AREA_LIGHTS > 0\n\n\t\tIncidentLight directLight;\n\t\tReflectedLight reflectedLight;\n\t\tvec3 lightPos, lightDir, worldLightDir, objectSpaceLightDir, lighDif, directDiffuse;\n\t\tfloat dotNL, lightDistance;\n\t\t#if NUM_SPOT_LIGHTS > 0\n\t\t\tSpotLightRayMarching spotLightRayMarching;\n\t\t\tSpotLight spotLight;\n\t\t\tfloat spotLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\t\t\t\tSpotLightShadow spotLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\t\t\tspotLightRayMarching = spotLightsRayMarching[ i ];\n\t\t\t\tspotLight = spotLights[ i ];\n\t\t\t\tgetSpotLightInfo( spotLight, geometryPosition, directLight );\n\n\t\t\t\t// #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t\t\t// \tspotLightShadow = spotLightShadows[ i ];\n\t\t\t\t// \tvec4 spotLightShadowCoord = spotLightMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t// \tdirectLight.color *= (directLight.visible && receiveShadow) ? getShadow(\n\t\t\t\t// \t\tspotShadowMap[ i ],\n\t\t\t\t// \t\tspotLightShadow.shadowMapSize,\n\t\t\t\t// \t\tspotLightShadow.shadowBias,\n\t\t\t\t// \t\tspotLightShadow.shadowRadius,\n\t\t\t\t// \t\tspotLightShadowCoord\n\t\t\t\t// \t) : 1.0;\n\t\t\t\t// #endif\n\n\t\t\t\tlightPos = spotLight.position;\n\t\t\t\tlightDir = normalize(lightPos-geometryPosition);\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tlightDistance = distance(geometryPosition,lightPos);\n\t\t\t\tspotLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < spotLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t: calcSoftshadow(\n\t\t\t\t\t\t_p,\n\t\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\t\tspotLightRayMarching.shadowBiasDistance,\n\t\t\t\t\t\tdistance(geometryPosition,lightPos),\n\t\t\t\t\t\t1./max(spotLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\t\tsdfContext\n\t\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * spotLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\t\t#if NUM_DIR_LIGHTS > 0\n\t\t\tDirectionalLightRayMarching directionalLightRayMarching;\n\t\t\tDirectionalLight directionalLight;\n\t\t\tfloat dirLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\t\t\t\tDirectionalLightShadow directionalLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\t\t\tdirectionalLightRayMarching = directionalLightsRayMarching[ i ];\n\t\t\t\tdirectionalLight = directionalLights[ i ];\n\t\t\t\t\n\t\t\t\tgetDirectionalLightInfo( directionalLight, directLight );\n\n\t\t\t\t// #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\t\t\t// \tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\t\t\t// \tvec4 dirLightShadowCoord = directionalShadowMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t// \tdirectLight.color *= (directLight.visible && receiveShadow) ? getShadow(\n\t\t\t\t// \t\tdirectionalShadowMap[ i ],\n\t\t\t\t// \t\tdirectionalLightShadow.shadowMapSize,\n\t\t\t\t// \t\tdirectionalLightShadow.shadowBias,\n\t\t\t\t// \t\tdirectionalLightShadow.shadowRadius,\n\t\t\t\t// \t\tdirLightShadowCoord\n\t\t\t\t// \t) : 1.0;\n\t\t\t\t// #endif\n\n\t\t\t\tlightDir = directionalLight.direction;\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tdirLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < directionalLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t:\n\t\t\t\t\tcalcSoftshadow(\n\t\t\t\t\t\t_p,\n\t\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\t\tdirectionalLightRayMarching.shadowBiasDistance,\n\t\t\t\t\t\tMAX_DIST,//distance(geometryPosition,lightPos),\n\t\t\t\t\t\t1./max(directionalLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\t\tsdfContext\n\t\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\t// lighDif = directLight.color * dotNL * dirLightSdfShadow;\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * dirLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\n\t\t#if ( NUM_HEMI_LIGHTS > 0 )\n\n\t\t\t#pragma unroll_loop_start\n\t\t\tHemisphereLight hemiLight;\n\t\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\t\themiLight = hemisphereLights[ i ];\n\t\t\t\tdif += getHemisphereLightIrradiance( hemiLight, geometryNormal ) * BRDF_Lambert( vec3(1.) );\n\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\n\t\t#endif\n\n\t\t#if NUM_POINT_LIGHTS > 0\n\t\t\tPointLightRayMarching pointLightRayMarching;\n\t\t\tPointLight pointLight;\n\t\t\tfloat pointLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\t\t\t\tPointLightShadow pointLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\t\t\tpointLightRayMarching = pointLightsRayMarching[ i ];\n\t\t\t\tpointLight = pointLights[ i ];\n\t\t\t\tgetPointLightInfo( pointLight, geometryPosition, directLight );\n\n\n\t\t\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\t\t\t\tpointLightShadow = pointLightShadows[ i ];\n\t\t\t\t\tvec4 pointLightShadowCoord = pointShadowMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t\tdirectLight.color *= (directLight.visible && receiveShadow) ? getPointShadow(\n\t\t\t\t\t\tpointShadowMap[ i ],\n\t\t\t\t\t\tpointLightShadow.shadowMapSize,\n\t\t\t\t\t\tpointLightShadow.shadowBias,\n\t\t\t\t\t\tpointLightShadow.shadowRadius,\n\t\t\t\t\t\tpointLightShadowCoord,\n\t\t\t\t\t\tpointLightShadow.shadowCameraNear,\n\t\t\t\t\t\tpointLightShadow.shadowCameraFar\n\t\t\t\t\t) : 1.0;\n\t\t\t\t#endif\n\n\t\t\t\tlightPos = pointLight.position;\n\t\t\t\tlightDir = normalize(lightPos-geometryPosition);\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tpointLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < pointLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t:\n\t\t\t\t\tcalcSoftshadow(\n\t\t\t\t\t_p,\n\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\tpointLightRayMarching.shadowBiasDistance,\n\t\t\t\t\tdistance(geometryPosition,lightPos),\n\t\t\t\t\t1./max(pointLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\tsdfContext\n\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * pointLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\n\t\t#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\n\t\t\tRectAreaLight rectAreaLight;\n\t\t\t// AreaLightRayMarching areaLightRayMarching;\n\t\t\tPhysicalMaterial material;\n\t\t\tmaterial.roughness = 1.;\n\t\t\tmaterial.specularColor = vec3(1.);\n\t\t\tmaterial.diffuseColor = vec3(1.);\n\n\t\t\tvec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( cameraPosition - geometryPosition );\n\t\t\tvec3 geometryClearcoatNormal = geometryNormal;\n\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\t\t\t// areaLightRayMarching = areaLightsRayMarching[ i ];\n\t\t\t\trectAreaLight = rectAreaLights[ i ];\n\t\t\t\t// rectAreaLight.position = areaLightRayMarching.worldPos;\n\n\t\t\t\tRE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t\tdif += reflectedLight.directDiffuse;\n\n\t\t#endif\n\t#endif\n\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\n\t#if defined( USE_LIGHT_PROBES )\n\n\t\tirradiance += getLightProbeIrradiance( lightProbe, geometryNormal );\n\n\t#endif\n\n\tdif += irradiance;\n\n\treturn dif;\n}\n\n\n\n\nvec3 applyMaterialWithoutRefraction(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(1.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n\nvec3 applyMaterialWithoutReflection(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(1.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n#ifdef RAYMARCHED_REFLECTIONS\nvec3 GetReflection(vec3 p, vec3 n, vec3 rayDir, float biasMult, float roughness, int reflectionDepth, inout SDFContext sdfContextMain){\n\tbool hitReflection = true;\n\tvec3 reflectedColor = vec3(0.);\n\t#pragma unroll_loop_start\n\tfor(int i=0; i < reflectionDepth; i++) {\n\t\tif(hitReflection){\n\t\t\trayDir = reflect(rayDir, n);\n\t\t\tp += n*SURF_DIST*biasMult;\n\t\t\tSDFContext sdfContext = RayMarch(p, rayDir, 1.);\n\t\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\t\tsdfContextMain.stepsCount += sdfContext.stepsCount;\n\t\t\t#endif\n\t\t\tif( sdfContext.d >= MAX_DIST){\n\t\t\t\thitReflection = false;\n\t\t\t\treflectedColor = envMapSample(rayDir, roughness);\n\t\t\t}\n\t\t\tif(hitReflection){\n\t\t\t\tp += rayDir * sdfContext.d;\n\t\t\t\tn = GetNormal(p);\n\t\t\t\tvec3 matCol = applyMaterialWithoutReflection(p, n, rayDir, sdfContext.matId, sdfContextMain);\n\t\t\t\treflectedColor += matCol;\n\t\t\t}\n\t\t}\n\t}\n\t#pragma unroll_loop_end\n\treturn reflectedColor;\n}\n#endif\n\n#ifdef RAYMARCHED_REFRACTIONS\n// xyz for color, w for distanceInsideMedium\nvec4 GetRefractedData(vec3 p, vec3 n, vec3 rayDir, float ior, float biasMult, float roughness, float refractionMaxDist, int refractionDepth, inout SDFContext sdfContextMain){\n\tbool hitRefraction = true;\n\tbool changeSide = true;\n\t#ifdef RAYMARCHED_REFRACTIONS_START_OUTSIDE_MEDIUM\n\tfloat side = -1.;\n\t#else\n\tfloat side = 1.;\n\t#endif\n\tfloat iorInverted = 1. / ior;\n\tvec3 refractedColor = vec3(0.);\n\tfloat distanceInsideMedium=0.;\n\tfloat totalRefractedDistance=0.;\n\n\t#pragma unroll_loop_start\n\tfor(int i=0; i < refractionDepth; i++) {\n\t\tif(hitRefraction){\n\t\t\tfloat currentIor = side<0. ? iorInverted : ior;\n\t\t\tvec3 rayDirPreRefract = rayDir;\n\t\t\trayDir = refract(rayDir, n, currentIor);\n\t\t\tchangeSide = dot(rayDir, rayDir)!=0.;\n\t\t\tif(changeSide == true) {\n\t\t\t\tp -= n*SURF_DIST*(2.+biasMult);\n\t\t\t} else {\n\t\t\t\tp += n*SURF_DIST*( biasMult);\n\t\t\t\trayDir = reflect(rayDirPreRefract, n);\n\t\t\t}\n\t\t\tSDFContext sdfContext = RayMarch(p, rayDir, side);\n\t\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\t\tsdfContextMain.stepsCount += sdfContext.stepsCount;\n\t\t\t#endif\n\t\t\ttotalRefractedDistance += sdfContext.d;\n\t\t\tif( abs(sdfContext.d) >= MAX_DIST || totalRefractedDistance > refractionMaxDist ){\n\t\t\t\thitRefraction = false;\n\t\t\t\trefractedColor = envMapSample(rayDir, roughness);\n\t\t\t}\n\t\t\tif(hitRefraction){\n\t\t\t\tp += rayDir * sdfContext.d;\n\t\t\t\tn = GetNormal(p) * side;\n\t\t\t\tvec3 matCol = applyMaterialWithoutRefraction(p, n, rayDir, sdfContext.matId, sdfContextMain);\n\t\t\t\trefractedColor = matCol;\n\n\t\t\t\t// same as: side < 0. ? abs(sdfContext.d) : 0.;\n\t\t\t\tdistanceInsideMedium += (side-1.)*-0.5*abs(sdfContext.d);\n\t\t\t\tif( changeSide ){\n\t\t\t\t\tside *= -1.;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#ifdef RAYMARCHED_REFRACTIONS_SAMPLE_ENV_MAP_ON_LAST\n\t\tif(i == refractionDepth-1){\n\t\t\trefractedColor = envMapSample(rayDir, roughness);\n\t\t}\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n\treturn vec4(refractedColor, distanceInsideMedium);\n}\nfloat refractionTint(float baseValue, float tint, float distanceInsideMedium, float absorption){\n\tfloat tintNegated = baseValue-tint;\n\tfloat t = tintNegated*( distanceInsideMedium*absorption );\n\treturn max(baseValue-t, 0.);\n}\nfloat applyRefractionAbsorption(float refractedDataColor, float baseValue, float tint, float distanceInsideMedium, float absorption){\n\treturn refractedDataColor*refractionTint(baseValue, tint, distanceInsideMedium, absorption);\n}\nvec3 applyRefractionAbsorption(vec3 refractedDataColor, vec3 baseValue, vec3 tint, float distanceInsideMedium, float absorption){\n\treturn vec3(\n\t\trefractedDataColor.r * refractionTint(baseValue.r, tint.r, distanceInsideMedium, absorption),\n\t\trefractedDataColor.g * refractionTint(baseValue.g, tint.g, distanceInsideMedium, absorption),\n\t\trefractedDataColor.b * refractionTint(baseValue.b, tint.b, distanceInsideMedium, absorption)\n\t);\n}\n\n#endif\n\nvec3 applyMaterial(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(0.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n\n\n\n\nvec4 applyShading(vec3 rayOrigin, vec3 rayDir, inout SDFContext sdfContext){\n\tvec3 p = rayOrigin + rayDir * sdfContext.d;\n\tvec3 n = GetNormal(p);\n\t\n\tvec3 col = applyMaterial(p, n, rayDir, sdfContext.matId, sdfContext);\n\tif(sdfContext.matBlend > 0.) {\n\t\t// blend material colors if needed\n\t\tvec3 col2 = applyMaterial(p, n, rayDir, sdfContext.matId2, sdfContext);\n\t\tcol = (1. - sdfContext.matBlend)*col + sdfContext.matBlend*col2;\n\t}\n\t\t\n\t// gamma\n\t//col = pow( col, vec3(0.4545) ); // this gamma leads to a different look than standard materials\n\treturn vec4(col, 1.);\n}\n\nvoid main()\t{\n\n\tvec3 rayDir = normalize(vPw - cameraPosition);\n\trayDir = transformDirection(rayDir, vInverseModelMatrix);\n\tvec3 rayOrigin = (vInverseModelMatrix * vec4( cameraPosition, 1.0 )).xyz;\n\n\tSDFContext sdfContext = RayMarch(rayOrigin, rayDir, 1.);\n\n\t#if defined( DEBUG_DEPTH )\n\t\tfloat normalizedDepth = 1.-(sdfContext.d - debugMinDepth ) / ( debugMaxDepth - debugMinDepth );\n\t\tnormalizedDepth = saturate(normalizedDepth); // clamp to [0,1]\n\t\tgl_FragColor = vec4(normalizedDepth);\n\t\treturn;\n\t#endif\n\t#if defined( SHADOW_DEPTH )\n\t\tfloat normalizedDepth = 1.-(sdfContext.d - debugMinDepth ) / ( debugMaxDepth - debugMinDepth );\n\t\t// float fragCoordZ = sdfContext.d / vHighPrecisionZW[1];\n\t\tfloat compoundedDepth = 0.5 * (normalizedDepth) + 0.5;\n\t\tfloat alpha = sdfContext.d < MAX_DIST ? 0.:1.;\n\t\tgl_FragColor = vec4( vec3(compoundedDepth), alpha );\n\t\t// normalizedDepth = 0.5*normalizedDepth+0.5;\n\t\t// gl_FragColor = packDepthToRGBA( normalizedDepth );\n\t\t// gl_FragColor = vec4(0.);\n\t\treturn;\n\t#endif\n\t#if defined( SHADOW_DISTANCE )\n\t\tfloat normalizedDepth = (sdfContext.d - shadowDistanceMin ) / ( shadowDistanceMax - shadowDistanceMin );\n\t\tnormalizedDepth = saturate(normalizedDepth); // clamp to [0,1]\n\t\tgl_FragColor = packDepthToRGBA( normalizedDepth );\n\t\treturn;\n\t#endif\n\n\tif( sdfContext.d < MAX_DIST ){\n\t\tgl_FragColor = applyShading(rayOrigin, rayDir, sdfContext);\n\t\t#if defined( TONE_MAPPING )\n\t\t\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n\t\t#endif\n\t\tgl_FragColor = linearToOutputTexel( gl_FragColor );\n\n\t\t#ifdef USE_FOG\n\t\t\tfloat vFogDepth = sdfContext.d;\n\t\t\t#ifdef FOG_EXP2\n\t\t\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );\n\t\t\t#else\n\t\t\t\tfloat fogFactor = smoothstep( fogNear, fogFar, vFogDepth );\n\t\t\t#endif\n\t\t\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n\t\t#endif\n\t\t#include <premultiplied_alpha_fragment>\n\t\t#include <dithering_fragment>\n\t} else {\n\t\tgl_FragColor = vec4(0.);\n\t}\n\n\t#if defined( DEBUG_STEPS_COUNT )\n\t\tfloat normalizedStepsCount = (float(sdfContext.stepsCount) - debugMinSteps ) / ( debugMaxSteps - debugMinSteps );\n\t\tgl_FragColor = vec4(normalizedStepsCount, 1.-normalizedStepsCount, 0., 1.);\n\t\treturn;\n\t#endif\n\t\n}","lights":false,"clipping":false,"depthPacking":3200},"onBeforeCompileDataJSONWithoutShaders":{"paramConfigs":[],"timeDependent":false,"resolutionDependent":false,"raymarchingLightsWorldCoordsDependent":true}},"customDistanceMaterial":{"material":{"metadata":{"version":4.6,"type":"Material","generator":"Material.toJSON"},"uuid":"/geo1/MAT/rayMarchingBuilder1-customDistanceMaterial","type":"ShaderMaterial","name":"customDistanceMaterial","blendColor":0,"alphaTest":0.5,"forceSinglePass":true,"fog":false,"glslVersion":null,"uniforms":{"diffuse":{"type":"c","value":16777215},"opacity":{"value":1},"map":{"value":null},"mapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"alphaMap":{"value":null},"alphaMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"alphaTest":{"value":0},"envMap":{"value":null},"flipEnvMap":{"value":-1},"reflectivity":{"value":1},"ior":{"value":1.5},"refractionRatio":{"value":0.98},"aoMap":{"value":null},"aoMapIntensity":{"value":1},"aoMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"lightMap":{"value":null},"lightMapIntensity":{"value":1},"lightMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"emissiveMap":{"value":null},"emissiveMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"bumpMap":{"value":null},"bumpMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"bumpScale":{"value":1},"normalMap":{"value":null},"normalMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"normalScale":{"type":"v2","value":[1,1]},"displacementMap":{"value":null},"displacementMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"displacementScale":{"value":1},"displacementBias":{"value":0},"roughnessMap":{"value":null},"roughnessMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"metalnessMap":{"value":null},"metalnessMapTransform":{"type":"m3","value":[1,0,0,0,1,0,0,0,1]},"fogDensity":{"value":0.00025},"fogNear":{"value":1},"fogFar":{"value":2000},"fogColor":{"type":"c","value":16777215},"ambientLightColor":{"value":[]},"lightProbe":{"value":[]},"directionalLights":{"value":[]},"directionalLightShadows":{"value":[]},"directionalShadowMap":{"value":[]},"directionalShadowMatrix":{"value":[]},"spotLights":{"value":[]},"spotLightShadows":{"value":[]},"spotLightMap":{"value":[]},"spotShadowMap":{"value":[]},"spotLightMatrix":{"value":[]},"pointLights":{"value":[]},"pointLightShadows":{"value":[]},"pointShadowMap":{"value":[]},"pointShadowMatrix":{"value":[]},"hemisphereLights":{"value":[]},"rectAreaLights":{"value":[]},"ltc_1":{"value":null},"ltc_2":{"value":null},"emissive":{"type":"c","value":0},"roughness":{"value":1},"metalness":{"value":0},"envMapIntensity":{"value":1},"MAX_STEPS":{"value":100},"MAX_DIST":{"value":100},"SURF_DIST":{"value":0.001},"NORMALS_BIAS":{"value":0.01},"SHADOW_BIAS":{"value":0},"debugMinSteps":{"value":0},"debugMaxSteps":{"value":128},"debugMinDepth":{"value":0},"debugMaxDepth":{"value":128},"shadowDistanceMin":{"value":0},"shadowDistanceMax":{"value":100},"shadowDepthMin":{"value":0},"shadowDepthMax":{"value":100},"envMapRotationY":{"value":0},"spotLightsRayMarching":{"value":[{"penumbra":0,"shadowBiasAngle":0.01,"shadowBiasDistance":0.1}]},"directionalLightsRayMarching":{"value":[]},"pointLightsRayMarching":{"value":[]}},"defines":{"SHADOW_DISTANCE":1},"vertexShader":"precision highp float;\nprecision highp int;\n\nvarying vec3 vPw;\nvarying mat4 vModelMatrix;\nvarying mat4 vInverseModelMatrix;\nvarying mat4 VViewMatrix;\n\n#include <common>\n\n// // for depth material\n// varying vec2 vHighPrecisionZW;\n\nvoid main()\t{\n\n\tvModelMatrix = modelMatrix;\n\tvInverseModelMatrix = inverse(modelMatrix);\n\tVViewMatrix = viewMatrix;\n\tvPw = (modelMatrix * vec4( position, 1.0 )).xyz;\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n\t// vHighPrecisionZW = gl_Position.zw;\n}","fragmentShader":"precision highp float;\nprecision highp int;\n\n// --- applyMaterial constants definition\nuniform int MAX_STEPS;\nuniform float MAX_DIST;\nuniform float SURF_DIST;\nuniform float NORMALS_BIAS;\nuniform float SHADOW_BIAS;\n#define ZERO 0\nuniform float debugMinSteps;\nuniform float debugMaxSteps;\nuniform float debugMinDepth;\nuniform float debugMaxDepth;\n\n#include <common>\n#include <packing>\n#include <lightmap_pars_fragment>\n#include <bsdfs>\n#include <cube_uv_reflection_fragment>\n#include <lights_pars_begin>\n#include <lights_physical_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <fog_pars_fragment>\n\n#if defined( SHADOW_DISTANCE )\n\tuniform float shadowDistanceMin;\n\tuniform float shadowDistanceMax;\n#endif \n#if defined( SHADOW_DEPTH )\n\tuniform float shadowDepthMin;\n\tuniform float shadowDepthMax;\n#endif\n\n// varying vec2 vHighPrecisionZW;\n\nvarying vec3 vPw;\nvarying mat4 vModelMatrix;\nvarying mat4 vInverseModelMatrix;\nvarying mat4 VViewMatrix;\n\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform SpotLightRayMarching spotLightsRayMarching[ NUM_SPOT_LIGHTS ];\n\t#if NUM_SPOT_LIGHT_COORDS > 0\n\n\t\tuniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];\n\n\t#endif\n#endif\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform DirectionalLightRayMarching directionalLightsRayMarching[ NUM_DIR_LIGHTS ];\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\n\t#endif\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform PointLightRayMarching pointLightsRayMarching[ NUM_POINT_LIGHTS ];\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\n\t#endif\n#endif\n\n\nstruct SDFContext {\n\tfloat d;\n\tint stepsCount;\n\tint matId;\n\tint matId2;\n\tfloat matBlend;\n};\n\nSDFContext DefaultSDFContext(){\n\treturn SDFContext( 0., 0, 0, 0, 0. );\n}\nint DefaultSDFMaterial(){\n\treturn 0;\n}\n\n// start raymarching builder define code\n\n\nSDFContext GetDist(vec3 p) {\n\tSDFContext sdfContext = SDFContext(0., 0, 0, 0, 0.);\n\n\t// start GetDist builder body code\n\t\n\n\treturn sdfContext;\n}\n\nSDFContext RayMarch(vec3 ro, vec3 rd, float side) {\n\tSDFContext dO = SDFContext(0.,0,0,0,0.);\n\n\t#pragma unroll_loop_start\n\tfor(int i=0; i<MAX_STEPS; i++) {\n\t\tvec3 p = ro + rd*dO.d;\n\t\tSDFContext sdfContext = GetDist(p);\n\t\tdO.d += sdfContext.d * side;\n\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\tdO.stepsCount += 1;\n\t\t#endif\n\t\tdO.matId = sdfContext.matId;\n\t\tdO.matId2 = sdfContext.matId2;\n\t\tdO.matBlend = sdfContext.matBlend;\n\t\tif(dO.d>MAX_DIST || abs(sdfContext.d)<SURF_DIST) break;\n\t}\n\t#pragma unroll_loop_end\n\n\treturn dO;\n}\n\nvec3 GetNormal(vec3 p) {\n\tSDFContext sdfContext = GetDist(p);\n\tvec2 e = vec2(NORMALS_BIAS, 0);\n\n\tvec3 n = sdfContext.d - vec3(\n\t\tGetDist(p-e.xyy).d,\n\t\tGetDist(p-e.yxy).d,\n\t\tGetDist(p-e.yyx).d);\n\n\treturn normalize(n);\n}\n// https://iquilezles.org/articles/rmshadows\nfloat calcSoftshadow( in vec3 ro, in vec3 rd, float mint, float maxt, float k, inout SDFContext sdfContext )\n{\n\tfloat res = 1.0;\n\tfloat ph = 1e20;\n\tfor( float t=mint; t<maxt; )\n\t{\n\t\tfloat h = GetDist(ro + rd*t).d;\n\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\tsdfContext.stepsCount += 1;\n\t\t#endif\n\t\tif( h<SURF_DIST )\n\t\t\treturn 0.0;\n\t\tfloat y = h*h/(2.0*ph);\n\t\tfloat d = sqrt(h*h-y*y);\n\t\tres = min( res, k*d/max(0.0,t-y) );\n\t\tph = h;\n\t\tt += h;\n\t}\n\treturn res;\n}\n\nvec3 GetLight(vec3 _p, vec3 _n, inout SDFContext sdfContext) {\n\tvec3 dif = vec3(0.,0.,0.);\n\t// GeometricContext geometry;\n\t// geometry.position = _p;\n\t// geometry.normal = _n;\n\t// geometry.viewDir = rayDir;\n\n\t// vec4 mvPosition = vec4( p, 1.0 );\n\t// mvPosition = modelViewMatrix * mvPosition;\n\t// vec3 vViewPosition = - mvPosition.xyz;\n\tvec3 pWorld = ( vModelMatrix * vec4( _p, 1.0 )).xyz;\n\tvec3 nWorld = transformDirection(_n, vModelMatrix);\n\t// geometry.position = (VViewMatrix * vec4( _p, 1.0 )).xyz;\n\tvec3 geometryPosition = (VViewMatrix * vec4(pWorld, 1.0 )).xyz;\n\t// geometry.normal = transformDirection(_n, VViewMatrix);\n\t// geometry.normal = inverseTransformDirection(transformDirection(_n, VViewMatrix), vInverseModelMatrix);\n\tvec3 geometryNormal = transformDirection(nWorld, VViewMatrix);\n\t\n\n\t#if NUM_SPOT_LIGHTS > 0 || NUM_DIR_LIGHTS > 0 || NUM_HEMI_LIGHTS > 0 || NUM_POINT_LIGHTS > 0 || NUM_RECT_AREA_LIGHTS > 0\n\n\t\tIncidentLight directLight;\n\t\tReflectedLight reflectedLight;\n\t\tvec3 lightPos, lightDir, worldLightDir, objectSpaceLightDir, lighDif, directDiffuse;\n\t\tfloat dotNL, lightDistance;\n\t\t#if NUM_SPOT_LIGHTS > 0\n\t\t\tSpotLightRayMarching spotLightRayMarching;\n\t\t\tSpotLight spotLight;\n\t\t\tfloat spotLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\t\t\t\tSpotLightShadow spotLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\t\t\tspotLightRayMarching = spotLightsRayMarching[ i ];\n\t\t\t\tspotLight = spotLights[ i ];\n\t\t\t\tgetSpotLightInfo( spotLight, geometryPosition, directLight );\n\n\t\t\t\t// #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t\t\t// \tspotLightShadow = spotLightShadows[ i ];\n\t\t\t\t// \tvec4 spotLightShadowCoord = spotLightMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t// \tdirectLight.color *= (directLight.visible && receiveShadow) ? getShadow(\n\t\t\t\t// \t\tspotShadowMap[ i ],\n\t\t\t\t// \t\tspotLightShadow.shadowMapSize,\n\t\t\t\t// \t\tspotLightShadow.shadowBias,\n\t\t\t\t// \t\tspotLightShadow.shadowRadius,\n\t\t\t\t// \t\tspotLightShadowCoord\n\t\t\t\t// \t) : 1.0;\n\t\t\t\t// #endif\n\n\t\t\t\tlightPos = spotLight.position;\n\t\t\t\tlightDir = normalize(lightPos-geometryPosition);\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tlightDistance = distance(geometryPosition,lightPos);\n\t\t\t\tspotLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < spotLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t: calcSoftshadow(\n\t\t\t\t\t\t_p,\n\t\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\t\tspotLightRayMarching.shadowBiasDistance,\n\t\t\t\t\t\tdistance(geometryPosition,lightPos),\n\t\t\t\t\t\t1./max(spotLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\t\tsdfContext\n\t\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * spotLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\t\t#if NUM_DIR_LIGHTS > 0\n\t\t\tDirectionalLightRayMarching directionalLightRayMarching;\n\t\t\tDirectionalLight directionalLight;\n\t\t\tfloat dirLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\t\t\t\tDirectionalLightShadow directionalLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\t\t\tdirectionalLightRayMarching = directionalLightsRayMarching[ i ];\n\t\t\t\tdirectionalLight = directionalLights[ i ];\n\t\t\t\t\n\t\t\t\tgetDirectionalLightInfo( directionalLight, directLight );\n\n\t\t\t\t// #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\t\t\t// \tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\t\t\t// \tvec4 dirLightShadowCoord = directionalShadowMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t// \tdirectLight.color *= (directLight.visible && receiveShadow) ? getShadow(\n\t\t\t\t// \t\tdirectionalShadowMap[ i ],\n\t\t\t\t// \t\tdirectionalLightShadow.shadowMapSize,\n\t\t\t\t// \t\tdirectionalLightShadow.shadowBias,\n\t\t\t\t// \t\tdirectionalLightShadow.shadowRadius,\n\t\t\t\t// \t\tdirLightShadowCoord\n\t\t\t\t// \t) : 1.0;\n\t\t\t\t// #endif\n\n\t\t\t\tlightDir = directionalLight.direction;\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tdirLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < directionalLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t:\n\t\t\t\t\tcalcSoftshadow(\n\t\t\t\t\t\t_p,\n\t\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\t\tdirectionalLightRayMarching.shadowBiasDistance,\n\t\t\t\t\t\tMAX_DIST,//distance(geometryPosition,lightPos),\n\t\t\t\t\t\t1./max(directionalLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\t\tsdfContext\n\t\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\t// lighDif = directLight.color * dotNL * dirLightSdfShadow;\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * dirLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\n\t\t#if ( NUM_HEMI_LIGHTS > 0 )\n\n\t\t\t#pragma unroll_loop_start\n\t\t\tHemisphereLight hemiLight;\n\t\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\t\themiLight = hemisphereLights[ i ];\n\t\t\t\tdif += getHemisphereLightIrradiance( hemiLight, geometryNormal ) * BRDF_Lambert( vec3(1.) );\n\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\n\t\t#endif\n\n\t\t#if NUM_POINT_LIGHTS > 0\n\t\t\tPointLightRayMarching pointLightRayMarching;\n\t\t\tPointLight pointLight;\n\t\t\tfloat pointLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\t\t\t\tPointLightShadow pointLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\t\t\tpointLightRayMarching = pointLightsRayMarching[ i ];\n\t\t\t\tpointLight = pointLights[ i ];\n\t\t\t\tgetPointLightInfo( pointLight, geometryPosition, directLight );\n\n\n\t\t\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\t\t\t\tpointLightShadow = pointLightShadows[ i ];\n\t\t\t\t\tvec4 pointLightShadowCoord = pointShadowMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t\tdirectLight.color *= (directLight.visible && receiveShadow) ? getPointShadow(\n\t\t\t\t\t\tpointShadowMap[ i ],\n\t\t\t\t\t\tpointLightShadow.shadowMapSize,\n\t\t\t\t\t\tpointLightShadow.shadowBias,\n\t\t\t\t\t\tpointLightShadow.shadowRadius,\n\t\t\t\t\t\tpointLightShadowCoord,\n\t\t\t\t\t\tpointLightShadow.shadowCameraNear,\n\t\t\t\t\t\tpointLightShadow.shadowCameraFar\n\t\t\t\t\t) : 1.0;\n\t\t\t\t#endif\n\n\t\t\t\tlightPos = pointLight.position;\n\t\t\t\tlightDir = normalize(lightPos-geometryPosition);\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tpointLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < pointLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t:\n\t\t\t\t\tcalcSoftshadow(\n\t\t\t\t\t_p,\n\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\tpointLightRayMarching.shadowBiasDistance,\n\t\t\t\t\tdistance(geometryPosition,lightPos),\n\t\t\t\t\t1./max(pointLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\tsdfContext\n\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * pointLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\n\t\t#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\n\t\t\tRectAreaLight rectAreaLight;\n\t\t\t// AreaLightRayMarching areaLightRayMarching;\n\t\t\tPhysicalMaterial material;\n\t\t\tmaterial.roughness = 1.;\n\t\t\tmaterial.specularColor = vec3(1.);\n\t\t\tmaterial.diffuseColor = vec3(1.);\n\n\t\t\tvec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( cameraPosition - geometryPosition );\n\t\t\tvec3 geometryClearcoatNormal = geometryNormal;\n\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\t\t\t// areaLightRayMarching = areaLightsRayMarching[ i ];\n\t\t\t\trectAreaLight = rectAreaLights[ i ];\n\t\t\t\t// rectAreaLight.position = areaLightRayMarching.worldPos;\n\n\t\t\t\tRE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t\tdif += reflectedLight.directDiffuse;\n\n\t\t#endif\n\t#endif\n\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\n\t#if defined( USE_LIGHT_PROBES )\n\n\t\tirradiance += getLightProbeIrradiance( lightProbe, geometryNormal );\n\n\t#endif\n\n\tdif += irradiance;\n\n\treturn dif;\n}\n\n\n\n// --- applyMaterial function definition\n\n\n\nvec4 applyShading(vec3 rayOrigin, vec3 rayDir, inout SDFContext sdfContext){\n\tvec3 p = rayOrigin + rayDir * sdfContext.d;\n\tvec3 n = GetNormal(p);\n\t\n\tvec3 col = applyMaterial(p, n, rayDir, sdfContext.matId, sdfContext);\n\tif(sdfContext.matBlend > 0.) {\n\t\t// blend material colors if needed\n\t\tvec3 col2 = applyMaterial(p, n, rayDir, sdfContext.matId2, sdfContext);\n\t\tcol = (1. - sdfContext.matBlend)*col + sdfContext.matBlend*col2;\n\t}\n\t\t\n\t// gamma\n\t//col = pow( col, vec3(0.4545) ); // this gamma leads to a different look than standard materials\n\treturn vec4(col, 1.);\n}\n\nvoid main()\t{\n\n\tvec3 rayDir = normalize(vPw - cameraPosition);\n\trayDir = transformDirection(rayDir, vInverseModelMatrix);\n\tvec3 rayOrigin = (vInverseModelMatrix * vec4( cameraPosition, 1.0 )).xyz;\n\n\tSDFContext sdfContext = RayMarch(rayOrigin, rayDir, 1.);\n\n\t#if defined( DEBUG_DEPTH )\n\t\tfloat normalizedDepth = 1.-(sdfContext.d - debugMinDepth ) / ( debugMaxDepth - debugMinDepth );\n\t\tnormalizedDepth = saturate(normalizedDepth); // clamp to [0,1]\n\t\tgl_FragColor = vec4(normalizedDepth);\n\t\treturn;\n\t#endif\n\t#if defined( SHADOW_DEPTH )\n\t\tfloat normalizedDepth = 1.-(sdfContext.d - debugMinDepth ) / ( debugMaxDepth - debugMinDepth );\n\t\t// float fragCoordZ = sdfContext.d / vHighPrecisionZW[1];\n\t\tfloat compoundedDepth = 0.5 * (normalizedDepth) + 0.5;\n\t\tfloat alpha = sdfContext.d < MAX_DIST ? 0.:1.;\n\t\tgl_FragColor = vec4( vec3(compoundedDepth), alpha );\n\t\t// normalizedDepth = 0.5*normalizedDepth+0.5;\n\t\t// gl_FragColor = packDepthToRGBA( normalizedDepth );\n\t\t// gl_FragColor = vec4(0.);\n\t\treturn;\n\t#endif\n\t#if defined( SHADOW_DISTANCE )\n\t\tfloat normalizedDepth = (sdfContext.d - shadowDistanceMin ) / ( shadowDistanceMax - shadowDistanceMin );\n\t\tnormalizedDepth = saturate(normalizedDepth); // clamp to [0,1]\n\t\tgl_FragColor = packDepthToRGBA( normalizedDepth );\n\t\treturn;\n\t#endif\n\n\tif( sdfContext.d < MAX_DIST ){\n\t\tgl_FragColor = applyShading(rayOrigin, rayDir, sdfContext);\n\t\t#if defined( TONE_MAPPING )\n\t\t\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n\t\t#endif\n\t\tgl_FragColor = linearToOutputTexel( gl_FragColor );\n\n\t\t#ifdef USE_FOG\n\t\t\tfloat vFogDepth = sdfContext.d;\n\t\t\t#ifdef FOG_EXP2\n\t\t\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );\n\t\t\t#else\n\t\t\t\tfloat fogFactor = smoothstep( fogNear, fogFar, vFogDepth );\n\t\t\t#endif\n\t\t\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n\t\t#endif\n\t\t#include <premultiplied_alpha_fragment>\n\t\t#include <dithering_fragment>\n\t} else {\n\t\tgl_FragColor = vec4(0.);\n\t}\n\n\t#if defined( DEBUG_STEPS_COUNT )\n\t\tfloat normalizedStepsCount = (float(sdfContext.stepsCount) - debugMinSteps ) / ( debugMaxSteps - debugMinSteps );\n\t\tgl_FragColor = vec4(normalizedStepsCount, 1.-normalizedStepsCount, 0., 1.);\n\t\treturn;\n\t#endif\n\t\n}","lights":false,"clipping":false},"onBeforeCompileDataJSONWithoutShaders":{"paramConfigs":[],"timeDependent":false,"resolutionDependent":false,"raymarchingLightsWorldCoordsDependent":true}}}}}}}},"params":{"CADLinearTolerance":{"overriden_options":{"callback":"{}"}},"CADAngularTolerance":{"overriden_options":{"callback":"{}"}},"CADCurveAbscissa":{"overriden_options":{"callback":"{}"}},"CADCurveTolerance":{"overriden_options":{"callback":"{}"}},"CADDisplayEdges":{"overriden_options":{"callback":"{}"}},"CADEdgesColor":{"overriden_options":{"callback":"{}"}},"CADDisplayMeshes":{"overriden_options":{"callback":"{}"}},"CADMeshesColor":{"overriden_options":{"callback":"{}"}},"CADWireframe":{"overriden_options":{"callback":"{}"}},"CSGFacetAngle":{"overriden_options":{"callback":"{}"}},"CSGLinesColor":{"overriden_options":{"callback":"{}"}},"CSGMeshesColor":{"overriden_options":{"callback":"{}"}},"CSGWireframe":{"overriden_options":{"callback":"{}"}},"QUADTriangles":{"overriden_options":{"callback":"{}"}},"QUADWireframe":{"overriden_options":{"callback":"{}"}},"TetScale":{"overriden_options":{"callback":"{}"}},"TetDisplayLines":{"overriden_options":{"callback":"{}"}},"TetDisplaySharedFaces":{"overriden_options":{"callback":"{}"}},"TetDisplayPoints":{"overriden_options":{"callback":"{}"}},"TetDisplayCenter":{"overriden_options":{"callback":"{}"}},"TetDisplaySphere":{"overriden_options":{"callback":"{}"}}},"flags":{"display":true}},"COP":{"type":"copNetwork","nodes":{"envMap":{"type":"envMap","inputs":["imageEnv"]},"imageEnv":{"type":"imageEXR","params":{"tminFilter":true,"tmagFilter":true,"tanisotropy":true,"useRendererMaxAnisotropy":true}},"image1":{"type":"image"}}},"lights":{"type":"geo","nodes":{"hemisphereLight1":{"type":"hemisphereLight","params":{"intensity":0.52}},"spotLight1":{"type":"spotLight","params":{"decay":0.1,"distance":10,"castShadow":1}},"polarTransform1":{"type":"polarTransform","params":{"center":[0,0.7,0],"latitude":25.2,"depth":3},"inputs":["spotLight1"]},"merge1":{"type":"merge","inputs":["hemisphereLight1","polarTransform1"],"flags":{"display":true}}},"params":{"CADLinearTolerance":{"overriden_options":{"callback":"{}"}},"CADAngularTolerance":{"overriden_options":{"callback":"{}"}},"CADCurveAbscissa":{"overriden_options":{"callback":"{}"}},"CADCurveTolerance":{"overriden_options":{"callback":"{}"}},"CADDisplayEdges":{"overriden_options":{"callback":"{}"}},"CADEdgesColor":{"overriden_options":{"callback":"{}"}},"CADDisplayMeshes":{"overriden_options":{"callback":"{}"}},"CADMeshesColor":{"overriden_options":{"callback":"{}"}},"CADWireframe":{"overriden_options":{"callback":"{}"}},"CSGFacetAngle":{"overriden_options":{"callback":"{}"}},"CSGLinesColor":{"overriden_options":{"callback":"{}"}},"CSGMeshesColor":{"overriden_options":{"callback":"{}"}},"CSGWireframe":{"overriden_options":{"callback":"{}"}},"QUADTriangles":{"overriden_options":{"callback":"{}"}},"QUADWireframe":{"overriden_options":{"callback":"{}"}},"TetScale":{"overriden_options":{"callback":"{}"}},"TetDisplayLines":{"overriden_options":{"callback":"{}"}},"TetDisplaySharedFaces":{"overriden_options":{"callback":"{}"}},"TetDisplayPoints":{"overriden_options":{"callback":"{}"}},"TetDisplayCenter":{"overriden_options":{"callback":"{}"}},"TetDisplaySphere":{"overriden_options":{"callback":"{}"}}},"flags":{"display":true}},"cameras":{"type":"geo","nodes":{"perspectiveCamera1":{"type":"perspectiveCamera","params":{"position":[3.3,3.3,3.3]}},"cameraControls1":{"type":"cameraControls","nodes":{"cameraOrbitControls1":{"type":"cameraOrbitControls","params":{"target":[0.09340836732398616,0.09450322255654031,-0.15671710041291376]}}},"params":{"node":"cameraOrbitControls1"},"inputs":["perspectiveCamera1"],"flags":{"display":true}}},"params":{"CADLinearTolerance":{"overriden_options":{"callback":"{}"}},"CADAngularTolerance":{"overriden_options":{"callback":"{}"}},"CADCurveAbscissa":{"overriden_options":{"callback":"{}"}},"CADCurveTolerance":{"overriden_options":{"callback":"{}"}},"CADDisplayEdges":{"overriden_options":{"callback":"{}"}},"CADEdgesColor":{"overriden_options":{"callback":"{}"}},"CADDisplayMeshes":{"overriden_options":{"callback":"{}"}},"CADMeshesColor":{"overriden_options":{"callback":"{}"}},"CADWireframe":{"overriden_options":{"callback":"{}"}},"CSGFacetAngle":{"overriden_options":{"callback":"{}"}},"CSGLinesColor":{"overriden_options":{"callback":"{}"}},"CSGMeshesColor":{"overriden_options":{"callback":"{}"}},"CSGWireframe":{"overriden_options":{"callback":"{}"}},"QUADTriangles":{"overriden_options":{"callback":"{}"}},"QUADWireframe":{"overriden_options":{"callback":"{}"}},"TetScale":{"overriden_options":{"callback":"{}"}},"TetDisplayLines":{"overriden_options":{"callback":"{}"}},"TetDisplaySharedFaces":{"overriden_options":{"callback":"{}"}},"TetDisplayPoints":{"overriden_options":{"callback":"{}"}},"TetDisplayCenter":{"overriden_options":{"callback":"{}"}},"TetDisplaySphere":{"overriden_options":{"callback":"{}"}}},"flags":{"display":true}}},"params":{"mainCameraPath":"/cameras/cameras:sopGroup/perspectiveCamera1"}},"ui":{"nodes":{"geo1":{"pos":[-50,-350],"selection":["MAT"],"nodes":{"box1":{"pos":[-100,100]},"material1":{"pos":[-100,250]},"MAT":{"pos":[-300,250],"selection":["rayMarchingBuilder1"],"nodes":{"rayMarchingBuilder1":{"pos":[-50,0],"nodes":{"globals1":{"pos":[-1300,-100]},"output1":{"pos":[300,0]},"SDFContext1":{"pos":[100,0]},"SDFMaterial1":{"pos":[-400,400]},"SDFSphere1":{"pos":[-700,-200]},"SDFSphere2":{"pos":[-700,0]},"SDFUnion1":{"pos":[-500,-100]},"floatToVec3_1":{"pos":[-900,0]},"cos1":{"pos":[-1100,0]},"constant1":{"pos":[-600,400]},"SDFSphere3":{"pos":[-400,-350]},"SDFSphere4":{"pos":[-450,50]},"SDFUnion2":{"pos":[-250,-150]},"SDFPlane1":{"pos":[-250,150]},"SDFUnion3":{"pos":[-100,0]},"grid1":{"pos":[-650,550]},"checkers1":{"pos":[-800,800]},"mix1":{"pos":[-600,650]},"constant2":{"pos":[-850,500]},"constant3":{"pos":[-850,650]},"globals2":{"pos":[-1150,800]},"vec3ToFloat1":{"pos":[-1050,800]},"floatToVec2_1":{"pos":[-950,800]}}}}}}},"COP":{"pos":[-300,-50],"selection":["image1"],"nodes":{"envMap":{"pos":[50,250]},"imageEnv":{"pos":[50,100]},"image1":{"pos":[-200,100]}}},"lights":{"pos":[-50,-250],"selection":["hemisphereLight1"],"nodes":{"hemisphereLight1":{"pos":[50,-50]},"spotLight1":{"pos":[300,-50]},"polarTransform1":{"pos":[300,150]},"merge1":{"pos":[100,300]}}},"cameras":{"pos":[-50,-150],"nodes":{"perspectiveCamera1":{"pos":[0,-50]},"cameraControls1":{"pos":[0,150],"nodes":{"cameraOrbitControls1":{"pos":[0,0]}}}}}}},"shaders":{"/geo1/MAT/rayMarchingBuilder1":{"vertex":"precision highp float;\nprecision highp int;\n\nvarying vec3 vPw;\nvarying mat4 vModelMatrix;\nvarying mat4 vInverseModelMatrix;\nvarying mat4 VViewMatrix;\n\n#include <common>\n\n// // for depth material\n// varying vec2 vHighPrecisionZW;\n\nvoid main()\t{\n\n\tvModelMatrix = modelMatrix;\n\tvInverseModelMatrix = inverse(modelMatrix);\n\tVViewMatrix = viewMatrix;\n\tvPw = (modelMatrix * vec4( position, 1.0 )).xyz;\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n\t// vHighPrecisionZW = gl_Position.zw;\n}","fragment":"precision highp float;\nprecision highp int;\n\n// --- applyMaterial constants definition\nuniform int MAX_STEPS;\nuniform float MAX_DIST;\nuniform float SURF_DIST;\nuniform float NORMALS_BIAS;\nuniform float SHADOW_BIAS;\n#define ZERO 0\nuniform float debugMinSteps;\nuniform float debugMaxSteps;\nuniform float debugMinDepth;\nuniform float debugMaxDepth;\n\n#include <common>\n#include <packing>\n#include <lightmap_pars_fragment>\n#include <bsdfs>\n#include <cube_uv_reflection_fragment>\n#include <lights_pars_begin>\n#include <lights_physical_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <fog_pars_fragment>\n\n#if defined( SHADOW_DISTANCE )\n\tuniform float shadowDistanceMin;\n\tuniform float shadowDistanceMax;\n#endif \n#if defined( SHADOW_DEPTH )\n\tuniform float shadowDepthMin;\n\tuniform float shadowDepthMax;\n#endif\n\n// varying vec2 vHighPrecisionZW;\n\nvarying vec3 vPw;\nvarying mat4 vModelMatrix;\nvarying mat4 vInverseModelMatrix;\nvarying mat4 VViewMatrix;\n\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform SpotLightRayMarching spotLightsRayMarching[ NUM_SPOT_LIGHTS ];\n\t#if NUM_SPOT_LIGHT_COORDS > 0\n\n\t\tuniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];\n\n\t#endif\n#endif\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform DirectionalLightRayMarching directionalLightsRayMarching[ NUM_DIR_LIGHTS ];\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\n\t#endif\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform PointLightRayMarching pointLightsRayMarching[ NUM_POINT_LIGHTS ];\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\n\t#endif\n#endif\n\n\nstruct SDFContext {\n\tfloat d;\n\tint stepsCount;\n\tint matId;\n\tint matId2;\n\tfloat matBlend;\n};\n\nSDFContext DefaultSDFContext(){\n\treturn SDFContext( 0., 0, 0, 0, 0. );\n}\nint DefaultSDFMaterial(){\n\treturn 0;\n}\n\n// start raymarching builder define code\n\n\n\n// /geo1/MAT/rayMarchingBuilder1/SDFSphere3\nfloat dot2( in vec2 v ) { return dot(v,v); }\nfloat dot2( in vec3 v ) { return dot(v,v); }\nfloat ndot( in vec2 a, in vec2 b ) { return a.x*b.x - a.y*b.y; }\n// https://iquilezles.org/articles/distfunctions/\n\n\n/*\n*\n* SDF PRIMITIVES\n*\n*/\nfloat sdSphere( vec3 p, float s )\n{\n\treturn length(p)-s;\n}\nfloat sdCutSphere( vec3 p, float r, float h )\n{\n\t// sampling independent computations (only depend on shape)\n\tfloat w = sqrt(r*r-h*h);\n\n\t// sampling dependant computations\n\tvec2 q = vec2( length(p.xz), p.y );\n\tfloat s = max( (h-r)*q.x*q.x+w*w*(h+r-2.0*q.y), h*q.x-w*q.y );\n\treturn (s<0.0) ? length(q)-r :\n\t\t\t\t(q.x<w) ? h - q.y :\n\t\t\t\t\tlength(q-vec2(w,h));\n}\nfloat sdCutHollowSphere( vec3 p, float r, float h, float t )\n{\n\t// sampling independent computations (only depend on shape)\n\tfloat w = sqrt(r*r-h*h);\n\t\n\t// sampling dependant computations\n\tvec2 q = vec2( length(p.xz), p.y );\n\treturn ((h*q.x<w*q.y) ? length(q-vec2(w,h)) : \n\t\t\t\t\t\t\tabs(length(q)-r) ) - t;\n}\n\nfloat sdBox( vec3 p, vec3 b )\n{\n\tvec3 q = abs(p) - b*0.5;\n\treturn length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0);\n}\nfloat sdRoundBox( vec3 p, vec3 b, float r )\n{\n\tvec3 q = abs(p) - b*0.5;\n\treturn length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0) - r;\n}\n\n\nfloat sdBoxFrame( vec3 p, vec3 b, float e )\n{\n\t\tp = abs(p )-b*0.5;\n\tvec3 q = abs(p+e)-e;\n\treturn min(min(\n\t\tlength(max(vec3(p.x,q.y,q.z),0.0))+min(max(p.x,max(q.y,q.z)),0.0),\n\t\tlength(max(vec3(q.x,p.y,q.z),0.0))+min(max(q.x,max(p.y,q.z)),0.0)),\n\t\tlength(max(vec3(q.x,q.y,p.z),0.0))+min(max(q.x,max(q.y,p.z)),0.0));\n}\nfloat sdCapsule( vec3 p, vec3 a, vec3 b, float r )\n{\n\tvec3 pa = p - a, ba = b - a;\n\tfloat h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n\treturn length( pa - ba*h ) - r;\n}\nfloat sdVerticalCapsule( vec3 p, float h, float r )\n{\n\tp.y -= clamp( p.y, 0.0, h );\n\treturn length( p ) - r;\n}\nfloat sdCone( in vec3 p, in vec2 c, float h )\n{\n\t// c is the sin/cos of the angle, h is height\n\t// Alternatively pass q instead of (c,h),\n\t// which is the point at the base in 2D\n\tvec2 q = h*vec2(c.x/c.y,-1.0);\n\n\tvec2 w = vec2( length(p.xz), p.y );\n\tvec2 a = w - q*clamp( dot(w,q)/dot(q,q), 0.0, 1.0 );\n\tvec2 b = w - q*vec2( clamp( w.x/q.x, 0.0, 1.0 ), 1.0 );\n\tfloat k = sign( q.y );\n\tfloat d = min(dot( a, a ),dot(b, b));\n\tfloat s = max( k*(w.x*q.y-w.y*q.x),k*(w.y-q.y) );\n\treturn sqrt(d)*sign(s);\n}\nfloat sdConeWrapped(vec3 pos, float angle, float height){\n\treturn sdCone(pos, vec2(sin(angle), cos(angle)), height);\n}\nfloat sdRoundCone( vec3 p, float r1, float r2, float h )\n{\n\tfloat b = (r1-r2)/h;\n\tfloat a = sqrt(1.0-b*b);\n\n\tvec2 q = vec2( length(p.xz), p.y );\n\tfloat k = dot(q,vec2(-b,a));\n\tif( k<0.0 ) return length(q) - r1;\n\tif( k>a*h ) return length(q-vec2(0.0,h)) - r2;\n\treturn dot(q, vec2(a,b) ) - r1;\n}\nfloat sdOctogonPrism( in vec3 p, in float r, float h )\n{\n\tconst vec3 k = vec3(-0.9238795325, // sqrt(2+sqrt(2))/2 \n\t\t\t\t\t\t0.3826834323, // sqrt(2-sqrt(2))/2\n\t\t\t\t\t\t0.4142135623 ); // sqrt(2)-1 \n\t// reflections\n\tp = abs(p);\n\tp.xy -= 2.0*min(dot(vec2( k.x,k.y),p.xy),0.0)*vec2( k.x,k.y);\n\tp.xy -= 2.0*min(dot(vec2(-k.x,k.y),p.xy),0.0)*vec2(-k.x,k.y);\n\t// polygon side\n\tp.xy -= vec2(clamp(p.x, -k.z*r, k.z*r), r);\n\tvec2 d = vec2( length(p.xy)*sign(p.y), p.z-h );\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdHexPrism( vec3 p, vec2 h )\n{\n\tconst vec3 k = vec3(-0.8660254, 0.5, 0.57735);\n\tp = abs(p);\n\tp.xy -= 2.0*min(dot(k.xy, p.xy), 0.0)*k.xy;\n\tvec2 d = vec2(\n\t\tlength(p.xy-vec2(clamp(p.x,-k.z*h.x,k.z*h.x), h.x))*sign(p.y-h.x),\n\t\tp.z-h.y );\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdHorseshoe( in vec3 p, in float angle, in float r, in float le, vec2 w )\n{\n\tvec2 c = vec2(cos(angle),sin(angle));\n\tp.x = abs(p.x);\n\tfloat l = length(p.xy);\n\tp.xy = mat2(-c.x, c.y, \n\t\t\tc.y, c.x)*p.xy;\n\tp.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x),\n\t\t\t\t(p.x>0.0)?p.y:l );\n\tp.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0);\n\t\n\tvec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z);\n\tvec2 d = abs(q) - w;\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdTriPrism( vec3 p, vec2 h )\n{\n\tvec3 q = abs(p);\n\treturn max(q.z-h.y,max(q.x*0.866025+p.y*0.5,-p.y)-h.x*0.5);\n}\nfloat sdPyramid( vec3 p, float h)\n{\n\tfloat m2 = h*h + 0.25;\n\n\tp.xz = abs(p.xz);\n\tp.xz = (p.z>p.x) ? p.zx : p.xz;\n\tp.xz -= 0.5;\n\n\tvec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y);\n\n\tfloat s = max(-q.x,0.0);\n\tfloat t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 );\n\n\tfloat a = m2*(q.x+s)*(q.x+s) + q.y*q.y;\n\tfloat b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t);\n\n\tfloat d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b);\n\n\treturn sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));\n}\n\nfloat sdPlane( vec3 p, vec3 n, float h )\n{\n\t// n must be normalized\n\treturn dot(p,n) + h;\n}\n\nfloat sdTorus( vec3 p, vec2 t )\n{\n\tvec2 q = vec2(length(p.xz)-t.x,p.y);\n\treturn length(q)-t.y;\n}\nfloat sdCappedTorus(in vec3 p, in float an, in float ra, in float rb)\n{\n\tvec2 sc = vec2(sin(an),cos(an));\n\tp.x = abs(p.x);\n\tfloat k = (sc.y*p.x>sc.x*p.z) ? dot(p.xz,sc) : length(p.xz);\n\treturn sqrt( dot(p,p) + ra*ra - 2.0*ra*k ) - rb;\n}\nfloat sdLink( vec3 p, float le, float r1, float r2 )\n{\n vec3 q = vec3( p.x, max(abs(p.y)-le,0.0), p.z );\n return length(vec2(length(q.xy)-r1,q.z)) - r2;\n}\n// c is the sin/cos of the desired cone angle\nfloat sdSolidAngle(vec3 pos, vec2 c, float radius)\n{\n\tvec2 p = vec2( length(pos.xz), pos.y );\n\tfloat l = length(p) - radius;\n\tfloat m = length(p - c*clamp(dot(p,c),0.0,radius) );\n\treturn max(l,m*sign(c.y*p.x-c.x*p.y));\n}\nfloat sdSolidAngleWrapped(vec3 pos, float angle, float radius){\n\treturn sdSolidAngle(pos, vec2(sin(angle), cos(angle)), radius);\n}\nfloat sdTube( vec3 p, float r )\n{\n\treturn length(p.xz)-r;\n}\nfloat sdTubeCapped( vec3 p, float h, float r )\n{\n\tvec2 d = abs(vec2(length(p.xz),p.y)) - vec2(r,h);\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdOctahedron( vec3 p, float s)\n{\n p = abs(p);\n float m = p.x+p.y+p.z-s;\n vec3 q;\n if( 3.0*p.x < m ) q = p.xyz;\n else if( 3.0*p.y < m ) q = p.yzx;\n else if( 3.0*p.z < m ) q = p.zxy;\n else return m*0.57735027;\n \n float k = clamp(0.5*(q.z-q.y+s),0.0,s); \n return length(vec3(q.x,q.y-s+k,q.z-k)); \n}\nfloat udTriangle( vec3 p, vec3 a, vec3 b, vec3 c, float thickness )\n{\n\tvec3 ba = b - a; vec3 pa = p - a;\n\tvec3 cb = c - b; vec3 pb = p - b;\n\tvec3 ac = a - c; vec3 pc = p - c;\n\tvec3 nor = cross( ba, ac );\n\n\treturn - thickness + sqrt(\n\t\t(sign(dot(cross(ba,nor),pa)) +\n\t\tsign(dot(cross(cb,nor),pb)) +\n\t\tsign(dot(cross(ac,nor),pc))<2.0)\n\t\t?\n\t\tmin( min(\n\t\tdot2(ba*clamp(dot(ba,pa)/dot2(ba),0.0,1.0)-pa),\n\t\tdot2(cb*clamp(dot(cb,pb)/dot2(cb),0.0,1.0)-pb) ),\n\t\tdot2(ac*clamp(dot(ac,pc)/dot2(ac),0.0,1.0)-pc) )\n\t\t:\n\t\tdot(nor,pa)*dot(nor,pa)/dot2(nor) );\n}\nfloat udQuad( vec3 p, vec3 a, vec3 b, vec3 c, vec3 d, float thickness )\n{\n\tvec3 ba = b - a; vec3 pa = p - a;\n\tvec3 cb = c - b; vec3 pb = p - b;\n\tvec3 dc = d - c; vec3 pc = p - c;\n\tvec3 ad = a - d; vec3 pd = p - d;\n\tvec3 nor = cross( ba, ad );\n\n\treturn - thickness + sqrt(\n\t\t(sign(dot(cross(ba,nor),pa)) +\n\t\tsign(dot(cross(cb,nor),pb)) +\n\t\tsign(dot(cross(dc,nor),pc)) +\n\t\tsign(dot(cross(ad,nor),pd))<3.0)\n\t\t?\n\t\tmin( min( min(\n\t\tdot2(ba*clamp(dot(ba,pa)/dot2(ba),0.0,1.0)-pa),\n\t\tdot2(cb*clamp(dot(cb,pb)/dot2(cb),0.0,1.0)-pb) ),\n\t\tdot2(dc*clamp(dot(dc,pc)/dot2(dc),0.0,1.0)-pc) ),\n\t\tdot2(ad*clamp(dot(ad,pd)/dot2(ad),0.0,1.0)-pd) )\n\t\t:\n\t\tdot(nor,pa)*dot(nor,pa)/dot2(nor) );\n}\n\n/*\n*\n* SDF OPERATIONS\n*\n*/\nfloat SDFUnion( float d1, float d2 ) { return min(d1,d2); }\nfloat SDFSubtract( float d1, float d2 ) { return max(-d1,d2); }\nfloat SDFIntersect( float d1, float d2 ) { return max(d1,d2); }\n\nfloat SDFSmoothUnion( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 + 0.5*(d2-d1)/k, 0.0, 1.0 );\n\treturn mix( d2, d1, h ) - k*h*(1.0-h);\n}\n\nfloat SDFSmoothSubtract( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 - 0.5*(d2+d1)/k, 0.0, 1.0 );\n\treturn mix( d2, -d1, h ) + k*h*(1.0-h);\n}\n\nfloat SDFSmoothIntersect( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 - 0.5*(d2-d1)/k, 0.0, 1.0 );\n\treturn mix( d2, d1, h ) + k*h*(1.0-h);\n}\n\nvec4 SDFElongateFast( in vec3 p, in vec3 h )\n{\n\treturn vec4( p-clamp(p,-h,h), 0.0 );\n}\nvec4 SDFElongateSlow( in vec3 p, in vec3 h )\n{\n\tvec3 q = abs(p)-h;\n\treturn vec4( max(q,0.0), min(max(q.x,max(q.y,q.z)),0.0) );\n}\n\nfloat SDFOnion( in float sdf, in float thickness )\n{\n\treturn abs(sdf)-thickness;\n}\n\n// /geo1/MAT/rayMarchingBuilder1/checkers1\n// https://iquilezles.org/articles/checkerfiltering/\nfloat checkers(vec2 p) {\n\tvec2 s = sign(fract(p*.5)-.5);\n\treturn .5 - .5*s.x*s.y;\n}\nfloat checkersGrad( in vec2 p, in vec2 ddx, in vec2 ddy )\n{\n // filter kernel\n vec2 w = max(abs(ddx), abs(ddy)) + 0.01;\n // analytical integral (box filter)\n vec2 i = 2.0*(abs(fract((p-0.5*w)/2.0)-0.5)-abs(fract((p+0.5*w)/2.0)-0.5))/w;\n // xor pattern\n return 0.5 - 0.5*i.x*i.y;\n}\n\n\n// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\nconst int _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1 = 1;\n\n\n// https://stackoverflow.com/questions/23793698/how-to-implement-slerp-in-glsl-hlsl\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t)\n// {\n// \tfloat dotp = dot(normalize(p0), normalize(p1));\n// \tif ((dotp > 0.9999) || (dotp < -0.9999))\n// \t{\n// \t\tif (t<=0.5)\n// \t\t\treturn p0;\n// \t\treturn p1;\n// \t}\n// \tfloat theta = acos(dotp);\n// \tvec4 P = ((p0*sin((1.0-t)*theta) + p1*sin(t*theta)) / sin(theta));\n// \tP.w = 1.0;\n// \treturn P;\n// }\n\n// https://devcry.heiho.net/html/2017/20170521-slerp.html\n// float lerp(float a, float b, float t) {\n// \treturn (1.0 - t) * a + t * b;\n// }\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t){\n// \tvec4 qb = p1;\n\n// \t// cos(a) = dot product\n// \tfloat cos_a = p0.x * qb.x + p0.y * qb.y + p0.z * qb.z + p0.w * qb.w;\n// \tif (cos_a < 0.0f) {\n// \t\tcos_a = -cos_a;\n// \t\tqb = -qb;\n// \t}\n\n// \t// close to zero, cos(a) ~= 1\n// \t// do linear interpolation\n// \tif (cos_a > 0.999) {\n// \t\treturn vec4(\n// \t\t\tlerp(p0.x, qb.x, t),\n// \t\t\tlerp(p0.y, qb.y, t),\n// \t\t\tlerp(p0.z, qb.z, t),\n// \t\t\tlerp(p0.w, qb.w, t)\n// \t\t);\n// \t}\n\n// \tfloat alpha = acos(cos_a);\n// \treturn (p0 * sin(1.0 - t) + p1 * sin(t * alpha)) / sin(alpha);\n// }\n\n// https://stackoverflow.com/questions/62943083/interpolate-between-two-quaternions-the-long-way\nvec4 quatSlerp(vec4 q1, vec4 q2, float t){\n\tfloat angle = acos(dot(q1, q2));\n\tfloat denom = sin(angle);\n\t//check if denom is zero\n\treturn (q1*sin((1.0-t)*angle)+q2*sin(t*angle))/denom;\n}\n// TO CHECK:\n// this page https://www.reddit.com/r/opengl/comments/704la7/glsl_quaternion_library/\n// has a link to a potentially nice pdf:\n// http://web.mit.edu/2.998/www/QuaternionReport1.pdf\n\n// https://github.com/mattatz/ShibuyaCrowd/blob/master/source/shaders/common/quaternion.glsl\nvec4 quatMult(vec4 q1, vec4 q2)\n{\n\treturn vec4(\n\tq1.w * q2.x + q1.x * q2.w + q1.z * q2.y - q1.y * q2.z,\n\tq1.w * q2.y + q1.y * q2.w + q1.x * q2.z - q1.z * q2.x,\n\tq1.w * q2.z + q1.z * q2.w + q1.y * q2.x - q1.x * q2.y,\n\tq1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z\n\t);\n}\n// http://glmatrix.net/docs/quat.js.html#line97\n// let ax = a[0], ay = a[1], az = a[2], aw = a[3];\n\n// let bx = b[0], by = b[1], bz = b[2], bw = b[3];\n\n// out[0] = ax * bw + aw * bx + ay * bz - az * by;\n\n// out[1] = ay * bw + aw * by + az * bx - ax * bz;\n\n// out[2] = az * bw + aw * bz + ax * by - ay * bx;\n\n// out[3] = aw * bw - ax * bx - ay * by - az * bz;\n\n// return out\n\n\n\n// http://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/\nmat4 rotationMatrix(vec3 axis, float angle)\n{\n\taxis = normalize(axis);\n\tfloat s = sin(angle);\n\tfloat c = cos(angle);\n\tfloat oc = 1.0 - c;\n\n \treturn mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 0.0, 0.0, 0.0, 1.0);\n}\n\n// https://www.geeks3d.com/20141201/how-to-rotate-a-vertex-by-a-quaternion-in-glsl/\nvec4 quatFromAxisAngle(vec3 axis, float angle)\n{\n\tvec4 qr;\n\tfloat half_angle = (angle * 0.5); // * 3.14159 / 180.0;\n\tfloat sin_half_angle = sin(half_angle);\n\tqr.x = axis.x * sin_half_angle;\n\tqr.y = axis.y * sin_half_angle;\n\tqr.z = axis.z * sin_half_angle;\n\tqr.w = cos(half_angle);\n\treturn qr;\n}\nvec3 rotateWithAxisAngle(vec3 position, vec3 axis, float angle)\n{\n\tvec4 q = quatFromAxisAngle(axis, angle);\n\tvec3 v = position.xyz;\n\treturn v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);\n}\n// vec3 applyQuaternionToVector( vec4 q, vec3 v ){\n// \treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n// }\nvec3 rotateWithQuat( vec3 v, vec4 q )\n{\n\t// vec4 qv = multQuat( quat, vec4(vec, 0.0) );\n\t// return multQuat( qv, vec4(-quat.x, -quat.y, -quat.z, quat.w) ).xyz;\n\treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n}\n// https://github.com/glslify/glsl-look-at/blob/gh-pages/index.glsl\n// mat3 rotation_matrix(vec3 origin, vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target - origin);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n// mat3 rotation_matrix(vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n\nfloat vectorAngle(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 c1 = cross(start, dest);\n\t// We use the dot product of the cross with the Y axis.\n\t// This is a little arbitrary, but can still give a good sense of direction\n\tvec3 y_axis = vec3(0.0, 1.0, 0.0);\n\tfloat d1 = dot(c1, y_axis);\n\tfloat angle = acos(cosTheta) * sign(d1);\n\treturn angle;\n}\n\n// http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/#i-need-an-equivalent-of-glulookat-how-do-i-orient-an-object-towards-a-point-\nvec4 vectorAlign(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 axis;\n\n\t// if (cosTheta < -1 + 0.001f){\n\t// \t// special case when vectors in opposite directions:\n\t// \t// there is no ideal rotation axis\n\t// \t// So guess one; any will do as long as it's perpendicular to start\n\t// \taxis = cross(vec3(0.0f, 0.0f, 1.0f), start);\n\t// \tif (length2(axis) < 0.01 ) // bad luck, they were parallel, try again!\n\t// \t\taxis = cross(vec3(1.0f, 0.0f, 0.0f), start);\n\n\t// \taxis = normalize(axis);\n\t// \treturn gtx::quaternion::angleAxis(glm::radians(180.0f), axis);\n\t// }\n\tif(cosTheta > (1.0 - 0.0001) || cosTheta < (-1.0 + 0.0001) ){\n\t\taxis = normalize(cross(start, vec3(0.0, 1.0, 0.0)));\n\t\tif (length(axis) < 0.001 ){ // bad luck, they were parallel, try again!\n\t\t\taxis = normalize(cross(start, vec3(1.0, 0.0, 0.0)));\n\t\t}\n\t} else {\n\t\taxis = normalize(cross(start, dest));\n\t}\n\n\tfloat angle = acos(cosTheta);\n\n\treturn quatFromAxisAngle(axis, angle);\n}\nvec4 vectorAlignWithUp(vec3 start, vec3 dest, vec3 up){\n\tvec4 rot1 = vectorAlign(start, dest);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\t// vec3 right = normalize(cross(dest, up));\n\t// up = normalize(cross(right, dest));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(vec3(0.0, 1.0, 0.0), rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(up, newUp);\n\n\t// return rot1;\n\treturn rot2;\n\t// return multQuat(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\n// https://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\nfloat quatToAngle(vec4 q){\n\treturn 2.0 * acos(q.w);\n}\nvec3 quatToAxis(vec4 q){\n\treturn vec3(\n\t\tq.x / sqrt(1.0-q.w*q.w),\n\t\tq.y / sqrt(1.0-q.w*q.w),\n\t\tq.z / sqrt(1.0-q.w*q.w)\n\t);\n}\n\nvec4 align(vec3 dir, vec3 up){\n\tvec3 start_dir = vec3(0.0, 0.0, 1.0);\n\tvec3 start_up = vec3(0.0, 1.0, 0.0);\n\tvec4 rot1 = vectorAlign(start_dir, dir);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\tvec3 right = normalize(cross(dir, up));\n\tif(length(right)<0.001){\n\t\tright = vec3(1.0, 0.0, 0.0);\n\t}\n\tup = normalize(cross(right, dir));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(start_up, rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(normalize(newUp), up);\n\n\t// return rot1;\n\treturn quatMult(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\nstruct EnvMapProps {\n\tvec3 tint;\n\tfloat intensity;\n\tfloat roughness;\n\tfloat fresnel;\n\tfloat fresnelPower;\n};\nuniform sampler2D envMap;\nuniform float envMapIntensity;\nuniform float roughness;\n#ifdef ROTATE_ENV_MAP_Y\n\tuniform float envMapRotationY;\n#endif\nvec3 envMapSample(vec3 rayDir, float envMapRoughness){\n\t// http://www.pocketgl.com/reflections/\n\tvec3 env = vec3(0.);\n\t// vec2 uv = vec2( atan( -rayDir.z, -rayDir.x ) * RECIPROCAL_PI2 + 0.5, rayDir.y * 0.5 + 0.5 );\n\t// vec3 env = texture2D(map, uv).rgb;\n\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t#ifdef ROTATE_ENV_MAP_Y\n\t\t\trayDir = rotateWithAxisAngle(rayDir, vec3(0.,1.,0.), envMapRotationY);\n\t\t#endif\n\t\tenv = textureCubeUV(envMap, rayDir, envMapRoughness * roughness).rgb;\n\t#endif\n\treturn env;\n}\nvec3 envMapSampleWithFresnel(vec3 rayDir, EnvMapProps envMapProps, vec3 n, vec3 cameraPosition){\n\t// http://www.pocketgl.com/reflections/\n\tvec3 env = envMapSample(rayDir, envMapProps.roughness);\n\tfloat fresnel = pow(1.-dot(normalize(cameraPosition), n), envMapProps.fresnelPower);\n\tfloat fresnelFactor = (1.-envMapProps.fresnel) + envMapProps.fresnel*fresnel;\n\treturn env * envMapIntensity * envMapProps.tint * envMapProps.intensity * fresnelFactor;\n}\n\n\n\n\n\n\nSDFContext GetDist(vec3 p) {\n\tSDFContext sdfContext = SDFContext(0., 0, 0, 0, 0.);\n\n\t// start GetDist builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/SDFSphere3\n\tfloat v_POLY_SDFSphere3_float = sdSphere(p - vec3(-0.25, 0.0, 0.0), 0.2);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFSphere4\n\tfloat v_POLY_SDFSphere4_float = sdSphere(p - vec3(0.25, 0.0, 0.0), 0.2);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFPlane1\n\tfloat v_POLY_SDFPlane1_float = sdPlane(p-vec3(0.0, -0.2, 0.0), vec3(0.0, 1.0, 0.0), 0.0);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFUnion2\n\tfloat v_POLY_SDFUnion2_union = SDFSmoothUnion(v_POLY_SDFSphere3_float, v_POLY_SDFSphere4_float, 0.31);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFUnion3\n\tfloat v_POLY_SDFUnion3_union = SDFSmoothUnion(v_POLY_SDFUnion2_union, v_POLY_SDFPlane1_float, 0.31);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFContext1\n\tSDFContext v_POLY_SDFContext1_SDFContext = SDFContext(v_POLY_SDFUnion3_union, 0, _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1, _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1, 0.);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/output1\n\tsdfContext = v_POLY_SDFContext1_SDFContext;\n\n\n\n\t\n\n\treturn sdfContext;\n}\n\nSDFContext RayMarch(vec3 ro, vec3 rd, float side) {\n\tSDFContext dO = SDFContext(0.,0,0,0,0.);\n\n\t#pragma unroll_loop_start\n\tfor(int i=0; i<MAX_STEPS; i++) {\n\t\tvec3 p = ro + rd*dO.d;\n\t\tSDFContext sdfContext = GetDist(p);\n\t\tdO.d += sdfContext.d * side;\n\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\tdO.stepsCount += 1;\n\t\t#endif\n\t\tdO.matId = sdfContext.matId;\n\t\tdO.matId2 = sdfContext.matId2;\n\t\tdO.matBlend = sdfContext.matBlend;\n\t\tif(dO.d>MAX_DIST || abs(sdfContext.d)<SURF_DIST) break;\n\t}\n\t#pragma unroll_loop_end\n\n\treturn dO;\n}\n\nvec3 GetNormal(vec3 p) {\n\tSDFContext sdfContext = GetDist(p);\n\tvec2 e = vec2(NORMALS_BIAS, 0);\n\n\tvec3 n = sdfContext.d - vec3(\n\t\tGetDist(p-e.xyy).d,\n\t\tGetDist(p-e.yxy).d,\n\t\tGetDist(p-e.yyx).d);\n\n\treturn normalize(n);\n}\n// https://iquilezles.org/articles/rmshadows\nfloat calcSoftshadow( in vec3 ro, in vec3 rd, float mint, float maxt, float k, inout SDFContext sdfContext )\n{\n\tfloat res = 1.0;\n\tfloat ph = 1e20;\n\tfor( float t=mint; t<maxt; )\n\t{\n\t\tfloat h = GetDist(ro + rd*t).d;\n\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\tsdfContext.stepsCount += 1;\n\t\t#endif\n\t\tif( h<SURF_DIST )\n\t\t\treturn 0.0;\n\t\tfloat y = h*h/(2.0*ph);\n\t\tfloat d = sqrt(h*h-y*y);\n\t\tres = min( res, k*d/max(0.0,t-y) );\n\t\tph = h;\n\t\tt += h;\n\t}\n\treturn res;\n}\n\nvec3 GetLight(vec3 _p, vec3 _n, inout SDFContext sdfContext) {\n\tvec3 dif = vec3(0.,0.,0.);\n\t// GeometricContext geometry;\n\t// geometry.position = _p;\n\t// geometry.normal = _n;\n\t// geometry.viewDir = rayDir;\n\n\t// vec4 mvPosition = vec4( p, 1.0 );\n\t// mvPosition = modelViewMatrix * mvPosition;\n\t// vec3 vViewPosition = - mvPosition.xyz;\n\tvec3 pWorld = ( vModelMatrix * vec4( _p, 1.0 )).xyz;\n\tvec3 nWorld = transformDirection(_n, vModelMatrix);\n\t// geometry.position = (VViewMatrix * vec4( _p, 1.0 )).xyz;\n\tvec3 geometryPosition = (VViewMatrix * vec4(pWorld, 1.0 )).xyz;\n\t// geometry.normal = transformDirection(_n, VViewMatrix);\n\t// geometry.normal = inverseTransformDirection(transformDirection(_n, VViewMatrix), vInverseModelMatrix);\n\tvec3 geometryNormal = transformDirection(nWorld, VViewMatrix);\n\t\n\n\t#if NUM_SPOT_LIGHTS > 0 || NUM_DIR_LIGHTS > 0 || NUM_HEMI_LIGHTS > 0 || NUM_POINT_LIGHTS > 0 || NUM_RECT_AREA_LIGHTS > 0\n\n\t\tIncidentLight directLight;\n\t\tReflectedLight reflectedLight;\n\t\tvec3 lightPos, lightDir, worldLightDir, objectSpaceLightDir, lighDif, directDiffuse;\n\t\tfloat dotNL, lightDistance;\n\t\t#if NUM_SPOT_LIGHTS > 0\n\t\t\tSpotLightRayMarching spotLightRayMarching;\n\t\t\tSpotLight spotLight;\n\t\t\tfloat spotLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\t\t\t\tSpotLightShadow spotLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\t\t\tspotLightRayMarching = spotLightsRayMarching[ i ];\n\t\t\t\tspotLight = spotLights[ i ];\n\t\t\t\tgetSpotLightInfo( spotLight, geometryPosition, directLight );\n\n\t\t\t\t// #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t\t\t// \tspotLightShadow = spotLightShadows[ i ];\n\t\t\t\t// \tvec4 spotLightShadowCoord = spotLightMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t// \tdirectLight.color *= (directLight.visible && receiveShadow) ? getShadow(\n\t\t\t\t// \t\tspotShadowMap[ i ],\n\t\t\t\t// \t\tspotLightShadow.shadowMapSize,\n\t\t\t\t// \t\tspotLightShadow.shadowBias,\n\t\t\t\t// \t\tspotLightShadow.shadowRadius,\n\t\t\t\t// \t\tspotLightShadowCoord\n\t\t\t\t// \t) : 1.0;\n\t\t\t\t// #endif\n\n\t\t\t\tlightPos = spotLight.position;\n\t\t\t\tlightDir = normalize(lightPos-geometryPosition);\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tlightDistance = distance(geometryPosition,lightPos);\n\t\t\t\tspotLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < spotLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t: calcSoftshadow(\n\t\t\t\t\t\t_p,\n\t\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\t\tspotLightRayMarching.shadowBiasDistance,\n\t\t\t\t\t\tdistance(geometryPosition,lightPos),\n\t\t\t\t\t\t1./max(spotLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\t\tsdfContext\n\t\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * spotLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\t\t#if NUM_DIR_LIGHTS > 0\n\t\t\tDirectionalLightRayMarching directionalLightRayMarching;\n\t\t\tDirectionalLight directionalLight;\n\t\t\tfloat dirLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\t\t\t\tDirectionalLightShadow directionalLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\t\t\tdirectionalLightRayMarching = directionalLightsRayMarching[ i ];\n\t\t\t\tdirectionalLight = directionalLights[ i ];\n\t\t\t\t\n\t\t\t\tgetDirectionalLightInfo( directionalLight, directLight );\n\n\t\t\t\t// #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\t\t\t// \tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\t\t\t// \tvec4 dirLightShadowCoord = directionalShadowMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t// \tdirectLight.color *= (directLight.visible && receiveShadow) ? getShadow(\n\t\t\t\t// \t\tdirectionalShadowMap[ i ],\n\t\t\t\t// \t\tdirectionalLightShadow.shadowMapSize,\n\t\t\t\t// \t\tdirectionalLightShadow.shadowBias,\n\t\t\t\t// \t\tdirectionalLightShadow.shadowRadius,\n\t\t\t\t// \t\tdirLightShadowCoord\n\t\t\t\t// \t) : 1.0;\n\t\t\t\t// #endif\n\n\t\t\t\tlightDir = directionalLight.direction;\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tdirLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < directionalLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t:\n\t\t\t\t\tcalcSoftshadow(\n\t\t\t\t\t\t_p,\n\t\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\t\tdirectionalLightRayMarching.shadowBiasDistance,\n\t\t\t\t\t\tMAX_DIST,//distance(geometryPosition,lightPos),\n\t\t\t\t\t\t1./max(directionalLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\t\tsdfContext\n\t\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\t// lighDif = directLight.color * dotNL * dirLightSdfShadow;\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * dirLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\n\t\t#if ( NUM_HEMI_LIGHTS > 0 )\n\n\t\t\t#pragma unroll_loop_start\n\t\t\tHemisphereLight hemiLight;\n\t\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\t\themiLight = hemisphereLights[ i ];\n\t\t\t\tdif += getHemisphereLightIrradiance( hemiLight, geometryNormal ) * BRDF_Lambert( vec3(1.) );\n\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\n\t\t#endif\n\n\t\t#if NUM_POINT_LIGHTS > 0\n\t\t\tPointLightRayMarching pointLightRayMarching;\n\t\t\tPointLight pointLight;\n\t\t\tfloat pointLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\t\t\t\tPointLightShadow pointLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\t\t\tpointLightRayMarching = pointLightsRayMarching[ i ];\n\t\t\t\tpointLight = pointLights[ i ];\n\t\t\t\tgetPointLightInfo( pointLight, geometryPosition, directLight );\n\n\n\t\t\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\t\t\t\tpointLightShadow = pointLightShadows[ i ];\n\t\t\t\t\tvec4 pointLightShadowCoord = pointShadowMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t\tdirectLight.color *= (directLight.visible && receiveShadow) ? getPointShadow(\n\t\t\t\t\t\tpointShadowMap[ i ],\n\t\t\t\t\t\tpointLightShadow.shadowMapSize,\n\t\t\t\t\t\tpointLightShadow.shadowBias,\n\t\t\t\t\t\tpointLightShadow.shadowRadius,\n\t\t\t\t\t\tpointLightShadowCoord,\n\t\t\t\t\t\tpointLightShadow.shadowCameraNear,\n\t\t\t\t\t\tpointLightShadow.shadowCameraFar\n\t\t\t\t\t) : 1.0;\n\t\t\t\t#endif\n\n\t\t\t\tlightPos = pointLight.position;\n\t\t\t\tlightDir = normalize(lightPos-geometryPosition);\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tpointLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < pointLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t:\n\t\t\t\t\tcalcSoftshadow(\n\t\t\t\t\t_p,\n\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\tpointLightRayMarching.shadowBiasDistance,\n\t\t\t\t\tdistance(geometryPosition,lightPos),\n\t\t\t\t\t1./max(pointLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\tsdfContext\n\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * pointLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\n\t\t#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\n\t\t\tRectAreaLight rectAreaLight;\n\t\t\t// AreaLightRayMarching areaLightRayMarching;\n\t\t\tPhysicalMaterial material;\n\t\t\tmaterial.roughness = 1.;\n\t\t\tmaterial.specularColor = vec3(1.);\n\t\t\tmaterial.diffuseColor = vec3(1.);\n\n\t\t\tvec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( cameraPosition - geometryPosition );\n\t\t\tvec3 geometryClearcoatNormal = geometryNormal;\n\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\t\t\t// areaLightRayMarching = areaLightsRayMarching[ i ];\n\t\t\t\trectAreaLight = rectAreaLights[ i ];\n\t\t\t\t// rectAreaLight.position = areaLightRayMarching.worldPos;\n\n\t\t\t\tRE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t\tdif += reflectedLight.directDiffuse;\n\n\t\t#endif\n\t#endif\n\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\n\t#if defined( USE_LIGHT_PROBES )\n\n\t\tirradiance += getLightProbeIrradiance( lightProbe, geometryNormal );\n\n\t#endif\n\n\tdif += irradiance;\n\n\treturn dif;\n}\n\n\n\n\nvec3 applyMaterialWithoutRefraction(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(1.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n\nvec3 applyMaterialWithoutReflection(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(1.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n#ifdef RAYMARCHED_REFLECTIONS\nvec3 GetReflection(vec3 p, vec3 n, vec3 rayDir, float biasMult, float roughness, int reflectionDepth, inout SDFContext sdfContextMain){\n\tbool hitReflection = true;\n\tvec3 reflectedColor = vec3(0.);\n\t#pragma unroll_loop_start\n\tfor(int i=0; i < reflectionDepth; i++) {\n\t\tif(hitReflection){\n\t\t\trayDir = reflect(rayDir, n);\n\t\t\tp += n*SURF_DIST*biasMult;\n\t\t\tSDFContext sdfContext = RayMarch(p, rayDir, 1.);\n\t\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\t\tsdfContextMain.stepsCount += sdfContext.stepsCount;\n\t\t\t#endif\n\t\t\tif( sdfContext.d >= MAX_DIST){\n\t\t\t\thitReflection = false;\n\t\t\t\treflectedColor = envMapSample(rayDir, roughness);\n\t\t\t}\n\t\t\tif(hitReflection){\n\t\t\t\tp += rayDir * sdfContext.d;\n\t\t\t\tn = GetNormal(p);\n\t\t\t\tvec3 matCol = applyMaterialWithoutReflection(p, n, rayDir, sdfContext.matId, sdfContextMain);\n\t\t\t\treflectedColor += matCol;\n\t\t\t}\n\t\t}\n\t}\n\t#pragma unroll_loop_end\n\treturn reflectedColor;\n}\n#endif\n\n#ifdef RAYMARCHED_REFRACTIONS\n// xyz for color, w for distanceInsideMedium\nvec4 GetRefractedData(vec3 p, vec3 n, vec3 rayDir, float ior, float biasMult, float roughness, float refractionMaxDist, int refractionDepth, inout SDFContext sdfContextMain){\n\tbool hitRefraction = true;\n\tbool changeSide = true;\n\t#ifdef RAYMARCHED_REFRACTIONS_START_OUTSIDE_MEDIUM\n\tfloat side = -1.;\n\t#else\n\tfloat side = 1.;\n\t#endif\n\tfloat iorInverted = 1. / ior;\n\tvec3 refractedColor = vec3(0.);\n\tfloat distanceInsideMedium=0.;\n\tfloat totalRefractedDistance=0.;\n\n\t#pragma unroll_loop_start\n\tfor(int i=0; i < refractionDepth; i++) {\n\t\tif(hitRefraction){\n\t\t\tfloat currentIor = side<0. ? iorInverted : ior;\n\t\t\tvec3 rayDirPreRefract = rayDir;\n\t\t\trayDir = refract(rayDir, n, currentIor);\n\t\t\tchangeSide = dot(rayDir, rayDir)!=0.;\n\t\t\tif(changeSide == true) {\n\t\t\t\tp -= n*SURF_DIST*(2.+biasMult);\n\t\t\t} else {\n\t\t\t\tp += n*SURF_DIST*( biasMult);\n\t\t\t\trayDir = reflect(rayDirPreRefract, n);\n\t\t\t}\n\t\t\tSDFContext sdfContext = RayMarch(p, rayDir, side);\n\t\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\t\tsdfContextMain.stepsCount += sdfContext.stepsCount;\n\t\t\t#endif\n\t\t\ttotalRefractedDistance += sdfContext.d;\n\t\t\tif( abs(sdfContext.d) >= MAX_DIST || totalRefractedDistance > refractionMaxDist ){\n\t\t\t\thitRefraction = false;\n\t\t\t\trefractedColor = envMapSample(rayDir, roughness);\n\t\t\t}\n\t\t\tif(hitRefraction){\n\t\t\t\tp += rayDir * sdfContext.d;\n\t\t\t\tn = GetNormal(p) * side;\n\t\t\t\tvec3 matCol = applyMaterialWithoutRefraction(p, n, rayDir, sdfContext.matId, sdfContextMain);\n\t\t\t\trefractedColor = matCol;\n\n\t\t\t\t// same as: side < 0. ? abs(sdfContext.d) : 0.;\n\t\t\t\tdistanceInsideMedium += (side-1.)*-0.5*abs(sdfContext.d);\n\t\t\t\tif( changeSide ){\n\t\t\t\t\tside *= -1.;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#ifdef RAYMARCHED_REFRACTIONS_SAMPLE_ENV_MAP_ON_LAST\n\t\tif(i == refractionDepth-1){\n\t\t\trefractedColor = envMapSample(rayDir, roughness);\n\t\t}\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n\treturn vec4(refractedColor, distanceInsideMedium);\n}\nfloat refractionTint(float baseValue, float tint, float distanceInsideMedium, float absorption){\n\tfloat tintNegated = baseValue-tint;\n\tfloat t = tintNegated*( distanceInsideMedium*absorption );\n\treturn max(baseValue-t, 0.);\n}\nfloat applyRefractionAbsorption(float refractedDataColor, float baseValue, float tint, float distanceInsideMedium, float absorption){\n\treturn refractedDataColor*refractionTint(baseValue, tint, distanceInsideMedium, absorption);\n}\nvec3 applyRefractionAbsorption(vec3 refractedDataColor, vec3 baseValue, vec3 tint, float distanceInsideMedium, float absorption){\n\treturn vec3(\n\t\trefractedDataColor.r * refractionTint(baseValue.r, tint.r, distanceInsideMedium, absorption),\n\t\trefractedDataColor.g * refractionTint(baseValue.g, tint.g, distanceInsideMedium, absorption),\n\t\trefractedDataColor.b * refractionTint(baseValue.b, tint.b, distanceInsideMedium, absorption)\n\t);\n}\n\n#endif\n\nvec3 applyMaterial(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(0.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n\n\n\n\nvec4 applyShading(vec3 rayOrigin, vec3 rayDir, inout SDFContext sdfContext){\n\tvec3 p = rayOrigin + rayDir * sdfContext.d;\n\tvec3 n = GetNormal(p);\n\t\n\tvec3 col = applyMaterial(p, n, rayDir, sdfContext.matId, sdfContext);\n\tif(sdfContext.matBlend > 0.) {\n\t\t// blend material colors if needed\n\t\tvec3 col2 = applyMaterial(p, n, rayDir, sdfContext.matId2, sdfContext);\n\t\tcol = (1. - sdfContext.matBlend)*col + sdfContext.matBlend*col2;\n\t}\n\t\t\n\t// gamma\n\t//col = pow( col, vec3(0.4545) ); // this gamma leads to a different look than standard materials\n\treturn vec4(col, 1.);\n}\n\nvoid main()\t{\n\n\tvec3 rayDir = normalize(vPw - cameraPosition);\n\trayDir = transformDirection(rayDir, vInverseModelMatrix);\n\tvec3 rayOrigin = (vInverseModelMatrix * vec4( cameraPosition, 1.0 )).xyz;\n\n\tSDFContext sdfContext = RayMarch(rayOrigin, rayDir, 1.);\n\n\t#if defined( DEBUG_DEPTH )\n\t\tfloat normalizedDepth = 1.-(sdfContext.d - debugMinDepth ) / ( debugMaxDepth - debugMinDepth );\n\t\tnormalizedDepth = saturate(normalizedDepth); // clamp to [0,1]\n\t\tgl_FragColor = vec4(normalizedDepth);\n\t\treturn;\n\t#endif\n\t#if defined( SHADOW_DEPTH )\n\t\tfloat normalizedDepth = 1.-(sdfContext.d - debugMinDepth ) / ( debugMaxDepth - debugMinDepth );\n\t\t// float fragCoordZ = sdfContext.d / vHighPrecisionZW[1];\n\t\tfloat compoundedDepth = 0.5 * (normalizedDepth) + 0.5;\n\t\tfloat alpha = sdfContext.d < MAX_DIST ? 0.:1.;\n\t\tgl_FragColor = vec4( vec3(compoundedDepth), alpha );\n\t\t// normalizedDepth = 0.5*normalizedDepth+0.5;\n\t\t// gl_FragColor = packDepthToRGBA( normalizedDepth );\n\t\t// gl_FragColor = vec4(0.);\n\t\treturn;\n\t#endif\n\t#if defined( SHADOW_DISTANCE )\n\t\tfloat normalizedDepth = (sdfContext.d - shadowDistanceMin ) / ( shadowDistanceMax - shadowDistanceMin );\n\t\tnormalizedDepth = saturate(normalizedDepth); // clamp to [0,1]\n\t\tgl_FragColor = packDepthToRGBA( normalizedDepth );\n\t\treturn;\n\t#endif\n\n\tif( sdfContext.d < MAX_DIST ){\n\t\tgl_FragColor = applyShading(rayOrigin, rayDir, sdfContext);\n\t\t#if defined( TONE_MAPPING )\n\t\t\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n\t\t#endif\n\t\tgl_FragColor = linearToOutputTexel( gl_FragColor );\n\n\t\t#ifdef USE_FOG\n\t\t\tfloat vFogDepth = sdfContext.d;\n\t\t\t#ifdef FOG_EXP2\n\t\t\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );\n\t\t\t#else\n\t\t\t\tfloat fogFactor = smoothstep( fogNear, fogFar, vFogDepth );\n\t\t\t#endif\n\t\t\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n\t\t#endif\n\t\t#include <premultiplied_alpha_fragment>\n\t\t#include <dithering_fragment>\n\t} else {\n\t\tgl_FragColor = vec4(0.);\n\t}\n\n\t#if defined( DEBUG_STEPS_COUNT )\n\t\tfloat normalizedStepsCount = (float(sdfContext.stepsCount) - debugMinSteps ) / ( debugMaxSteps - debugMinSteps );\n\t\tgl_FragColor = vec4(normalizedStepsCount, 1.-normalizedStepsCount, 0., 1.);\n\t\treturn;\n\t#endif\n\t\n}","customDepthMaterial.vertex":"precision highp float;\nprecision highp int;\n\nvarying vec3 vPw;\nvarying mat4 vModelMatrix;\nvarying mat4 vInverseModelMatrix;\nvarying mat4 VViewMatrix;\n\n#include <common>\n\n// // for depth material\n// varying vec2 vHighPrecisionZW;\n\nvoid main()\t{\n\n\tvModelMatrix = modelMatrix;\n\tvInverseModelMatrix = inverse(modelMatrix);\n\tVViewMatrix = viewMatrix;\n\tvPw = (modelMatrix * vec4( position, 1.0 )).xyz;\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n\t// vHighPrecisionZW = gl_Position.zw;\n}","customDepthMaterial.fragment":"precision highp float;\nprecision highp int;\n\n// --- applyMaterial constants definition\nuniform int MAX_STEPS;\nuniform float MAX_DIST;\nuniform float SURF_DIST;\nuniform float NORMALS_BIAS;\nuniform float SHADOW_BIAS;\n#define ZERO 0\nuniform float debugMinSteps;\nuniform float debugMaxSteps;\nuniform float debugMinDepth;\nuniform float debugMaxDepth;\n\n#include <common>\n#include <packing>\n#include <lightmap_pars_fragment>\n#include <bsdfs>\n#include <cube_uv_reflection_fragment>\n#include <lights_pars_begin>\n#include <lights_physical_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <fog_pars_fragment>\n\n#if defined( SHADOW_DISTANCE )\n\tuniform float shadowDistanceMin;\n\tuniform float shadowDistanceMax;\n#endif \n#if defined( SHADOW_DEPTH )\n\tuniform float shadowDepthMin;\n\tuniform float shadowDepthMax;\n#endif\n\n// varying vec2 vHighPrecisionZW;\n\nvarying vec3 vPw;\nvarying mat4 vModelMatrix;\nvarying mat4 vInverseModelMatrix;\nvarying mat4 VViewMatrix;\n\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform SpotLightRayMarching spotLightsRayMarching[ NUM_SPOT_LIGHTS ];\n\t#if NUM_SPOT_LIGHT_COORDS > 0\n\n\t\tuniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];\n\n\t#endif\n#endif\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform DirectionalLightRayMarching directionalLightsRayMarching[ NUM_DIR_LIGHTS ];\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\n\t#endif\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform PointLightRayMarching pointLightsRayMarching[ NUM_POINT_LIGHTS ];\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\n\t#endif\n#endif\n\n\nstruct SDFContext {\n\tfloat d;\n\tint stepsCount;\n\tint matId;\n\tint matId2;\n\tfloat matBlend;\n};\n\nSDFContext DefaultSDFContext(){\n\treturn SDFContext( 0., 0, 0, 0, 0. );\n}\nint DefaultSDFMaterial(){\n\treturn 0;\n}\n\n// start raymarching builder define code\n\n\n\n// /geo1/MAT/rayMarchingBuilder1/SDFSphere3\nfloat dot2( in vec2 v ) { return dot(v,v); }\nfloat dot2( in vec3 v ) { return dot(v,v); }\nfloat ndot( in vec2 a, in vec2 b ) { return a.x*b.x - a.y*b.y; }\n// https://iquilezles.org/articles/distfunctions/\n\n\n/*\n*\n* SDF PRIMITIVES\n*\n*/\nfloat sdSphere( vec3 p, float s )\n{\n\treturn length(p)-s;\n}\nfloat sdCutSphere( vec3 p, float r, float h )\n{\n\t// sampling independent computations (only depend on shape)\n\tfloat w = sqrt(r*r-h*h);\n\n\t// sampling dependant computations\n\tvec2 q = vec2( length(p.xz), p.y );\n\tfloat s = max( (h-r)*q.x*q.x+w*w*(h+r-2.0*q.y), h*q.x-w*q.y );\n\treturn (s<0.0) ? length(q)-r :\n\t\t\t\t(q.x<w) ? h - q.y :\n\t\t\t\t\tlength(q-vec2(w,h));\n}\nfloat sdCutHollowSphere( vec3 p, float r, float h, float t )\n{\n\t// sampling independent computations (only depend on shape)\n\tfloat w = sqrt(r*r-h*h);\n\t\n\t// sampling dependant computations\n\tvec2 q = vec2( length(p.xz), p.y );\n\treturn ((h*q.x<w*q.y) ? length(q-vec2(w,h)) : \n\t\t\t\t\t\t\tabs(length(q)-r) ) - t;\n}\n\nfloat sdBox( vec3 p, vec3 b )\n{\n\tvec3 q = abs(p) - b*0.5;\n\treturn length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0);\n}\nfloat sdRoundBox( vec3 p, vec3 b, float r )\n{\n\tvec3 q = abs(p) - b*0.5;\n\treturn length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0) - r;\n}\n\n\nfloat sdBoxFrame( vec3 p, vec3 b, float e )\n{\n\t\tp = abs(p )-b*0.5;\n\tvec3 q = abs(p+e)-e;\n\treturn min(min(\n\t\tlength(max(vec3(p.x,q.y,q.z),0.0))+min(max(p.x,max(q.y,q.z)),0.0),\n\t\tlength(max(vec3(q.x,p.y,q.z),0.0))+min(max(q.x,max(p.y,q.z)),0.0)),\n\t\tlength(max(vec3(q.x,q.y,p.z),0.0))+min(max(q.x,max(q.y,p.z)),0.0));\n}\nfloat sdCapsule( vec3 p, vec3 a, vec3 b, float r )\n{\n\tvec3 pa = p - a, ba = b - a;\n\tfloat h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n\treturn length( pa - ba*h ) - r;\n}\nfloat sdVerticalCapsule( vec3 p, float h, float r )\n{\n\tp.y -= clamp( p.y, 0.0, h );\n\treturn length( p ) - r;\n}\nfloat sdCone( in vec3 p, in vec2 c, float h )\n{\n\t// c is the sin/cos of the angle, h is height\n\t// Alternatively pass q instead of (c,h),\n\t// which is the point at the base in 2D\n\tvec2 q = h*vec2(c.x/c.y,-1.0);\n\n\tvec2 w = vec2( length(p.xz), p.y );\n\tvec2 a = w - q*clamp( dot(w,q)/dot(q,q), 0.0, 1.0 );\n\tvec2 b = w - q*vec2( clamp( w.x/q.x, 0.0, 1.0 ), 1.0 );\n\tfloat k = sign( q.y );\n\tfloat d = min(dot( a, a ),dot(b, b));\n\tfloat s = max( k*(w.x*q.y-w.y*q.x),k*(w.y-q.y) );\n\treturn sqrt(d)*sign(s);\n}\nfloat sdConeWrapped(vec3 pos, float angle, float height){\n\treturn sdCone(pos, vec2(sin(angle), cos(angle)), height);\n}\nfloat sdRoundCone( vec3 p, float r1, float r2, float h )\n{\n\tfloat b = (r1-r2)/h;\n\tfloat a = sqrt(1.0-b*b);\n\n\tvec2 q = vec2( length(p.xz), p.y );\n\tfloat k = dot(q,vec2(-b,a));\n\tif( k<0.0 ) return length(q) - r1;\n\tif( k>a*h ) return length(q-vec2(0.0,h)) - r2;\n\treturn dot(q, vec2(a,b) ) - r1;\n}\nfloat sdOctogonPrism( in vec3 p, in float r, float h )\n{\n\tconst vec3 k = vec3(-0.9238795325, // sqrt(2+sqrt(2))/2 \n\t\t\t\t\t\t0.3826834323, // sqrt(2-sqrt(2))/2\n\t\t\t\t\t\t0.4142135623 ); // sqrt(2)-1 \n\t// reflections\n\tp = abs(p);\n\tp.xy -= 2.0*min(dot(vec2( k.x,k.y),p.xy),0.0)*vec2( k.x,k.y);\n\tp.xy -= 2.0*min(dot(vec2(-k.x,k.y),p.xy),0.0)*vec2(-k.x,k.y);\n\t// polygon side\n\tp.xy -= vec2(clamp(p.x, -k.z*r, k.z*r), r);\n\tvec2 d = vec2( length(p.xy)*sign(p.y), p.z-h );\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdHexPrism( vec3 p, vec2 h )\n{\n\tconst vec3 k = vec3(-0.8660254, 0.5, 0.57735);\n\tp = abs(p);\n\tp.xy -= 2.0*min(dot(k.xy, p.xy), 0.0)*k.xy;\n\tvec2 d = vec2(\n\t\tlength(p.xy-vec2(clamp(p.x,-k.z*h.x,k.z*h.x), h.x))*sign(p.y-h.x),\n\t\tp.z-h.y );\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdHorseshoe( in vec3 p, in float angle, in float r, in float le, vec2 w )\n{\n\tvec2 c = vec2(cos(angle),sin(angle));\n\tp.x = abs(p.x);\n\tfloat l = length(p.xy);\n\tp.xy = mat2(-c.x, c.y, \n\t\t\tc.y, c.x)*p.xy;\n\tp.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x),\n\t\t\t\t(p.x>0.0)?p.y:l );\n\tp.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0);\n\t\n\tvec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z);\n\tvec2 d = abs(q) - w;\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdTriPrism( vec3 p, vec2 h )\n{\n\tvec3 q = abs(p);\n\treturn max(q.z-h.y,max(q.x*0.866025+p.y*0.5,-p.y)-h.x*0.5);\n}\nfloat sdPyramid( vec3 p, float h)\n{\n\tfloat m2 = h*h + 0.25;\n\n\tp.xz = abs(p.xz);\n\tp.xz = (p.z>p.x) ? p.zx : p.xz;\n\tp.xz -= 0.5;\n\n\tvec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y);\n\n\tfloat s = max(-q.x,0.0);\n\tfloat t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 );\n\n\tfloat a = m2*(q.x+s)*(q.x+s) + q.y*q.y;\n\tfloat b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t);\n\n\tfloat d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b);\n\n\treturn sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));\n}\n\nfloat sdPlane( vec3 p, vec3 n, float h )\n{\n\t// n must be normalized\n\treturn dot(p,n) + h;\n}\n\nfloat sdTorus( vec3 p, vec2 t )\n{\n\tvec2 q = vec2(length(p.xz)-t.x,p.y);\n\treturn length(q)-t.y;\n}\nfloat sdCappedTorus(in vec3 p, in float an, in float ra, in float rb)\n{\n\tvec2 sc = vec2(sin(an),cos(an));\n\tp.x = abs(p.x);\n\tfloat k = (sc.y*p.x>sc.x*p.z) ? dot(p.xz,sc) : length(p.xz);\n\treturn sqrt( dot(p,p) + ra*ra - 2.0*ra*k ) - rb;\n}\nfloat sdLink( vec3 p, float le, float r1, float r2 )\n{\n vec3 q = vec3( p.x, max(abs(p.y)-le,0.0), p.z );\n return length(vec2(length(q.xy)-r1,q.z)) - r2;\n}\n// c is the sin/cos of the desired cone angle\nfloat sdSolidAngle(vec3 pos, vec2 c, float radius)\n{\n\tvec2 p = vec2( length(pos.xz), pos.y );\n\tfloat l = length(p) - radius;\n\tfloat m = length(p - c*clamp(dot(p,c),0.0,radius) );\n\treturn max(l,m*sign(c.y*p.x-c.x*p.y));\n}\nfloat sdSolidAngleWrapped(vec3 pos, float angle, float radius){\n\treturn sdSolidAngle(pos, vec2(sin(angle), cos(angle)), radius);\n}\nfloat sdTube( vec3 p, float r )\n{\n\treturn length(p.xz)-r;\n}\nfloat sdTubeCapped( vec3 p, float h, float r )\n{\n\tvec2 d = abs(vec2(length(p.xz),p.y)) - vec2(r,h);\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdOctahedron( vec3 p, float s)\n{\n p = abs(p);\n float m = p.x+p.y+p.z-s;\n vec3 q;\n if( 3.0*p.x < m ) q = p.xyz;\n else if( 3.0*p.y < m ) q = p.yzx;\n else if( 3.0*p.z < m ) q = p.zxy;\n else return m*0.57735027;\n \n float k = clamp(0.5*(q.z-q.y+s),0.0,s); \n return length(vec3(q.x,q.y-s+k,q.z-k)); \n}\nfloat udTriangle( vec3 p, vec3 a, vec3 b, vec3 c, float thickness )\n{\n\tvec3 ba = b - a; vec3 pa = p - a;\n\tvec3 cb = c - b; vec3 pb = p - b;\n\tvec3 ac = a - c; vec3 pc = p - c;\n\tvec3 nor = cross( ba, ac );\n\n\treturn - thickness + sqrt(\n\t\t(sign(dot(cross(ba,nor),pa)) +\n\t\tsign(dot(cross(cb,nor),pb)) +\n\t\tsign(dot(cross(ac,nor),pc))<2.0)\n\t\t?\n\t\tmin( min(\n\t\tdot2(ba*clamp(dot(ba,pa)/dot2(ba),0.0,1.0)-pa),\n\t\tdot2(cb*clamp(dot(cb,pb)/dot2(cb),0.0,1.0)-pb) ),\n\t\tdot2(ac*clamp(dot(ac,pc)/dot2(ac),0.0,1.0)-pc) )\n\t\t:\n\t\tdot(nor,pa)*dot(nor,pa)/dot2(nor) );\n}\nfloat udQuad( vec3 p, vec3 a, vec3 b, vec3 c, vec3 d, float thickness )\n{\n\tvec3 ba = b - a; vec3 pa = p - a;\n\tvec3 cb = c - b; vec3 pb = p - b;\n\tvec3 dc = d - c; vec3 pc = p - c;\n\tvec3 ad = a - d; vec3 pd = p - d;\n\tvec3 nor = cross( ba, ad );\n\n\treturn - thickness + sqrt(\n\t\t(sign(dot(cross(ba,nor),pa)) +\n\t\tsign(dot(cross(cb,nor),pb)) +\n\t\tsign(dot(cross(dc,nor),pc)) +\n\t\tsign(dot(cross(ad,nor),pd))<3.0)\n\t\t?\n\t\tmin( min( min(\n\t\tdot2(ba*clamp(dot(ba,pa)/dot2(ba),0.0,1.0)-pa),\n\t\tdot2(cb*clamp(dot(cb,pb)/dot2(cb),0.0,1.0)-pb) ),\n\t\tdot2(dc*clamp(dot(dc,pc)/dot2(dc),0.0,1.0)-pc) ),\n\t\tdot2(ad*clamp(dot(ad,pd)/dot2(ad),0.0,1.0)-pd) )\n\t\t:\n\t\tdot(nor,pa)*dot(nor,pa)/dot2(nor) );\n}\n\n/*\n*\n* SDF OPERATIONS\n*\n*/\nfloat SDFUnion( float d1, float d2 ) { return min(d1,d2); }\nfloat SDFSubtract( float d1, float d2 ) { return max(-d1,d2); }\nfloat SDFIntersect( float d1, float d2 ) { return max(d1,d2); }\n\nfloat SDFSmoothUnion( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 + 0.5*(d2-d1)/k, 0.0, 1.0 );\n\treturn mix( d2, d1, h ) - k*h*(1.0-h);\n}\n\nfloat SDFSmoothSubtract( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 - 0.5*(d2+d1)/k, 0.0, 1.0 );\n\treturn mix( d2, -d1, h ) + k*h*(1.0-h);\n}\n\nfloat SDFSmoothIntersect( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 - 0.5*(d2-d1)/k, 0.0, 1.0 );\n\treturn mix( d2, d1, h ) + k*h*(1.0-h);\n}\n\nvec4 SDFElongateFast( in vec3 p, in vec3 h )\n{\n\treturn vec4( p-clamp(p,-h,h), 0.0 );\n}\nvec4 SDFElongateSlow( in vec3 p, in vec3 h )\n{\n\tvec3 q = abs(p)-h;\n\treturn vec4( max(q,0.0), min(max(q.x,max(q.y,q.z)),0.0) );\n}\n\nfloat SDFOnion( in float sdf, in float thickness )\n{\n\treturn abs(sdf)-thickness;\n}\n\n// /geo1/MAT/rayMarchingBuilder1/checkers1\n// https://iquilezles.org/articles/checkerfiltering/\nfloat checkers(vec2 p) {\n\tvec2 s = sign(fract(p*.5)-.5);\n\treturn .5 - .5*s.x*s.y;\n}\nfloat checkersGrad( in vec2 p, in vec2 ddx, in vec2 ddy )\n{\n // filter kernel\n vec2 w = max(abs(ddx), abs(ddy)) + 0.01;\n // analytical integral (box filter)\n vec2 i = 2.0*(abs(fract((p-0.5*w)/2.0)-0.5)-abs(fract((p+0.5*w)/2.0)-0.5))/w;\n // xor pattern\n return 0.5 - 0.5*i.x*i.y;\n}\n\n\n// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\nconst int _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1 = 1;\n\n\n// https://stackoverflow.com/questions/23793698/how-to-implement-slerp-in-glsl-hlsl\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t)\n// {\n// \tfloat dotp = dot(normalize(p0), normalize(p1));\n// \tif ((dotp > 0.9999) || (dotp < -0.9999))\n// \t{\n// \t\tif (t<=0.5)\n// \t\t\treturn p0;\n// \t\treturn p1;\n// \t}\n// \tfloat theta = acos(dotp);\n// \tvec4 P = ((p0*sin((1.0-t)*theta) + p1*sin(t*theta)) / sin(theta));\n// \tP.w = 1.0;\n// \treturn P;\n// }\n\n// https://devcry.heiho.net/html/2017/20170521-slerp.html\n// float lerp(float a, float b, float t) {\n// \treturn (1.0 - t) * a + t * b;\n// }\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t){\n// \tvec4 qb = p1;\n\n// \t// cos(a) = dot product\n// \tfloat cos_a = p0.x * qb.x + p0.y * qb.y + p0.z * qb.z + p0.w * qb.w;\n// \tif (cos_a < 0.0f) {\n// \t\tcos_a = -cos_a;\n// \t\tqb = -qb;\n// \t}\n\n// \t// close to zero, cos(a) ~= 1\n// \t// do linear interpolation\n// \tif (cos_a > 0.999) {\n// \t\treturn vec4(\n// \t\t\tlerp(p0.x, qb.x, t),\n// \t\t\tlerp(p0.y, qb.y, t),\n// \t\t\tlerp(p0.z, qb.z, t),\n// \t\t\tlerp(p0.w, qb.w, t)\n// \t\t);\n// \t}\n\n// \tfloat alpha = acos(cos_a);\n// \treturn (p0 * sin(1.0 - t) + p1 * sin(t * alpha)) / sin(alpha);\n// }\n\n// https://stackoverflow.com/questions/62943083/interpolate-between-two-quaternions-the-long-way\nvec4 quatSlerp(vec4 q1, vec4 q2, float t){\n\tfloat angle = acos(dot(q1, q2));\n\tfloat denom = sin(angle);\n\t//check if denom is zero\n\treturn (q1*sin((1.0-t)*angle)+q2*sin(t*angle))/denom;\n}\n// TO CHECK:\n// this page https://www.reddit.com/r/opengl/comments/704la7/glsl_quaternion_library/\n// has a link to a potentially nice pdf:\n// http://web.mit.edu/2.998/www/QuaternionReport1.pdf\n\n// https://github.com/mattatz/ShibuyaCrowd/blob/master/source/shaders/common/quaternion.glsl\nvec4 quatMult(vec4 q1, vec4 q2)\n{\n\treturn vec4(\n\tq1.w * q2.x + q1.x * q2.w + q1.z * q2.y - q1.y * q2.z,\n\tq1.w * q2.y + q1.y * q2.w + q1.x * q2.z - q1.z * q2.x,\n\tq1.w * q2.z + q1.z * q2.w + q1.y * q2.x - q1.x * q2.y,\n\tq1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z\n\t);\n}\n// http://glmatrix.net/docs/quat.js.html#line97\n// let ax = a[0], ay = a[1], az = a[2], aw = a[3];\n\n// let bx = b[0], by = b[1], bz = b[2], bw = b[3];\n\n// out[0] = ax * bw + aw * bx + ay * bz - az * by;\n\n// out[1] = ay * bw + aw * by + az * bx - ax * bz;\n\n// out[2] = az * bw + aw * bz + ax * by - ay * bx;\n\n// out[3] = aw * bw - ax * bx - ay * by - az * bz;\n\n// return out\n\n\n\n// http://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/\nmat4 rotationMatrix(vec3 axis, float angle)\n{\n\taxis = normalize(axis);\n\tfloat s = sin(angle);\n\tfloat c = cos(angle);\n\tfloat oc = 1.0 - c;\n\n \treturn mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 0.0, 0.0, 0.0, 1.0);\n}\n\n// https://www.geeks3d.com/20141201/how-to-rotate-a-vertex-by-a-quaternion-in-glsl/\nvec4 quatFromAxisAngle(vec3 axis, float angle)\n{\n\tvec4 qr;\n\tfloat half_angle = (angle * 0.5); // * 3.14159 / 180.0;\n\tfloat sin_half_angle = sin(half_angle);\n\tqr.x = axis.x * sin_half_angle;\n\tqr.y = axis.y * sin_half_angle;\n\tqr.z = axis.z * sin_half_angle;\n\tqr.w = cos(half_angle);\n\treturn qr;\n}\nvec3 rotateWithAxisAngle(vec3 position, vec3 axis, float angle)\n{\n\tvec4 q = quatFromAxisAngle(axis, angle);\n\tvec3 v = position.xyz;\n\treturn v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);\n}\n// vec3 applyQuaternionToVector( vec4 q, vec3 v ){\n// \treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n// }\nvec3 rotateWithQuat( vec3 v, vec4 q )\n{\n\t// vec4 qv = multQuat( quat, vec4(vec, 0.0) );\n\t// return multQuat( qv, vec4(-quat.x, -quat.y, -quat.z, quat.w) ).xyz;\n\treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n}\n// https://github.com/glslify/glsl-look-at/blob/gh-pages/index.glsl\n// mat3 rotation_matrix(vec3 origin, vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target - origin);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n// mat3 rotation_matrix(vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n\nfloat vectorAngle(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 c1 = cross(start, dest);\n\t// We use the dot product of the cross with the Y axis.\n\t// This is a little arbitrary, but can still give a good sense of direction\n\tvec3 y_axis = vec3(0.0, 1.0, 0.0);\n\tfloat d1 = dot(c1, y_axis);\n\tfloat angle = acos(cosTheta) * sign(d1);\n\treturn angle;\n}\n\n// http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/#i-need-an-equivalent-of-glulookat-how-do-i-orient-an-object-towards-a-point-\nvec4 vectorAlign(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 axis;\n\n\t// if (cosTheta < -1 + 0.001f){\n\t// \t// special case when vectors in opposite directions:\n\t// \t// there is no ideal rotation axis\n\t// \t// So guess one; any will do as long as it's perpendicular to start\n\t// \taxis = cross(vec3(0.0f, 0.0f, 1.0f), start);\n\t// \tif (length2(axis) < 0.01 ) // bad luck, they were parallel, try again!\n\t// \t\taxis = cross(vec3(1.0f, 0.0f, 0.0f), start);\n\n\t// \taxis = normalize(axis);\n\t// \treturn gtx::quaternion::angleAxis(glm::radians(180.0f), axis);\n\t// }\n\tif(cosTheta > (1.0 - 0.0001) || cosTheta < (-1.0 + 0.0001) ){\n\t\taxis = normalize(cross(start, vec3(0.0, 1.0, 0.0)));\n\t\tif (length(axis) < 0.001 ){ // bad luck, they were parallel, try again!\n\t\t\taxis = normalize(cross(start, vec3(1.0, 0.0, 0.0)));\n\t\t}\n\t} else {\n\t\taxis = normalize(cross(start, dest));\n\t}\n\n\tfloat angle = acos(cosTheta);\n\n\treturn quatFromAxisAngle(axis, angle);\n}\nvec4 vectorAlignWithUp(vec3 start, vec3 dest, vec3 up){\n\tvec4 rot1 = vectorAlign(start, dest);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\t// vec3 right = normalize(cross(dest, up));\n\t// up = normalize(cross(right, dest));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(vec3(0.0, 1.0, 0.0), rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(up, newUp);\n\n\t// return rot1;\n\treturn rot2;\n\t// return multQuat(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\n// https://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\nfloat quatToAngle(vec4 q){\n\treturn 2.0 * acos(q.w);\n}\nvec3 quatToAxis(vec4 q){\n\treturn vec3(\n\t\tq.x / sqrt(1.0-q.w*q.w),\n\t\tq.y / sqrt(1.0-q.w*q.w),\n\t\tq.z / sqrt(1.0-q.w*q.w)\n\t);\n}\n\nvec4 align(vec3 dir, vec3 up){\n\tvec3 start_dir = vec3(0.0, 0.0, 1.0);\n\tvec3 start_up = vec3(0.0, 1.0, 0.0);\n\tvec4 rot1 = vectorAlign(start_dir, dir);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\tvec3 right = normalize(cross(dir, up));\n\tif(length(right)<0.001){\n\t\tright = vec3(1.0, 0.0, 0.0);\n\t}\n\tup = normalize(cross(right, dir));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(start_up, rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(normalize(newUp), up);\n\n\t// return rot1;\n\treturn quatMult(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\nstruct EnvMapProps {\n\tvec3 tint;\n\tfloat intensity;\n\tfloat roughness;\n\tfloat fresnel;\n\tfloat fresnelPower;\n};\nuniform sampler2D envMap;\nuniform float envMapIntensity;\nuniform float roughness;\n#ifdef ROTATE_ENV_MAP_Y\n\tuniform float envMapRotationY;\n#endif\nvec3 envMapSample(vec3 rayDir, float envMapRoughness){\n\t// http://www.pocketgl.com/reflections/\n\tvec3 env = vec3(0.);\n\t// vec2 uv = vec2( atan( -rayDir.z, -rayDir.x ) * RECIPROCAL_PI2 + 0.5, rayDir.y * 0.5 + 0.5 );\n\t// vec3 env = texture2D(map, uv).rgb;\n\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t#ifdef ROTATE_ENV_MAP_Y\n\t\t\trayDir = rotateWithAxisAngle(rayDir, vec3(0.,1.,0.), envMapRotationY);\n\t\t#endif\n\t\tenv = textureCubeUV(envMap, rayDir, envMapRoughness * roughness).rgb;\n\t#endif\n\treturn env;\n}\nvec3 envMapSampleWithFresnel(vec3 rayDir, EnvMapProps envMapProps, vec3 n, vec3 cameraPosition){\n\t// http://www.pocketgl.com/reflections/\n\tvec3 env = envMapSample(rayDir, envMapProps.roughness);\n\tfloat fresnel = pow(1.-dot(normalize(cameraPosition), n), envMapProps.fresnelPower);\n\tfloat fresnelFactor = (1.-envMapProps.fresnel) + envMapProps.fresnel*fresnel;\n\treturn env * envMapIntensity * envMapProps.tint * envMapProps.intensity * fresnelFactor;\n}\n\n\n\n\n\n\nSDFContext GetDist(vec3 p) {\n\tSDFContext sdfContext = SDFContext(0., 0, 0, 0, 0.);\n\n\t// start GetDist builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/SDFSphere3\n\tfloat v_POLY_SDFSphere3_float = sdSphere(p - vec3(-0.25, 0.0, 0.0), 0.2);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFSphere4\n\tfloat v_POLY_SDFSphere4_float = sdSphere(p - vec3(0.25, 0.0, 0.0), 0.2);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFPlane1\n\tfloat v_POLY_SDFPlane1_float = sdPlane(p-vec3(0.0, -0.2, 0.0), vec3(0.0, 1.0, 0.0), 0.0);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFUnion2\n\tfloat v_POLY_SDFUnion2_union = SDFSmoothUnion(v_POLY_SDFSphere3_float, v_POLY_SDFSphere4_float, 0.31);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFUnion3\n\tfloat v_POLY_SDFUnion3_union = SDFSmoothUnion(v_POLY_SDFUnion2_union, v_POLY_SDFPlane1_float, 0.31);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFContext1\n\tSDFContext v_POLY_SDFContext1_SDFContext = SDFContext(v_POLY_SDFUnion3_union, 0, _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1, _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1, 0.);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/output1\n\tsdfContext = v_POLY_SDFContext1_SDFContext;\n\n\n\n\t\n\n\treturn sdfContext;\n}\n\nSDFContext RayMarch(vec3 ro, vec3 rd, float side) {\n\tSDFContext dO = SDFContext(0.,0,0,0,0.);\n\n\t#pragma unroll_loop_start\n\tfor(int i=0; i<MAX_STEPS; i++) {\n\t\tvec3 p = ro + rd*dO.d;\n\t\tSDFContext sdfContext = GetDist(p);\n\t\tdO.d += sdfContext.d * side;\n\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\tdO.stepsCount += 1;\n\t\t#endif\n\t\tdO.matId = sdfContext.matId;\n\t\tdO.matId2 = sdfContext.matId2;\n\t\tdO.matBlend = sdfContext.matBlend;\n\t\tif(dO.d>MAX_DIST || abs(sdfContext.d)<SURF_DIST) break;\n\t}\n\t#pragma unroll_loop_end\n\n\treturn dO;\n}\n\nvec3 GetNormal(vec3 p) {\n\tSDFContext sdfContext = GetDist(p);\n\tvec2 e = vec2(NORMALS_BIAS, 0);\n\n\tvec3 n = sdfContext.d - vec3(\n\t\tGetDist(p-e.xyy).d,\n\t\tGetDist(p-e.yxy).d,\n\t\tGetDist(p-e.yyx).d);\n\n\treturn normalize(n);\n}\n// https://iquilezles.org/articles/rmshadows\nfloat calcSoftshadow( in vec3 ro, in vec3 rd, float mint, float maxt, float k, inout SDFContext sdfContext )\n{\n\tfloat res = 1.0;\n\tfloat ph = 1e20;\n\tfor( float t=mint; t<maxt; )\n\t{\n\t\tfloat h = GetDist(ro + rd*t).d;\n\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\tsdfContext.stepsCount += 1;\n\t\t#endif\n\t\tif( h<SURF_DIST )\n\t\t\treturn 0.0;\n\t\tfloat y = h*h/(2.0*ph);\n\t\tfloat d = sqrt(h*h-y*y);\n\t\tres = min( res, k*d/max(0.0,t-y) );\n\t\tph = h;\n\t\tt += h;\n\t}\n\treturn res;\n}\n\nvec3 GetLight(vec3 _p, vec3 _n, inout SDFContext sdfContext) {\n\tvec3 dif = vec3(0.,0.,0.);\n\t// GeometricContext geometry;\n\t// geometry.position = _p;\n\t// geometry.normal = _n;\n\t// geometry.viewDir = rayDir;\n\n\t// vec4 mvPosition = vec4( p, 1.0 );\n\t// mvPosition = modelViewMatrix * mvPosition;\n\t// vec3 vViewPosition = - mvPosition.xyz;\n\tvec3 pWorld = ( vModelMatrix * vec4( _p, 1.0 )).xyz;\n\tvec3 nWorld = transformDirection(_n, vModelMatrix);\n\t// geometry.position = (VViewMatrix * vec4( _p, 1.0 )).xyz;\n\tvec3 geometryPosition = (VViewMatrix * vec4(pWorld, 1.0 )).xyz;\n\t// geometry.normal = transformDirection(_n, VViewMatrix);\n\t// geometry.normal = inverseTransformDirection(transformDirection(_n, VViewMatrix), vInverseModelMatrix);\n\tvec3 geometryNormal = transformDirection(nWorld, VViewMatrix);\n\t\n\n\t#if NUM_SPOT_LIGHTS > 0 || NUM_DIR_LIGHTS > 0 || NUM_HEMI_LIGHTS > 0 || NUM_POINT_LIGHTS > 0 || NUM_RECT_AREA_LIGHTS > 0\n\n\t\tIncidentLight directLight;\n\t\tReflectedLight reflectedLight;\n\t\tvec3 lightPos, lightDir, worldLightDir, objectSpaceLightDir, lighDif, directDiffuse;\n\t\tfloat dotNL, lightDistance;\n\t\t#if NUM_SPOT_LIGHTS > 0\n\t\t\tSpotLightRayMarching spotLightRayMarching;\n\t\t\tSpotLight spotLight;\n\t\t\tfloat spotLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\t\t\t\tSpotLightShadow spotLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\t\t\tspotLightRayMarching = spotLightsRayMarching[ i ];\n\t\t\t\tspotLight = spotLights[ i ];\n\t\t\t\tgetSpotLightInfo( spotLight, geometryPosition, directLight );\n\n\t\t\t\t// #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t\t\t// \tspotLightShadow = spotLightShadows[ i ];\n\t\t\t\t// \tvec4 spotLightShadowCoord = spotLightMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t// \tdirectLight.color *= (directLight.visible && receiveShadow) ? getShadow(\n\t\t\t\t// \t\tspotShadowMap[ i ],\n\t\t\t\t// \t\tspotLightShadow.shadowMapSize,\n\t\t\t\t// \t\tspotLightShadow.shadowBias,\n\t\t\t\t// \t\tspotLightShadow.shadowRadius,\n\t\t\t\t// \t\tspotLightShadowCoord\n\t\t\t\t// \t) : 1.0;\n\t\t\t\t// #endif\n\n\t\t\t\tlightPos = spotLight.position;\n\t\t\t\tlightDir = normalize(lightPos-geometryPosition);\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tlightDistance = distance(geometryPosition,lightPos);\n\t\t\t\tspotLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < spotLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t: calcSoftshadow(\n\t\t\t\t\t\t_p,\n\t\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\t\tspotLightRayMarching.shadowBiasDistance,\n\t\t\t\t\t\tdistance(geometryPosition,lightPos),\n\t\t\t\t\t\t1./max(spotLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\t\tsdfContext\n\t\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * spotLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\t\t#if NUM_DIR_LIGHTS > 0\n\t\t\tDirectionalLightRayMarching directionalLightRayMarching;\n\t\t\tDirectionalLight directionalLight;\n\t\t\tfloat dirLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\t\t\t\tDirectionalLightShadow directionalLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\t\t\tdirectionalLightRayMarching = directionalLightsRayMarching[ i ];\n\t\t\t\tdirectionalLight = directionalLights[ i ];\n\t\t\t\t\n\t\t\t\tgetDirectionalLightInfo( directionalLight, directLight );\n\n\t\t\t\t// #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\t\t\t// \tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\t\t\t// \tvec4 dirLightShadowCoord = directionalShadowMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t// \tdirectLight.color *= (directLight.visible && receiveShadow) ? getShadow(\n\t\t\t\t// \t\tdirectionalShadowMap[ i ],\n\t\t\t\t// \t\tdirectionalLightShadow.shadowMapSize,\n\t\t\t\t// \t\tdirectionalLightShadow.shadowBias,\n\t\t\t\t// \t\tdirectionalLightShadow.shadowRadius,\n\t\t\t\t// \t\tdirLightShadowCoord\n\t\t\t\t// \t) : 1.0;\n\t\t\t\t// #endif\n\n\t\t\t\tlightDir = directionalLight.direction;\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tdirLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < directionalLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t:\n\t\t\t\t\tcalcSoftshadow(\n\t\t\t\t\t\t_p,\n\t\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\t\tdirectionalLightRayMarching.shadowBiasDistance,\n\t\t\t\t\t\tMAX_DIST,//distance(geometryPosition,lightPos),\n\t\t\t\t\t\t1./max(directionalLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\t\tsdfContext\n\t\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\t// lighDif = directLight.color * dotNL * dirLightSdfShadow;\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * dirLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\n\t\t#if ( NUM_HEMI_LIGHTS > 0 )\n\n\t\t\t#pragma unroll_loop_start\n\t\t\tHemisphereLight hemiLight;\n\t\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\t\themiLight = hemisphereLights[ i ];\n\t\t\t\tdif += getHemisphereLightIrradiance( hemiLight, geometryNormal ) * BRDF_Lambert( vec3(1.) );\n\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\n\t\t#endif\n\n\t\t#if NUM_POINT_LIGHTS > 0\n\t\t\tPointLightRayMarching pointLightRayMarching;\n\t\t\tPointLight pointLight;\n\t\t\tfloat pointLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\t\t\t\tPointLightShadow pointLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\t\t\tpointLightRayMarching = pointLightsRayMarching[ i ];\n\t\t\t\tpointLight = pointLights[ i ];\n\t\t\t\tgetPointLightInfo( pointLight, geometryPosition, directLight );\n\n\n\t\t\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\t\t\t\tpointLightShadow = pointLightShadows[ i ];\n\t\t\t\t\tvec4 pointLightShadowCoord = pointShadowMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t\tdirectLight.color *= (directLight.visible && receiveShadow) ? getPointShadow(\n\t\t\t\t\t\tpointShadowMap[ i ],\n\t\t\t\t\t\tpointLightShadow.shadowMapSize,\n\t\t\t\t\t\tpointLightShadow.shadowBias,\n\t\t\t\t\t\tpointLightShadow.shadowRadius,\n\t\t\t\t\t\tpointLightShadowCoord,\n\t\t\t\t\t\tpointLightShadow.shadowCameraNear,\n\t\t\t\t\t\tpointLightShadow.shadowCameraFar\n\t\t\t\t\t) : 1.0;\n\t\t\t\t#endif\n\n\t\t\t\tlightPos = pointLight.position;\n\t\t\t\tlightDir = normalize(lightPos-geometryPosition);\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tpointLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < pointLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t:\n\t\t\t\t\tcalcSoftshadow(\n\t\t\t\t\t_p,\n\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\tpointLightRayMarching.shadowBiasDistance,\n\t\t\t\t\tdistance(geometryPosition,lightPos),\n\t\t\t\t\t1./max(pointLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\tsdfContext\n\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * pointLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\n\t\t#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\n\t\t\tRectAreaLight rectAreaLight;\n\t\t\t// AreaLightRayMarching areaLightRayMarching;\n\t\t\tPhysicalMaterial material;\n\t\t\tmaterial.roughness = 1.;\n\t\t\tmaterial.specularColor = vec3(1.);\n\t\t\tmaterial.diffuseColor = vec3(1.);\n\n\t\t\tvec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( cameraPosition - geometryPosition );\n\t\t\tvec3 geometryClearcoatNormal = geometryNormal;\n\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\t\t\t// areaLightRayMarching = areaLightsRayMarching[ i ];\n\t\t\t\trectAreaLight = rectAreaLights[ i ];\n\t\t\t\t// rectAreaLight.position = areaLightRayMarching.worldPos;\n\n\t\t\t\tRE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t\tdif += reflectedLight.directDiffuse;\n\n\t\t#endif\n\t#endif\n\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\n\t#if defined( USE_LIGHT_PROBES )\n\n\t\tirradiance += getLightProbeIrradiance( lightProbe, geometryNormal );\n\n\t#endif\n\n\tdif += irradiance;\n\n\treturn dif;\n}\n\n\n\n\nvec3 applyMaterialWithoutRefraction(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(1.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n\nvec3 applyMaterialWithoutReflection(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(1.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n#ifdef RAYMARCHED_REFLECTIONS\nvec3 GetReflection(vec3 p, vec3 n, vec3 rayDir, float biasMult, float roughness, int reflectionDepth, inout SDFContext sdfContextMain){\n\tbool hitReflection = true;\n\tvec3 reflectedColor = vec3(0.);\n\t#pragma unroll_loop_start\n\tfor(int i=0; i < reflectionDepth; i++) {\n\t\tif(hitReflection){\n\t\t\trayDir = reflect(rayDir, n);\n\t\t\tp += n*SURF_DIST*biasMult;\n\t\t\tSDFContext sdfContext = RayMarch(p, rayDir, 1.);\n\t\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\t\tsdfContextMain.stepsCount += sdfContext.stepsCount;\n\t\t\t#endif\n\t\t\tif( sdfContext.d >= MAX_DIST){\n\t\t\t\thitReflection = false;\n\t\t\t\treflectedColor = envMapSample(rayDir, roughness);\n\t\t\t}\n\t\t\tif(hitReflection){\n\t\t\t\tp += rayDir * sdfContext.d;\n\t\t\t\tn = GetNormal(p);\n\t\t\t\tvec3 matCol = applyMaterialWithoutReflection(p, n, rayDir, sdfContext.matId, sdfContextMain);\n\t\t\t\treflectedColor += matCol;\n\t\t\t}\n\t\t}\n\t}\n\t#pragma unroll_loop_end\n\treturn reflectedColor;\n}\n#endif\n\n#ifdef RAYMARCHED_REFRACTIONS\n// xyz for color, w for distanceInsideMedium\nvec4 GetRefractedData(vec3 p, vec3 n, vec3 rayDir, float ior, float biasMult, float roughness, float refractionMaxDist, int refractionDepth, inout SDFContext sdfContextMain){\n\tbool hitRefraction = true;\n\tbool changeSide = true;\n\t#ifdef RAYMARCHED_REFRACTIONS_START_OUTSIDE_MEDIUM\n\tfloat side = -1.;\n\t#else\n\tfloat side = 1.;\n\t#endif\n\tfloat iorInverted = 1. / ior;\n\tvec3 refractedColor = vec3(0.);\n\tfloat distanceInsideMedium=0.;\n\tfloat totalRefractedDistance=0.;\n\n\t#pragma unroll_loop_start\n\tfor(int i=0; i < refractionDepth; i++) {\n\t\tif(hitRefraction){\n\t\t\tfloat currentIor = side<0. ? iorInverted : ior;\n\t\t\tvec3 rayDirPreRefract = rayDir;\n\t\t\trayDir = refract(rayDir, n, currentIor);\n\t\t\tchangeSide = dot(rayDir, rayDir)!=0.;\n\t\t\tif(changeSide == true) {\n\t\t\t\tp -= n*SURF_DIST*(2.+biasMult);\n\t\t\t} else {\n\t\t\t\tp += n*SURF_DIST*( biasMult);\n\t\t\t\trayDir = reflect(rayDirPreRefract, n);\n\t\t\t}\n\t\t\tSDFContext sdfContext = RayMarch(p, rayDir, side);\n\t\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\t\tsdfContextMain.stepsCount += sdfContext.stepsCount;\n\t\t\t#endif\n\t\t\ttotalRefractedDistance += sdfContext.d;\n\t\t\tif( abs(sdfContext.d) >= MAX_DIST || totalRefractedDistance > refractionMaxDist ){\n\t\t\t\thitRefraction = false;\n\t\t\t\trefractedColor = envMapSample(rayDir, roughness);\n\t\t\t}\n\t\t\tif(hitRefraction){\n\t\t\t\tp += rayDir * sdfContext.d;\n\t\t\t\tn = GetNormal(p) * side;\n\t\t\t\tvec3 matCol = applyMaterialWithoutRefraction(p, n, rayDir, sdfContext.matId, sdfContextMain);\n\t\t\t\trefractedColor = matCol;\n\n\t\t\t\t// same as: side < 0. ? abs(sdfContext.d) : 0.;\n\t\t\t\tdistanceInsideMedium += (side-1.)*-0.5*abs(sdfContext.d);\n\t\t\t\tif( changeSide ){\n\t\t\t\t\tside *= -1.;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#ifdef RAYMARCHED_REFRACTIONS_SAMPLE_ENV_MAP_ON_LAST\n\t\tif(i == refractionDepth-1){\n\t\t\trefractedColor = envMapSample(rayDir, roughness);\n\t\t}\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n\treturn vec4(refractedColor, distanceInsideMedium);\n}\nfloat refractionTint(float baseValue, float tint, float distanceInsideMedium, float absorption){\n\tfloat tintNegated = baseValue-tint;\n\tfloat t = tintNegated*( distanceInsideMedium*absorption );\n\treturn max(baseValue-t, 0.);\n}\nfloat applyRefractionAbsorption(float refractedDataColor, float baseValue, float tint, float distanceInsideMedium, float absorption){\n\treturn refractedDataColor*refractionTint(baseValue, tint, distanceInsideMedium, absorption);\n}\nvec3 applyRefractionAbsorption(vec3 refractedDataColor, vec3 baseValue, vec3 tint, float distanceInsideMedium, float absorption){\n\treturn vec3(\n\t\trefractedDataColor.r * refractionTint(baseValue.r, tint.r, distanceInsideMedium, absorption),\n\t\trefractedDataColor.g * refractionTint(baseValue.g, tint.g, distanceInsideMedium, absorption),\n\t\trefractedDataColor.b * refractionTint(baseValue.b, tint.b, distanceInsideMedium, absorption)\n\t);\n}\n\n#endif\n\nvec3 applyMaterial(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(0.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n\n\n\n\nvec4 applyShading(vec3 rayOrigin, vec3 rayDir, inout SDFContext sdfContext){\n\tvec3 p = rayOrigin + rayDir * sdfContext.d;\n\tvec3 n = GetNormal(p);\n\t\n\tvec3 col = applyMaterial(p, n, rayDir, sdfContext.matId, sdfContext);\n\tif(sdfContext.matBlend > 0.) {\n\t\t// blend material colors if needed\n\t\tvec3 col2 = applyMaterial(p, n, rayDir, sdfContext.matId2, sdfContext);\n\t\tcol = (1. - sdfContext.matBlend)*col + sdfContext.matBlend*col2;\n\t}\n\t\t\n\t// gamma\n\t//col = pow( col, vec3(0.4545) ); // this gamma leads to a different look than standard materials\n\treturn vec4(col, 1.);\n}\n\nvoid main()\t{\n\n\tvec3 rayDir = normalize(vPw - cameraPosition);\n\trayDir = transformDirection(rayDir, vInverseModelMatrix);\n\tvec3 rayOrigin = (vInverseModelMatrix * vec4( cameraPosition, 1.0 )).xyz;\n\n\tSDFContext sdfContext = RayMarch(rayOrigin, rayDir, 1.);\n\n\t#if defined( DEBUG_DEPTH )\n\t\tfloat normalizedDepth = 1.-(sdfContext.d - debugMinDepth ) / ( debugMaxDepth - debugMinDepth );\n\t\tnormalizedDepth = saturate(normalizedDepth); // clamp to [0,1]\n\t\tgl_FragColor = vec4(normalizedDepth);\n\t\treturn;\n\t#endif\n\t#if defined( SHADOW_DEPTH )\n\t\tfloat normalizedDepth = 1.-(sdfContext.d - debugMinDepth ) / ( debugMaxDepth - debugMinDepth );\n\t\t// float fragCoordZ = sdfContext.d / vHighPrecisionZW[1];\n\t\tfloat compoundedDepth = 0.5 * (normalizedDepth) + 0.5;\n\t\tfloat alpha = sdfContext.d < MAX_DIST ? 0.:1.;\n\t\tgl_FragColor = vec4( vec3(compoundedDepth), alpha );\n\t\t// normalizedDepth = 0.5*normalizedDepth+0.5;\n\t\t// gl_FragColor = packDepthToRGBA( normalizedDepth );\n\t\t// gl_FragColor = vec4(0.);\n\t\treturn;\n\t#endif\n\t#if defined( SHADOW_DISTANCE )\n\t\tfloat normalizedDepth = (sdfContext.d - shadowDistanceMin ) / ( shadowDistanceMax - shadowDistanceMin );\n\t\tnormalizedDepth = saturate(normalizedDepth); // clamp to [0,1]\n\t\tgl_FragColor = packDepthToRGBA( normalizedDepth );\n\t\treturn;\n\t#endif\n\n\tif( sdfContext.d < MAX_DIST ){\n\t\tgl_FragColor = applyShading(rayOrigin, rayDir, sdfContext);\n\t\t#if defined( TONE_MAPPING )\n\t\t\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n\t\t#endif\n\t\tgl_FragColor = linearToOutputTexel( gl_FragColor );\n\n\t\t#ifdef USE_FOG\n\t\t\tfloat vFogDepth = sdfContext.d;\n\t\t\t#ifdef FOG_EXP2\n\t\t\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );\n\t\t\t#else\n\t\t\t\tfloat fogFactor = smoothstep( fogNear, fogFar, vFogDepth );\n\t\t\t#endif\n\t\t\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n\t\t#endif\n\t\t#include <premultiplied_alpha_fragment>\n\t\t#include <dithering_fragment>\n\t} else {\n\t\tgl_FragColor = vec4(0.);\n\t}\n\n\t#if defined( DEBUG_STEPS_COUNT )\n\t\tfloat normalizedStepsCount = (float(sdfContext.stepsCount) - debugMinSteps ) / ( debugMaxSteps - debugMinSteps );\n\t\tgl_FragColor = vec4(normalizedStepsCount, 1.-normalizedStepsCount, 0., 1.);\n\t\treturn;\n\t#endif\n\t\n}","customDistanceMaterial.vertex":"precision highp float;\nprecision highp int;\n\nvarying vec3 vPw;\nvarying mat4 vModelMatrix;\nvarying mat4 vInverseModelMatrix;\nvarying mat4 VViewMatrix;\n\n#include <common>\n\n// // for depth material\n// varying vec2 vHighPrecisionZW;\n\nvoid main()\t{\n\n\tvModelMatrix = modelMatrix;\n\tvInverseModelMatrix = inverse(modelMatrix);\n\tVViewMatrix = viewMatrix;\n\tvPw = (modelMatrix * vec4( position, 1.0 )).xyz;\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n\t// vHighPrecisionZW = gl_Position.zw;\n}","customDistanceMaterial.fragment":"precision highp float;\nprecision highp int;\n\n// --- applyMaterial constants definition\nuniform int MAX_STEPS;\nuniform float MAX_DIST;\nuniform float SURF_DIST;\nuniform float NORMALS_BIAS;\nuniform float SHADOW_BIAS;\n#define ZERO 0\nuniform float debugMinSteps;\nuniform float debugMaxSteps;\nuniform float debugMinDepth;\nuniform float debugMaxDepth;\n\n#include <common>\n#include <packing>\n#include <lightmap_pars_fragment>\n#include <bsdfs>\n#include <cube_uv_reflection_fragment>\n#include <lights_pars_begin>\n#include <lights_physical_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <fog_pars_fragment>\n\n#if defined( SHADOW_DISTANCE )\n\tuniform float shadowDistanceMin;\n\tuniform float shadowDistanceMax;\n#endif \n#if defined( SHADOW_DEPTH )\n\tuniform float shadowDepthMin;\n\tuniform float shadowDepthMax;\n#endif\n\n// varying vec2 vHighPrecisionZW;\n\nvarying vec3 vPw;\nvarying mat4 vModelMatrix;\nvarying mat4 vInverseModelMatrix;\nvarying mat4 VViewMatrix;\n\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform SpotLightRayMarching spotLightsRayMarching[ NUM_SPOT_LIGHTS ];\n\t#if NUM_SPOT_LIGHT_COORDS > 0\n\n\t\tuniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];\n\n\t#endif\n#endif\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform DirectionalLightRayMarching directionalLightsRayMarching[ NUM_DIR_LIGHTS ];\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\n\t#endif\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLightRayMarching {\n\t\tfloat penumbra;\n\t\tfloat shadowBiasAngle;\n\t\tfloat shadowBiasDistance;\n\t};\n\tuniform PointLightRayMarching pointLightsRayMarching[ NUM_POINT_LIGHTS ];\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\n\t#endif\n#endif\n\n\nstruct SDFContext {\n\tfloat d;\n\tint stepsCount;\n\tint matId;\n\tint matId2;\n\tfloat matBlend;\n};\n\nSDFContext DefaultSDFContext(){\n\treturn SDFContext( 0., 0, 0, 0, 0. );\n}\nint DefaultSDFMaterial(){\n\treturn 0;\n}\n\n// start raymarching builder define code\n\n\n\n// /geo1/MAT/rayMarchingBuilder1/SDFSphere3\nfloat dot2( in vec2 v ) { return dot(v,v); }\nfloat dot2( in vec3 v ) { return dot(v,v); }\nfloat ndot( in vec2 a, in vec2 b ) { return a.x*b.x - a.y*b.y; }\n// https://iquilezles.org/articles/distfunctions/\n\n\n/*\n*\n* SDF PRIMITIVES\n*\n*/\nfloat sdSphere( vec3 p, float s )\n{\n\treturn length(p)-s;\n}\nfloat sdCutSphere( vec3 p, float r, float h )\n{\n\t// sampling independent computations (only depend on shape)\n\tfloat w = sqrt(r*r-h*h);\n\n\t// sampling dependant computations\n\tvec2 q = vec2( length(p.xz), p.y );\n\tfloat s = max( (h-r)*q.x*q.x+w*w*(h+r-2.0*q.y), h*q.x-w*q.y );\n\treturn (s<0.0) ? length(q)-r :\n\t\t\t\t(q.x<w) ? h - q.y :\n\t\t\t\t\tlength(q-vec2(w,h));\n}\nfloat sdCutHollowSphere( vec3 p, float r, float h, float t )\n{\n\t// sampling independent computations (only depend on shape)\n\tfloat w = sqrt(r*r-h*h);\n\t\n\t// sampling dependant computations\n\tvec2 q = vec2( length(p.xz), p.y );\n\treturn ((h*q.x<w*q.y) ? length(q-vec2(w,h)) : \n\t\t\t\t\t\t\tabs(length(q)-r) ) - t;\n}\n\nfloat sdBox( vec3 p, vec3 b )\n{\n\tvec3 q = abs(p) - b*0.5;\n\treturn length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0);\n}\nfloat sdRoundBox( vec3 p, vec3 b, float r )\n{\n\tvec3 q = abs(p) - b*0.5;\n\treturn length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0) - r;\n}\n\n\nfloat sdBoxFrame( vec3 p, vec3 b, float e )\n{\n\t\tp = abs(p )-b*0.5;\n\tvec3 q = abs(p+e)-e;\n\treturn min(min(\n\t\tlength(max(vec3(p.x,q.y,q.z),0.0))+min(max(p.x,max(q.y,q.z)),0.0),\n\t\tlength(max(vec3(q.x,p.y,q.z),0.0))+min(max(q.x,max(p.y,q.z)),0.0)),\n\t\tlength(max(vec3(q.x,q.y,p.z),0.0))+min(max(q.x,max(q.y,p.z)),0.0));\n}\nfloat sdCapsule( vec3 p, vec3 a, vec3 b, float r )\n{\n\tvec3 pa = p - a, ba = b - a;\n\tfloat h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n\treturn length( pa - ba*h ) - r;\n}\nfloat sdVerticalCapsule( vec3 p, float h, float r )\n{\n\tp.y -= clamp( p.y, 0.0, h );\n\treturn length( p ) - r;\n}\nfloat sdCone( in vec3 p, in vec2 c, float h )\n{\n\t// c is the sin/cos of the angle, h is height\n\t// Alternatively pass q instead of (c,h),\n\t// which is the point at the base in 2D\n\tvec2 q = h*vec2(c.x/c.y,-1.0);\n\n\tvec2 w = vec2( length(p.xz), p.y );\n\tvec2 a = w - q*clamp( dot(w,q)/dot(q,q), 0.0, 1.0 );\n\tvec2 b = w - q*vec2( clamp( w.x/q.x, 0.0, 1.0 ), 1.0 );\n\tfloat k = sign( q.y );\n\tfloat d = min(dot( a, a ),dot(b, b));\n\tfloat s = max( k*(w.x*q.y-w.y*q.x),k*(w.y-q.y) );\n\treturn sqrt(d)*sign(s);\n}\nfloat sdConeWrapped(vec3 pos, float angle, float height){\n\treturn sdCone(pos, vec2(sin(angle), cos(angle)), height);\n}\nfloat sdRoundCone( vec3 p, float r1, float r2, float h )\n{\n\tfloat b = (r1-r2)/h;\n\tfloat a = sqrt(1.0-b*b);\n\n\tvec2 q = vec2( length(p.xz), p.y );\n\tfloat k = dot(q,vec2(-b,a));\n\tif( k<0.0 ) return length(q) - r1;\n\tif( k>a*h ) return length(q-vec2(0.0,h)) - r2;\n\treturn dot(q, vec2(a,b) ) - r1;\n}\nfloat sdOctogonPrism( in vec3 p, in float r, float h )\n{\n\tconst vec3 k = vec3(-0.9238795325, // sqrt(2+sqrt(2))/2 \n\t\t\t\t\t\t0.3826834323, // sqrt(2-sqrt(2))/2\n\t\t\t\t\t\t0.4142135623 ); // sqrt(2)-1 \n\t// reflections\n\tp = abs(p);\n\tp.xy -= 2.0*min(dot(vec2( k.x,k.y),p.xy),0.0)*vec2( k.x,k.y);\n\tp.xy -= 2.0*min(dot(vec2(-k.x,k.y),p.xy),0.0)*vec2(-k.x,k.y);\n\t// polygon side\n\tp.xy -= vec2(clamp(p.x, -k.z*r, k.z*r), r);\n\tvec2 d = vec2( length(p.xy)*sign(p.y), p.z-h );\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdHexPrism( vec3 p, vec2 h )\n{\n\tconst vec3 k = vec3(-0.8660254, 0.5, 0.57735);\n\tp = abs(p);\n\tp.xy -= 2.0*min(dot(k.xy, p.xy), 0.0)*k.xy;\n\tvec2 d = vec2(\n\t\tlength(p.xy-vec2(clamp(p.x,-k.z*h.x,k.z*h.x), h.x))*sign(p.y-h.x),\n\t\tp.z-h.y );\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdHorseshoe( in vec3 p, in float angle, in float r, in float le, vec2 w )\n{\n\tvec2 c = vec2(cos(angle),sin(angle));\n\tp.x = abs(p.x);\n\tfloat l = length(p.xy);\n\tp.xy = mat2(-c.x, c.y, \n\t\t\tc.y, c.x)*p.xy;\n\tp.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x),\n\t\t\t\t(p.x>0.0)?p.y:l );\n\tp.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0);\n\t\n\tvec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z);\n\tvec2 d = abs(q) - w;\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdTriPrism( vec3 p, vec2 h )\n{\n\tvec3 q = abs(p);\n\treturn max(q.z-h.y,max(q.x*0.866025+p.y*0.5,-p.y)-h.x*0.5);\n}\nfloat sdPyramid( vec3 p, float h)\n{\n\tfloat m2 = h*h + 0.25;\n\n\tp.xz = abs(p.xz);\n\tp.xz = (p.z>p.x) ? p.zx : p.xz;\n\tp.xz -= 0.5;\n\n\tvec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y);\n\n\tfloat s = max(-q.x,0.0);\n\tfloat t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 );\n\n\tfloat a = m2*(q.x+s)*(q.x+s) + q.y*q.y;\n\tfloat b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t);\n\n\tfloat d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b);\n\n\treturn sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));\n}\n\nfloat sdPlane( vec3 p, vec3 n, float h )\n{\n\t// n must be normalized\n\treturn dot(p,n) + h;\n}\n\nfloat sdTorus( vec3 p, vec2 t )\n{\n\tvec2 q = vec2(length(p.xz)-t.x,p.y);\n\treturn length(q)-t.y;\n}\nfloat sdCappedTorus(in vec3 p, in float an, in float ra, in float rb)\n{\n\tvec2 sc = vec2(sin(an),cos(an));\n\tp.x = abs(p.x);\n\tfloat k = (sc.y*p.x>sc.x*p.z) ? dot(p.xz,sc) : length(p.xz);\n\treturn sqrt( dot(p,p) + ra*ra - 2.0*ra*k ) - rb;\n}\nfloat sdLink( vec3 p, float le, float r1, float r2 )\n{\n vec3 q = vec3( p.x, max(abs(p.y)-le,0.0), p.z );\n return length(vec2(length(q.xy)-r1,q.z)) - r2;\n}\n// c is the sin/cos of the desired cone angle\nfloat sdSolidAngle(vec3 pos, vec2 c, float radius)\n{\n\tvec2 p = vec2( length(pos.xz), pos.y );\n\tfloat l = length(p) - radius;\n\tfloat m = length(p - c*clamp(dot(p,c),0.0,radius) );\n\treturn max(l,m*sign(c.y*p.x-c.x*p.y));\n}\nfloat sdSolidAngleWrapped(vec3 pos, float angle, float radius){\n\treturn sdSolidAngle(pos, vec2(sin(angle), cos(angle)), radius);\n}\nfloat sdTube( vec3 p, float r )\n{\n\treturn length(p.xz)-r;\n}\nfloat sdTubeCapped( vec3 p, float h, float r )\n{\n\tvec2 d = abs(vec2(length(p.xz),p.y)) - vec2(r,h);\n\treturn min(max(d.x,d.y),0.0) + length(max(d,0.0));\n}\nfloat sdOctahedron( vec3 p, float s)\n{\n p = abs(p);\n float m = p.x+p.y+p.z-s;\n vec3 q;\n if( 3.0*p.x < m ) q = p.xyz;\n else if( 3.0*p.y < m ) q = p.yzx;\n else if( 3.0*p.z < m ) q = p.zxy;\n else return m*0.57735027;\n \n float k = clamp(0.5*(q.z-q.y+s),0.0,s); \n return length(vec3(q.x,q.y-s+k,q.z-k)); \n}\nfloat udTriangle( vec3 p, vec3 a, vec3 b, vec3 c, float thickness )\n{\n\tvec3 ba = b - a; vec3 pa = p - a;\n\tvec3 cb = c - b; vec3 pb = p - b;\n\tvec3 ac = a - c; vec3 pc = p - c;\n\tvec3 nor = cross( ba, ac );\n\n\treturn - thickness + sqrt(\n\t\t(sign(dot(cross(ba,nor),pa)) +\n\t\tsign(dot(cross(cb,nor),pb)) +\n\t\tsign(dot(cross(ac,nor),pc))<2.0)\n\t\t?\n\t\tmin( min(\n\t\tdot2(ba*clamp(dot(ba,pa)/dot2(ba),0.0,1.0)-pa),\n\t\tdot2(cb*clamp(dot(cb,pb)/dot2(cb),0.0,1.0)-pb) ),\n\t\tdot2(ac*clamp(dot(ac,pc)/dot2(ac),0.0,1.0)-pc) )\n\t\t:\n\t\tdot(nor,pa)*dot(nor,pa)/dot2(nor) );\n}\nfloat udQuad( vec3 p, vec3 a, vec3 b, vec3 c, vec3 d, float thickness )\n{\n\tvec3 ba = b - a; vec3 pa = p - a;\n\tvec3 cb = c - b; vec3 pb = p - b;\n\tvec3 dc = d - c; vec3 pc = p - c;\n\tvec3 ad = a - d; vec3 pd = p - d;\n\tvec3 nor = cross( ba, ad );\n\n\treturn - thickness + sqrt(\n\t\t(sign(dot(cross(ba,nor),pa)) +\n\t\tsign(dot(cross(cb,nor),pb)) +\n\t\tsign(dot(cross(dc,nor),pc)) +\n\t\tsign(dot(cross(ad,nor),pd))<3.0)\n\t\t?\n\t\tmin( min( min(\n\t\tdot2(ba*clamp(dot(ba,pa)/dot2(ba),0.0,1.0)-pa),\n\t\tdot2(cb*clamp(dot(cb,pb)/dot2(cb),0.0,1.0)-pb) ),\n\t\tdot2(dc*clamp(dot(dc,pc)/dot2(dc),0.0,1.0)-pc) ),\n\t\tdot2(ad*clamp(dot(ad,pd)/dot2(ad),0.0,1.0)-pd) )\n\t\t:\n\t\tdot(nor,pa)*dot(nor,pa)/dot2(nor) );\n}\n\n/*\n*\n* SDF OPERATIONS\n*\n*/\nfloat SDFUnion( float d1, float d2 ) { return min(d1,d2); }\nfloat SDFSubtract( float d1, float d2 ) { return max(-d1,d2); }\nfloat SDFIntersect( float d1, float d2 ) { return max(d1,d2); }\n\nfloat SDFSmoothUnion( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 + 0.5*(d2-d1)/k, 0.0, 1.0 );\n\treturn mix( d2, d1, h ) - k*h*(1.0-h);\n}\n\nfloat SDFSmoothSubtract( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 - 0.5*(d2+d1)/k, 0.0, 1.0 );\n\treturn mix( d2, -d1, h ) + k*h*(1.0-h);\n}\n\nfloat SDFSmoothIntersect( float d1, float d2, float k ) {\n\tfloat h = clamp( 0.5 - 0.5*(d2-d1)/k, 0.0, 1.0 );\n\treturn mix( d2, d1, h ) + k*h*(1.0-h);\n}\n\nvec4 SDFElongateFast( in vec3 p, in vec3 h )\n{\n\treturn vec4( p-clamp(p,-h,h), 0.0 );\n}\nvec4 SDFElongateSlow( in vec3 p, in vec3 h )\n{\n\tvec3 q = abs(p)-h;\n\treturn vec4( max(q,0.0), min(max(q.x,max(q.y,q.z)),0.0) );\n}\n\nfloat SDFOnion( in float sdf, in float thickness )\n{\n\treturn abs(sdf)-thickness;\n}\n\n// /geo1/MAT/rayMarchingBuilder1/checkers1\n// https://iquilezles.org/articles/checkerfiltering/\nfloat checkers(vec2 p) {\n\tvec2 s = sign(fract(p*.5)-.5);\n\treturn .5 - .5*s.x*s.y;\n}\nfloat checkersGrad( in vec2 p, in vec2 ddx, in vec2 ddy )\n{\n // filter kernel\n vec2 w = max(abs(ddx), abs(ddy)) + 0.01;\n // analytical integral (box filter)\n vec2 i = 2.0*(abs(fract((p-0.5*w)/2.0)-0.5)-abs(fract((p+0.5*w)/2.0)-0.5))/w;\n // xor pattern\n return 0.5 - 0.5*i.x*i.y;\n}\n\n\n// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\nconst int _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1 = 1;\n\n\n// https://stackoverflow.com/questions/23793698/how-to-implement-slerp-in-glsl-hlsl\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t)\n// {\n// \tfloat dotp = dot(normalize(p0), normalize(p1));\n// \tif ((dotp > 0.9999) || (dotp < -0.9999))\n// \t{\n// \t\tif (t<=0.5)\n// \t\t\treturn p0;\n// \t\treturn p1;\n// \t}\n// \tfloat theta = acos(dotp);\n// \tvec4 P = ((p0*sin((1.0-t)*theta) + p1*sin(t*theta)) / sin(theta));\n// \tP.w = 1.0;\n// \treturn P;\n// }\n\n// https://devcry.heiho.net/html/2017/20170521-slerp.html\n// float lerp(float a, float b, float t) {\n// \treturn (1.0 - t) * a + t * b;\n// }\n// vec4 quatSlerp(vec4 p0, vec4 p1, float t){\n// \tvec4 qb = p1;\n\n// \t// cos(a) = dot product\n// \tfloat cos_a = p0.x * qb.x + p0.y * qb.y + p0.z * qb.z + p0.w * qb.w;\n// \tif (cos_a < 0.0f) {\n// \t\tcos_a = -cos_a;\n// \t\tqb = -qb;\n// \t}\n\n// \t// close to zero, cos(a) ~= 1\n// \t// do linear interpolation\n// \tif (cos_a > 0.999) {\n// \t\treturn vec4(\n// \t\t\tlerp(p0.x, qb.x, t),\n// \t\t\tlerp(p0.y, qb.y, t),\n// \t\t\tlerp(p0.z, qb.z, t),\n// \t\t\tlerp(p0.w, qb.w, t)\n// \t\t);\n// \t}\n\n// \tfloat alpha = acos(cos_a);\n// \treturn (p0 * sin(1.0 - t) + p1 * sin(t * alpha)) / sin(alpha);\n// }\n\n// https://stackoverflow.com/questions/62943083/interpolate-between-two-quaternions-the-long-way\nvec4 quatSlerp(vec4 q1, vec4 q2, float t){\n\tfloat angle = acos(dot(q1, q2));\n\tfloat denom = sin(angle);\n\t//check if denom is zero\n\treturn (q1*sin((1.0-t)*angle)+q2*sin(t*angle))/denom;\n}\n// TO CHECK:\n// this page https://www.reddit.com/r/opengl/comments/704la7/glsl_quaternion_library/\n// has a link to a potentially nice pdf:\n// http://web.mit.edu/2.998/www/QuaternionReport1.pdf\n\n// https://github.com/mattatz/ShibuyaCrowd/blob/master/source/shaders/common/quaternion.glsl\nvec4 quatMult(vec4 q1, vec4 q2)\n{\n\treturn vec4(\n\tq1.w * q2.x + q1.x * q2.w + q1.z * q2.y - q1.y * q2.z,\n\tq1.w * q2.y + q1.y * q2.w + q1.x * q2.z - q1.z * q2.x,\n\tq1.w * q2.z + q1.z * q2.w + q1.y * q2.x - q1.x * q2.y,\n\tq1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z\n\t);\n}\n// http://glmatrix.net/docs/quat.js.html#line97\n// let ax = a[0], ay = a[1], az = a[2], aw = a[3];\n\n// let bx = b[0], by = b[1], bz = b[2], bw = b[3];\n\n// out[0] = ax * bw + aw * bx + ay * bz - az * by;\n\n// out[1] = ay * bw + aw * by + az * bx - ax * bz;\n\n// out[2] = az * bw + aw * bz + ax * by - ay * bx;\n\n// out[3] = aw * bw - ax * bx - ay * by - az * bz;\n\n// return out\n\n\n\n// http://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/\nmat4 rotationMatrix(vec3 axis, float angle)\n{\n\taxis = normalize(axis);\n\tfloat s = sin(angle);\n\tfloat c = cos(angle);\n\tfloat oc = 1.0 - c;\n\n \treturn mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 0.0, 0.0, 0.0, 1.0);\n}\n\n// https://www.geeks3d.com/20141201/how-to-rotate-a-vertex-by-a-quaternion-in-glsl/\nvec4 quatFromAxisAngle(vec3 axis, float angle)\n{\n\tvec4 qr;\n\tfloat half_angle = (angle * 0.5); // * 3.14159 / 180.0;\n\tfloat sin_half_angle = sin(half_angle);\n\tqr.x = axis.x * sin_half_angle;\n\tqr.y = axis.y * sin_half_angle;\n\tqr.z = axis.z * sin_half_angle;\n\tqr.w = cos(half_angle);\n\treturn qr;\n}\nvec3 rotateWithAxisAngle(vec3 position, vec3 axis, float angle)\n{\n\tvec4 q = quatFromAxisAngle(axis, angle);\n\tvec3 v = position.xyz;\n\treturn v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);\n}\n// vec3 applyQuaternionToVector( vec4 q, vec3 v ){\n// \treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n// }\nvec3 rotateWithQuat( vec3 v, vec4 q )\n{\n\t// vec4 qv = multQuat( quat, vec4(vec, 0.0) );\n\t// return multQuat( qv, vec4(-quat.x, -quat.y, -quat.z, quat.w) ).xyz;\n\treturn v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );\n}\n// https://github.com/glslify/glsl-look-at/blob/gh-pages/index.glsl\n// mat3 rotation_matrix(vec3 origin, vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target - origin);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n// mat3 rotation_matrix(vec3 target, float roll) {\n// \tvec3 rr = vec3(sin(roll), cos(roll), 0.0);\n// \tvec3 ww = normalize(target);\n// \tvec3 uu = normalize(cross(ww, rr));\n// \tvec3 vv = normalize(cross(uu, ww));\n\n// \treturn mat3(uu, vv, ww);\n// }\n\nfloat vectorAngle(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 c1 = cross(start, dest);\n\t// We use the dot product of the cross with the Y axis.\n\t// This is a little arbitrary, but can still give a good sense of direction\n\tvec3 y_axis = vec3(0.0, 1.0, 0.0);\n\tfloat d1 = dot(c1, y_axis);\n\tfloat angle = acos(cosTheta) * sign(d1);\n\treturn angle;\n}\n\n// http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/#i-need-an-equivalent-of-glulookat-how-do-i-orient-an-object-towards-a-point-\nvec4 vectorAlign(vec3 start, vec3 dest){\n\tstart = normalize(start);\n\tdest = normalize(dest);\n\n\tfloat cosTheta = dot(start, dest);\n\tvec3 axis;\n\n\t// if (cosTheta < -1 + 0.001f){\n\t// \t// special case when vectors in opposite directions:\n\t// \t// there is no ideal rotation axis\n\t// \t// So guess one; any will do as long as it's perpendicular to start\n\t// \taxis = cross(vec3(0.0f, 0.0f, 1.0f), start);\n\t// \tif (length2(axis) < 0.01 ) // bad luck, they were parallel, try again!\n\t// \t\taxis = cross(vec3(1.0f, 0.0f, 0.0f), start);\n\n\t// \taxis = normalize(axis);\n\t// \treturn gtx::quaternion::angleAxis(glm::radians(180.0f), axis);\n\t// }\n\tif(cosTheta > (1.0 - 0.0001) || cosTheta < (-1.0 + 0.0001) ){\n\t\taxis = normalize(cross(start, vec3(0.0, 1.0, 0.0)));\n\t\tif (length(axis) < 0.001 ){ // bad luck, they were parallel, try again!\n\t\t\taxis = normalize(cross(start, vec3(1.0, 0.0, 0.0)));\n\t\t}\n\t} else {\n\t\taxis = normalize(cross(start, dest));\n\t}\n\n\tfloat angle = acos(cosTheta);\n\n\treturn quatFromAxisAngle(axis, angle);\n}\nvec4 vectorAlignWithUp(vec3 start, vec3 dest, vec3 up){\n\tvec4 rot1 = vectorAlign(start, dest);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\t// vec3 right = normalize(cross(dest, up));\n\t// up = normalize(cross(right, dest));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(vec3(0.0, 1.0, 0.0), rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(up, newUp);\n\n\t// return rot1;\n\treturn rot2;\n\t// return multQuat(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\n// https://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm\nfloat quatToAngle(vec4 q){\n\treturn 2.0 * acos(q.w);\n}\nvec3 quatToAxis(vec4 q){\n\treturn vec3(\n\t\tq.x / sqrt(1.0-q.w*q.w),\n\t\tq.y / sqrt(1.0-q.w*q.w),\n\t\tq.z / sqrt(1.0-q.w*q.w)\n\t);\n}\n\nvec4 align(vec3 dir, vec3 up){\n\tvec3 start_dir = vec3(0.0, 0.0, 1.0);\n\tvec3 start_up = vec3(0.0, 1.0, 0.0);\n\tvec4 rot1 = vectorAlign(start_dir, dir);\n\tup = normalize(up);\n\n\t// Recompute desiredUp so that it's perpendicular to the direction\n\t// You can skip that part if you really want to force desiredUp\n\tvec3 right = normalize(cross(dir, up));\n\tif(length(right)<0.001){\n\t\tright = vec3(1.0, 0.0, 0.0);\n\t}\n\tup = normalize(cross(right, dir));\n\n\t// Because of the 1rst rotation, the up is probably completely screwed up.\n\t// Find the rotation between the up of the rotated object, and the desired up\n\tvec3 newUp = rotateWithQuat(start_up, rot1);//rot1 * vec3(0.0, 1.0, 0.0);\n\tvec4 rot2 = vectorAlign(normalize(newUp), up);\n\n\t// return rot1;\n\treturn quatMult(rot1, rot2);\n\t// return rot2 * rot1;\n\n}\n\nstruct EnvMapProps {\n\tvec3 tint;\n\tfloat intensity;\n\tfloat roughness;\n\tfloat fresnel;\n\tfloat fresnelPower;\n};\nuniform sampler2D envMap;\nuniform float envMapIntensity;\nuniform float roughness;\n#ifdef ROTATE_ENV_MAP_Y\n\tuniform float envMapRotationY;\n#endif\nvec3 envMapSample(vec3 rayDir, float envMapRoughness){\n\t// http://www.pocketgl.com/reflections/\n\tvec3 env = vec3(0.);\n\t// vec2 uv = vec2( atan( -rayDir.z, -rayDir.x ) * RECIPROCAL_PI2 + 0.5, rayDir.y * 0.5 + 0.5 );\n\t// vec3 env = texture2D(map, uv).rgb;\n\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t#ifdef ROTATE_ENV_MAP_Y\n\t\t\trayDir = rotateWithAxisAngle(rayDir, vec3(0.,1.,0.), envMapRotationY);\n\t\t#endif\n\t\tenv = textureCubeUV(envMap, rayDir, envMapRoughness * roughness).rgb;\n\t#endif\n\treturn env;\n}\nvec3 envMapSampleWithFresnel(vec3 rayDir, EnvMapProps envMapProps, vec3 n, vec3 cameraPosition){\n\t// http://www.pocketgl.com/reflections/\n\tvec3 env = envMapSample(rayDir, envMapProps.roughness);\n\tfloat fresnel = pow(1.-dot(normalize(cameraPosition), n), envMapProps.fresnelPower);\n\tfloat fresnelFactor = (1.-envMapProps.fresnel) + envMapProps.fresnel*fresnel;\n\treturn env * envMapIntensity * envMapProps.tint * envMapProps.intensity * fresnelFactor;\n}\n\n\n\n\n\n\nSDFContext GetDist(vec3 p) {\n\tSDFContext sdfContext = SDFContext(0., 0, 0, 0, 0.);\n\n\t// start GetDist builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/SDFSphere3\n\tfloat v_POLY_SDFSphere3_float = sdSphere(p - vec3(-0.25, 0.0, 0.0), 0.2);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFSphere4\n\tfloat v_POLY_SDFSphere4_float = sdSphere(p - vec3(0.25, 0.0, 0.0), 0.2);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFPlane1\n\tfloat v_POLY_SDFPlane1_float = sdPlane(p-vec3(0.0, -0.2, 0.0), vec3(0.0, 1.0, 0.0), 0.0);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFUnion2\n\tfloat v_POLY_SDFUnion2_union = SDFSmoothUnion(v_POLY_SDFSphere3_float, v_POLY_SDFSphere4_float, 0.31);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFUnion3\n\tfloat v_POLY_SDFUnion3_union = SDFSmoothUnion(v_POLY_SDFUnion2_union, v_POLY_SDFPlane1_float, 0.31);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFContext1\n\tSDFContext v_POLY_SDFContext1_SDFContext = SDFContext(v_POLY_SDFUnion3_union, 0, _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1, _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1, 0.);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/output1\n\tsdfContext = v_POLY_SDFContext1_SDFContext;\n\n\n\n\t\n\n\treturn sdfContext;\n}\n\nSDFContext RayMarch(vec3 ro, vec3 rd, float side) {\n\tSDFContext dO = SDFContext(0.,0,0,0,0.);\n\n\t#pragma unroll_loop_start\n\tfor(int i=0; i<MAX_STEPS; i++) {\n\t\tvec3 p = ro + rd*dO.d;\n\t\tSDFContext sdfContext = GetDist(p);\n\t\tdO.d += sdfContext.d * side;\n\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\tdO.stepsCount += 1;\n\t\t#endif\n\t\tdO.matId = sdfContext.matId;\n\t\tdO.matId2 = sdfContext.matId2;\n\t\tdO.matBlend = sdfContext.matBlend;\n\t\tif(dO.d>MAX_DIST || abs(sdfContext.d)<SURF_DIST) break;\n\t}\n\t#pragma unroll_loop_end\n\n\treturn dO;\n}\n\nvec3 GetNormal(vec3 p) {\n\tSDFContext sdfContext = GetDist(p);\n\tvec2 e = vec2(NORMALS_BIAS, 0);\n\n\tvec3 n = sdfContext.d - vec3(\n\t\tGetDist(p-e.xyy).d,\n\t\tGetDist(p-e.yxy).d,\n\t\tGetDist(p-e.yyx).d);\n\n\treturn normalize(n);\n}\n// https://iquilezles.org/articles/rmshadows\nfloat calcSoftshadow( in vec3 ro, in vec3 rd, float mint, float maxt, float k, inout SDFContext sdfContext )\n{\n\tfloat res = 1.0;\n\tfloat ph = 1e20;\n\tfor( float t=mint; t<maxt; )\n\t{\n\t\tfloat h = GetDist(ro + rd*t).d;\n\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\tsdfContext.stepsCount += 1;\n\t\t#endif\n\t\tif( h<SURF_DIST )\n\t\t\treturn 0.0;\n\t\tfloat y = h*h/(2.0*ph);\n\t\tfloat d = sqrt(h*h-y*y);\n\t\tres = min( res, k*d/max(0.0,t-y) );\n\t\tph = h;\n\t\tt += h;\n\t}\n\treturn res;\n}\n\nvec3 GetLight(vec3 _p, vec3 _n, inout SDFContext sdfContext) {\n\tvec3 dif = vec3(0.,0.,0.);\n\t// GeometricContext geometry;\n\t// geometry.position = _p;\n\t// geometry.normal = _n;\n\t// geometry.viewDir = rayDir;\n\n\t// vec4 mvPosition = vec4( p, 1.0 );\n\t// mvPosition = modelViewMatrix * mvPosition;\n\t// vec3 vViewPosition = - mvPosition.xyz;\n\tvec3 pWorld = ( vModelMatrix * vec4( _p, 1.0 )).xyz;\n\tvec3 nWorld = transformDirection(_n, vModelMatrix);\n\t// geometry.position = (VViewMatrix * vec4( _p, 1.0 )).xyz;\n\tvec3 geometryPosition = (VViewMatrix * vec4(pWorld, 1.0 )).xyz;\n\t// geometry.normal = transformDirection(_n, VViewMatrix);\n\t// geometry.normal = inverseTransformDirection(transformDirection(_n, VViewMatrix), vInverseModelMatrix);\n\tvec3 geometryNormal = transformDirection(nWorld, VViewMatrix);\n\t\n\n\t#if NUM_SPOT_LIGHTS > 0 || NUM_DIR_LIGHTS > 0 || NUM_HEMI_LIGHTS > 0 || NUM_POINT_LIGHTS > 0 || NUM_RECT_AREA_LIGHTS > 0\n\n\t\tIncidentLight directLight;\n\t\tReflectedLight reflectedLight;\n\t\tvec3 lightPos, lightDir, worldLightDir, objectSpaceLightDir, lighDif, directDiffuse;\n\t\tfloat dotNL, lightDistance;\n\t\t#if NUM_SPOT_LIGHTS > 0\n\t\t\tSpotLightRayMarching spotLightRayMarching;\n\t\t\tSpotLight spotLight;\n\t\t\tfloat spotLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\t\t\t\tSpotLightShadow spotLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\t\t\tspotLightRayMarching = spotLightsRayMarching[ i ];\n\t\t\t\tspotLight = spotLights[ i ];\n\t\t\t\tgetSpotLightInfo( spotLight, geometryPosition, directLight );\n\n\t\t\t\t// #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t\t\t// \tspotLightShadow = spotLightShadows[ i ];\n\t\t\t\t// \tvec4 spotLightShadowCoord = spotLightMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t// \tdirectLight.color *= (directLight.visible && receiveShadow) ? getShadow(\n\t\t\t\t// \t\tspotShadowMap[ i ],\n\t\t\t\t// \t\tspotLightShadow.shadowMapSize,\n\t\t\t\t// \t\tspotLightShadow.shadowBias,\n\t\t\t\t// \t\tspotLightShadow.shadowRadius,\n\t\t\t\t// \t\tspotLightShadowCoord\n\t\t\t\t// \t) : 1.0;\n\t\t\t\t// #endif\n\n\t\t\t\tlightPos = spotLight.position;\n\t\t\t\tlightDir = normalize(lightPos-geometryPosition);\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tlightDistance = distance(geometryPosition,lightPos);\n\t\t\t\tspotLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < spotLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t: calcSoftshadow(\n\t\t\t\t\t\t_p,\n\t\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\t\tspotLightRayMarching.shadowBiasDistance,\n\t\t\t\t\t\tdistance(geometryPosition,lightPos),\n\t\t\t\t\t\t1./max(spotLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\t\tsdfContext\n\t\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * spotLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\t\t#if NUM_DIR_LIGHTS > 0\n\t\t\tDirectionalLightRayMarching directionalLightRayMarching;\n\t\t\tDirectionalLight directionalLight;\n\t\t\tfloat dirLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\t\t\t\tDirectionalLightShadow directionalLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\t\t\tdirectionalLightRayMarching = directionalLightsRayMarching[ i ];\n\t\t\t\tdirectionalLight = directionalLights[ i ];\n\t\t\t\t\n\t\t\t\tgetDirectionalLightInfo( directionalLight, directLight );\n\n\t\t\t\t// #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\t\t\t// \tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\t\t\t// \tvec4 dirLightShadowCoord = directionalShadowMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t// \tdirectLight.color *= (directLight.visible && receiveShadow) ? getShadow(\n\t\t\t\t// \t\tdirectionalShadowMap[ i ],\n\t\t\t\t// \t\tdirectionalLightShadow.shadowMapSize,\n\t\t\t\t// \t\tdirectionalLightShadow.shadowBias,\n\t\t\t\t// \t\tdirectionalLightShadow.shadowRadius,\n\t\t\t\t// \t\tdirLightShadowCoord\n\t\t\t\t// \t) : 1.0;\n\t\t\t\t// #endif\n\n\t\t\t\tlightDir = directionalLight.direction;\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tdirLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < directionalLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t:\n\t\t\t\t\tcalcSoftshadow(\n\t\t\t\t\t\t_p,\n\t\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\t\tdirectionalLightRayMarching.shadowBiasDistance,\n\t\t\t\t\t\tMAX_DIST,//distance(geometryPosition,lightPos),\n\t\t\t\t\t\t1./max(directionalLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\t\tsdfContext\n\t\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\t// lighDif = directLight.color * dotNL * dirLightSdfShadow;\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * dirLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\n\t\t#if ( NUM_HEMI_LIGHTS > 0 )\n\n\t\t\t#pragma unroll_loop_start\n\t\t\tHemisphereLight hemiLight;\n\t\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\t\themiLight = hemisphereLights[ i ];\n\t\t\t\tdif += getHemisphereLightIrradiance( hemiLight, geometryNormal ) * BRDF_Lambert( vec3(1.) );\n\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\n\t\t#endif\n\n\t\t#if NUM_POINT_LIGHTS > 0\n\t\t\tPointLightRayMarching pointLightRayMarching;\n\t\t\tPointLight pointLight;\n\t\t\tfloat pointLightSdfShadow;\n\t\t\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\t\t\t\tPointLightShadow pointLightShadow;\n\t\t\t#endif\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\t\t\tpointLightRayMarching = pointLightsRayMarching[ i ];\n\t\t\t\tpointLight = pointLights[ i ];\n\t\t\t\tgetPointLightInfo( pointLight, geometryPosition, directLight );\n\n\n\t\t\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\t\t\t\tpointLightShadow = pointLightShadows[ i ];\n\t\t\t\t\tvec4 pointLightShadowCoord = pointShadowMatrix[ i ] * vec4(pWorld+SHADOW_BIAS*nWorld, 1.0);\n\t\t\t\t\tdirectLight.color *= (directLight.visible && receiveShadow) ? getPointShadow(\n\t\t\t\t\t\tpointShadowMap[ i ],\n\t\t\t\t\t\tpointLightShadow.shadowMapSize,\n\t\t\t\t\t\tpointLightShadow.shadowBias,\n\t\t\t\t\t\tpointLightShadow.shadowRadius,\n\t\t\t\t\t\tpointLightShadowCoord,\n\t\t\t\t\t\tpointLightShadow.shadowCameraNear,\n\t\t\t\t\t\tpointLightShadow.shadowCameraFar\n\t\t\t\t\t) : 1.0;\n\t\t\t\t#endif\n\n\t\t\t\tlightPos = pointLight.position;\n\t\t\t\tlightDir = normalize(lightPos-geometryPosition);\n\t\t\t\tworldLightDir = inverseTransformDirection(lightDir, VViewMatrix);\n\t\t\t\tobjectSpaceLightDir = inverseTransformDirection(worldLightDir, vModelMatrix);\n\t\t\t\tpointLightSdfShadow =\n\t\t\t\t\tdot( _n, objectSpaceLightDir ) < pointLightRayMarching.shadowBiasAngle\n\t\t\t\t\t? 1.\n\t\t\t\t\t:\n\t\t\t\t\tcalcSoftshadow(\n\t\t\t\t\t_p,\n\t\t\t\t\tobjectSpaceLightDir,\n\t\t\t\t\tpointLightRayMarching.shadowBiasDistance,\n\t\t\t\t\tdistance(geometryPosition,lightPos),\n\t\t\t\t\t1./max(pointLightRayMarching.penumbra*0.2,0.001),\n\t\t\t\t\tsdfContext\n\t\t\t\t);\n\t\t\t\tdotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\t\t\t\tdirectDiffuse = dotNL * directLight.color * BRDF_Lambert( vec3(1.) );\n\t\t\t\tdif += directDiffuse * pointLightSdfShadow;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t#endif\n\n\t\t#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\n\t\t\tRectAreaLight rectAreaLight;\n\t\t\t// AreaLightRayMarching areaLightRayMarching;\n\t\t\tPhysicalMaterial material;\n\t\t\tmaterial.roughness = 1.;\n\t\t\tmaterial.specularColor = vec3(1.);\n\t\t\tmaterial.diffuseColor = vec3(1.);\n\n\t\t\tvec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( cameraPosition - geometryPosition );\n\t\t\tvec3 geometryClearcoatNormal = geometryNormal;\n\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\t\t\t// areaLightRayMarching = areaLightsRayMarching[ i ];\n\t\t\t\trectAreaLight = rectAreaLights[ i ];\n\t\t\t\t// rectAreaLight.position = areaLightRayMarching.worldPos;\n\n\t\t\t\tRE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t\tdif += reflectedLight.directDiffuse;\n\n\t\t#endif\n\t#endif\n\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\n\t#if defined( USE_LIGHT_PROBES )\n\n\t\tirradiance += getLightProbeIrradiance( lightProbe, geometryNormal );\n\n\t#endif\n\n\tdif += irradiance;\n\n\treturn dif;\n}\n\n\n\n\nvec3 applyMaterialWithoutRefraction(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(1.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n\nvec3 applyMaterialWithoutReflection(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(1.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n#ifdef RAYMARCHED_REFLECTIONS\nvec3 GetReflection(vec3 p, vec3 n, vec3 rayDir, float biasMult, float roughness, int reflectionDepth, inout SDFContext sdfContextMain){\n\tbool hitReflection = true;\n\tvec3 reflectedColor = vec3(0.);\n\t#pragma unroll_loop_start\n\tfor(int i=0; i < reflectionDepth; i++) {\n\t\tif(hitReflection){\n\t\t\trayDir = reflect(rayDir, n);\n\t\t\tp += n*SURF_DIST*biasMult;\n\t\t\tSDFContext sdfContext = RayMarch(p, rayDir, 1.);\n\t\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\t\tsdfContextMain.stepsCount += sdfContext.stepsCount;\n\t\t\t#endif\n\t\t\tif( sdfContext.d >= MAX_DIST){\n\t\t\t\thitReflection = false;\n\t\t\t\treflectedColor = envMapSample(rayDir, roughness);\n\t\t\t}\n\t\t\tif(hitReflection){\n\t\t\t\tp += rayDir * sdfContext.d;\n\t\t\t\tn = GetNormal(p);\n\t\t\t\tvec3 matCol = applyMaterialWithoutReflection(p, n, rayDir, sdfContext.matId, sdfContextMain);\n\t\t\t\treflectedColor += matCol;\n\t\t\t}\n\t\t}\n\t}\n\t#pragma unroll_loop_end\n\treturn reflectedColor;\n}\n#endif\n\n#ifdef RAYMARCHED_REFRACTIONS\n// xyz for color, w for distanceInsideMedium\nvec4 GetRefractedData(vec3 p, vec3 n, vec3 rayDir, float ior, float biasMult, float roughness, float refractionMaxDist, int refractionDepth, inout SDFContext sdfContextMain){\n\tbool hitRefraction = true;\n\tbool changeSide = true;\n\t#ifdef RAYMARCHED_REFRACTIONS_START_OUTSIDE_MEDIUM\n\tfloat side = -1.;\n\t#else\n\tfloat side = 1.;\n\t#endif\n\tfloat iorInverted = 1. / ior;\n\tvec3 refractedColor = vec3(0.);\n\tfloat distanceInsideMedium=0.;\n\tfloat totalRefractedDistance=0.;\n\n\t#pragma unroll_loop_start\n\tfor(int i=0; i < refractionDepth; i++) {\n\t\tif(hitRefraction){\n\t\t\tfloat currentIor = side<0. ? iorInverted : ior;\n\t\t\tvec3 rayDirPreRefract = rayDir;\n\t\t\trayDir = refract(rayDir, n, currentIor);\n\t\t\tchangeSide = dot(rayDir, rayDir)!=0.;\n\t\t\tif(changeSide == true) {\n\t\t\t\tp -= n*SURF_DIST*(2.+biasMult);\n\t\t\t} else {\n\t\t\t\tp += n*SURF_DIST*( biasMult);\n\t\t\t\trayDir = reflect(rayDirPreRefract, n);\n\t\t\t}\n\t\t\tSDFContext sdfContext = RayMarch(p, rayDir, side);\n\t\t\t#if defined( DEBUG_STEPS_COUNT )\n\t\t\t\tsdfContextMain.stepsCount += sdfContext.stepsCount;\n\t\t\t#endif\n\t\t\ttotalRefractedDistance += sdfContext.d;\n\t\t\tif( abs(sdfContext.d) >= MAX_DIST || totalRefractedDistance > refractionMaxDist ){\n\t\t\t\thitRefraction = false;\n\t\t\t\trefractedColor = envMapSample(rayDir, roughness);\n\t\t\t}\n\t\t\tif(hitRefraction){\n\t\t\t\tp += rayDir * sdfContext.d;\n\t\t\t\tn = GetNormal(p) * side;\n\t\t\t\tvec3 matCol = applyMaterialWithoutRefraction(p, n, rayDir, sdfContext.matId, sdfContextMain);\n\t\t\t\trefractedColor = matCol;\n\n\t\t\t\t// same as: side < 0. ? abs(sdfContext.d) : 0.;\n\t\t\t\tdistanceInsideMedium += (side-1.)*-0.5*abs(sdfContext.d);\n\t\t\t\tif( changeSide ){\n\t\t\t\t\tside *= -1.;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#ifdef RAYMARCHED_REFRACTIONS_SAMPLE_ENV_MAP_ON_LAST\n\t\tif(i == refractionDepth-1){\n\t\t\trefractedColor = envMapSample(rayDir, roughness);\n\t\t}\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n\treturn vec4(refractedColor, distanceInsideMedium);\n}\nfloat refractionTint(float baseValue, float tint, float distanceInsideMedium, float absorption){\n\tfloat tintNegated = baseValue-tint;\n\tfloat t = tintNegated*( distanceInsideMedium*absorption );\n\treturn max(baseValue-t, 0.);\n}\nfloat applyRefractionAbsorption(float refractedDataColor, float baseValue, float tint, float distanceInsideMedium, float absorption){\n\treturn refractedDataColor*refractionTint(baseValue, tint, distanceInsideMedium, absorption);\n}\nvec3 applyRefractionAbsorption(vec3 refractedDataColor, vec3 baseValue, vec3 tint, float distanceInsideMedium, float absorption){\n\treturn vec3(\n\t\trefractedDataColor.r * refractionTint(baseValue.r, tint.r, distanceInsideMedium, absorption),\n\t\trefractedDataColor.g * refractionTint(baseValue.g, tint.g, distanceInsideMedium, absorption),\n\t\trefractedDataColor.b * refractionTint(baseValue.b, tint.b, distanceInsideMedium, absorption)\n\t);\n}\n\n#endif\n\nvec3 applyMaterial(vec3 p, vec3 n, vec3 rayDir, int mat, inout SDFContext sdfContext){\n\n\tvec3 col = vec3(0.);\n\t// start applyMaterial builder body code\n\n\n\n\t// /geo1/MAT/rayMarchingBuilder1/constant2\n\tvec3 v_POLY_constant2_val = vec3(0.04091519690055698, 0.19806931954941637, 0.5271151256969157);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/constant3\n\tvec3 v_POLY_constant3_val = vec3(0.3049873140591091, 0.4452011945063733, 0.623960391667596);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/globals2\n\tvec3 v_POLY_globals2_position = p;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/vec3ToFloat1\n\tfloat v_POLY_vec3ToFloat1_x = v_POLY_globals2_position.x;\n\tfloat v_POLY_vec3ToFloat1_z = v_POLY_globals2_position.z;\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/floatToVec2_1\n\tvec2 v_POLY_floatToVec2_1_vec2 = vec2(v_POLY_vec3ToFloat1_x, v_POLY_vec3ToFloat1_z);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/checkers1\n\tvec2 v_POLY_checkers1_coord = v_POLY_floatToVec2_1_vec2*vec2(1.0, 1.0)*1.8;\n\tfloat v_POLY_checkers1_checker = checkersGrad(v_POLY_checkers1_coord, dFdx(v_POLY_checkers1_coord), dFdy(v_POLY_checkers1_coord));\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/mix1\n\tvec3 v_POLY_mix1_mix = mix(v_POLY_constant2_val, v_POLY_constant3_val, v_POLY_checkers1_checker);\n\t\n\t// /geo1/MAT/rayMarchingBuilder1/SDFMaterial1\n\tif(mat == _GEO1_MAT_RAYMARCHINGBUILDER1_SDFMATERIAL1){\n\t\tcol = vec3(0., 0., 0.);\n\t\tvec3 diffuse = v_POLY_mix1_mix * vec3(1.0, 1.0, 1.0) * GetLight(p, n, sdfContext);\n\t\tcol += diffuse;\n\t\tcol += vec3(0.0, 0.0, 0.0);\n\t}\n\n\n\n\t\n\treturn col;\n}\n\n\n\n\nvec4 applyShading(vec3 rayOrigin, vec3 rayDir, inout SDFContext sdfContext){\n\tvec3 p = rayOrigin + rayDir * sdfContext.d;\n\tvec3 n = GetNormal(p);\n\t\n\tvec3 col = applyMaterial(p, n, rayDir, sdfContext.matId, sdfContext);\n\tif(sdfContext.matBlend > 0.) {\n\t\t// blend material colors if needed\n\t\tvec3 col2 = applyMaterial(p, n, rayDir, sdfContext.matId2, sdfContext);\n\t\tcol = (1. - sdfContext.matBlend)*col + sdfContext.matBlend*col2;\n\t}\n\t\t\n\t// gamma\n\t//col = pow( col, vec3(0.4545) ); // this gamma leads to a different look than standard materials\n\treturn vec4(col, 1.);\n}\n\nvoid main()\t{\n\n\tvec3 rayDir = normalize(vPw - cameraPosition);\n\trayDir = transformDirection(rayDir, vInverseModelMatrix);\n\tvec3 rayOrigin = (vInverseModelMatrix * vec4( cameraPosition, 1.0 )).xyz;\n\n\tSDFContext sdfContext = RayMarch(rayOrigin, rayDir, 1.);\n\n\t#if defined( DEBUG_DEPTH )\n\t\tfloat normalizedDepth = 1.-(sdfContext.d - debugMinDepth ) / ( debugMaxDepth - debugMinDepth );\n\t\tnormalizedDepth = saturate(normalizedDepth); // clamp to [0,1]\n\t\tgl_FragColor = vec4(normalizedDepth);\n\t\treturn;\n\t#endif\n\t#if defined( SHADOW_DEPTH )\n\t\tfloat normalizedDepth = 1.-(sdfContext.d - debugMinDepth ) / ( debugMaxDepth - debugMinDepth );\n\t\t// float fragCoordZ = sdfContext.d / vHighPrecisionZW[1];\n\t\tfloat compoundedDepth = 0.5 * (normalizedDepth) + 0.5;\n\t\tfloat alpha = sdfContext.d < MAX_DIST ? 0.:1.;\n\t\tgl_FragColor = vec4( vec3(compoundedDepth), alpha );\n\t\t// normalizedDepth = 0.5*normalizedDepth+0.5;\n\t\t// gl_FragColor = packDepthToRGBA( normalizedDepth );\n\t\t// gl_FragColor = vec4(0.);\n\t\treturn;\n\t#endif\n\t#if defined( SHADOW_DISTANCE )\n\t\tfloat normalizedDepth = (sdfContext.d - shadowDistanceMin ) / ( shadowDistanceMax - shadowDistanceMin );\n\t\tnormalizedDepth = saturate(normalizedDepth); // clamp to [0,1]\n\t\tgl_FragColor = packDepthToRGBA( normalizedDepth );\n\t\treturn;\n\t#endif\n\n\tif( sdfContext.d < MAX_DIST ){\n\t\tgl_FragColor = applyShading(rayOrigin, rayDir, sdfContext);\n\t\t#if defined( TONE_MAPPING )\n\t\t\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n\t\t#endif\n\t\tgl_FragColor = linearToOutputTexel( gl_FragColor );\n\n\t\t#ifdef USE_FOG\n\t\t\tfloat vFogDepth = sdfContext.d;\n\t\t\t#ifdef FOG_EXP2\n\t\t\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );\n\t\t\t#else\n\t\t\t\tfloat fogFactor = smoothstep( fogNear, fogFar, vFogDepth );\n\t\t\t#endif\n\t\t\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n\t\t#endif\n\t\t#include <premultiplied_alpha_fragment>\n\t\t#include <dithering_fragment>\n\t} else {\n\t\tgl_FragColor = vec4(0.);\n\t}\n\n\t#if defined( DEBUG_STEPS_COUNT )\n\t\tfloat normalizedStepsCount = (float(sdfContext.stepsCount) - debugMinSteps ) / ( debugMaxSteps - debugMinSteps );\n\t\tgl_FragColor = vec4(normalizedStepsCount, 1.-normalizedStepsCount, 0., 1.);\n\t\treturn;\n\t#endif\n\t\n}"}},"jsFunctionBodies":{}}
Code editor
{"multiple_panel":{"split_ratio":0.66,"split_panel0":{"split_ratio":0.5,"split_panel0":{"split_ratio":0.5543217692883486,"split_panel0":{"panelTypes":["viewer"],"currentPanelIndex":0,"panel_data":{"camera":"/cameras/cameras:sopGroup/perspectiveCamera1","isViewerInitLayoutData":true,"linkIndex":1,"overlayedNetwork":{"allowed":false,"displayed":false}}},"split_panel1":{"panelTypes":["params"],"currentPanelIndex":0,"panel_data":{"active_folder":331,"linkIndex":1}},"split_mode":"vertical"},"split_panel1":{"panelTypes":["network","params","viewer"],"currentPanelIndex":0,"panel_data":{"camera":{"position":{"x":309.23864388044683,"y":-248.3325657959398},"zoom":0.5720000000000005},"history":{"2":{"position":{"x":111.45858092111928,"y":211.41919762987428},"zoom":1.0222221069335933},"36":{"position":{"x":164.5,"y":-211.5},"zoom":1.8350000000000004},"325":{"position":{"x":50,"y":0},"zoom":0.8490000000000008},"328":{"position":{"x":309.23864388044683,"y":-248.3325657959398},"zoom":0.5720000000000005},"1049":{"position":{"x":0,"y":0},"zoom":2},"1129":{"position":{"x":129.98560442179834,"y":-52.624173335152435},"zoom":0.6820000000000005}},"paramsDisplayed":false,"linkIndex":1}},"split_mode":"horizontal"},"split_panel1":{"panelTypes":["codePreview"],"currentPanelIndex":0,"panel_data":{"linkIndex":1}},"split_mode":"horizontal"},"currentNodes":["/geo1/MAT/rayMarchingBuilder1","/","/","/","/","/","/","/"],"navigationHistory":{"nodePaths":{"1":["/","/geo1","/geo1/MAT","/geo1/MAT/rayMarchingBuilder1","/geo1/MAT","/geo1","/geo1/MAT","/geo1/MAT/rayMarchingBuilder1","/geo1/MAT","/geo1","/","/geo1","/geo1/MAT","/geo1/MAT/rayMarchingBuilder1"],"2":["/"],"3":["/"],"4":["/"],"5":["/"],"6":["/"],"7":["/"],"8":["/"]},"index":{"1":13,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0}},"fullscreenPanelId":null,"saveOptions":{"checkRemoteAssetsUse":true,"minimizeFilesCount":false},"paramsModal":[]}
Used nodes
cop/envMap;cop/image;cop/imageEXR;event/cameraOrbitControls;mat/rayMarchingBuilder;obj/copNetwork;obj/geo;sop/box;sop/cameraControls;sop/hemisphereLight;sop/material;sop/materialsNetwork;sop/merge;sop/perspectiveCamera;sop/polarTransform;sop/spotLight
Used operations
Used modules
Used assemblers
GL_RAYMARCHING
Used integrations
[]
Used assets
Nodes map
{"/geo1":"obj/geo","/geo1/box1":"sop/box","/geo1/material1":"sop/material","/geo1/MAT":"sop/materialsNetwork","/geo1/MAT/rayMarchingBuilder1":"mat/rayMarchingBuilder","/COP":"obj/copNetwork","/COP/envMap":"cop/envMap","/COP/imageEnv":"cop/imageEXR","/COP/image1":"cop/image","/lights":"obj/geo","/lights/hemisphereLight1":"sop/hemisphereLight","/lights/spotLight1":"sop/spotLight","/lights/polarTransform1":"sop/polarTransform","/lights/merge1":"sop/merge","/cameras":"obj/geo","/cameras/perspectiveCamera1":"sop/perspectiveCamera","/cameras/cameraControls1":"sop/cameraControls","/cameras/cameraControls1/cameraOrbitControls1":"event/cameraOrbitControls"}
Js version
Editor version
Engine version
Logout
0%
There was a problem displaying your scene:
view scene source