着色器 ZanLib/ClutBiliniar 的其中一个 SubProgram:
SubProgram "gles hw_tier00 " {
Keywords { "_TRANSPARENT_OFF" "_DITHERALPHA_OFF" "_VERTEXCOLOR_OFF" "_BLENDFACTOR_OFF" }
"#ifdef VERTEX
#version 100
uniform vec4 hlslcc_mtx4x4unity_ObjectToWorld[4];
uniform vec4 hlslcc_mtx4x4unity_MatrixVP[4];
uniform vec4 _MainTex_ST;
uniform vec4 _MainTex_TexelSize;
attribute highp vec4 in_POSITION0;
attribute highp vec4 in_TEXCOORD0;
varying mediump vec2 vs_TEXCOORD0;
varying mediump vec2 vs_TEXCOORD1;
varying mediump vec2 vs_TEXCOORD2;
varying mediump vec2 vs_TEXCOORD3;
varying highp vec2 vs_TEXCOORD4;
vec4 u_xlat0;
vec4 u_xlat1;
vec2 u_xlat4;
void main()
{
u_xlat0 = in_POSITION0.yyyy * hlslcc_mtx4x4unity_ObjectToWorld[1];
u_xlat0 = hlslcc_mtx4x4unity_ObjectToWorld[0] * in_POSITION0.xxxx + u_xlat0;
u_xlat0 = hlslcc_mtx4x4unity_ObjectToWorld[2] * in_POSITION0.zzzz + u_xlat0;
u_xlat0 = u_xlat0 + hlslcc_mtx4x4unity_ObjectToWorld[3];
u_xlat1 = u_xlat0.yyyy * hlslcc_mtx4x4unity_MatrixVP[1];
u_xlat1 = hlslcc_mtx4x4unity_MatrixVP[0] * u_xlat0.xxxx + u_xlat1;
u_xlat1 = hlslcc_mtx4x4unity_MatrixVP[2] * u_xlat0.zzzz + u_xlat1;
gl_Position = hlslcc_mtx4x4unity_MatrixVP[3] * u_xlat0.wwww + u_xlat1;
u_xlat4.x = 0.0;
u_xlat4.y = _MainTex_TexelSize.y;
u_xlat0.xy = in_TEXCOORD0.xy * _MainTex_ST.xy + _MainTex_ST.zw;
u_xlat0.xy = (-_MainTex_TexelSize.xy) * vec2(0.5, 0.5) + u_xlat0.xy;
vs_TEXCOORD1.xy = u_xlat4.xy + u_xlat0.xy;
vs_TEXCOORD0.xy = u_xlat0.xy;
u_xlat1.x = _MainTex_TexelSize.x;
u_xlat1.y = 0.0;
vs_TEXCOORD2.xy = u_xlat0.xy + u_xlat1.xy;
vs_TEXCOORD3.xy = u_xlat0.xy + _MainTex_TexelSize.xy;
vs_TEXCOORD4.xy = u_xlat0.xy * _MainTex_TexelSize.zw;
return;
}
#endif
#ifdef FRAGMENT
#version 100
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
precision highp int;
uniform vec4 _CLUT_TexelSize;
uniform lowp sampler2D _MainTex;
uniform lowp sampler2D _CLUT;
varying mediump vec2 vs_TEXCOORD0;
varying mediump vec2 vs_TEXCOORD1;
varying mediump vec2 vs_TEXCOORD2;
varying mediump vec2 vs_TEXCOORD3;
varying highp vec2 vs_TEXCOORD4;
#define SV_Target0 gl_FragData[0]
vec4 u_xlat0;
lowp float u_xlat10_0;
vec4 u_xlat1;
mediump vec4 u_xlat16_1;
lowp vec4 u_xlat10_1;
vec4 u_xlat2;
mediump vec4 u_xlat16_2;
lowp vec4 u_xlat10_2;
float u_xlat3;
lowp vec4 u_xlat10_3;
vec2 u_xlat8;
vec2 u_xlat10;
void main()
{
u_xlat10_0 = texture2D(_MainTex, vs_TEXCOORD3.xy).w;
u_xlat0.x = u_xlat10_0 * _CLUT_TexelSize.z + (-_CLUT_TexelSize.x);
u_xlat0.x = u_xlat0.x / _CLUT_TexelSize.z;
u_xlat0.y = float(0.0);
u_xlat8.y = float(0.0);
u_xlat10_1 = texture2D(_CLUT, u_xlat0.xy);
u_xlat10_0 = texture2D(_MainTex, vs_TEXCOORD1.xy).w;
u_xlat0.x = u_xlat10_0 * _CLUT_TexelSize.z + (-_CLUT_TexelSize.x);
u_xlat2.x = u_xlat0.x / _CLUT_TexelSize.z;
u_xlat2.y = float(0.0);
u_xlat10.y = float(0.0);
u_xlat10_3 = texture2D(_CLUT, u_xlat2.xy);
u_xlat16_1 = u_xlat10_1 + (-u_xlat10_3);
u_xlat0.xy = fract(vs_TEXCOORD4.xy);
u_xlat1 = u_xlat0.xxxx * u_xlat16_1 + u_xlat10_3;
u_xlat10_2.x = texture2D(_MainTex, vs_TEXCOORD2.xy).w;
u_xlat2.x = u_xlat10_2.x * _CLUT_TexelSize.z + (-_CLUT_TexelSize.x);
u_xlat10.x = u_xlat2.x / _CLUT_TexelSize.z;
u_xlat10_2 = texture2D(_CLUT, u_xlat10.xy);
u_xlat10_3.x = texture2D(_MainTex, vs_TEXCOORD0.xy).w;
u_xlat3 = u_xlat10_3.x * _CLUT_TexelSize.z + (-_CLUT_TexelSize.x);
u_xlat8.x = u_xlat3 / _CLUT_TexelSize.z;
u_xlat10_3 = texture2D(_CLUT, u_xlat8.xy);
u_xlat16_2 = u_xlat10_2 + (-u_xlat10_3);
u_xlat2 = u_xlat0.xxxx * u_xlat16_2 + u_xlat10_3;
u_xlat1 = u_xlat1 + (-u_xlat2);
u_xlat0 = u_xlat0.yyyy * u_xlat1 + u_xlat2;
SV_Target0.w = ceil(u_xlat0.w);
SV_Target0.xyz = u_xlat0.xyz;
return;
}
#endif
"
}
图形学零基础,会写一点 Python 但完全没用过 NumPy ,有 V 友能帮帮忙么?
附上 ChatGPT 的聊天记录:
不知道正确率有多少,但能胡编出这么多看起来相关的内容也挺厉害了
1
edis0n0 OP 这是我照着 ChatGPT 的指点瞎写的: https://pastebin.com/QEshP61s
|
2
HuPu 2022-12-24 08:14:10 +08:00
挺有意思 如何跟 chatgpt 说话是门学问啊 我感觉我就不太会
|
3
beijiaoff 2022-12-24 09:27:11 +08:00
观望一下,感觉目前做不到吧
|
4
musi 2022-12-24 11:03:33 +08:00
我觉得这你要是 google 你已经写完了
|
6
ruanimal 2022-12-24 18:15:05 +08:00
真的有人信 chatGPT 能教人写代码?
|
9
c0t 2022-12-25 13:06:40 +08:00 via Android 1
贴出来的代码没什么难度啊...很字面意思,voxel 类的游戏全是这样的贴图
|
10
c0t 2022-12-25 13:10:44 +08:00 via Android 1
@c0t 不过你可能首先得知道比如 unity 里的 texelsize 这种语义里惯例存的是啥,不知道 chatgpt 有这种知识没有
|
11
edis0n0 OP @c0t #10 我 google 了一下 texelsize 存的应该是 (1/width, 1/height, width, height),所以 chatgpt 输出的有点错了
它说的逻辑我简化了下貌似就是根据 index 图的 alpha 值去 clut 取对应点颜色,自己写了一遍: import numpy as np from skimage import io index_image = io.imread('index.png') clut_image = io.imread('clut.png') x_coord = index_image[:, :, 3] y_coord = np.zeros_like(x_coord) clut_colors = clut_image[y_coord.astype(int), x_coord.astype(int), :] io.imsave('output.png', clut_colors) 貌似输出结果还很正常,不知道有没有漏了什么东西 |
12
edis0n0 OP @c0t #10 google 到的那贴子说的是 1/width 是从 unity 源码看到的,那-_CLUT_TexelSize.x 应该是一个接近 0 的值,因为我看后面是根据它的值去对应位置取数据,那应该是按 int 处理,小数部分没有意义,那我就直接按 0 处理了。不知道为什么原始的 GL 代码会这么长,总觉得我简化逻辑的时候搞错了什么,一直没看出来,请大佬再帮忙分析下。
|
13
c0t 2022-12-25 18:15:32 +08:00 1
@edis0n0
因为采样了四个像素(大概这么理解就好)吧?不过不用模型 uv 的话,loop main texture 解码出来的结果可能没啥意义?可能是很多个模型公用了一张 main texture 。 上一半 vertex shader 里输出到 frag shader 里的东西: // four pixel // 0 2 // 1 3 varying mediump vec2 vs_TEXCOORD0; // texture sample position varying mediump vec2 vs_TEXCOORD1; // texture sample position + (0,1/height), pixel below varying mediump vec2 vs_TEXCOORD2; // texture sample positin + (1/width,0), next pixel varying mediump vec2 vs_TEXCOORD3; // texture sample position + (1/width,1/height), varying highp vec2 vs_TEXCOORD4; // texture sample position in pixel |
14
c0t 2022-12-25 18:24:15 +08:00 1
@edis0n0
然后 frag shader 里,从四个 alpha 值得到四个像素颜色,然后做一次 bilinear interpolation ,大概就是这样 |
16
c0t 2022-12-25 18:56:33 +08:00 1
@edis0n0
texture2D 是用 uv 坐标采样的,所以不是整数 (-_CLUT_TexelSize.x); 这个不太好说,主要是看 main texture 里存的到底是什么?可能和生成图片方式有关系吧?不过好像确实有点奇怪: u_xlat10_0 = texture2D(_MainTex, vs_TEXCOORD1.xy).w; u_xlat0.x = u_xlat10_0 * _CLUT_TexelSize.z + (-_CLUT_TexelSize.x); u_xlat2.x = u_xlat0.x / _CLUT_TexelSize.z; u_xlat2.y = float(0.0); u_xlat10_3 = texture2D(_CLUT, u_xlat2.xy); 没搞懂意义,u_xlat10_0 * _CLUT_TexelSize.z + (-_CLUT_TexelSize.x); 照理来说,这个式子两边都不是一个单位的啊,u_xlat10_0 * _CLUT_TexelSize.z 单位是 pixel ,(-_CLUT_TexelSize.x); 这个是 1/pixel ,最终除一个 _CLUT_TexelSize.z 之后,这个部分也几乎没作用了 |
17
edis0n0 OP @c0t 谢谢大佬指点。刚 google 了下插值算法一般用于放大图片,请问这个 bilinear interpolation 是还有放大图片的作用么? main texture 存的是一张只有 alpha 通道有数据的游戏背景图,vertex shader 中没看出还有放大的代码以及倍数一类的信息。如果倍数是 1.0 的话是不是相当于可以不用考虑?它和 opencv 的 cv2.resize()插值效果有差异么?
|
18
c0t 2022-12-25 20:13:15 +08:00
@edis0n0
嗯嗯,背景图的话就是单纯的放大的时候,平滑像素用的了,不会有一块一块的情况。比例一样就无所谓了。你上面代码应该直接用就好。 那这个功能就是为了节约存储空间,原本图形硬件上是自带插值的,分了两张贴图没法用了 看了 cv2.resize() 的说明,默认就是线性插值,应该没有差异 |
19
cherryas 2022-12-26 13:37:46 +08:00
小心 chatgpt 投毒.
我问了个 vits 模型怎么写,给我编的有模有样的,怎么导包,方法名是什么.都像那回事. 折腾了一会我发现 python 根本没 vits 这个包. |