Open7
URPで動くシェーダーを作る
ゲーミングPC的に光るやつ
Shader "Custom/Gaming"
{
Properties
{
_ColorCycle ("ColorCycle", float) = 0.5
_BrightCycle ("BrightCycle", float) = 3.0
}
CGINCLUDE
uniform float _ColorCycle;
uniform float _BrightCycle;
float3 color(float level)
{
// level: 0~6 -> rgb
float r = float(level <= 2.0) + float(level > 4.0) * 0.5;
float g = max(1.0 - abs(level - 2.0) * 0.5, 0.0);
float b = (1.0 - (level - 4.0) * 0.5) * float(level >= 4.0);
return float3(r, g, b);
}
float3 smoothColor(float x)
{
float level1 = floor(x * 6.0);
float level2 = min(6.0, floor(x*6.0) + 1.0);
float3 a = color(level1);
float3 b = color(level2);
return lerp(a, b, frac(x * 6.0));
}
float4 paint(float2 uv)
{
float repeat = abs(fmod(uv.x * _ColorCycle + _Time.y, 1));
float3 col = smoothColor(repeat);
float timeBrightness = sin(_Time.y * _BrightCycle) + 1.5;
return float4(col * timeBrightness, 1);
}
ENDCG
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct fin
{
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
};
fin vert(appdata v)
{
fin o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.texcoord = v.texcoord;
return o;
}
float4 frag(fin IN) : SV_TARGET
{
return paint(IN.texcoord.xy);
}
ENDCG
}
}
}
shaderの作法全くわからないが、とりあえずgithubにも上げた
HLSLシェーダーの魔導書のunity向け改変
2.3.4 頂点シェーダー
Shader "Custom/Hlsl"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
};
sampler2D _MainTex;
v2f vert(appdata v)
{
v2f o;
o.vertex = v.vertex;
o.vertex.x *= 1.5f;
o.vertex.y *= 0.5f;
o.texcoord = v.texcoord;
return o;
}
float4 frag(v2f i) : SV_TARGET
{
fixed4 col = tex2D(_MainTex, i.texcoord);
return col;
}
ENDCG
}
}
}
2.4 ピクセルシェーダー入門 赤色の表示
Shader "Custom/Hlsl"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
};
sampler2D _MainTex;
v2f vert(appdata v)
{
v2f o;
o.vertex = v.vertex;
o.texcoord = v.texcoord;
return o;
}
float4 frag(v2f i) : SV_TARGET
{
fixed4 red = float4(1.0f, 0.0f, 0.0f, 1.0f);
return red;
}
ENDCG
}
}
}
2.4 ピクセルシェーダー入門 step-4 頂点シェーダーから受け取ったカラーを出力する
Shader "Custom/Hlsl"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
float3 color : COLOR;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
float3 color : COLOR;
};
sampler2D _MainTex;
v2f vert(appdata v)
{
v2f o;
o.vertex = v.vertex;
o.color = float4(round(v.texcoord.x), round(v.texcoord.y), 0.0f, 1.0f); // 仮に頂点に色指定
return o;
}
float4 frag(v2f i) : SV_TARGET
{
float4 color;
color.x = i.color.x;
color.y = i.color.y;
color.z = i.color.z;
color.w = 1.0f;
return color;
}
ENDCG
}
}
}
c++側を書いていないため、頂点の色を仮で置いている
3.1 ワールド行列と座標を乗算して座標変換を行う
行列はHLSL内で作成
スクリーン座標への変換はUnityObjectToClipPosを使用。
Shader "Custom/Hlsl"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType" = "Transparent" "Queue"="Transparent" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
float3 color : COLOR;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
float3 color : COLOR;
};
sampler2D _MainTex;
v2f vert(appdata v)
{
v2f o;
float x = 0.3;
float y = 0.5;
float z = 0.2;
half4x4 moveMatrix = half4x4(1, 0, 0, x,
0, 1, 0, y,
0, 0, 1, z,
0, 0, 0, 1);
v.vertex = mul(moveMatrix, v.vertex);
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}
float4 frag(v2f i) : SV_TARGET
{
fixed4 red = float4(1.0f, 0.0f, 0.0f, 1.0f);
return red;
}
ENDCG
}
}
}
4.3.2 Lambert拡散反射モデルを実装する
書籍だと内積を取ったあとに-1を乗算しているが、
しなくても正しくレンダリングできているように見える。
_WorldSpaceLightPos0.xyz
のベクトルの向きが逆なのかも
Shader "Custom/Hlsl"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType" = "Transparent" "Queue"="Transparent" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
float3 color : COLOR;
float3 normal: NORMAL;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
float3 color : COLOR;
float3 normal: NORMAL;
};
sampler2D _MainTex;
half4 _LightColor0;
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.normal = UnityObjectToWorldNormal(v.normal);
return o;
}
float4 frag(v2f i) : SV_TARGET
{
float t = dot(normalize(i.normal), _WorldSpaceLightPos0.xyz);
t = max(t, 0);
fixed4 red = float4(1.0f, 0.0f, 0.0f, 1.0f);
fixed4 ligColor = _LightColor0 * t;
return red * ligColor;
}
ENDCG
}
}
}