2021SC@SDUSC
目录
1、什么是着色器?
2、Ebiten API
NewShader
(*Image).DrawRectShader
DrawRectShaderOptions
其他
3、阴影语言Kage
句法
入口点
内置类型
内置类型的初始化函数
Swizzling
统一变量
内置函数 (Go)
内置函数(数学)
内置函数(图像)
纹理和图像
着色器是在 GPU 上执行的程序。自定义着色器是 Ebiten 用户可以编写的着色器。使用着色器,可以高效地在 GPU 上执行复杂的渲染。
在 Ebiten 中,可以编写“片段着色器”。片段着色器是在每个像素上执行的着色器。粗略地说,这是一个为每个像素计算颜色的函数。此颜色计算在 GPU 上并行执行。
使用着色器,可以执行各种效果,例如照明或模糊。
go run -tags=example github.com/hajimehoshi/ebiten/v2/examples/shader@latest
Ebiten 采用了原始的着色语言“Kage”。这与 Go 具有兼容的语法,但细节不同。Kage具有很高的便携性。Ebiten 使用 OpenGL 或 Metal 等图形库,这取决于环境,但 Kage 是即时编译的,因此它在任何地方都可以正常工作。
例子
package main
// Uniform variables.
var Time float
var Cursor vec2
var ScreenSize vec2
// Fragment is the entry point of the fragment shader.
// Fragment returns the color value for the current position.
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
// You can define variables with a short variable declaration like Go.
lightpos := vec3(Cursor, 50)
lightdir := normalize(lightpos - position.xyz)
normal := normalize(imageSrc1UnsafeAt(texCoord) - 0.5)
ambient := 0.25
diffuse := 0.75 * max(0.0, dot(normal.xyz, lightdir))
// You can treat multiple source images by
// imageSrc[N]At or imageSrc[N]UnsafeAt.
return imageSrc0UnsafeAt(texCoord) * (ambient + diffuse)
}
NewShader
func NewShader(src []byte) (*Shader, error)
NewShader
用着色语言 Kage 编译着色器程序,并返回结果。
如果编译失败,则NewShader
返回错误。
(*Image).DrawRectShader
func DrawRectShader(width, height int, shader *Shader, options *DrawRectShaderOptions)
DrawRectShader
使用指定的着色器绘制具有指定宽度和高度的矩形。
DrawRectShaderOptions
type DrawRectShaderOptions struct {
// GeoM is a geometry matrix to draw.
// The default (zero) value is identity, which draws the rectangle at (0, 0).
GeoM GeoM
// CompositeMode is a composite mode to draw.
// The default (zero) value is regular alpha blending.
CompositeMode CompositeMode
// Uniforms is a set of uniform variables for the shader.
// The keys are the names of the uniform variables.
// The values must be float or []float.
// If the uniform variable type is an array, a vector or a matrix,
// you have to specify linearly flattened values as a slice.
// For example, if the uniform variable type is [4]vec4, the number of the slice values will be 16.
Uniforms map[string]interface{}
// Images is a set of the source images.
// All the image must be the same size with the rectangle.
Images [4]*Image
}
对于更原始的渲染,还有(*Image).DrawTrianglesShader
和DrawTrianglesShaderOptions
。
语法与 Go 基本相同。这在语法级别上完全相同。你甚至可以做到gofmt
。
到目前为止,Kage 还没有这些 Go 的功能。
rune
, string
, 除int
, interface
、切片、指针、结构、函数类型、通道外的数字类型)len
(例如,new
, make
, panic
)type
import
switch
goto
for-range
defer
init
职能Kage 只能定义一个片段着色器。Fragment
具有以下输入参数的函数是入口点。
func Fragment(position vec4, texCoord vec2, color vec4) vec4
姓名 | 类型 | 描述 |
---|---|---|
position |
vec4 |
以像素为单位的目标位置。第 3 和第 4 分量始终为 0 和 1。 |
texCoord |
vec2 |
源纹理在纹素中的位置。 |
color |
vec4 |
从顶点给出的补充颜色信息。每个组件的值都在 0 到 1 之间。这个值只有在DrawTrianglesShader 使用时才有意义。 |
(返回值) | vec4 |
当前位置的颜色。每个组件的值都在 0 到 1 之间。 |
Kage 有这些内置类型。
bool
int
float
vec2
, vec3
, vec4
(矢量)mat2
, mat3
, mat4
(矩阵)float
是一个浮点数。与 Go 的float32
and不同float64
,float
它不能保证精度。
vec2
, vec3
,vec4
称为向量,是分别具有 2、3 和 4 个分量的元组。每个组件都是float
. Swizzling 操作可用于向量值。
mat2
, mat3
,mat4
是 2、3 和 4 维方阵。每个组件都是float
.
Kage 还支持数组。Kage 不支持结构体。
与 Go 类似,您可以通过将类型名称用作函数来获取类型的值。向量类型和矩阵类型非常特殊,它们可以采用灵活的参数。
v1 := vec4(0) // Returns a vec4 whose components are all 0.
v2 := vec4(1, 2, 3, 4) // Returns a vec4 whose components are 1, 2, 3 and 4.
v3 := vec3(5, 6, 7)
v4 := vec4(1, v3) // Returns a vec4 whose components are 1, 5, 6 and 7.
m1 := mat4(2) // Returns a mat4 whose diagonal components are 2 and the others are 0.
m2 := mat4(v1, v2, v3, v1) // Returns a mat4 whose columns are v1, v2, v3 and v1.
有一个特殊的操作叫做 Swizzling -搅拌 用于向量类型。可以同时读写多个组件。
v1 := vec4(1, 2, 3, 4)
v2 := v1.xyz // Get vec3(1, 2, 3) and initialize v2 with this.
v2.xyz = v2.xxx // Get vec3(1, 1, 1), and set it to all the components to v2.
// Then, v2 is now (1, 1, 1).
每个组件如下所示。可以将它们混合在同一组中,但不能在不同组中混合。例如,.xxyy
和.abgr
可用,但.xxgg
无效。
x
, y
, z
,w
r
, g
, b
,a
s
, t
, p
,q
统一变量是一个全局变量,其值在外部给出。无论像素的位置如何,该值都是相同的。
在 Kage 中,uniform 变量是以大写开头的全局变量(即导出变量)。
不能在 Kage 中为统一变量赋值。
不能在 Kage 中定义除统一变量之外的其他全局变量。
功能 | 描述 |
---|---|
cap(x T) int |
T 是数组类型。返回数组的长度。(v2.1.0) |
len(x T) int |
T 是数组类型。返回数组的长度。 |
大多数内置函数都是通用的。T
表示float
, vec2
,vec3
或vec4
除非另有说明。当类型为向量时,该函数适用于每个组件。
功能 | 描述 |
---|---|
imageSrcNAt(pos vec2) vec4 |
返回源图像N 的纹素中vec4 给定位置pos的颜色值。N为 0 到 3。 |
imageSrcNUnsafeAt(pos vec2) vec4 |
返回源图像N 的纹素中vec4 给定位置pos的颜色值。N为 0 到 3。与安全版本 (imageSrcNAt )的区别在于位置越界时的返回值。在这种情况下,安全版本返回 vec4(0) ,而不安全版本的返回值未定义。不安全的版本更快。如果您确定位置在边界内,则可以使用不安全版本来提高性能。 |
imageSrcTextureSize() vec2 |
以像素为单位返回源图像的纹理大小 |
imageDstTextureSize() vec2 |
以像素为单位返回目标图像的纹理大小 |
imageSrcRegionOnTexture() (vec2, vec2) |
以 texels 为单位返回源图像的原点位置和纹理上的大小 |
imageDstRegionOnTexture() (vec2, vec2) |
返回目标图像的原点位置和纹理大小(以 texels 为单位)(v2.1.0) |