Google Filament 源码学习(五):Material System (四) - 材质系统 API

目录

  • Shader public APIs
    • Introduction
    • Types
    • Math
    • Matrices
    • Frame constants
    • Vertex only
    • Fragment only
  • Handling colors
    • Linear colors
    • Pre-multiplied alpha
  • 总结

Shader public APIs

Introduction

   将 Shader public APIs小节单独做总结是有必要的,这部分与材质框架代码编写相关。资料依然来自于官方文档:

  • https://github.com/google/filament/tree/main/docs/Materials.html

Types

  • 虽然 GLSL 的变量类型可以直接使用(如vec4 或 mat4),但 Filament 建议使用以下类型别名:(大部分开C++程序员都喜欢这种方式)
名称 GLSL 类型
bool2 bvec2
bool3 bvec3
bool4 bvec4
int2 ivec2
int3 ivec3
int4 ivec4
uint2 uvec2
uint3 uvec3
uint4 uvec4
float2 float2
float3 float3
float4 float4
float4×4 mat4
float3×3 mat3

Math

名称 GLSL 类型 描述
PI float π \pi π
HALF_PI float π 2 \cfrac{\pi}{2} 2π
saturate(float x) float 将指定值Clamp到 0.0 和1.0 之间
pow5(float x) float x 5 x^5 x5
sq(float x) float x 2 x^2 x2
max3(float3 v) float 返回 float3 中最大的值
mulMat4×4Float3(float4×4 m, float3 v) float4 返回 m ∗ v m * v mv
mulMat3×3Float3(float4×4 m, float3 v) float4 返回 m ∗ v m * v mv

Matrices

名称 类型 描述
getViewFromWorldMatrix() float4×4 从世界空间转换为视图空间的矩阵
getWorldFromViewMatrix() float4×4 从视图空间转换为世界空间的矩阵
getClipFromViewMatrix() float4×4 从视图空间转换为裁剪空间的矩阵
getViewFromClipMatrix() float4×4 从裁剪空间转换为视图空间的矩阵
getClipFromWorldMatrix() float4×4 从世界转换为裁剪空间的矩阵
getWorldFromClipMatrix() float4×4 从裁剪空间转换为世界空间的矩阵

Frame constants

名称 类型 描述
getResolution() float4 视图的分辨率(以像素为单位):宽度、高度、1 /宽度、1 /高度
getWorldCameraPosition() float3 camera/eye 在世界空间中的位置
getWorldOffset() float3 获得 API 级(API-level)世界空间所需的变换
getTime() float 当前时间秒以内的部分。为介于 0 和 1 之间的值
getUserTime() float4 当前时间(以秒为单位): time, (double)time - time, 0, 0
getUserTimeMode(float m) float 当前时间除余 m(以秒为单位)
getExposure() float 相机的曝光量
getEV100() float 相机 ISO100 时的曝光量
  • world space
    • 为了获得良好的精度,Filament的着色系统中的"世界空间"不一定与API级别的世界空间相匹配。要获得 API 级像机的位置,自定义材质可以将 getWorldOffset()添加到 getWorldCameraPosition()中。

Vertex only

  • 只在 vertex 块中使用的 API
名称 类型 描述
getPosition() float4 材质定义域中的顶点位置(默认:对象/模型空间)
getCustom0() 到 getCustom7() float4 自定义顶点属性 (attribute)
getWorldFromModelMatrix() float4×4 从模型(对象)空间转换为世界空间的矩阵
getWorldFromModelNormalMatrix() float3×3 将法线从模型(对象)空间转换为世界空间的矩阵
getVertexIndex() int 当前顶点的索引

Fragment only

  • 以下 API 只能用于 fragment block
名称 类型 描述
getWorldTangentFrame() float3×3 矩阵在每列中包含世界空间中顶点的 tangent (frame[0]),bi-tangent(frame[1])和 normal (frame[2])。如果材质不计算bump mapping 的切线空间法线,或者渲染不是各向异性的,则在此矩阵中只有法线有效。
getWorldPosition() float3 片元在世界空间中的位置
getWorldViewVector() float3 世界空间中从片元位置到 eye 的归一化向量
getWorldNormalVector() float3 在 bump mapping 之后,世界空间中归一化法线(必须在prepareMaterial() 之后使用)
getWorldGeometricNormalVector() float3 在 bump mapping 之前,世界空间中归一化法线(可以在 prepareMaterial() 之前使用)
getWorldReflectedVector() float3 view vector 关于法线的反射向量(必须在prepareMaterial() 之后使用)
getNormalizedViewportCoord() float3 归一化视口位置 (viewport position)(即NDC坐标归一化为[0,1],可以在 prepareMaterial() 之前使用)
getNdotV() float dot(normal, view) 的结果,总是严格大于0(必须在prepareMaterial() 之后使用)
getColor() float4 片元的插值颜色(如果需要颜色属性)
getUV0() float2 UV 坐标,仅当需要 uv0 属性时才可用
getUV1() float2 UV 坐标,仅当需要 uv1 属性时才可用
getMaskThreshold() float 返回 mask 阈值,仅当混合设置为 masked 时才可用
inverseTonemap(float3) float3 将 inverse tone mapping 运算符应用于指定的线性sRGB颜色,并返回一个线性sRGB颜色。此操作可能是一种近似操作,最好与“Filmic” tone mapping 操作符配合使用
inverseTonemapSRGB(float3) float3 将 inverse tone mapping 运算符应用于指定的非线性sRGB颜色,并返回线性sRGB颜色。此操作可能是一种近似操作,最好与“Filmic” tone mapping 操作符配合使用
luminance(float3) float 计算指定线性 sRGB 颜色的 luminance
ycbcrToRgb(float, float2) float3 将 luminance 和 CbCr 对转换为 sRGB 颜色
uvToRenderTargetUV(float2) float2 转换 UV 坐标以允许从 RenderTarget attachment 进行采样
  • sampling from render targets
    • 对于曲面域 (surface domain) 中的材质,从 filament::RenderTarget 的一个 filament::Texture采样时,请使用uvToRenderTargetUV变换纹理坐标。这会将根据正在使用的backend 来翻转坐标 (不同backend 对uv坐标的坐标轴定义不同)。

Handling colors

Linear colors

  • 如果颜色数据来自纹理,只需确保使用 sRGB 纹理即可从 sRGB 到线性的自动硬件转换中受益。

  • 如果颜色数据作为参数传递给材质,则可以通过在每个颜色通道上运行以下算法,将 sRGB 转换为线性:

    float sRGB_to_linear(float color) {
    	return color <= 0.04045 ? color / 12.92 : pow((color + 0.055) / 1.055, 2.4);
    }
    
  • 或者,可以使用下面两个简化、但不太准确的版本之一:

    // Cheaper
    linearColor = pow(color, 2.2);
    // Cheapest
    linearColor = color * color;
    

Pre-multiplied alpha

  • 如果颜色的 RGB 分量乘以 Alpha 通道,则使用Pre-multiplied alpha:

    // Compute pre-multiplied color
    color.rgb *= color.a;
    
  • 如果从纹理中对颜色进行采样,则只需确保提前 pre-multiplied 纹理数据即可。

    • 默认情况下,在 Android 设备上,从 Bitmap 上传的任何纹理都将预先 pre-multiplied。

总结

   本节主要整理一下材质框架使用的API,以便后期进行查询使用。

你可能感兴趣的:(Filament,学习)