Unity中 URP 下的棋盘格Shader


前言

我们展示我们Shader效果,一般放于棋盘格中来展示。我们在这篇文章中,制作棋盘格效果。


一、制作思路

法1:使用纹理采样后,修改重铺效果

法2:计算实现

我们在这篇文章中,主要计算实现该效果


二、粗略计算实现棋盘格效果

1、使 uv.x < 0.5 区域 = 0 。反之, = 0.5

if(i.uv.x < 0.5)
col1 = 0;
else
col1 = 0.5;

在这里插入图片描述

2、使 uv.y < 0.5 区域 = 0 。反之, = 0.5

if(i.uv.y < 0.5)
col2 = 0;
else
col2 = 0.5;

在这里插入图片描述

3、使两个颜色相加

在这里插入图片描述

4、取小数部分

frac(col1 + col2)

在这里插入图片描述

5、乘以2

return 2 * frac(col1 + col2);

在这里插入图片描述


三、去除 if 条件语句后的精简方法

1、我们在图形计算器中看一下

  • 当 y = x 下取整后,把 x 轴缩小为原来的二分之一,y轴也缩小为原来的二分之一
  • 即可在(0,1)之间实现 0.5以下 = 0,0.5以上 = 0.5的效果。
    在这里插入图片描述

float2 uv = floor(i.uv * 2) * 0.5;
return uv.x + uv.y;

在这里插入图片描述

2、向下取整

float col = frac(uv.x +uv.y);

在这里插入图片描述

3、乘以2

float col = frac(uv.x +uv.y) * 2;

在这里插入图片描述

4、我们在属性面板使用参数控制棋盘格重复度

  • 属性面板

_Repeat(“Repeat”,Float) = 0

  • CBUFFER 常量缓存区

CBUFFER_START(UnityPerMaterial)
float _Repeat;
CBUFFER_END

  • 在 顶点着色器 对 uv 进行传值时,使乘以_Repeat以达到修改重复度的目的

o.uv = v.uv * _Repeat;

请添加图片描述

5、使棋盘格Shader适用于Cube

因为我们的棋盘格一般为一个Cube。那么要看见内部的东西,则需要把面片的前面剔除

Cull Front

请添加图片描述

6、使棋盘格颜色从下到上渐变

因为,我们棋盘格的颜色单一且过曝,看着很不舒服。所以,我们给其加一个遮罩,让其有点渐变的区分

  • 渐变遮罩效果,我们肯定会想到使用模型的本地空间下的坐标。所以,我们用本地空间下的y坐标实现。
  • 这里需要准备在片元着色器中,传入模型顶点本地空间下的坐标

float mask = i.vertexOS.y;
return col + mask;

在这里插入图片描述

7、我们可以给棋盘格Cube加一个父对象,使缩放时,不会Cube中心为调整的位置(按需使用)

8、可以在属性面板加一个颜色来调整棋盘格颜色(按需使用)

col = col *_Color + mask;

请添加图片描述


四、测试代码

我们需要适配BRP。所以,得加一个SubShader以同样的逻辑实现该效果

Shader "MyShader/URP/P3_3_3"
{
    Properties
    {
        _Repeat("Repeat",Float) = 0
        _Color("Color",Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags
        {
            "PenderPipeline"="UniversalPipeline"
            "RenderType"="Opaque"
            "Queue"="Geometry"
        }
        Cull Front
        Pass
        {
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag

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

            struct Attribute
            {
                float3 vertexOS : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct Varying
            {
                float3 vertexOS : TEXCOORD0;
                float4 vertexCS : SV_POSITION;
                float2 uv : TEXCOORD1;
            };

            CBUFFER_START(UnityPerMaterial)
                float _Repeat;
                float4 _Color;
            CBUFFER_END

            Varying vert(Attribute v)
            {
                Varying o;
                o.vertexOS = v.vertexOS;
                o.vertexCS = TransformObjectToHClip(v.vertexOS);
                o.uv = v.uv * _Repeat;
                return o;
            }

            half4 frag(Varying i) : SV_Target
            {
                /*half4 col1;
                half4 col2;
                if(i.uv.x < 0.5)
                    col1 = 0;
                else
                    col1 = 0.5;
                if(i.uv.y < 0.5)
                    col2 = 0;
                else
                    col2 = 0.5;*/
                half4 col;
                float2 uv = floor(i.uv * 2) * 0.5;
                col = frac(uv.x + uv.y) * 2;
                float mask = i.vertexOS.y;
                col = col * _Color + mask;
                return col;
            }
            ENDHLSL
        }
    }
    SubShader
    {
        Tags
        {
            "RenderType"="Opaque"
            "Queue"="Geometry"
        }
        Cull Front
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float3 vertexOS : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float3 vertexOS : TEXCOORD0;
                float4 vertexCS : SV_POSITION;
                float2 uv : TEXCOORD1;
            };

            float _Repeat;
            float4 _Color;

            v2f vert(appdata v)
            {
                v2f o;
                o.vertexOS = v.vertexOS;
                o.vertexCS = UnityObjectToClipPos(v.vertexOS);
                o.uv = v.uv * _Repeat;
                return o;
            }

            half4 frag(v2f i) : SV_Target
            {
                half4 col;
                float2 uv = floor(i.uv * 2) * 0.5;
                col = frac(uv.x + uv.y) * 2;
                float mask = i.vertexOS.y;
                col = col * _Color + mask;
                return col;
            }
            ENDCG
        }
    }
}

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>