본문으로 건너뛰기
cccskills
무료GitHub에 공개

3d-wood-material

Create wood surfaces in Three.js using a single material with code-generated grain, pores, end grain, and finishes. Coordinate color, roughness, and surface relief to improve close-up detail and reduce visible repetition across boards.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

원문원문 설명 보기

Build convincing timber for Three.js as one procedural MeshPhysicalMaterial with growth rings, cathedral figure, pores, medullary rays, checks, tool marks, end grain, and oil, wax, or lacquer finishes, so the grain follows the form and survives macro close-ups without image textures. Use for wood boards, benches, carved panels, tool handles, joinery, floors, and any request to make 3D wood look real, detailed, or less like a tiled photo or plastic.

설치 방법 보기

이럴 때 유용합니다

  • Creating wood grain for furniture, floors, and tool handles
  • Adding pores and end-grain detail for close-up views
  • Adjusting oil, wax, and lacquer finishes
  • Fixing repeated grain patterns and plastic-looking surfaces

포함된 파일(5)

  • SKILL.md10.8 KB
  • agents/openai.yaml311 B
  • demo.html36.7 KB
  • preview.jpg266.3 KB
  • PROMPT.md3.0 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

3D Wood Material

Mechanism: one small periodic noise field, mip-filtered, is read at several different stretches and scales inside the fragment shader, so ring position, latewood, pores, fibres, rays and tool marks all come from the same wandering grain and feed colour, roughness and relief together, each fading out by its own screen footprint.

Boundary. This skill is the wood surface itself. For whole-scene light, rays and scoring wood renders, use 3d-wood-lighting-scorecard. For image-based PBR sets (downloaded maps, texel budgets, KTX2 delivery) use 3d-high-resolution-textures; reach for it when you need a photographed or scanned species. For silhouette, bevel and LOD geometry use 3d-high-poly-models; this skill only needs a rounded arris (below). Cloth, metal and paper have their own siblings.

Run demo.html first (Kibori bench, four species, four finishes, macro views, and a switch that swaps in the failure). PROMPT.md recreates it.

Recipe

  1. Patch, do not replace. Build MeshPhysicalMaterial({color:0xffffff, roughness:max(0.43,r), ior:1.43, specularIntensity:0.72}) and edit it in onBeforeCompile: #include <map_fragment> multiplies diffuseColor by the wood colour, #include <roughnessmap_fragment> sets roughnessFactor=clamp(roughness*W.rough,0.35,1), #include <normal_fragment_maps> replaces the normal with a screen-space bump of the wood height W.h. Lighting, shadows, IBL and tone-mapping stay stock. The vertex stage only passes object-space position vOP and the object normal.
  2. Bake one field. A 1024² RepeatWrapping, LinearMipmapLinear, NoColorSpace render target of periodic gradient noise (period 64, three octaves: .r base, .g fbm 0.60/0.27/0.13, .b a shifted copy). Reading it as texture(p/64) costs one tap. All timber shares it; per-board difference is a seed offset, not a texture.
  3. Grain axis. uAxis 0/1/2 picks the log axis; along is that coordinate and cross2 the other two. endgrain = pow(|n·axis|, 6) flips pores from streaks to open cells and dulls the colour on cut faces.
  4. Rings. Drift the pith with two slow fields, radius=|(cross2+(-drift, offAxis+0.48))*(1,0.56)|, growth=radius*ringFreq plus fbm wobble (±1.25 rings), ring=floor(growth), phase=fract. Each ring draws its own width from annual noise: lateWidth=0.065+annual*0.21. Latewood is a steep smoothstep(0.94-w, 0.97-w, phase) cut off by 1-smoothstep(0.965,1,phase). Small offAxis gives cathedral arcs; large offAxis gives straight quarter-sawn lines.
  5. Detail layers, each faded by its own footprint (fwidth of growth, length(dFdx,dFdy) of the pore, fibre and ray coordinates):
layercoordinatesstrength
pores (vessels)(fiberX*96, along*7.5), cells at end grain cross2*88, smoothstep(0.59,0.75)tone +0.25, rough +0.19, height -0.42
fibres(fiberX*230, along*2.4)tone -0.16, height +0.09, x0.25 at end grain
rays(across*13, along*115), smoothstep(0.64,0.78)tone +0.26 towards pale, rough -0.075
checkscurl.b smoothstep(0.70,0.82) x uCheckstone toward dark*0.68, height -0.20
knotshash cell 1.85 x 4.6, 29% occupied, influence dies at the cell edgetone +0.44 core, deflects fibres
tool marks(along*17, across*0.4)height +0.045 x uTool
  1. Tone: tone=0.075+late*0.40+early*0.070+pores*0.25-fibres*0.16+(broad.g-0.5)*0.23+knotCore*0.44, colour mix(pale,dark,clamp(tone,0.035,0.83)), then *(0.93+annual*0.095+…). Roughness 0.91+late*0.13+pores*0.19+(broad.b-0.5)*0.20-rays*0.075+endgrain*0.14.
  2. Bump, not normal map. bumpNormal uses the derivative-based Mikkelsen bump and clamps the gradient to 0.38*|det|, so a steep step never flips the normal. uBump=bump*0.020.
  3. Finishes are parameters, not textures. Raw: clearcoat 0. Oil: pow(rgb,1.16) and rough*0.88, clearcoat 0.10 / 0.55. Wax: clearcoat 0.22 / 0.38. Urushi: luminance curve pow(l,0.5), end grain darkened *(1-eg*0.55), warm tint, worn arrises rubbed back to the pale colour, clearcoat 0.42 / 0.40.
  4. Round the arris. chamferBox on every board, radius min(w,h,d)*0.055 (at most 0.24 of any side), 3 to 5 segments, with normals set from the rounded corner. A sharp box edge has no highlight and reads as a cut-out.
  5. Give every board its own seed, and keep it stable when species or finish changes (save and restore woodMaterialSerial around the build, seed n*7.113). Offset the geometry through the field (woodBox(..., ox,oy,oz)) so merged or shared materials still differ.

Species constants (from the workshop)

speciespale / darkroughgrainringFreqoffAxisnotes
keyaki#8a5f38 / #3d24120.621.520 to 340.75rays 0.35, bump 0.10
sugi#c8a579 / #9b774d0.581.88 to 302.8crisp latewood, tool 0.30
hinoki#d8c096 / #8a6b400.44 to 0.502.26 to 421.6close-grained, low contrast
kuri#6f4d2c / #2c1a0b0.553.05 to 221.4rays 0.5, checks 0.10
charred siding#1a1511 / #0e0b080.970.890.55rays 0, checks 0.30

ringFreq is per unit of the model, so set it from real ring spacing (about 2 to 5 mm at the scale you are modelling) rather than copying a number between scenes: the workshop's 7 to 8 read as bold stripes at demo scale until raised to 20 to 42.

Anchored failures

  • A repeated tile is visible at the second board. A canvas tile with repeat prints identical rings on every board and shows its seam in a raking light. Sample object-space position, seed per material, offset geometry through the field.
  • Flat roughness looks like plastic. Roughness must move with the grain: pores rougher (+0.19), latewood slightly rougher (+0.13), rays glossier (-0.075). A constant 0.3 gives a uniform bright sheen that never breaks along a ring.
  • Colour only, no relief. Rings drawn only in albedo go flat when the light rakes. Feed the same late, pores and fibres into the height and bump it; and clamp the gradient or a hard ring edge turns the normal inside out.
  • Grain not following the form. Take along from the member's real axis, not from UV. UV on a chamfered box stretches the pores at the rounded edge and turns a board into a stripe test. With object-space sampling the grain runs straight through corners and end faces switch pores to cells automatically.
  • Detail shimmers or crawls at distance and on grazing faces. Every high-frequency layer must fade by its own screen footprint: x *= 1 - smoothstep(a, b, fwidth-of-its-coordinate). Mip the field, and blend late and early toward their averages when fwidth(growth) passes 0.16..0.72. Without this, rings moire into the wall of the board at 3 m.
  • Macro looks smeared, blobby, or a faint square lattice shows in the relief. The 1024² field is being magnified past about 2,500 to 4,000 px per unit at grain 1.0: bilinear texel edges leak into the bump derivatives as a grid, pore cells go soft and ring edges dot at the boundary. Raise uGrainScale for a finer fibre size, or raise the bake to 2048 for hero surfaces; never rescale the mesh instead.
  • Colour-space slip. The field is data: NoColorSpace, not sRGB. Tone-mapping is applied once at the end (the workshop does it in a hand-written final pass; the demo uses ACESFilmicToneMapping).
  • The oil finish lit the raw finish. Materials that differ only by the extra snippet share one program cache key (onBeforeCompile.toString()), so the second material silently reuses the first program. Set a distinct customProgramCacheKey per finish; the Urushi wrapper does.
  • Environment lights no roughness variation. envMapIntensity is ignored when only scene.environment is set (r163+); use scene.environmentIntensity. The wood needs a bright window card in the PMREM to show its roughness map; a grey dome hides it.
  • Cut faces read the same as the top. Multiply cut faces by 1 - endgrain*(0.045+pores*0.10) and raise their roughness +0.14: end grain drinks finish and stays matt, the fastest cue that this is a solid block.
  • Sharp boards float. A box with no arris and no contact shadow looks pasted. Rest each part exactly on its support (y = h/2), bake the shadow map once (shadowMap.autoUpdate=false) and check the close-up for a gap.

Budgets

  • Bake once, 1024² RGBA8 with mips (about 5.6 MB GPU), shared by every timber.
  • Measured on this Apple GPU in headless Chrome, 13 draw calls and about 2,000 triangles (chamfered boxes, bench, wall) with MSAA on: 1.0 to 1.5 ms per frame at 1440 by 900, 3.4 to 4.5 ms at 2880 by 1800, against 0.65 ms and 4.2 ms for a plain tiled MeshStandardMaterial. The procedural shader costs roughly 0.4 ms at 1x on this scene and vanishes into fill cost at 2x. Fill rate (DPR, MSAA) is the lever, not the noise.
  • Cap DPR at 2. Bake shadows once when the boards are static. Pause on document.hidden and reset the clock. Clamp dt to 1/30 s.
  • Under prefers-reduced-motion skip the slow orbit and snap camera moves; the still is the composed hero view. Controls stay live.

Self-score of this material (0 to 10, anchored)

Anchors: 2 tiled photo with flat roughness. 4 procedural stripes with albedo only. 6 rings plus relief plus varied roughness, holds at arm's length. 8 pores, rays and end grain hold at 5 cm, finish and wear are believable, no shimmer. 10 scanned-species photograph at every distance.

dimensionscorewhy
grain structure at arm's length7.5per-ring widths, cathedral arcs and knots; keyaki at default still reads a little ruled
macro (3 to 5 cm)6.5pores, fibres and tool marks resolve; the 1024² field softens past 4,000 px per unit
roughness and finish7.5oil, wax and urushi respond to rings and pores; no anisotropic highlight
end grain and edges7open cells and matt cut faces; arris round, no true edge wear
shimmer and grazing8footprint fades leave grazing and distance clean
overall7.3

Provenance

Extracted from the Kibori 木彫 workshop page, where one woodMat() timber shader dresses the walls, benches, tool handles, kumiko lattice and lacquered chests; the generators in demo.html are copied from that file unchanged. The wood was tuned for a close inspect camera, so every constant above is the workshop's own.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Build woven fabric in Three.js with visible threads, realistic sheen, seams, and thick hems. The skill covers folds that preserve texture proportions, light passing through thin cloth, and variations in dye and wear.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Creating backlit curtains
  • Differentiating linen, silk, and wool
  • Adding hems and stitches for close-up views
MengTo/Skills6.9천2026년 10월 18일 업데이트

Build falling leaves in Three.js and similar 3D scenes, with visible front, edge, and back views as they tumble and drift. Coordinate wind, scene depth, camera-aware recycling, and performance checks for a convincing autumn effect.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Adding falling autumn leaves to a 3D scene
  • Coordinating leaf tumble, sideways drift, and wind
  • Managing leaves around buildings and camera movement
MengTo/Skills6.9천2026년 10월 18일 업데이트

Add coordinated seasonal transitions to an existing 3D scene. Blend foliage, lighting, sky, ground, snow, and particles from one shared state while preserving camera controls and interactions, so the same place remains recognizable throughout spring, summer, fall, and winter.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Add a four-season selector to an outdoor 3D scene
  • Show seasonal changes in an architectural walkthrough
  • Coordinate foliage, sunlight, sky, and ground appearance
MengTo/Skills6.9천2026년 10월 18일 업데이트

Create or integrate detailed 3D models with smooth outlines and believable edges for close-up views. Prepare lower-detail versions for distant viewing, prioritize loading, and measure rendering costs in the actual scene.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Creating a detailed 3D model for close-up views
  • Replacing visibly faceted curves with smoother geometry
  • Preparing detailed architectural assets for rendering
MengTo/Skills6.9천2026년 10월 18일 업데이트

Prepare detailed 3D materials that remain clear in close-up views. The skill guides texture resolution, physically based material maps, surface mapping, filtering, and progressive loading while checking download size and GPU memory use.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Prepare wood, stone, and fabric materials for close-up views
  • Fix texture seams, grain direction, and normal map orientation
  • Preserve floor and foliage detail at oblique or distant views
MengTo/Skills6.9천2026년 10월 18일 업데이트

Create realistic metal surfaces in Three.js by combining structured reflections, studio lighting, scratches, fingerprints, and beveled edges. Includes polished, brushed, and aged finishes for objects such as tools, rings, and metal product parts.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Fixing metal that looks like gray plastic
  • Creating polished or brushed metal finishes
  • Adding patina and worn edges
MengTo/Skills6.9천2026년 10월 18일 업데이트

MengTo의 스킬 모두 보기

이 스킬의 문제 신고