程序化生成星空图

目录

程序化生成星点图

主要思路是伪随机生成,随机因子是晶格化后的晶格坐标。生成星点后再添加一些动态效果。

随机生成

参考了这篇文章。对扩大了某个倍数的三角函数取小数部分,可以得到混乱的效果。

float random(float x, float factor){
                return  abs(frac(sin(x) * factor));
                }

为每个晶格生成一个星点

首先要划分晶格,直接将uv扩大就可以。扩大的倍数直接决定了晶格的数量。

这里要根据晶格坐标的整数部分划分晶格,作为每个晶格独特的ID。之后,需要用这个ID来作为随机因子,为每个晶格生成一个星点坐标。这样,在片元着色器中便可以求得当前像素到星点坐标的距离,从而求得其亮度。

fixed4 galaxy(float2 uv, int tessFactor, int luminPower,fixed4 color , float rad){
                
                uv *= tessFactor;
                float u = floor(uv.x);
                float v = floor(uv.y);
                u = random(u,134.56);
                v= random(v,56.546);
                float2 xy = random2(float2(u,v));
                u = xy.x;
                v= xy.y;
                float x = frac(uv.x);
                float y = frac(uv.y);
                float distance = pow(u - x,2) + pow(v - y,2);
                distance = sqrt(distance);
                
                float radians = rad*saturate(u/v);
                radians = pow(radians,1);
                fixed lumin  =  pow(saturate((radians - distance)),luminPower);
                fixed4 randomColor =  color *saturate(v/u);
                fixed4 col = lumin * randomColor * (saturate(sin(_Time.y + 5 * u/v)) + 0.5);
                return fixed4(col.rgb, 1);
            }

不仅星点的坐标需要随机生成,每个星点的亮度、半径也需要一个随机值。

float radians = rad*saturate(u/v);
fixed4 randomColor =  color *saturate(v/u);

实际上,需要对一维随机函数升级,使其能生成二维的随机数,才能正确生成随机的星点坐标

float2 random2(float2 xy){
                return frac(sin(float2(dot(xy,float2(23423.1,54544.7)), sin(dot(xy,float2(33332.5,18563.3))))) *323434.34344);
            }

一些动态效果

闪烁

首先是使其随时间闪烁,使用sin函数即可。要注意的是不同晶格的闪烁周期要错开。

fixed4 col = lumin * randomColor * (saturate(sin(_Time.y + 5 * u/v)) + 0.5);

偏移

星空是一个经典的样式,因此它有许多不同的动态样式。在做效果之前要把目标明确。我这次是为一个卡牌卡面做背景,考虑到没有视角反转,且大概率只有平移效果,我用世界坐标系下的xy坐标作为其偏移的基准,且做了两层。

fixed4 frag (v2f i) : SV_Target
            {
                
                float2 uv = i.vertex.xy/1000;
                
                float3 clipPos = UnityWorldToClipPos(_WorldPos);
                float exchange = (_WorldPos.x+ _WorldPos.y)/2;
                exchange = (sin(exchange) + 1)/2;
                float2 uv2 = uv + float2(1 * (2*_WorldPos.x/2000 - 1), 1* (2*_WorldPos.y/4000 -1));
                float2 uv1 = uv + float2(1 * (2*_WorldPos.x/8000 - 1), 1* (2*_WorldPos.y/8000 -1));
                fixed4 col = galaxy(uv1, _TessFactor, _Power, _Color, _Radians);
                fixed4 col2 = galaxy(uv2,_TessFactor2, _Power2, _Color2, _Radians2);
                fixed distanceFromSpec = sqrt(pow(uv.x - _SpecCenter.x, 2) +pow(uv.y - _SpecCenter.y,2));
                distanceFromSpec = pow(distanceFromSpec, _SpecPower);
                fixed4 specColor= saturate(lerp(0,1,_SpecRadius - distanceFromSpec)) * _SpecColor;
                return col  + col2 + lerp(0,col, exchange) + lerp(0,col2, 1 - exchange) + specColor;
            }

在这里插入图片描述

接下来再做程序化生成星云噪声的效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值