nx_tex_sample_mip_alpha_candidate_t241.nx source
↩ module page · 67 lines · 4683 B
1// nx_tex_sample_mip_alpha_candidate_t241.nx -- Computes mip levels for texture sampling with alpha-weighted RGB integration and linear alpha handling.
2import "nx_tex_sample.nx"
3import "nx_shader_ir.nx"
4// Area integration for one mip level. Input/output texture views carry sRGB transfer;
5// alpha remains linear. No alpha-test coverage rescaling is applied here.
6func txm_call1(m:*i64,name:*u8,e:i64,ty:i64)->i64{let c:i64=sir_call(m,name,ty);sir_arg(m,c,e);return c}
7func txm_call2(m:*i64,name:*u8,a:i64,b:i64,ty:i64)->i64{let c:i64=sir_call(m,name,ty);sir_arg(m,c,a);sir_arg(m,c,b);return c}
8func txm_f(m:*i64,s:*u8)->i64{return sir_lit(m,s,T_F32)}
9func txm_v2(m:*i64,x:i64,y:i64)->i64{let c:i64=sir_ctor(m,T_V2F);sir_arg(m,c,x);sir_arg(m,c,y);return c}
10// alpha_weighted=1 integrates visible RGB in linear light and writes straight-alpha RGB.
11// Zero total alpha produces zero RGB without an epsilon policy. MASK coverage is separate.
12func nx_txs_mip_fragment_alpha(alpha_weighted:i64)->*i64{
13 let m:*i64=sir_new();sir_uniform(m,"uSourceSize",T_V2F,0);sir_uniform(m,"uTargetSize",T_V2F,0);sir_texture(m,"uSource",T_TEX2F);sir_fragout(m,"fc",T_V4F,0)
14 let f:i64=sir_func(m,"main",T_VOID);sir_param_position(m,f,"position")
15 let src:i64=sir_ident(m,"uSourceSize",T_V2F);let dst:i64=sir_ident(m,"uTargetSize",T_V2F)
16 let pos:i64=sir_swz(m,sir_ident(m,"position",T_V4F),"xy",T_V2F)
17 let floorpos:i64=txm_call1(m,"floor",pos,T_V2F)
18 let lo:i64=sir_bin(m,"/",sir_bin(m,"*",floorpos,src,T_V2F),dst,T_V2F)
19 let one:i64=txm_v2(m,txm_f(m,"1.0"),txm_f(m,"1.0"))
20 let hi:i64=sir_bin(m,"/",sir_bin(m,"*",sir_bin(m,"+",floorpos,one,T_V2F),src,T_V2F),dst,T_V2F)
21 sir_stmt(m,f,sir_let(m,"lo",T_V2F,lo));sir_stmt(m,f,sir_let(m,"hi",T_V2F,hi))
22 let l:i64=sir_ident(m,"lo",T_V2F);let h:i64=sir_ident(m,"hi",T_V2F)
23 let z4:i64=sir_ctor(m,T_V4F);sir_arg(m,z4,txm_f(m,"0.0"));sir_stmt(m,f,sir_var(m,"sum",T_V4F,z4))
24 let yi:i64=sir_cast(m,txm_call1(m,"floor",sir_swz(m,l,"y",T_F32),T_F32),T_I32)
25 sir_stmt(m,f,sir_var(m,"iy",T_I32,yi))
26 let y:i64=sir_ident(m,"iy",T_I32);let x:i64=sir_ident(m,"ix",T_I32)
27 let yf:i64=sir_cast(m,y,T_F32);let xf:i64=sir_cast(m,x,T_F32)
28 let ystop:i64=sir_if(m,sir_bin(m,">=",yf,sir_swz(m,h,"y",T_F32),T_BOOL),sir_break(m),0)
29 let xi:i64=sir_cast(m,txm_call1(m,"floor",sir_swz(m,l,"x",T_F32),T_F32),T_I32)
30 let xinit:i64=sir_var(m,"ix",T_I32,xi)
31 let xstop:i64=sir_if(m,sir_bin(m,">=",xf,sir_swz(m,h,"x",T_F32),T_BOOL),sir_break(m),0)
32 let wx:i64=sir_bin(m,"-",txm_call2(m,"min",sir_swz(m,h,"x",T_F32),sir_bin(m,"+",xf,txm_f(m,"1.0"),T_F32),T_F32),txm_call2(m,"max",sir_swz(m,l,"x",T_F32),xf,T_F32),T_F32)
33 let wy:i64=sir_bin(m,"-",txm_call2(m,"min",sir_swz(m,h,"y",T_F32),sir_bin(m,"+",yf,txm_f(m,"1.0"),T_F32),T_F32),txm_call2(m,"max",sir_swz(m,l,"y",T_F32),yf,T_F32),T_F32)
34 let xy:i64=sir_ctor(m,T_V2I);sir_arg(m,xy,x);sir_arg(m,xy,y)
35 let loadtex:i64=sir_texload(m,sir_ident(m,"uSource",T_TEX2F),xy,sir_lit(m,"0",T_I32))
36 let sampled:i64=sir_let(m,"sampled",T_V4F,loadtex)
37 let tex:i64=sir_ident(m,"sampled",T_V4F)
38 var filtered:i64=tex
39 if alpha_weighted!=0 {
40 let weighted:i64=sir_ctor(m,T_V4F)
41 sir_arg(m,weighted,sir_bin(m,"*",sir_swz(m,tex,"rgb",T_V3F),sir_swz(m,tex,"a",T_F32),T_V3F))
42 sir_arg(m,weighted,sir_swz(m,tex,"a",T_F32));filtered=weighted
43 }
44 let sum:i64=sir_ident(m,"sum",T_V4F)
45 let add:i64=sir_assign(m,sum,sir_bin(m,"+",sum,sir_bin(m,"*",filtered,sir_bin(m,"*",wx,wy,T_F32),T_V4F),T_V4F))
46 let incx:i64=sir_assign(m,x,sir_bin(m,"+",x,sir_lit(m,"1",T_I32),T_I32))
47 let xbody:i64=sir_seq(m,xstop,sir_seq(m,sampled,sir_seq(m,add,incx)))
48 let incy:i64=sir_assign(m,y,sir_bin(m,"+",y,sir_lit(m,"1",T_I32),T_I32))
49 let ybody:i64=sir_seq(m,ystop,sir_seq(m,xinit,sir_seq(m,sir_loop(m,xbody),incy)))
50 sir_stmt(m,f,sir_loop(m,ybody))
51 let extent:i64=sir_bin(m,"-",h,l,T_V2F)
52 let area:i64=sir_bin(m,"*",sir_swz(m,extent,"x",T_F32),sir_swz(m,extent,"y",T_F32),T_F32)
53 var result:i64=sir_bin(m,"/",sum,area,T_V4F)
54 if alpha_weighted!=0 {
55 let rgbzero:i64=sir_ctor(m,T_V3F);sir_arg(m,rgbzero,txm_f(m,"0.0"))
56 sir_stmt(m,f,sir_var(m,"straightRgb",T_V3F,rgbzero))
57 let alpha:i64=sir_swz(m,sum,"a",T_F32)
58 let unweight:i64=sir_assign(m,sir_ident(m,"straightRgb",T_V3F),sir_bin(m,"/",sir_swz(m,sum,"rgb",T_V3F),alpha,T_V3F))
59 sir_stmt(m,f,sir_if(m,sir_bin(m,">",alpha,txm_f(m,"0.0"),T_BOOL),unweight,0))
60 result=sir_ctor(m,T_V4F);sir_arg(m,result,sir_ident(m,"straightRgb",T_V3F));sir_arg(m,result,sir_bin(m,"/",alpha,area,T_F32))
61 }
62 sir_stmt(m,f,sir_assign(m,sir_ident(m,"fc",T_V4F),result))
63 return m
64}
65
66// Retain the original scalar/straight-component filtering entry point.
67func nx_txs_mip_fragment_v1()->*i64{return nx_txs_mip_fragment_alpha(0)}