mirror of https://github.com/AxioDL/metaforce.git
258 lines
6.6 KiB
GLSL
258 lines
6.6 KiB
GLSL
#shader CThermalColdFilter
|
|
#attribute position4
|
|
#attribute uv4 0
|
|
#attribute uv4 1
|
|
#srcfac one
|
|
#dstfac zero
|
|
#primitive tristrips
|
|
#depthtest none
|
|
#depthwrite false
|
|
#culling none
|
|
|
|
#vertex glsl
|
|
layout(location=0) in vec4 posIn;
|
|
layout(location=1) in vec4 uvIn;
|
|
layout(location=2) in vec4 uvNoiseIn;
|
|
|
|
UBINDING0 uniform ThermalColdUniform
|
|
{
|
|
mat4 indMtx;
|
|
vec4 colorReg0;
|
|
vec4 colorReg1;
|
|
vec4 colorReg2;
|
|
float randOff;
|
|
};
|
|
|
|
struct VertToFrag
|
|
{
|
|
mat3 indMtx;
|
|
vec4 colorReg0;
|
|
vec4 colorReg1;
|
|
vec4 colorReg2;
|
|
vec2 sceneUv;
|
|
vec2 noiseUv;
|
|
float randOff;
|
|
};
|
|
|
|
SBINDING(0) out VertToFrag vtf;
|
|
void main()
|
|
{
|
|
vtf.indMtx = mat3(indMtx);
|
|
vtf.colorReg0 = colorReg0;
|
|
vtf.colorReg1 = colorReg1;
|
|
vtf.colorReg2 = colorReg2;
|
|
vtf.sceneUv = uvIn.xy;
|
|
vtf.noiseUv = uvNoiseIn.xy;
|
|
vtf.randOff = randOff;
|
|
gl_Position = vec4(posIn.xyz, 1.0);
|
|
}
|
|
|
|
#fragment glsl
|
|
struct VertToFrag
|
|
{
|
|
mat3 indMtx;
|
|
vec4 colorReg0;
|
|
vec4 colorReg1;
|
|
vec4 colorReg2;
|
|
vec2 sceneUv;
|
|
vec2 noiseUv;
|
|
float randOff;
|
|
};
|
|
|
|
ivec2 Lookup8BPP(in vec2 uv, in float randOff)
|
|
{
|
|
int bx = int(uv.x) >> 3;
|
|
int rx = int(uv.x) & 0x7;
|
|
int by = int(uv.y) >> 2;
|
|
int ry = int(uv.y) & 0x3;
|
|
int bidx = by * 128 + bx;
|
|
int addr = bidx * 32 + ry * 8 + rx + int(randOff);
|
|
return ivec2(addr & 0x3ff, addr >> 10);
|
|
}
|
|
|
|
SBINDING(0) in VertToFrag vtf;
|
|
layout(location=0) out vec4 colorOut;
|
|
TBINDING0 uniform sampler2D sceneTex;
|
|
TBINDING1 uniform sampler2D noiseTex;
|
|
const vec4 kRGBToYPrime = vec4(0.257, 0.504, 0.098, 0.0);
|
|
void main()
|
|
{
|
|
vec4 noiseTexel = texelFetch(noiseTex, Lookup8BPP(vtf.noiseUv, vtf.randOff), 0);
|
|
vec2 indCoord = (vtf.indMtx * vec3(noiseTexel.r - 0.5, noiseTexel.a - 0.5, 1.0)).xy;
|
|
float indScene = dot(texture(sceneTex, vtf.sceneUv + indCoord), kRGBToYPrime) + 16.0 / 255.0;
|
|
colorOut = vtf.colorReg0 * indScene + vtf.colorReg2 - vtf.colorReg1 * noiseTexel.r;
|
|
colorOut.a = vtf.colorReg1.a + vtf.colorReg1.a * noiseTexel.r + vtf.colorReg2.a;
|
|
}
|
|
|
|
#vertex hlsl
|
|
struct VertData
|
|
{
|
|
float4 posIn : POSITION;
|
|
float4 uvIn : UV0;
|
|
float4 uvNoiseIn : UV1;
|
|
};
|
|
|
|
cbuffer ThermalColdUniform : register(b0)
|
|
{
|
|
float4x4 indMtx;
|
|
float4 colorReg0;
|
|
float4 colorReg1;
|
|
float4 colorReg2;
|
|
float randOff;
|
|
};
|
|
|
|
struct VertToFrag
|
|
{
|
|
float4 position : SV_Position;
|
|
float3x3 indMtx : INDMTX;
|
|
float4 colorReg0 : COLORREG0;
|
|
float4 colorReg1 : COLORREG1;
|
|
float4 colorReg2 : COLORREG2;
|
|
float2 sceneUv : SCENEUV;
|
|
float2 noiseUv : NOISEUV;
|
|
float randOff : RANDOFF;
|
|
};
|
|
|
|
VertToFrag main(in VertData v)
|
|
{
|
|
VertToFrag vtf;
|
|
vtf.indMtx = float3x3(indMtx[0].xyz, indMtx[1].xyz, indMtx[2].xyz);
|
|
vtf.colorReg0 = colorReg0;
|
|
vtf.colorReg1 = colorReg1;
|
|
vtf.colorReg2 = colorReg2;
|
|
vtf.sceneUv = v.uvIn.xy;
|
|
vtf.noiseUv = v.uvNoiseIn.xy;
|
|
vtf.randOff = randOff;
|
|
vtf.position = float4(v.posIn.xyz, 1.0);
|
|
return vtf;
|
|
}
|
|
|
|
#fragment hlsl
|
|
Texture2D sceneTex : register(t0);
|
|
Texture2D noiseTex : register(t1);
|
|
SamplerState samp : register(s3);
|
|
struct VertToFrag
|
|
{
|
|
float4 position : SV_Position;
|
|
float3x3 indMtx : INDMTX;
|
|
float4 colorReg0 : COLORREG0;
|
|
float4 colorReg1 : COLORREG1;
|
|
float4 colorReg2 : COLORREG2;
|
|
float2 sceneUv : SCENEUV;
|
|
float2 noiseUv : NOISEUV;
|
|
float randOff : RANDOFF;
|
|
};
|
|
|
|
static int3 Lookup8BPP(float2 uv, float randOff)
|
|
{
|
|
int bx = int(uv.x) >> 3;
|
|
int rx = int(uv.x) & 0x7;
|
|
int by = int(uv.y) >> 2;
|
|
int ry = int(uv.y) & 0x3;
|
|
int bidx = by * 128 + bx;
|
|
int addr = bidx * 32 + ry * 8 + rx + int(randOff);
|
|
return int3(addr & 0x3ff, addr >> 10, 0);
|
|
}
|
|
|
|
static const float4 kRGBToYPrime = {0.257, 0.504, 0.098, 0.0};
|
|
float4 main(in VertToFrag vtf) : SV_Target0
|
|
{
|
|
float4 noiseTexel = noiseTex.Load(Lookup8BPP(vtf.noiseUv, vtf.randOff));
|
|
float2 indCoord = mul(vtf.indMtx, float3(noiseTexel.r - 0.5, noiseTexel.a - 0.5, 1.0)).xy;
|
|
float2 sceneUv = vtf.sceneUv + indCoord;
|
|
sceneUv.y = 1.0 - sceneUv.y;
|
|
float indScene = dot(sceneTex.Sample(samp, sceneUv), kRGBToYPrime) + 16.0 / 255.0;
|
|
float4 colorOut = vtf.colorReg0 * indScene + vtf.colorReg2 - vtf.colorReg1 * noiseTexel.r;
|
|
colorOut.a = vtf.colorReg1.a + vtf.colorReg1.a * noiseTexel.r + vtf.colorReg2.a;
|
|
return colorOut;
|
|
}
|
|
|
|
#vertex metal
|
|
struct VertData
|
|
{
|
|
float4 posIn [[ attribute(0) ]];
|
|
float4 uvIn [[ attribute(1) ]];
|
|
float4 uvNoiseIn [[ attribute(2) ]];
|
|
};
|
|
|
|
struct ThermalColdUniform
|
|
{
|
|
float4x4 indMtx;
|
|
float4 colorReg0;
|
|
float4 colorReg1;
|
|
float4 colorReg2;
|
|
float randOff;
|
|
};
|
|
|
|
struct VertToFrag
|
|
{
|
|
float4 position [[ position ]];
|
|
float3 indMtx0;
|
|
float3 indMtx1;
|
|
float3 indMtx2;
|
|
float4 colorReg0;
|
|
float4 colorReg1;
|
|
float4 colorReg2;
|
|
float2 sceneUv;
|
|
float2 noiseUv;
|
|
float randOff;
|
|
};
|
|
|
|
vertex VertToFrag vmain(VertData v [[ stage_in ]], constant ThermalColdUniform& tcu [[ buffer(2) ]])
|
|
{
|
|
VertToFrag vtf;
|
|
vtf.indMtx0 = tcu.indMtx[0].xyz;
|
|
vtf.indMtx1 = tcu.indMtx[1].xyz;
|
|
vtf.indMtx2 = tcu.indMtx[2].xyz;
|
|
vtf.colorReg0 = tcu.colorReg0;
|
|
vtf.colorReg1 = tcu.colorReg1;
|
|
vtf.colorReg2 = tcu.colorReg2;
|
|
vtf.sceneUv = v.uvIn.xy;
|
|
vtf.noiseUv = v.uvNoiseIn.xy;
|
|
vtf.randOff = tcu.randOff;
|
|
vtf.position = float4(v.posIn.xyz, 1.0);
|
|
return vtf;
|
|
}
|
|
|
|
#fragment metal
|
|
struct VertToFrag
|
|
{
|
|
float4 position [[ position ]];
|
|
float3 indMtx0;
|
|
float3 indMtx1;
|
|
float3 indMtx2;
|
|
float4 colorReg0;
|
|
float4 colorReg1;
|
|
float4 colorReg2;
|
|
float2 sceneUv;
|
|
float2 noiseUv;
|
|
float randOff;
|
|
};
|
|
|
|
static uint2 Lookup8BPP(float2 uv, float randOff)
|
|
{
|
|
int bx = int(uv.x) >> 3;
|
|
int rx = int(uv.x) & 0x7;
|
|
int by = int(uv.y) >> 2;
|
|
int ry = int(uv.y) & 0x3;
|
|
int bidx = by * 128 + bx;
|
|
int addr = bidx * 32 + ry * 8 + rx + int(randOff);
|
|
return uint2(addr & 0x3ff, addr >> 10);
|
|
}
|
|
|
|
constant float4 kRGBToYPrime = {0.257, 0.504, 0.098, 0.0};
|
|
fragment float4 fmain(VertToFrag vtf [[ stage_in ]],
|
|
sampler samp [[ sampler(3) ]],
|
|
texture2d<float> sceneTex [[ texture(0) ]],
|
|
texture2d<float> noiseTex [[ texture(1) ]])
|
|
{
|
|
float4 noiseTexel = noiseTex.read(Lookup8BPP(vtf.noiseUv, vtf.randOff));
|
|
float2 indCoord = (float3x3(vtf.indMtx0, vtf.indMtx1, vtf.indMtx2) * float3(noiseTexel.r - 0.5, noiseTexel.a - 0.5, 1.0)).xy;
|
|
float2 sceneUv = vtf.sceneUv + indCoord;
|
|
sceneUv.y = 1.0 - sceneUv.y;
|
|
float indScene = dot(sceneTex.sample(samp, sceneUv), kRGBToYPrime) + 16.0 / 255.0;
|
|
float4 colorOut = vtf.colorReg0 * indScene + vtf.colorReg2 - vtf.colorReg1 * noiseTexel.r;
|
|
colorOut.a = vtf.colorReg1.a + vtf.colorReg1.a * noiseTexel.r + vtf.colorReg2.a;
|
|
return colorOut;
|
|
}
|