SceneKit water like in Badger example

安稳与你 提交于 2019-11-30 10:47:26

This water effect was achieved using shader modifiers as shown in the SceneKit Scene Editor within Xcode. The most important material property is the normal map that will be used to affect lighting in order to simulate wavelets on a perfectly flat geometry.

More specifically the modifier for the .surface entry point is

float waterSpeed = u_time * -0.1;vec2 uvs = _surface.normalTexcoord;uvs.x *= 2;vec3 tn = texture2D(u_normalTexture, vec2(uvs.x, uvs.y + waterSpeed)).xyz;tn = tn * 2 - 1;vec3 tn2 = texture2D(u_normalTexture, vec2(uvs.x + 0.35 , uvs.y + 0.35 + (waterSpeed * 1.3))).xyz;tn2 = tn2 * 2 - 1;vec3 rn = (tn + tn2) * 0.5;mat3 ts = mat3(_surface.tangent, _surface.bitangent, _surface.geometryNormal);_surface.normal = normalize(ts * rn);

Here's a commented version of the code:

// Elapsed time in seconds
float waterSpeed = u_time * -0.1;

// Texture coordinates that will be used to sample the normal map
vec2 uvs = _surface.normalTexcoord;
uvs.x *= 2;

// Sample the normal map
vec3 tn = texture2D(u_normalTexture, vec2(uvs.x, uvs.y + waterSpeed)).xyz;

// The texture stores values in the [0, 1] range
// Express the coordinates of the normal vector in the [-1, +1] range
tn = tn * 2 - 1;

// Sample the normal map again, using the `waterSpeed` offset this time
// in order to produce the animation effect
vec3 tn2 = texture2D(u_normalTexture, vec2(uvs.x + 0.35 , uvs.y + 0.35 + (waterSpeed * 1.3))).xyz;
tn2 = tn2 * 2 - 1;

// Combine the two normals (static and animated) to produce a richer (more complex and less uniform) effect
vec3 rn = (tn + tn2) * 0.5;

// Normals in the normal map are expressed in tangent space
// Convert them to object space and override the surface normal to simulate wavelets
mat3 ts = mat3(_surface.tangent, _surface.bitangent, _surface.geometryNormal);
_surface.normal = normalize(ts * rn);
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!