最終的にはshaderlabに移植していきたいです.
skyboxのシェーダーの書き方の勉強のために書いています.(問形式なのは個人的にそのほうが理解しやすかったからです.)
問,2Dで星空(星のみでよい,配置は星表にしたがわなくてよい)を出力せよ.
まず,ノイズ関数の作り方を考える.
https://thebookofshaders.com/10/?lan=jp
thebookofshadersには,ノイズの作り方に関していろいろ書いてあったので,全面的に参考にしました.
https://www.shadertoy.com/view/lsXGWH
また,2Dの星のノイズを使った関数に関しては,上記のshadertoyのコードを改変することによって,コードを書こうと思います.星は基本的にノイズを使って配置していきます.
#ifdef GL_ES
precision mediump float;
#endif
uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;
//random関数と,noise関数はthebookofshadersのものを使用.
float random (in vec2 st) {
return fract(sin(dot(st.xy,
vec2(11.9898,78.233)))
* 43758.5453123);
}
float noise (in vec2 st) {
vec2 i = floor(st);
vec2 f = fract(st);
// Four corners in 2D of a tile
float a = random(i);
float b = random(i + vec2(1.0, 0.0));
float c = random(i + vec2(0.0, 1.0));
float d = random(i + vec2(1.0, 1.0));
// Smooth Interpolation
// Cubic Hermine Curve. Same as SmoothStep()
vec2 u = f*f*(3.0-2.0*f);
// u = smoothstep(0.,1.,f);
// Mix 4 coorners percentages
return mix(a, b, u.x) +
(c - a)* u.y * (1.0 - u.x) +
(d - b) * u.x * u.y;
}
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
float time = iTime;
vec2 position = (fragCoord.xy * 2. - resolution.xy) / resolution.yy;
float color = pow(noise(fragCoord.xy), 40.0) * 1000.0;
float r1 = noise(fragCoord.xy*noise(vec2(1.)));
fragColor = vec4(vec3(color*r1), 1.0);
}
別解)最短コード
https://www.shadertoy.com/view/4lSSRw
問,shaderlabにて,skyboxで星空を出力せよ.
移植しつつ,Unityのskyboxに表示する方法を考えていきます.
Shader "Unlit/skyboxstars01"
{
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;
float3 uv : TEXCOORD0;
};
struct v2f
{
float3 uv : TEXCOORD0;
//UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
float4 vertex2: TEXCOORD1;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
//o.uv = TRANSFORM_TEX(v.uv, _MainTex);
//UNITY_TRANSFER_FOG(o,o.vertex);
o.uv = v.uv;
o.vertex2 = v.vertex;
return o;
}
//random関数と,noise関数はthebookofshadersのものを使用.
float random (in float2 st) {
return frac(sin(dot(st.xy,
float2(11.9898,78.233)))
* 43758.5453123);
}
float noise (in float2 st) {
float2 i = floor(st);
float2 f = frac(st);
// Four corners in 2D of a tile
float a = random(i);
float b = random(i + float2(1.0, 0.0));
float c = random(i + float2(0.0, 1.0));
float d = random(i + float2(1.0, 1.0));
// Smooth Interpolation
// Cubic Hermine Curve. Same as SmoothStep()
float2 u = f*f*(3.0-2.0*f);
// u = smoothstep(0.,1.,f);
// lerp 4 coorners percentages
return lerp(a, b, u.x) +
(c - a)* u.y * (1.0 - u.x) +
(d - b) * u.x * u.y;
}
float2 random2 ( in float3 uv){
return float2(frac(sin(dot(uv.xyz,float3(21,31,45)))*7315),frac(cos(dot(uv.xyz, float3(43,29,53)))*6325));
}
fixed4 frag (v2f i) : SV_Target
{
float4 fragColor;
float time = _Time.y;
// float3 vec = normalize(i.vertex2);
float3 pos = i.uv;
float3 rot =float3(atan2(pos.x, pos.z), atan2(pos.y, length(pos.xz)), length(pos));
float2 st = random2(rot);
// float2 position = i.uv.xyz *2. -float3(1,1,1);
float color = pow(noise(st), 40.0) * 8.0;
float r1 = noise(st*noise(float2(1.,1.)));
fragColor = float4(float3(color*r1,color*r1,color * r1), 1.0);
//fragColor = float4(vec.x,0,0,1);
return fragColor;
}
ENDCG
}
}
}
(球座標変換して,それに対応するノイズかければうまくいくのかな,ってアイディアをもとにskyboxのシェーダーに移植していきましたが,コードにいろいろいらない部分も含んでいます.)
ランダムにする関数の定数は基本適当に入力しています.もっとうまく描く方法は全然あると思います.
参考にしたもの
http://wordpress.notargs.com/blog/blog/2015/11/08/unity自作のskyboxでジュリア集合に囲まれる/
https://qiita.com/aa_debdeb/items/2739745b3ab1a003d767