文章目录
最近工作忙成狗
一直没有时间充电
后续制作半透明阴影时,可以用到 dithering 来 clip shadow caster + soft shadow 来实现
所以提前搞一下 dithering tex 3d 的创建
环境
Unity : 2020.3.37f1
Pipeline : BRP
手动创建 dithering tex 3d
手动在 PS 中标记位置
// jave.lin 2022/11/02 参考:https://docs.unity3d.com/cn/2020.3/Manual/class-Texture3D.html
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
public class ExampleEditorScript : MonoBehaviour
{
[MenuItem("CreateExamples/3DTexture")]
static void CreateTexture3D()
{
// 配置纹理
const int width = 4, heigh = 4, depth = 16;
TextureFormat format = TextureFormat.RGBA32;
TextureWrapMode wrapMode = TextureWrapMode.Clamp;
// 创建纹理并应用配置
Texture3D texture = new Texture3D(width, heigh, depth, format, false);
texture.wrapMode = wrapMode;
// 创建 3 维数组以存储颜色数据
Color[] colors = new Color[width * heigh * depth];
const int one_depth_count = width * heigh;
Color[] depth0_cols = new Color[one_depth_count]
{
Color.white, Color.white, Color.white, Color.white,
Color.white, Color.white, Color.white, Color.white,
Color.white, Color.white, Color.white, Color.white,
Color.white, Color.white, Color.white, Color.white,
};
Color[] depth1_cols = new Color[one_depth_count]
{
Color.white, Color.white, Color.white, Color.white,
Color.white, Color.white, Color.white, Color.white,
Color.white, Color.white, Color.white, Color.white,
Color.black, Color.white, Color.white, Color.white,
};
Color[] depth2_cols = new Color[one_depth_count]
{
Color.white, Color.white, Color.white, Color.white,
Color.white, Color.white, Color.black, Color.white,
Color.white, Color.white, Color.white, Color.white,
Color.black, Color.white, Color.white, Color.white,
};
Color[] depth3_cols = new Color[one_depth_count]
{
Color.white, Color.white, Color.white, Color.white,
Color.black, Color.white, Color.black, Color.white,
Color.white, Color.white, Color.white, Color.white,
Color.black, Color.white, Color.white, Color.white,
};
Color[] depth4_cols = new Color[one_depth_count]
{
Color.white, Color.white, Color.white, Color.white,
Color.black, Color.white, Color.black, Color.white,
Color.white, Color.white, Color.white, Color.white,
Color.black, Color.white, Color.black, Color.white,
};
Color[] depth5_cols = new Color[one_depth_count]
{
Color.white, Color.white, Color.white, Color.white,
Color.black, Color.white, Color.black, Color.white,
Color.white, Color.black, Color.white, Color.white,
Color.black, Color.white, Color.black, Color.white,
};
Color[] depth6_cols = new Color[one_depth_count]
{
Color.white, Color.white, Color.white, Color.black,
Color.black, Color.white, Color.black, Color.white,
Color.white, Color.black, Color.white, Color.white,
Color.black, Color.white, Color.black, Color.white,
};
Color[] depth7_cols = new Color[one_depth_count]
{
Color.white, Color.black, Color.white, Color.black,
Color.black, Color.white, Color.black, Color.white,
Color.white, Color.black, Color.white, Color.white,
Color.black, Color.white, Color.black, Color.white,
};
Color[] depth8_cols = new Color[one_depth_count]
{
Color.black, Color.white, Color.black, Color.white,
Color.white, Color.black, Color.white, Color.black,
Color.black, Color.white, Color.black, Color.black,
Color.white, Color.black, Color.white, Color.black,
};
Color[] depth9_cols = new Color[one_depth_count]
{
Color.black, Color.black, Color.black, Color.white,
Color.white, Color.black, Color.white, Color.black,
Color.black, Color.white, Color.black, Color.black,
Color.white, Color.black, Color.white, Color.black,
};
Color[] depth10_cols = new Color[one_depth_count]
{
Color.black, Color.black, Color.black, Color.black,
Color.white, Color.black, Color.white, Color.black,
Color.black, Color.white, Color.black, Color.black,
Color.white, Color.black, Color.white, Color.black,
};
Color[] depth11_cols = new Color[one_depth_count]
{
Color.black, Color.black, Color.black, Color.black,
Color.white, Color.black, Color.white, Color.black,
Color.black, Color.black, Color.black, Color.black,
Color.white, Color.black, Color.white, Color.black,
};
Color[] depth12_cols = new Color[one_depth_count]
{
Color.black, Color.black, Color.black, Color.black,
Color.white, Color.black, Color.white, Color.black,
Color.black, Color.black, Color.black, Color.black,
Color.white, Color.black, Color.black, Color.black,
};
Color[] depth13_cols = new Color[one_depth_count]
{
Color.black, Color.black, Color.black, Color.black,
Color.black, Color.black, Color.white, Color.black,
Color.black, Color.black, Color.black, Color.black,
Color.white, Color.black, Color.black, Color.black,
};
Color[] depth14_cols = new Color[one_depth_count]
{
Color.black, Color.black, Color.black, Color.black,
Color.black, Color.black, Color.black, Color.black,
Color.black, Color.black, Color.black, Color.black,
Color.white, Color.black, Color.black, Color.black,
};
Color[] depth15_cols = new Color[one_depth_count]
{
Color.black, Color.black, Color.black, Color.black,
Color.black, Color.black, Color.black, Color.black,
Color.black, Color.black, Color.black, Color.black,
Color.black, Color.black, Color.black, Color.black,
};
List<Color[]> datas = new List<Color[]>();
datas.Add(depth0_cols);
datas.Add(depth1_cols);
datas.Add(depth2_cols);
datas.Add(depth3_cols);
datas.Add(depth4_cols);
datas.Add(depth5_cols);
datas.Add(depth6_cols);
datas.Add(depth7_cols);
datas.Add(depth8_cols);
datas.Add(depth9_cols);
datas.Add(depth10_cols);
datas.Add(depth11_cols);
datas.Add(depth12_cols);
datas.Add(depth13_cols);
datas.Add(depth14_cols);
datas.Add(depth15_cols);
datas.Reverse(); // 添加了 Reverse 的效果就等同于: unity shader 中的 _DitherMaskLOD 效果
for (int i = 0; i < depth; i++)
{
Array.Copy(datas[i], 0, colors, i * one_depth_count, one_depth_count);
}
// 将颜色值复制到纹理
texture.SetPixels(colors);
// jave.lin : 用于 dithering 的话,建议使用 point filter, repeat wrap
texture.filterMode = FilterMode.Point;
texture.wrapMode = TextureWrapMode.Repeat;
// 将更改应用到纹理,然后将更新的纹理上传到 GPU
texture.Apply();
// 将纹理保存到 Unity 项目
AssetDatabase.CreateAsset(texture, "Assets/Textures/Example3DTexture.asset");
}
}
创建完后的 texture 3d
TextureViewShader
TextureViewShader - 使用 unity 内置的 _DitherMaskLOD
Shader "Custom/TextureViewShader"
{
Properties
{
_UV_Scale ("UV Scale", Float) = 16
_TargetDepth ("Target Depth", Int) = 1
}
SubShader
{
Tags {
"RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler3D _DitherMaskLOD;
half _UV_Scale;
int _TargetDepth;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
i.uv *= _UV_Scale;
fixed4 col = tex3D(_DitherMaskLOD, float3(i.uv, floor(_TargetDepth) * 0.0625)).a;
return col;
}
ENDCG
}
}
}
TextureViewShader - 使用 自定义的 MyDitheringTex3D
Shader "Custom/TextureViewShader1"
{
Properties
{
_MyDitheringTex3D ("My Dithering Tex 3D", 3D) = "white" {
}
_UV_Scale ("UV Scale", Float) = 16
_TargetDepth ("Target Depth", Int) = 1
}
SubShader
{
Tags {
"RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler3D _MyDitheringTex3D;
half _UV_Scale;
int _TargetDepth;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
i.uv *= _UV_Scale;
fixed4 col = tex3D(_MyDitheringTex3D, float3(i.uv, floor(_TargetDepth) * 0.0625)).r;
return col;
}
ENDCG
}
}
}
效果
左边是 unity 知道的,右边的是我们自己创建的 dithering tex 3d