#shader CEnvFxSnowShader #instattribute position4 0 #instattribute position4 1 #instattribute position4 2 #instattribute position4 3 #instattribute color #instattribute uv4 0 #instattribute uv4 1 #instattribute uv4 2 #instattribute uv4 3 #srcfac one #dstfac one #primitive tristrips #depthtest lequal #depthwrite false #alphawrite false #culling none #vertex glsl layout(location=0) in vec4 posIn[4]; layout(location=4) in vec4 colorIn; layout(location=5) in vec4 uvsIn[4]; UBINDING0 uniform EnvFxUniform { mat4 mv; mat4 proj; mat4 envMtx; vec4 moduColor; }; struct VertToFrag { vec4 mvPos; vec4 color; vec2 uvFlake; vec2 uvEnv; }; SBINDING(0) out VertToFrag vtf; void main() { vec4 pos = vec4(posIn[gl_VertexID].xyz, 1.0); vtf.color = colorIn * moduColor; vtf.uvFlake = uvsIn[gl_VertexID].xy; vtf.uvEnv = (envMtx * pos).xy; vtf.mvPos = mv * pos; gl_Position = proj * vtf.mvPos; } #fragment glsl struct VertToFrag { vec4 mvPos; vec4 color; vec2 uvFlake; vec2 uvEnv; }; SBINDING(0) in VertToFrag vtf; layout(location=0) out vec4 colorOut; TBINDING0 uniform sampler2D texFlake; TBINDING1 uniform sampler2D texEnv; UBINDING1 uniform FogUniform { int mode; vec4 color; float rangeScale; float start; }; vec4 MainPostFunc(vec4 colorIn) { float fogZ, temp; switch (mode) { case 2: fogZ = (-vtf.mvPos.z - start) * rangeScale; break; case 4: fogZ = 1.0 - exp2(-8.0 * (-vtf.mvPos.z - start) * rangeScale); break; case 5: temp = (-vtf.mvPos.z - start) * rangeScale; fogZ = 1.0 - exp2(-8.0 * temp * temp); break; case 6: fogZ = exp2(-8.0 * (start + vtf.mvPos.z) * rangeScale); break; case 7: temp = (start + vtf.mvPos.z) * rangeScale; fogZ = exp2(-8.0 * temp * temp); break; default: fogZ = 0.0; break; } return vec4(mix(colorIn, color, clamp(fogZ, 0.0, 1.0)).rgb, colorIn.a); } void main() { colorOut = MainPostFunc(vtf.color * texture(texFlake, vtf.uvFlake) * texture(texEnv, vtf.uvEnv)); } #vertex hlsl struct VertData { float4 posIn[4] : POSITION; float4 colorIn : COLOR; float4 uvsIn[4] : UV; }; cbuffer EnvFxUniform : register(b0) { float4x4 mv; float4x4 proj; float4x4 envMtx; float4 moduColor; }; struct VertToFrag { float4 position : SV_Position; float4 mvPos : POSITION; float4 color : COLOR; float2 uvFlake : UV0; float2 uvEnv : UV1; }; VertToFrag main(in VertData v, in uint vertId : SV_VertexID) { VertToFrag vtf; vtf.color = v.colorIn * moduColor; vtf.uvFlake = v.uvsIn[vertId].xy; float4 pos = float4(v.posIn[vertId].xyz, 1.0); vtf.uvEnv = mul(envMtx, pos).xy; vtf.mvPos = mul(mv, pos); vtf.position = mul(proj, vtf.mvPos); return vtf; } #fragment hlsl SamplerState samp : register(s0); SamplerState sampClamp : register(s3); Texture2D texFlake : register(t0); Texture2D texEnv : register(t1); struct VertToFrag { float4 position : SV_Position; float4 mvPos : POSITION; float4 color : COLOR; float2 uvFlake : UV0; float2 uvEnv : UV1; }; cbuffer FogUniform : register(b1) { int mode; float4 color; float rangeScale; float start; }; static float4 MainPostFunc(in VertToFrag vtf, float4 colorIn) { float fogZ, temp; switch (mode) { case 2: fogZ = (-vtf.mvPos.z - start) * rangeScale; break; case 4: fogZ = 1.0 - exp2(-8.0 * (-vtf.mvPos.z - start) * rangeScale); break; case 5: temp = (-vtf.mvPos.z - start) * rangeScale; fogZ = 1.0 - exp2(-8.0 * temp * temp); break; case 6: fogZ = exp2(-8.0 * (start + vtf.mvPos.z) * rangeScale); break; case 7: temp = (start + vtf.mvPos.z) * rangeScale; fogZ = exp2(-8.0 * temp * temp); break; default: fogZ = 0.0; break; } return float4(lerp(colorIn, color, saturate(fogZ)).rgb, colorIn.a); } float4 main(in VertToFrag vtf) : SV_Target0 { return MainPostFunc(vtf, vtf.color * texFlake.Sample(samp, vtf.uvFlake) * texEnv.Sample(sampClamp, vtf.uvEnv)); } #vertex metal struct VertData { float4 posIn[4]; float4 colorIn; float4 uvsIn[4]; }; struct EnvFxUniform { float4x4 mv; float4x4 proj; float4x4 envMtx; float4 moduColor; }; struct VertToFrag { float4 position [[ position ]]; float4 mvPos; float4 color; float2 uvFlake; float2 uvEnv; }; vertex VertToFrag vmain(constant VertData* va [[ buffer(1) ]], uint vertId [[ vertex_id ]], uint instId [[ instance_id ]], constant EnvFxUniform& particle [[ buffer(2) ]]) { VertToFrag vtf; constant VertData& v = va[instId]; vtf.color = v.colorIn * particle.moduColor; vtf.uvFlake = v.uvsIn[vertId].xy; float4 pos = float4(v.posIn[vertId].xyz, 1.0); vtf.uvEnv = (particle.envMtx * pos).xy; vtf.mvPos = particle.mv * pos; vtf.position = particle.proj * vtf.mvPos; return vtf; } #fragment metal struct VertToFrag { float4 position [[ position ]]; float4 mvPos; float4 color; float2 uvFlake; float2 uvEnv; }; struct FogUniform { int mode; float4 color; float rangeScale; float start; }; float4 MainPostFunc(thread VertToFrag& vtf, constant FogUniform& fu, float4 colorIn) { float fogZ, temp; switch (fu.mode) { case 2: fogZ = (-vtf.mvPos.z - fu.start) * fu.rangeScale; break; case 4: fogZ = 1.0 - exp2(-8.0 * (-vtf.mvPos.z - fu.start) * fu.rangeScale); break; case 5: temp = (-vtf.mvPos.z - fu.start) * fu.rangeScale; fogZ = 1.0 - exp2(-8.0 * temp * temp); break; case 6: fogZ = exp2(-8.0 * (fu.start + vtf.mvPos.z) * fu.rangeScale); break; case 7: temp = (fu.start + vtf.mvPos.z) * fu.rangeScale; fogZ = exp2(-8.0 * temp * temp); break; default: fogZ = 0.0; break; } return float4(mix(colorIn, fu.color, saturate(fogZ)).rgb, colorIn.a); } fragment float4 fmain(VertToFrag vtf [[ stage_in ]], sampler samp [[ sampler(0) ]], sampler sampClamp [[ sampler(3) ]], constant FogUniform& fu [[ buffer(3) ]], texture2d texFlake [[ texture(0) ]], texture2d texEnv [[ texture(1) ]]) { return MainPostFunc(vtf, fu, vtf.color * texFlake.sample(samp, vtf.uvFlake) * texEnv.sample(sampClamp, vtf.uvEnv)); } #shader CEnvFxUnderwaterShader : CEnvFxSnowShader #srcfac srcalpha #dstfac invsrcalpha