//отобразить пиксель текстуры или нет
Clip(bool?-1:0);
\n\n
//отобразить пиксель текстуры или нет
Clip(bool?-1:0);
это инстанс шейдера
файл с расширением .mat
экземпляр какого-то шейдера, в котором мы заранее настраиваем значения свойств этого шейдера.
«/» слеш в имени шейдера
разбирает парсингом как меню
чем больше слешей, тем больше вложенностей в меню имени шейдера
Плюсы
Минус
требуется только бинарный шейдер компилировать
Shader "Custom/sh3"{
Properties{
//размер куба 2^d (максимальное значение координат xyz)
_d ("d",Integer) = 0
//координаты цветного куба в шейдере
_nx ("xn",Integer) = 1
_ny ("yn",Integer) = 1
_nz ("zn",Integer) = 1
//цвет куба с координатами в шейдере
_c("Example color", Color) = (1, 0, 0, 1)
//текстура геометрического shader куба
_MainTex ("Albedo (RGB)", 2D) = "white" {}
}
SubShader{
Pass {
CGPROGRAM
#pragma vertex vert
#pragma geometry geo
#pragma fragment frag
#pragma target 4.6
struct geometryOutput{
float4 pos:SV_POSITION;
float2 uv:TEXCOORD0;
int normal : NORMAL;
};
geometryOutput VertexOutput(float3 pos, float2 uv, int normal){
geometryOutput o;
//преобразует точку из пространства объекта в пространство отсечения камеры
o.pos = UnityObjectToClipPos(pos);
o.uv = uv;
o.normal = normal;
return o;
}
sampler2D _MainTex;
int _nx;
int _ny;
int _nz;
float _d;
fixed4 _c;
[maxvertexcount(36)]
void geo(triangle geometryOutput IN[3] : SV_POSITION, inout TriangleStream<geometryOutput> OutputStream){
geometryOutput o;
float3 pos = IN[0].pos;
float x = pow(2.0, _d);
//down
//нижний
OutputStream.Append(VertexOutput(x*float3(-1, -1, 1), float2(0, 1),0));
OutputStream.Append(VertexOutput(x*float3(-1, -1, -1), float2(0, 0),0));
OutputStream.Append(VertexOutput(x*float3(1, -1, -1), float2(1, 0),0));
//верхний
OutputStream.Append(VertexOutput(x*float3(1, -1, -1), float2(1, 0),0));
OutputStream.Append(VertexOutput(x*float3(-1, -1, 1), float2(0, 1),0));
OutputStream.Append(VertexOutput(x*float3(1, -1, 1), float2(1, 1),0));
//forward
//нижний
OutputStream.Append(VertexOutput(x*float3(1, -1, 1), float2(1, 0),1));
OutputStream.Append(VertexOutput(x*float3(1, 1, 1), float2(1, 1),1));
OutputStream.Append(VertexOutput(x*float3(-1, -1, 1), float2(0, 0),1));
//верхний
OutputStream.Append(VertexOutput(x*float3(-1, -1, 1), float2(0, 0),1));
OutputStream.Append(VertexOutput(x*float3(-1, 1, 1), float2(0, 1),1));
OutputStream.Append(VertexOutput(x*float3(1, 1, 1), float2(1, 1),1));
//right
//нижний
OutputStream.Append(VertexOutput(x*float3(1, 1, 1), float2(1, 1),2));
OutputStream.Append(VertexOutput(x*float3(1, -1, 1), float2(1, 0),2));
OutputStream.Append(VertexOutput(x*float3(1, -1, -1), float2(0, 0),2));
//верхний
OutputStream.Append(VertexOutput(x*float3(1, -1, -1), float2(0, 0),2));
OutputStream.Append(VertexOutput(x*float3(1, 1, 1), float2(1, 1),2));
OutputStream.Append(VertexOutput(x*float3(1, 1, -1), float2(0, 1),2));
//back
//нижний
OutputStream.Append(VertexOutput(x*float3(1, 1, -1), float2(1, 1),3));
OutputStream.Append(VertexOutput(x*float3(1, -1, -1), float2(1, 0),3));
OutputStream.Append(VertexOutput(x*float3(-1, -1, -1), float2(0, 0),3));
//верхний
OutputStream.Append(VertexOutput(x*float3(-1, -1, -1), float2(0, 0),3));
OutputStream.Append(VertexOutput(x*float3(1, 1, -1), float2(1, 1),3));
OutputStream.Append(VertexOutput(x*float3(-1, 1, -1), float2(0, 1),3));
//left
//нижний
OutputStream.Append(VertexOutput(x*float3(-1, 1, -1), float2(0, 1),4));
OutputStream.Append(VertexOutput(x*float3(-1, -1, -1), float2(0, 0),4));
OutputStream.Append(VertexOutput(x*float3(-1, -1, 1), float2(1, 0),4));
//верхний
OutputStream.Append(VertexOutput(x*float3(-1, -1, 1), float2(1, 0),4));
OutputStream.Append(VertexOutput(x*float3(-1, 1, -1), float2(0, 1),4));
OutputStream.Append(VertexOutput(x*float3(-1, 1, 1), float2(1, 1),4));
//up
//верхний
OutputStream.Append(VertexOutput(x*float3(-1, 1, 1), float2(0, 1),5));
OutputStream.Append(VertexOutput(x*float3(1, 1, 1), float2(1, 1),5));
OutputStream.Append(VertexOutput(x*float3(-1, 1, -1), float2(0, 0),5));
//нижний
OutputStream.Append(VertexOutput(x*float3(-1, 1, -1), float2(0, 0),5));
OutputStream.Append(VertexOutput(x*float3(1, 1, -1), float2(1, 0),5));
OutputStream.Append(VertexOutput(x*float3(1, 1, 1), float2(1, 1),5));
}
float4 vert(float4 vertex : POSITION) : SV_POSITION{
return UnityObjectToClipPos(vertex);
}
int color_cube(geometryOutput i){
//1 2 4 8 16
int N=(int)pow(2.0, _d);
//100-1
//200-2
//400-3
//800-4
int max=(int)N*100-1;
//смещение
float D=1/(N*100.0);
int x1,y1,z1;
switch (i.normal){
case 0://down
x1=i.uv.x>_nx*D&i.uv.x<_nx*D+D?1:0;
z1=i.uv.y>_nz*D&i.uv.y<_nz*D+D?1:0;
y1=_ny==0?1:0;
if (x1+y1+z1==3) return 1;
break;
case 1://forward
x1=i.uv.x>_nx*D&i.uv.x<_nx*D+D?1:0;
y1=i.uv.y>_ny*D&i.uv.y<_ny*D+D?1:0;
z1=_nz==max?1:0;
if (x1+y1+z1==3) return 1;
break;
case 2://right
z1=i.uv.x>_nz*D&i.uv.x<_nz*D+D?1:0;
y1=i.uv.y>_ny*D&i.uv.y<_ny*D+D?1:0;
x1=_nx==max?1:0;
if (x1+y1+z1==3) return 1;
break;
case 3://back
x1=i.uv.x>_nx*D&i.uv.x<_nx*D+D?1:0;
y1=i.uv.y>_ny*D&i.uv.y<_ny*D+D?1:0;
z1=_nz==0?1:0;
if (x1+y1+z1==3) return 1;
break;
case 4://left
z1=i.uv.x>_nz*D&i.uv.x<_nz*D+D?1:0;
y1=i.uv.y>_ny*D&i.uv.y<_ny*D+D?1:0;
x1=_nx==0?1:0;
if (x1+y1+z1==3) return 1;
break;
case 5://up
x1=i.uv.x>_nx*D&i.uv.x<_nx*D+D?1:0;
z1=i.uv.y>_nz*D&i.uv.y<_nz*D+D?1:0;
y1=_ny==max?1:0;
if (x1+y1+z1==3) return 1;
break;
}
return 0;
}
float4 frag(geometryOutput i) : SV_Target{
return color_cube(i)==1?_c:tex2D(_MainTex,i.uv);
}
ENDCG
}
}
FallBack "Diffuse"
}
using UnityEditor;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour{
void Start(){
var m = new Mesh();
var v = new Vector3(0, 0, 0);
var d = 0.5f;
m.vertices = new Vector3[]{v,v+d*Vector3.up, v+d* Vector3.right};
m.triangles = new int[] { 0, 1, 2};
m.uv=new Vector2[]{d*new Vector2(1,1),d*new Vector2(1,0),d*new Vector2(0,1)};
m.RecalculateBounds();
m.RecalculateNormals();
var mr = gameObject.GetComponent<MeshRenderer>();
if (mr == null) gameObject.AddComponent<MeshRenderer>();
var mf = gameObject.GetComponent<MeshFilter>();
if (mf == null) mf = gameObject.AddComponent<MeshFilter>();
mf.sharedMesh = m;
AssetDatabase.CreateAsset(m,"Assets/Resources/2207170827/test.asset");
}
}
static public void Создать(){
//создание текстуры 3d с определёнными характеристиками
TEXTURE = new Texture3D(R * MAX, R * MAX, R * MAX, TextureFormat.RGB24, false);
TEXTURE.filterMode = FilterMode.Point;
//создание цветового массива для текстуры 3d
Color[] colors = new Color[MAX * R * MAX * R * MAX * R];
//наполнение путём прохода по ячейкам
for (byte z = 0; z < R; z++){
int zOffset = z * MAX * R * MAX * R;
for (byte y = 0; y < R; y++){
int yOffset = y * MAX * R;
for (byte x = 0; x < R; x++)
colors[x + yOffset + zOffset] = Color.green;
}
}
//запись в текстуру
TEXTURE.SetPixels(colors);
TEXTURE.Apply();
Сохранить();
//return tex;
}
//сохранить текстуру в файл asset
static public void Сохранить()
{
var res = "Assets/Resources/";
var f = res + PATH + ".asset";
if (System.IO.File.Exists(f))
AssetDatabase.SaveAssets();
else
AssetDatabase.CreateAsset(TEXTURE, f);
}