8/24までの進捗
unityのshaderで星空風の絵を描いてみた。
たまにはコードを晒して自分の理解を整理してみる。
Shader "Unlit/UnlitStarryShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
//座標変換。空間座標からカメラ座標への変換を行っている
o.vertex = UnityObjectToClipPos(v.vertex);
//テクスチャとuv座標の対応付け
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
float rand(float2 co){
return frac(sin(dot(co.xy, fixed2(12.9898,78.233))) * 43758.5453);
}
fixed4 frag (v2f i) : SV_Target
{
float s = _Time * 20;
float2 p = i.uv * 2.0 - 1.0;//正規化
float c = rand(p);//各座標ごとにランダムな値を生成
float2 q = float2(c, c);
//ランダム値によって星の明るさの初期値を設定。また、時間によって星の明るさが変動:0.5~1.5
float l = 0.01/length(q) * abs(sin(s) * 0.5 + 1.0);
fixed4 col = float4( 33/255.0 + l, 32/255.0 + l, 142.0/255.0 + l, 1.0);
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
GrabPass{}
//パーリンノイズつくってる
Pass {
//Blend SrcAlpha OneMinusSrcAlpha // Alpha blending
//Blend One One // Additive
//Blend OneMinusDstColor One // Soft Additive
Blend DstColor Zero // Multiplicative
//Blend DstColor SrcColor // 2x Multiplicative
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _GrabTexture;
float4 _GrabTexture_ST;
float Circle(float2 p){
p*= 10.0;
return ((p.x*p.x+p.y*p.y)-10);
}
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _GrabTexture);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
float rand(float3 co){
return frac(sin(dot(co.xyz, float3(12.9898, 78.233, 56.787))) * 43758.5453);
}
float rings(float2 p){
return sin(length(p)*100);
}
float noise(float3 pos){
float3 ip = floor(pos);
float3 fp = smoothstep(0, 1, frac(pos));
//smoothstep関数
//x<minの時、0を返す
//max>xの時、1を返す
//min<=x<maxの時、0から1の間の滑らかな値を返す
float4 a = float4(
rand(ip + float3(0, 0, 0)),
rand(ip + float3(1, 0, 0)),
rand(ip + float3(0, 1, 0)),
rand(ip + float3(1, 1, 0)));
float4 b = float4(
rand(ip + float3(0, 0, 1)),
rand(ip + float3(1, 0, 1)),
rand(ip + float3(0, 1, 1)),
rand(ip + float3(1, 1, 1)));
a = lerp(a, b, fp.z);
a.xy = lerp(a.xy, a.zw, fp.y);
return lerp(a.x, a.y, fp.x);
}
float perlin(float3 pos,float time){
return
(noise(pos) * 32 +
noise(pos * 2 ) * 16 +
noise(pos * 4) * 8 +
noise(pos * 8) * 4 +
noise(pos * 16 - s) * 2 +
noise(pos * 32 + s) ) / 63;
}
fixed4 frag (v2f i) : SV_Target
{
float s = 0;
float4 col = float4(perlin (float3(i.uv,0),s),perlin (float3(i.uv,0),s),perlin (float3(i.uv,0),s),1);
return col;
}
ENDCG
}
}
}
今回は2パスで作ってみた。
1パス目で背景色と星っぽい点を描画、2パス目でパーリンノイズをBlendして星雲っぽい感じを出してみた。
基本的にはfrag関数をいじれば描画されるものを操作できるのかな?
という印象を受けた。完成図を想像しながら色々いじっていくのは結構面白かった。
次はもう少し複雑な絵を作ってみたい。
あと、今回はunlit shaderで作成したけど、standard surface shaderとどっちが一般的に使われてるのかも調べたい。
※参考
この記事が気に入ったらサポートをしてみませんか?