dither


半透明剔除(dither/Screen-Door Transparency Shader)

参考网站

核心代码

  • Dither Noise
    (% = fmod 取余)
1
2
3
4
5
6
7
8
9
10
11
12
13
void Unity_Dither_float(float4 ScreenPosition, out float Out)
{
    float2 uv = ScreenPosition.xy * _ScreenParams.xy;
    float DITHER_THRESHOLDS[16] =
    {
        1.0 / 17.0,  9.0 / 17.0,  3.0 / 17.011.0 / 17.0,
        13.0 / 17.0,  5.0 / 17.015.0 / 17.0,  7.0 / 17.0,
        4.0 / 17.012.0 / 17.0,  2.0 / 17.010.0 / 17.0,
        16.0 / 17.0,  8.0 / 17.014.0 / 17.0,  6.0 / 17.0
    };
    uint index = (uint(uv.x) % 4) * 4 + uint(uv.y) % 4;
    Out = 1 - DITHER_THRESHOLDS[index];
}
  • 将Noise映射到屏幕
    float dither84 = Dither4x4Bayer( fmod(screenPosition.x, 4), fmod(screenPosition.y, 4) );

  • 需要一个深度
    可以直接用LinearEyeDepth(需要深度图)或算物体与相机的距离

连连看

这边算的是物体和相机的距离,然后减去noise,结果用smoothstep进行微调

Unilt shader(代码有点问题,连连看连反了)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
Shader "ASESampleShaders/DitheringFade"
{
    Properties
    {
        _Distance ("有效距离", float) = 1
    }
    SubShader
    {
        Pass
        {
            Tags { "Queue" = "Geometry" "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }

            HLSLPROGRAM

            #pragma prefer_hlslcc gles
            #pragma exclude_renderers d3d11_9x

            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fog

            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"

            struct appdata
            {
                float4 positionOS: POSITION;
                float4 color: COLOR;
            };
           
            struct v2f
            {
                float4 positionHCS: SV_POSITION;
                float3 worldPos: TEXCOORD0;
            };

            CBUFFER_START(UnityPerMaterial)
            half _Distance;
            CBUFFER_END

            inline float Dither4x4Bayer(int x, int y)
            {
                const float dither[ 16 ] = {
                    1, 9, 3, 11,
                    13, 5, 15, 7,
                    4, 12, 2, 10,
                    16, 8, 14, 6
                };
                int r = y * 4 + x;
                return dither[r] / 16; // same # of instructions as pre-dividing due to compiler magic
            }
           
            v2f vert(appdata v)
            {
                v2f o;
                float4 clipPos = TransformObjectToHClip(v.positionOS);
                o.positionHCS = TransformObjectToHClip(v.positionOS);
                o.worldPos = mul(unity_ObjectToWorld, v.positionOS).xyz;
                return o;
            }
           
            float4 frag(v2f i): SV_Target
            {
                float3 posObj = TransformObjectToWorld(float3(0, 0, 0));
                float3 WorldPosition = i.worldPos;
                // float2 screenPos = i.positionHCS.xy;// / _ScreenParams.xy;
                // half4 HCS = screenPos / screenPos.w;
                // HCS.z = ( UNITY_NEAR_CLIP_VALUE >= 0 ) ? HCS.z : HCS.z * 0.5 + 0.5; //TODO:more cheap?
                // half2 clipScreen = screenPos.xy;// * _ScreenParams.xy;
                half dither = Dither4x4Bayer(fmod(i.positionHCS.x, 4), fmod(i.positionHCS.y, 4));
                half ditherResult = smoothstep(0, _Distance, (distance(posObj, _WorldSpaceCameraPos) - dither));
                clip(ditherResult - 1);

                return float4(0, 0, 0, 0);
            }
            ENDHLSL
        }
    }
}

消除色阶

Dithering:使用8-bit dithering像素点抖动技术,消除色阶。

https://zhuanlan.zhihu.com/p/84434802

https://bartwronski.com/2016/10/30/dithering-in-games-mini-series/

补充方案

射线检测对象是否在后面然后材质改成透明

https://bobsong.cn/1084.html


文章作者: Neilyodog
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Neilyodog !
评论
评论