完整资源:
前情提要:
从0开始编写minecraft光影包(0)GLSL,坐标系,光影包结构介绍
从零开始编写minecraft光影包(4)泛光性能与品质优化
从零开始编写minecraft光影包(5)简单光照系统,曝光调节,色调映射与饱和度
前言
国庆快完了。。。还是来更新下博客,不能太摸鱼了。。。
好了不扯了。。。今天来实现水面的渲染。
注:本次着色器特效的编写基于上一篇博客中完成的着色器。
gbuffer阶段着色器是如何渲染水面的
要渲染水面,首先我们编写 gbuffers_water 着色器。他们的内容是:
gbuffers_water.vsh:
#version 120
varying vec4 texcoord;
varying vec4 color;
void main() {
gl_Position = ftransform();
color = gl_Color; // 基色
texcoord = gl_TextureMatrix[0] * gl_MultiTexCoord0;
}
gbuffers_water.fsh:
#version 120
uniform sampler2D texture;
varying vec4 texcoord;
varying vec4 color;
void main() {
gl_FragData[0] = color * texture2D(texture, texcoord.st);
}
重新加载光影包,你会发现啥变化都没有。。。这不是废话🐎,我们只是把颜色直接输出了而已。。。
和其他方块的绘制一样,颜色的绘制分为两个部分:
- 水方块基色
- 水方块纹理
我们当然可以无视这个过程,比如我们直接输出颜色,将 gbuffers_water.fsh 中输出颜色的部分改为:
gl_FragData[0] = vec4(vec3(0.1, 0.2, 0.4), 0.5);
其中 w 分量表示颜色的 alpha 通道,即透明度,下面展示不同透明度的水面渲染结果:
但是问题就来了,当我们直接输出 vec4(vec3(0.1, 0.2, 0.4), 0.5)
的时候,会发现染色玻璃,冰块等透明方块,也变成了水的颜色:
这是因为 gbuffers_water 着色器除了负责渲染水,还负责这些透明方块的渲染,因此我们要渲染水面,首先得进行一次筛选。
我们在 block.properties 中添加一行,将水方块的 id 设置为 10091:
block.10091 = flowing_water water
随后我们将 gbuffers_water.vsh 的内容改为:
#version 120
attribute vec2 mc_Entity;
varying float id;
varying vec4 texcoord;
varying vec4 color;
void main() {
gl_Position = ftransform();
color = gl_Color; // 基色
texcoord = gl_TextureMatrix[0] * gl_Mu