shader - seraph526/godot-se GitHub Wiki
Shading 语言
介绍
Godot使用简单的shader语言(基本是GLSL的子集).Shader可以用来:
- 材质(Materials)
- 后期处理(Post-Process)
- 2D 它被划分为Vertex和"Fragment"部分.
语言
归类 (Typing)
这个语言是静态类型,只支持一些操作。Arrays, classes, structures等等是不支持的。提供了一些内建类型:
数据类型
数据类型 | 描述 |
---|---|
void | Void |
bool | boolean (true or false) |
float | floating point |
vec2 | 2-component vector, float subindices (x,y or r,g ) |
vec3 | 3-component vector, float subindices (x,y,z or r,g,b ) |
vec4,color | 4-component vector, float subindices (x,y,z,w or r,g,b,a ) |
mat3 | 3x3 matrix, vec3 subindices (x,y,z) |
mat4 | 4x4 matrix, vec4 subindices (x,y,z,w) |
texture | texture sampler, can only be used as uniform |
cubemap | cubemap sampler, can only be used as uniform |
语法
语法和C类似,语句以";"结束,注释是//和/**/. Example:
float a = 3;
vec3 b;
b.x = a;
混合(Swizzling)
可以使用混合按顺序重新定义索引或组的索引:
vec3 a = vec3(1,2,3);
vec3 b = a.zyx; // b will contain vec3(3,2,1)
vec2 c = a.xy; // c will contain vec2(1,2)
vec4 d = a.xyzz; // d will contain vec4(1,2,3,3)
构造函数 (Constructors)
构造函数通常需要一定数量的参数,但也可以接收少于指定数量的参数,如果接收的参数中有子索引,如:
vec3 a = vec3( 1, vec2(2,3) );
vec3 b = vec3( a );
vec3 c = vec3( vec2(2,3), 1 );
vec4 d = vec4( a, 5 );
mat3 m = mat3( a,b,c );
条件 (Conditionals)
现在,只支持if条件,如:
if (a < b) {
c = b;
}
Uniforms
变量可以被声明为uniform.这样,它的值可以来自shader以外(它可以是材质或任何提供给shader使用的变量)
uniform vec3 direction;
uniform color tint;
vec3 result = tint.rgb * direction;
Functions
只提供对函数的简单支持。函数不可以访问uniforms或其他的shader变量。
vec3 addtwo( vec3 a, vec3 b) {
return a+b;
}
vec3 c = addtwo(vec3(1,1,1)+vec3(2,2,2));
Built-In Functions
为了方便提供了一些内置函数,列表如下:
Function | Description |
---|---|
float sin( float ) | Sine |
float cos( float ) | Cosine |
float tan( float ) | Tangent |
float asin( float ) | arc-Sine |
float acos( float ) | arc-Cosine |
float atan( float ) | arc-Tangent |
vec_type pow( vec_type, float ) | Power |
vec_type pow( vec_type, vec_type ) | Power (Vec. Exponent) |
vec_type exp( vec_type ) | Base-e Exponential |
vec_type log( vec_type ) | Natural Logarithm |
vec_type sqrt( vec_type ) | Square Root |
vec_type abs( vec_type ) | Absolute |
vec_type sign( vec_type ) | Sign |
vec_type floor( vec_type ) | Floor |
vec_type trunc( vec_type ) | Trunc |
vec_type ceil( vec_type ) | Ceiling |
vec_type fract( vec_type ) | Fractional |
vec_type mod( vec_type,vec_type ) | Remainder |
vec_type min( vec_type,vec_type ) | Minimum |
vec_type min( vec_type,vec_type ) | Maximum |
vec_type clamp( vec_type value,vec_type min, vec_type max ) | Clamp to Min-Max |
vec_type mix( vec_type a,vec_type b, float c ) | Linear Interpolate |
vec_type mix( vec_type a,vec_type b, vec_type c ) | Linear Interpolate (Vector Coef.) |
vec_type step( vec_type a,vec_type b) | a[i] < b[i] ? 0.0 : 1.0 |
vec_type smoothstep( vec_type a,vec_type b,vec_type c) | |
float length( vec_type ) | Vector Length |
float distance( vec_type, vec_type ) | Distance between vector. |
float dot( vec_type, vec_type ) | Dot Product |
vec3 dot( vec3, vec3 ) | Cross Product |
vec_type normalize( vec_type ) | Normalize to unit length |
vec3 reflect( vec3, vec3 ) | Reflect |
color tex( texture, vec2 ) | Read from a texture in noormalized coords |
color texcube( texture, vec3 ) | Read from a cubemap |
color texscreen( texture, vec1 ) | Read from screen (generates a copy) |
Built-In Variables
基于shader类型,有一些内置变量可用,列表如下:
Material - VertexShader
Variable | Description |
---|---|
vec3 VERTEX | Pre-Transformed Vertex |
vec3 NORMAL | Pre-Transformed Normal |
vec3 TANGENT | Pre-Transformed Tangent |
vec2 UV | UV |
vec2 UV2 | UV2 |
color COLOR | Vertex Color |
out vec4 VAR1 | Varying 1 Output |
out vec4 VAR2 | Varying 2 Output |
out float SPEC_EXP | Specular Exponent (for Vertex Lighting) |
out float POINT_SIZE | Point Size (for points) |
const mat4 WORLD_MATRIX | Object World Matrix |
const mat4 INV_CAMERA_MATRIX | Inverse Camera Matrix |
const mat4 PROJECTION_MATRIX | Projection Matrix |
const float INSTANCE_ID | Instance ID (for multimesh) |
const float TIME | Time (in seconds) |
Material - FragmentShader
Variable | Description |
---|---|
const vec3 VERTEX | View-Space vertex |
const vec4 POSITION | View-Space Position |
const vec3 NORMAL | View-Space Normal |
const vec3 TANGENT | View-Space Tangent |
const vec3 BINORMAL | View-Space Binormal |
const vec2 UV | UV |
const vec2 UV2 | UV2 |
const color COLOR | Vertex Color |
const vec4 VAR1 | Varying 1 |
const vec4 VAR2 | Varying 2 |
const vec2 SCREEN_TEXEL_SIZE | Size of Screen Pixel (for texscreen) |
const float TIME | Time (in seconds) |
out vec3 DIFFUSE | Diffuse Color |
out vec4 DIFFUSE_ALPHA | Diffuse Color with Alpha |
out vec3 SPECULAR | Specular Color |
out vec3 EMISSION | Emission Color |
out float SPEC_EXP | Specular Exponent (Fragment Version) |
out float GLOW | Glow |
out float DISCARD | Discard (any write > 0.5 discards the pixel) |
Material - LightShader
Variable | Description |
---|---|
const vec3 NORMAL | View-Space normal |
const vec3 LIGHT_DIR | View-Space Light Direction |
const vec3 EYE_VEC | View-Space Eye-Point Vector |
const vec3 DIFFUSE | Material Diffuse Color |
const vec3 LIGHT_DIFFUSE | Light Diffuse Color |
const vec3 SPECULAR | Material Specular Color |
const vec3 LIGHT_SPECULAR | Light Specular Color |
const float SPECULAR_EXP | Specular Exponent |
const vec1 SHADE_PARAM | Generic Shade Parameter |
const vec2 POINT_COORD | Current Pixel Coordinate |
out vec2 LIGHT | Resulting Light |
const float TIME | Time (in seconds) |
Examples
材质读取一张纹理图texture,一个颜色color,相乘,fragment程序:
uniform color modulate;
uniform texture source;
DIFFUSE = color.rgb * tex(source,UV).rgb;
材质发光从红色变成白色:
DIFFUSE = vec3(1,0,0) + vec(1,1,1)*mod(TIME,1.0);
Standard Blinn Lighting Shader
float NdotL = max(0.0,dot( NORMAL, LIGHT_DIR ));
vec3 half_vec = normalize(LIGHT_DIR + EYE_VEC);
float eye_light = max(dot(NORMAL, half_vec),0.0);
LIGHT = LIGHT_DIFFUSE * DIFFUSE * NdotL;
if (NdotL > 0.0) {
LIGHT+=LIGHT_SPECULAR * SPECULAR * pow( eye_light, SPECULAR_EXP );
};
Notes
- Do not:不要使用DIFFUSE_ALPHA,除非你真的要使用透明.透明材质要使用深度存储,这会降低渲染管线。对于不透明的材质,只要使用DIFFUSE.
-
- Do not:除非你真的需要,不要使用DISCARD,Discard会让渲染变慢,特别是在mobile设备上.
- 一定时间后TIME会被重置(大概持续一个小时左右),所以效果是一直在变化的。
- 通常,不要为了写更少的shader代码,而使用内置变量,为了某个伟大的shader而写大量的代码或有很多可选性通常不是一个好主意.
--- //[email protected] 2013/11/10 18:10//