前言

上期我们已经学会了 Shader 的基本概念和基础语法,并且实现了溶解效果。现在你已经学会了 1+1 ,现在我们就可以来学 微积分 解方程啦!这期将会展现 Shader 的更加深入的内容!

正片

需要用到的数学曲线之一:

float3 Sphere(float u, float v, float t)
{
    float r = 0.9 + 0.1 * sin(PI * (12.0 * u + 8.0 * v + t));
    float s = r * cos(0.5 * PI * v);
    float3 p;
    p.x = s * sin(PI * u);
    p.y = r * sin(0.5 * PI * v);
    p.z = s * cos(PI * u);
    return p;
}

这个函数用于生成3D球体,且带有斜体的波动效果,如果你精通数学/图形学,你可以尝试编写更复杂的代码来生成更复杂的数学模型。u、v 对应平面上的 x、y 坐标,t 代表时间——没错这个球会随时间波动

我们需要什么效果

一个纯白色的球,十分单调,但将 Shader 和这个数学曲线结合起来可以让他看上去吸引人得多。作为初学产品,我们可以实现一个颜色渐变的球体。

具体的思路可以是:获取每个粒子的世界坐标,并且根据世界坐标(world position)来设置对应的 rgb ,从而实现渐变。这种渐变的流畅程度取决于你的分辨率(resolution)大小。

在这里分辨率指的是什么?

可以理解为你为了实现这个球体创建了多少个 Cube,Cube 越多,分辨率越高,锯齿越小,这和分辨率的通常意义差不多。为了达到高分辨率,你需要提高 Cube 的数量,不要忘记缩小 Cube 的大小(Scale),以防止球体过大或者方块重叠

代码实现

从上期我们知道了如何获取点的位置(按照标准定义一个结构体即可),现在我们需要实现根据不同的位置实现颜色渐变,给出代码如下:

Shader "Custom/Surface_Shader"
{
    Properties
    {
       _Smoothness ("Smoothness", Range(0,1)) = 0.5
    }
    SubShader
    {
        CGPROGRAM
        #pragma surface ConfigureSurface Standard fullforwardshadows
        #pragma target 3.0

        struct Input
        {
            float3 worldPos;
        };

        float _Smoothness;

        void ConfigureSurface(Input input, inout SurfaceOutputStandard surface)
        {
            surface.Albedo = saturate(input.worldPos * 0.5 + 0.5);
            surface.Smoothness = _Smoothness;
            
            // surface.Metallic = _Metallic;
            // surface.Smoothness = _Glossiness;
            // surface.Alpha = _Color.a;
        }
        
        ENDCG
    }
    FallBack "Diffuse"
}

给出一些这段代码的关键部分:

  • Input结构体

    struct Input: 定义了一个输入结构体,包含着色器程序需要的输入数据。在这个例子中,只有一个worldPos字段,表示顶点的世界坐标。

  • ConfigureSurface函数

    void ConfigureSurface(Input input, inout SurfaceOutputStandard surface): 这是表面着色器的核心函数,用于根据输入计算表面的视觉属性。input参数包含输入数据(在这里是顶点的世界坐标),而surface参数用于输出计算得到的材质属性。

    • surface.Albedo = saturate(input.worldPos * 0.5 + 0.5): 计算反照率(Albedo,即基础颜色),使顶点的世界位置映射到[0,1]范围,以生成基于位置的颜色变化效果。

    • surface.Smoothness = _Smoothness: 设置表面的光滑度属性,其值从之前定义的_Smoothness属性中获取。

成果

我们可以得到一个表面颜色渐变的斜波浪球体

接下来...

现在你已经对 Shader 有了更多了解,如果你还想继续深入学习,可以去找一些教程自学!或者等我的下一篇夸父说(随缘更新(´・ω・`)。刚开始这几期的内容借鉴另一篇 Unity 基础教程,等基础过完就可以进入高级内容了,肝肝肝…

Life is a Rainmeter