code wiki / (root) / nx_cast_surface_normal_t133.nx

nx_cast_surface_normal_t133.nx source

↩ module page · 113 lines · 7728 B

1// Private stage adapter: reuse canonical cast deformation IR without duplicating skinning arithmetic. 2// Input: four vec4 lanes per body vertex (position,normal,joints,weights). 3// Output: two vec4 lanes per actor/source vertex (world position, deformed normal). 4// Header dimensions extend the SAME uniform declaration owner; host uses emitted layout. 5import "nx_cast_shader_src.nx" 6const CSURF_INPUT_BIND:i64=5 7const CSURF_OUTPUT_BIND:i64=6 8const CSURF_INPUT_LANES:i64=4 9const CSURF_OUTPUT_LANES:i64=2 10func csurf_lane(m:*i64,slot:*u8)->i64{ 11 return sir_index(m,sir_ident(m,"surfaceIn",T_V4F),cs_iadd(m,cs_imul(m,cs_i(m,"svIndex"),ws_i(m,"4")),ws_i(m,slot)),T_V4F) 12} 13func shsrc_cast_surface_compute_v1(m:*i64)->i64{ 14 shsrc_cast_decls(m) 15 // Attributes/varyings become private per-invocation state for compute. Uniforms/textures stay identical. 16 var d:i64=m[M_DECLH];while d!=0{let k:i64=sir_get(m,d,SIR_KIND) 17 if k==K_ATTRIB||k==K_VARY{sir_set(m,d,SIR_KIND,K_PRIVATE);sir_set(m,d,SIR_A,0);sir_set(m,d,SIR_B,0);sir_set(m,d,SIR_C,0)} 18 d=sir_get(m,d,SIR_NEXT) 19 } 20 sir_uniform(m,"uSurfaceVertices",T_I32,0);sir_uniform(m,"uSurfaceActors",T_I32,0) 21 sir_storage(m,"surfaceIn",T_V4F,CSURF_INPUT_BIND,0,0);sir_storage(m,"surfaceOut",T_V4F,CSURF_OUTPUT_BIND,1,0) 22 shsrc_cast_fn_hsh(m) 23 let f:i64=sir_func(m,"main",T_VOID) 24 let gid:i64=sir_builtin(m,"global_invocation_id",T_V3U) 25 ws_st(m,f,sir_var(m,"svIndex",T_I32,cs_i32(m,sir_swz(m,gid,"x",T_U32)))) 26 ws_st(m,f,sir_var(m,"ii",T_I32,cs_i32(m,sir_swz(m,gid,"y",T_U32)))) 27 let outside:i64=ws_or(m,ws_cmp(m,">=",cs_i(m,"svIndex"),cs_i(m,"uSurfaceVertices")),ws_cmp(m,">=",cs_i(m,"ii"),cs_i(m,"uSurfaceActors"))) 28 let unsupported:i64=ws_or(m,ws_cmp(m,"!=",cs_i(m,"uGar"),ws_i(m,"0")),ws_cmp(m,"!=",cs_i(m,"uHM"),ws_i(m,"1"))) 29 ws_st(m,f,ws_if(m,ws_or(m,outside,unsupported),sir_return(m,0),0)) 30 ws_st(m,f,ws_set(m,cs_v3(m,"aP"),ws_sw(m,csurf_lane(m,"0"),"xyz",T_V3F))) 31 ws_st(m,f,ws_set(m,cs_v3(m,"aN"),ws_sw(m,csurf_lane(m,"1"),"xyz",T_V3F))) 32 ws_st(m,f,ws_set(m,cs_v4(m,"aJ"),csurf_lane(m,"2"))) 33 ws_st(m,f,ws_set(m,cs_v4(m,"aW"),csurf_lane(m,"3"))) 34 ws_st(m,f,ws_set(m,cs_fl(m,"aHS"),ws_f(m,"0.0"))) 35 ws_st(m,f,ws_set(m,cs_fl(m,"vSh"),ws_f(m,"1.0"))) 36 ws_st(m,f,sir_var(m,"jit",T_V3F,ws_v1(m,T_V3F,ws_f(m,"0.0")))) 37 cs_slice2(m,f);cs_slice3(m,f) 38 // The pre-skin garment branch references vertex_index; compute uses the same explicit source index. 39 var id:i64=1;while id<m[M_NCOUNT]{if sir_get(m,id,SIR_KIND)==E_BUILTIN{ 40 if sir_slen(sir_cstr(m,sir_get(m,id,SIR_NAME)))==12{let nm:*u8=sir_cstr(m,sir_get(m,id,SIR_NAME));let expected:*u8="vertex_index";var eq:i64=1;var at:i64=0;while at<12{if nm[at]!=expected[at]{eq=0};at=at+1};if eq==1{ 41 sir_set(m,id,SIR_KIND,E_IDENT);sir_set(m,id,SIR_NAME,sir_str(m,"svIndex")) 42 }} 43 };id=id+1} 44 let oi:i64=cs_imul(m,cs_iadd(m,cs_imul(m,cs_i(m,"ii"),cs_i(m,"uSurfaceVertices")),cs_i(m,"svIndex")),ws_i(m,"2")) 45 ws_st(m,f,sir_var(m,"surfaceIndex",T_I32,oi)) 46 let op:i64=sir_index(m,sir_ident(m,"surfaceOut",T_V4F),cs_i(m,"surfaceIndex"),T_V4F) 47 let on:i64=sir_index(m,sir_ident(m,"surfaceOut",T_V4F),cs_iadd(m,cs_i(m,"surfaceIndex"),ws_i(m,"1")),T_V4F) 48 ws_st(m,f,ws_set(m,op,ws_v4(m,cs_sx3(m,"wp","x"),cs_sx3(m,"wp","y"),cs_sx3(m,"wp","z"),ws_f(m,"1.0")))) 49 ws_st(m,f,ws_set(m,on,ws_v4(m,cs_sx3(m,"vN","x"),cs_sx3(m,"vN","y"),cs_sx3(m,"vN","z"),ws_f(m,"0.0")))) 50 return f 51} 52 53// Preserve the incumbent smooth normal when it has a direction. Exact cancellation 54// uses the current deformed triangle's geometric normal, not an invented world axis. 55// A collapsed deformed triangle has zero normal and zero normal offset; it is not a fit pass. 56func csurf_finish_normal_v1(m:*i64,f:i64,n:i64,edge_a:i64,edge_b:i64)->i64{ 57 ws_st(m,f,sir_var(m,"surfaceNormal",T_V3F,n)) 58 ws_st(m,f,ws_set(m,cs_v3(m,"vN"),ws_v1(m,T_V3F,ws_f(m,"0.0")))) 59 let geometric:i64=sir_var(m,"surfaceGeometric",T_V3F,cs_cross(m,edge_a,edge_b)) 60 let geom_ok:i64=ws_cmp(m,">",cs_dot(m,cs_v3(m,"surfaceGeometric"),cs_v3(m,"surfaceGeometric")),ws_f(m,"0.0")) 61 let fallback:i64=ws_q2(m,geometric,ws_if(m,geom_ok,ws_set(m,cs_v3(m,"vN"),ws_c1(m,"normalize",cs_v3(m,"surfaceGeometric"),T_V3F)),0)) 62 let smooth_ok:i64=ws_cmp(m,">",cs_dot(m,cs_v3(m,"surfaceNormal"),cs_v3(m,"surfaceNormal")),ws_f(m,"0.0")) 63 ws_st(m,f,ws_if(m,smooth_ok,ws_set(m,cs_v3(m,"vN"),ws_c1(m,"normalize",cs_v3(m,"surfaceNormal"),T_V3F)),fallback));return 0 64} 65 66// Post-deformation attachments consume the shared source surface; they never re-skin blended weights. 67// aJ.xyz are validated source vertex indices; aW.xyz are ratios of retained exact rational records; 68// aW.w is normal offset in original model units, aP is original barycentric source position. 69func csurf_attachment_sample(m:*i64,axis:*u8,lane:*u8)->i64{ 70 let source:i64=cs_i32(m,ws_sw(m,cs_v4(m,"aJ"),axis,T_F32)) 71 let index:i64=cs_iadd(m,cs_imul(m,cs_iadd(m,cs_imul(m,cs_i(m,"ii"),cs_i(m,"uSurfaceVertices")),source),ws_i(m,"2")),ws_i(m,lane)) 72 return ws_sw(m,sir_index(m,sir_ident(m,"surfaceOut",T_V4F),index,T_V4F),"xyz",T_V3F) 73} 74func csurf_attachment_blend(m:*i64,lane:*u8)->i64{ 75 let x:i64=ws_bin(m,"*",csurf_attachment_sample(m,"x",lane),cs_sx4(m,"aW","x"),T_V3F) 76 let y:i64=ws_bin(m,"*",csurf_attachment_sample(m,"y",lane),cs_sx4(m,"aW","y"),T_V3F) 77 let z:i64=ws_bin(m,"*",csurf_attachment_sample(m,"z",lane),cs_sx4(m,"aW","z"),T_V3F) 78 return ws_bin(m,"+",ws_bin(m,"+",x,y,T_V3F),z,T_V3F) 79} 80func shsrc_cast_attachment_vs_v1(m:*i64)->i64{ 81 m[M_CLIP_DEPTH]=SIR_CLIP_NEGATIVE_ONE_TO_ONE;shsrc_cast_decls(m) 82 sir_uniform(m,"uSurfaceVertices",T_I32,0);sir_uniform(m,"uSurfaceActors",T_I32,0) 83 sir_storage(m,"surfaceOut",T_V4F,CSURF_OUTPUT_BIND,0,0) 84 let f:i64=sir_func(m,"main",T_VOID) 85 ws_st(m,f,sir_var(m,"ii",T_I32,sir_builtin(m,"instance_index",T_I32))) 86 ws_st(m,f,ws_set(m,cs_i(m,"vII"),cs_i(m,"ii"))) 87 ws_st(m,f,ws_set(m,cs_v3(m,"vB"),cs_v3(m,"aP"))) 88 ws_st(m,f,ws_set(m,ws_id(m,"vUV",T_V2F),ws_id(m,"aUV",T_V2F))) 89 ws_st(m,f,ws_set(m,cs_fl(m,"vSh"),ws_f(m,"1.0"))) 90 csurf_finish_normal_v1(m,f,csurf_attachment_blend(m,"1"),cs_v3sub(m,csurf_attachment_sample(m,"y","0"),csurf_attachment_sample(m,"x","0")),cs_v3sub(m,csurf_attachment_sample(m,"z","0"),csurf_attachment_sample(m,"x","0"))) 91 let scale:i64=cs_fmul(m,cs_fl(m,"uSc"),ws_sw(m,cs_idx(m,"uIH",T_V4F,cs_i(m,"ii")),"z",T_F32)) 92 let offset:i64=ws_bin(m,"*",cs_v3(m,"vN"),cs_fmul(m,cs_sx4(m,"aW","w"),scale),T_V3F) 93 ws_st(m,f,sir_var(m,"wp",T_V3F,ws_bin(m,"+",csurf_attachment_blend(m,"0"),offset,T_V3F))) 94 // Reuse canonical wardrobe rejection, shadow projection, camera and clip-depth conventions. 95 cs_slice4(m,f);return f 96} 97 98// Runtime boundary descriptor: vertices,active_rows,native_actor_count,input_bytes,output_bytes, 99// uniform_bytes,max_storage_binding,max_buffer,max_dispatch_x,max_dispatch_y,uGar,uHM. 100// Limits are supplied from the actual device. IDs are the compact render row's stable native IDs. 101// No allocation/dispatch; caller keeps accepted row order unchanged through compute and drawing. 102func csurf_dispatch_validate_v1(d:*i64,dn:i64,ids:*i64,idn:i64)->i64{ 103 if (d as i64)==0||dn!=12||(ids as i64)==0{return -50} 104 let nv:i64=d[0];let na:i64=d[1];if nv<1||nv>2147483647||na<1||na>12||idn!=na||d[2]<na{return -51} 105 if nv>2147483647/4||nv>2147483647/2/na{return -53} 106 if d[10]!=0||d[11]!=1{return -52} 107 if d[6]<1||d[7]<1||d[8]<1||d[9]<1||d[5]<3344||d[5]>d[7]{return -53} 108 if nv>d[7]/64||nv>d[6]/64{return -53};let input:i64=nv*64 109 if nv>d[7]/32/na||nv>d[6]/32/na{return -53};let output:i64=nv*32*na 110 if d[3]<input||d[4]<output||d[3]>d[7]||d[4]>d[7]||d[3]>d[6]||d[4]>d[6]{return -53} 111 if (nv-1)/64+1>d[8]||na>d[9]{return -53} 112 var i:i64=0;while i<na{if ids[i]<0||ids[i]>=d[2]{return -54};var j:i64=0;while j<i{if ids[j]==ids[i]{return -54};j=j+1};i=i+1};return 0 113}