[{"data":1,"prerenderedAt":393},["ShallowReactive",2],{"project-44187645":3},{"id":4,"name":5,"line":6,"line_source":7,"title":8,"url":9,"domain":10,"maker":11,"posted_at":12,"year":13,"points":14,"comments":15,"rank_in_year":16,"shown_in_year":17,"top":18,"tier":19,"category":20,"subcategory":21,"format":22,"keywords":23,"reception":29,"sentiment":30,"stance_mix":31,"scored_comments":36,"aspects":37,"strip":46,"post_text":48,"what":49,"said":74,"maker_in_thread":160,"shape":173,"grid":177,"attempts":356,"same_week":357,"maker_shows":40,"maker_hidden":385,"reader_version":386,"card":387},"44187645","simple-3d-svg","A 3D SVG Renderer that projects textures without rasterization","title","Show HN: I made a 3D SVG Renderer that projects textures without rasterization","https:\u002F\u002Fseve.blog\u002Fp\u002Fi-made-a-3d-svg-renderer-that-projects","seve.blog","seveibar",1749089133,2025,206,71,305,3837,8,"notable","dev_tools","svg renderer","library",[24,25,26,27,28],"svg","3d rendering","perspective projection","texture mapping","typescript","roasted",-0.269,{"positive":32,"neutral":33,"mixed":34,"critical":35},4,13,0,19,36,{"execution":38,"idea":41,"design":44,"performance":45},{"positive":39,"critical":40},1,5,{"positive":42,"critical":43},2,10,{"positive":39,"critical":34},{"positive":34,"critical":32},[39,34,39,47,47,39,40,40,39,34,47,34,47,39,34,39,39,39,47,47,34,47,47,39,39,39,39,47,34,47,40,34,34,39,39,39,39,47,34,34],3,null,{"problem":50,"audience":48,"pricing":48,"motivation":60,"time_to_build":48,"stack":67,"openness":72,"stage":73,"team_size":73},{"value":51,"source":52,"evidence":53},"Renders 3D scenes and textured surfaces as SVG without a browser or rasterization.","maker",[54,57],{"id":55,"by":11,"text":56},"44188530","The goal for this vanilla TS renderer is to have visual diffing on GitHub and a renderer that works without a browser environment. Most 3D renderers focus on realtime speed, not…",{"id":58,"by":11,"text":59},"44192070","The top of the PCB (the lines etc) are computed as an SVG, i would have to have an SVG rasterizer just to begin with that approach, then would be limited by what images I could…",{"value":61,"source":52,"evidence":62},"Visual diffing of PCB renders on GitHub and portable rendering without a browser.",[63,64],{"id":55,"by":11,"text":56},{"id":65,"by":11,"text":66},"44191998","Very small files and a much simpler rendering scheme! I don’t have to rasterize my SVGs that represent the top of my board",[68],{"value":69,"source":52,"evidence":70},"TypeScript",[71],{"id":55,"by":11,"text":56},"open_source","unknown",{"praise":75,"objections":89,"requests":119,"questions":128,"alternatives":140},[76],{"value":77,"source":78,"evidence":79},"Clever technique and cool to see SVG doing 3D projection.","commenter",[80,84,88],{"id":81,"by":82,"text":83},"44188259","dedicate","This is seriously cool! I've always mentally boxed SVG into the 2D corner, so seeing it handle 3D projection like this is pretty mind-bending...",{"id":85,"by":86,"text":87},"44189963","stuaxo","Awesome. If this gets really popular I could imagine perspective transforms being proposed for SVG itself.",{"id":55,"by":11,"text":56},[90,105],{"value":91,"source":78,"evidence":92},"The perspective math is wrong; diagonals curve and squares look equal area.",[93,97,101],{"id":94,"by":95,"text":96},"44190178","badmintonbaseba","I don't think your algorithm is correct. At least on the checkerboard example on the cube face the diagonals are curved. Perspective transformation doesn't do that. Possibly you…",{"id":98,"by":99,"text":100},"44191215","mistercow","Even more obviously, the squares in the front aren’t bigger than the squares in the back. It looks like each square has equal area even as their shapes change. It’s fascinating…",{"id":102,"by":103,"text":104},"44192479","Masterjun","I think the original commenter is correct that there is a mistake in the perspective code. It seems the code calculates the linear interpolation for the grid points too late. It…",{"value":106,"source":78,"evidence":107},"SVG is the wrong tool; performance will suffer with many elements.",[108,112,116],{"id":109,"by":110,"text":111},"44188501","jesse__","\"it's a lightweight SVG renderer\" Meanwhile.. drawing 512 subdivisions for a single textured quad. It's a cute trick, certainly, but ask this thing to draw anything more than a…",{"id":113,"by":114,"text":115},"44194550","leptons","SVG is the wrong tool for this job.",{"id":117,"by":114,"text":118},"44196372","I think you'll probably run into performance problems with SVG before you get too far. I can't imagine SVG will perform fluidly with complex circuit boards. SVG elements are DOM…",[120],{"value":121,"source":78,"evidence":122},"Use WebGL or a plain JS rasterizer instead.",[123,124],{"id":109,"by":110,"text":111},{"id":125,"by":126,"text":127},"44189216","kookamamie","Why use SVG for this, though? This could be easily implemented as pure JS software rasterizer without all the tessellation workarounds.",[129],{"value":130,"source":78,"evidence":131},"Why use SVG for this rather than a canvas or PNG?",[132,133,137],{"id":125,"by":126,"text":127},{"id":134,"by":135,"text":136},"44191820","itishappy","This doesn't answer the question. If you're doing all this work in JS to render a static SVG, why not just \"do it right\" and output a static PNG instead?",{"id":138,"by":114,"text":139},"44194599","When things like Three.js exist, developing an SVG 3D engine to display circuit boards seems like a ridiculous thing to do. Why did you feel you had to do this with SVG?",[141,149,153],{"value":142,"source":78,"evidence":143},"Three.js",[144,145],{"id":138,"by":114,"text":139},{"id":146,"by":147,"text":148},"44190524","moron4hire","Three.js has had an SVG rendering back end for 13 years. It's going to be pretty hard to get much more popular than Three.js to get over the browser vendors' reluctance to make…",{"value":150,"source":78,"evidence":151},"WebGL",[152],{"id":109,"by":110,"text":111},{"value":154,"source":78,"evidence":155},"librsvg",[156],{"id":157,"by":158,"text":159},"44193477","jahewson","You might find that librsvg works for you.",{"comments":161,"answered":162,"key":163},12,6,[164,167,170],{"id":165,"text":166},"44194570","I've updated the article with the fixed projection transform! I had to make an animation as well just to validate it- I fooled myself!",{"id":168,"text":169},"44191965","Author here: I don’t think the commenter here has set the same focal length, the focal length can make a surface appear curved, I set it explicitly to a low value to test the…",{"id":171,"text":172},"44192602","That admittedly looks a lot more correct! Thanks for digging in, i will absolutely test and submit a correction to the article (i am still concerned the straight edges are…",{"commenters":174,"max_depth":18,"maker_replies":161,"first_comment_mins":175,"lifespan_hours":176},40,24,199,[178,180,184,187,190,193,197,200,202,204,205,207,210,212,214,215,216,218,220,223,227,230,233,236,240,244,247,248,250,252,255,256,257,258,260,263,266,269,271,274,278,280,284,287,290,292,294,295,299,301,303,305,308,313,316,317,320,322,324,327,328,331,335,338,340,341,343,345,346,349,352],[94,34,39,179,95,34],"project\u002Fcritical\u002Fexecution",[181,34,34,182,183,34],"44190332","commenter\u002Fneutral\u002Fnone","Karliss",[185,34,34,182,186,34],"44191017","frizlab",[188,34,34,182,189,34],"44197018","fc417fc802",[191,34,39,179,192,34],"44190633","jeremyscanvic",[194,34,47,195,196,34],"44190693","project\u002Fneutral\u002Fidea","ricardobeat",[198,34,47,199,95,34],"44190931","project\u002Fneutral\u002Fexecution",[201,34,47,199,135,34],"44191645",[203,34,39,179,192,34],"44190945",[98,34,39,179,99,34],[165,34,34,206,11,39],"maker\u002Fpositive\u002Fexecution",[208,34,40,209,192,34],"44195310","project\u002Fpositive\u002Fdesign",[211,34,40,206,99,34],"44267032",[168,34,34,213,11,39],"maker\u002Fneutral\u002Fexecution",[102,34,39,179,103,34],[171,34,34,213,11,39],[217,34,34,182,192,34],"44192919",[219,34,34,213,11,39],"44193563",[221,39,47,195,222,34],"44188554","gyf304",[224,39,34,225,226,34],"44190376","other\u002Fneutral\u002Fnone","bhouston",[228,39,34,225,229,34],"44191571","BearOso",[231,39,34,225,232,34],"44192089","bn-l",[234,42,47,195,235,34],"44187802","JKCalhoun",[237,42,39,238,239,34],"44188228","project\u002Fcritical\u002Fperformance","kibibu",[241,42,34,242,243,34],"44189343","other\u002Fneutral\u002Fperformance","taylorius",[245,42,34,242,246,34],"44193418","rixed",[109,47,39,238,110,34],[55,47,34,249,11,39],"maker\u002Fneutral\u002Fperformance",[125,47,39,251,126,34],"project\u002Fcritical\u002Fidea",[253,47,47,254,196,34],"44190719","maker\u002Fneutral\u002Fidea",[134,47,39,251,135,34],[58,47,34,254,11,39],[157,47,47,199,158,34],[259,47,47,199,135,34],"44193769",[261,32,34,225,262,34],"44194002","exabrial",[264,40,34,225,265,34],"44196579","shaftway",[267,162,34,225,268,34],"44189247","laszlokorte",[270,162,47,195,95,34],"44190431",[272,162,34,273,11,39],"44194543","project\u002Fpositive\u002Fidea",[275,162,47,276,277,34],"44194734","project\u002Fneutral\u002Fperformance","CrimsonCape",[279,162,34,242,268,34],"44196563",[281,282,39,251,283,34],"44188406",7,"rollulus",[285,282,34,182,286,34],"44192198","bufferoverflow",[288,18,39,251,289,34],"44191984","iamleppert",[291,18,39,251,135,34],"44192133",[293,18,39,238,246,34],"44193429",[113,18,39,251,114,34],[296,297,47,199,298,34],"44189166",9,"unwind",[300,297,34,213,11,39],"44192257",[302,43,34,225,235,34],"44187824",[304,43,34,213,11,39],"44187839",[306,43,34,225,307,34],"44188028","90s_dev",[309,310,47,311,312,34],"44189783",11,"project\u002Fneutral\u002Fdesign","weinzierl",[314,310,34,315,11,39],"44192674","maker\u002Fneutral\u002Fdesign",[81,161,40,273,82,34],[318,33,34,225,319,34],"44190641","m-a-t-t-i",[321,33,34,182,95,34],"44190683",[323,33,34,182,319,34],"44192329",[325,326,39,251,135,34],"44191835",14,[65,326,34,254,11,39],[329,326,39,330,135,34],"44192117","maker\u002Fcritical\u002Fidea",[332,333,47,195,334,34],"44192891",15,"looneysquash",[336,337,39,251,246,34],"44193453",16,[339,337,34,195,11,39],"44194421",[117,337,39,238,114,34],[138,342,39,251,114,34],17,[85,344,40,273,86,34],18,[146,344,34,225,147,34],[347,344,34,225,348,34],"44191492","chrismorgan",[350,35,34,225,351,34],"44188948","est",[353,354,34,225,355,34],"44188197",20,"ndgold",[],[358,363,367,371,376,380],{"id":359,"name":360,"points":361,"category":362},"44189329","Air Lab",497,"hardware",{"id":364,"name":365,"points":366,"category":362},"44241278","tsungxu.com",418,{"id":368,"name":369,"points":370,"category":20},"44238171","Chili3d",408,{"id":372,"name":373,"points":374,"category":375},"44249565","Spark",377,"languages",{"id":377,"name":378,"points":379,"category":20},"44225352","Bugdrop",335,{"id":381,"name":382,"points":383,"category":384},"44226879","Munal OS",313,"infrastructure",false,"v2",{"id":388,"name":5,"line":6,"ai":385,"cat":20,"year":13,"points":14,"comments":15,"rec":29,"s":389,"top":18,"kw":390,"maker":11,"domain":10,"tier":19,"attempts":34,"strip":391,"url":9,"mix":392,"praise":77,"objection":91,"sub":21},44187645,-0.27,[24,25,26,27,28],"1013315510303101113303311113035001111300",[32,33,34,35],1793991122560]