GameTech/URP 渲染实战
源码 / shaders/Ch17/VertexAnimCommon.glsl
shaders/Ch17/VertexAnimCommon.glsl
// 第 17 章顶点动画的公共部分:输入结构 + 光照 + 三个 Pass 的顶点函数。(GLSL 版,对应 Ch17/VertexAnimCommon.hlsl)
//
// 用法(写在 Shader 的 GLSLINCLUDE 里):
//   1. 声明材质属性的 uniform
//   2. #include 本文件 "Ch17/VertexAnimCommon.glsl"(只有结构体和工具函数)
//   3. 实现 void Deform(inout VAAttributes v):在物体空间里改 positionOS / normalOS
//   4. #include "Ch17/VertexAnimPasses.glsl":ForwardLit / ShadowCaster / DepthOnly 的顶点函数都会调用 Deform
// 这样“同一个变形”被所有 Pass 共用,阴影和深度天然与画面一致。
#ifndef COOKBOOK_CH17_VA_COMMON_INCLUDED
#define COOKBOOK_CH17_VA_COMMON_INCLUDED

// GLSL 的顶点输入是固定名字的全局变量(positionOS、normalOS、color、texcoord0..3),
// 这里把它们装进一个结构体,Deform 才能像 HLSL 版一样 inout 修改
struct VAAttributes
{
    vec4 positionOS;
    vec3 normalOS;
    vec4 color;       // 草:R = 高度权重,G = 随机数
    vec2 uv;
    vec4 uv1;         // 草:根部位置;碎裂:三角形中心 + 随机数;VAT:顶点编号
    vec4 uv2;         // 碎裂:面法线;也可在 Deform 里写入,传给片元(extra)
};

// Varyings(WebGL 不允许结构体做 varying;color 和顶点输入重名,改叫 vertColor)
VARYING vec2 uv;
VARYING vec3 positionWS;
VARYING vec3 normalWS;
VARYING vec4 vertColor;
VARYING vec4 extra;     // Deform 写进 uv2 的数据,原样交给片元

#ifdef VERTEX
VAAttributes VAGetAttributes()
{
    VAAttributes v;
    v.positionOS = positionOS;
    v.normalOS = normalOS;
    v.color = color;
    v.uv = texcoord0.xy;
    v.uv1 = texcoord1;
    v.uv2 = texcoord2;
    return v;
}
#endif

// 简单的 Lambert + Blinn-Phong + 球谐环境光 + 主光阴影
vec3 VALighting(vec3 albedo, vec3 N, vec3 positionWS, float specular, float gloss)
{
    Light L = GetMainLight(TransformWorldToShadowCoord(positionWS));
    vec3 V = GetWorldSpaceNormalizeViewDir(positionWS);
    vec3 H = normalize(L.direction + V);
    float atten = L.shadowAttenuation;
    vec3 col = albedo * (saturate(dot(N, L.direction)) * atten * L.color + SampleSH(N));
    col += pow(saturate(dot(N, H)), gloss) * specular * atten * L.color;
    return col;
}

// _LightDirection:ShadowCaster 用,由引擎设置(Lighting.glsl 里已声明)

#endif