feat: initialize sunrise with 100-player shared rooms
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
"""Sculpt a weathered, thick side and rear while preserving the painted front."""
|
||||
import bpy,bmesh,math
|
||||
from mathutils import Vector
|
||||
from mathutils.noise import noise_vector
|
||||
s=bpy.data.scenes['Summit slab and marker'];bpy.context.window.scene=s
|
||||
body=bpy.data.objects['Photo matched summit boulder'];m=body.data
|
||||
if body.get('weatheredSides'):raise RuntimeError('Side study already sculpted; edit it in place.')
|
||||
backup=m.copy();backup.name='Monument before side sculpt';backup.use_fake_user=True
|
||||
half=len(m.vertices)//2
|
||||
# A fuller foot and a rear face that retreats under the narrow shoulder.
|
||||
for v in m.vertices:
|
||||
if v.index>=half:
|
||||
v.co.y+=.15+.20*max(0,1-v.co.z/2.1)
|
||||
for p in m.polygons:
|
||||
if all(i>=half for i in p.vertices):p.material_index=1
|
||||
bm=bmesh.new();bm.from_mesh(m)
|
||||
edges={e for f in bm.faces if f.material_index==1 and any(v.co.y<0 for v in f.verts) for e in f.edges}
|
||||
bmesh.ops.subdivide_edges(bm,edges=list(edges),cuts=9,use_grid_fill=True)
|
||||
bm.normal_update()
|
||||
for v in bm.verts:
|
||||
# Only change the connecting rock wall, with zero displacement at the painted face.
|
||||
if not all(f.material_index==1 for f in v.link_faces):continue
|
||||
x,y,z=v.co
|
||||
if y<-.48+.13*x+.05*z+.03:continue
|
||||
noise=noise_vector(Vector((x*5,y*6,z*5)))[0]
|
||||
bulge=.055*noise+.035*math.sin(z*9+y*4)
|
||||
# Shallow oblique joints break the broad plane; no repeated vertical striping.
|
||||
seam=.055*math.exp(-((z-.64-.32*y)/.045)**2)+.035*math.exp(-((z-1.35+.22*y)/.055)**2)
|
||||
amount=bulge-seam
|
||||
if abs(v.normal.x)>.25:v.co.x+=v.normal.x*amount
|
||||
if v.normal.y>.3:v.co.y+=v.normal.y*amount
|
||||
v.co.z+=v.normal.z*amount*.5
|
||||
bmesh.ops.recalc_face_normals(bm,faces=list(bm.faces));bm.to_mesh(m);bm.free();m.update()
|
||||
# Side and rear each receive spatially scaled UVs instead of collapsed front projections.
|
||||
uv=m.uv_layers['Granite grain UV']
|
||||
for p in m.polygons:
|
||||
if p.material_index!=1:continue
|
||||
n=p.normal
|
||||
for li in p.loop_indices:
|
||||
v=m.vertices[m.loops[li].vertex_index].co
|
||||
if abs(n.z)>.65:coord=(v.x*.9,v.y*.9)
|
||||
elif abs(n.x)>abs(n.y):coord=(v.y*.9,v.z*.9)
|
||||
else:coord=(v.x*.9,v.z*.9)
|
||||
uv.data[li].uv=coord
|
||||
p.use_smooth=True
|
||||
side=m.materials[1];nodes=side.node_tree.nodes;links=side.node_tree.links
|
||||
bs=next(n for n in nodes if n.type=='BSDF_PRINCIPLED')
|
||||
scan=next(n for n in nodes if n.type=='TEX_IMAGE' and n.image and n.image.name.startswith('rock-color'))
|
||||
normal=next(n for n in nodes if n.type=='TEX_IMAGE' and n.image and n.image.name.startswith('rock-normal'))
|
||||
uvnode=next(n for n in nodes if n.type=='UVMAP' and n.uv_map=='Granite grain UV')
|
||||
links.new(uvnode.outputs['UV'],scan.inputs['Vector']);links.new(uvnode.outputs['UV'],normal.inputs['Vector'])
|
||||
links.new(scan.outputs['Color'],bs.inputs['Base Color'])
|
||||
nm=next(n for n in nodes if n.type=='NORMAL_MAP');nm.uv_map='Granite grain UV';nm.inputs['Strength'].default_value=.48
|
||||
links.new(normal.outputs['Color'],nm.inputs['Color']);links.new(nm.outputs['Normal'],bs.inputs['Normal'])
|
||||
bs.inputs['Roughness'].default_value=.96
|
||||
body['weatheredSides']=True
|
||||
r=bpy.data.objects['summit-marker'];s.camera.location=r.location+Vector((4.6,-4.8,2.6));s.camera.rotation_euler=(r.location+Vector((0,.1,.9))-s.camera.location).to_track_quat('-Z','Y').to_euler();s.camera.data.lens=55
|
||||
s.render.filepath='D:/project/sunrise/assets/summit/blender-plateau-study/marker-weathered-side.png'
|
||||
bpy.ops.render.render(write_still=True)
|
||||
print('Sculpted sides:',len(m.vertices),'vertices;',len(m.polygons),'faces. Front paint UVs preserved; sides and rear retextured.')
|
||||
Reference in New Issue
Block a user