Skip to content

Commit 43b0c94

Browse files
authored
[examples] Add new example: shaders_vertex_displacement (#4186)
* shaders-vertex_displacement init * implement simulation of wave in ocean * update examples/README & add some comments * update comments * add gl100 shaders
1 parent 92f60a9 commit 43b0c94

File tree

9 files changed

+261
-11
lines changed

9 files changed

+261
-11
lines changed

examples/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,8 @@ SHADERS = \
612612
shaders/shaders_texture_outline \
613613
shaders/shaders_texture_tiling \
614614
shaders/shaders_texture_waves \
615-
shaders/shaders_write_depth
615+
shaders/shaders_write_depth \
616+
shaders/shaders_vertex_displacement
616617

617618
AUDIO = \
618619
audio/audio_mixed_processor \

examples/Makefile.Web

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,8 @@ SHADERS = \
476476
shaders/shaders_texture_outline \
477477
shaders/shaders_texture_tiling \
478478
shaders/shaders_texture_waves \
479-
shaders/shaders_write_depth
479+
shaders/shaders_write_depth \
480+
shaders/shaders_vertex_displacement
480481

481482
AUDIO = \
482483
audio/audio_mixed_processor \

examples/README.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -178,29 +178,30 @@ Examples using raylib shaders functionality, including shaders loading, paramete
178178
| 115 | [shaders_multi_sample2d](shaders/shaders_multi_sample2d.c) | <img src="shaders/shaders_multi_sample2d.png" alt="shaders_multi_sample2d" width="80"> | ⭐️⭐️☆☆ | 3.5 | 3.5 | [Ray](https://github.com/raysan5) |
179179
| 116 | [shaders_spotlight](shaders/shaders_spotlight.c) | <img src="shaders/shaders_spotlight.png" alt="shaders_spotlight" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/codifies) |
180180
| 117 | [shaders_deferred_render](shaders/shaders_deferred_render.c) | <img src="shaders/shaders_deferred_render.png" alt="shaders_deferred_render" width="80"> | ⭐️⭐️⭐️⭐️ | 4.5 | 4.5 | [Justin Andreas Lacoste](https://github.com/27justin) |
181+
| 118 | [shaders_vertex_displacement](shaders/shaders_vertex_displacement.c) | <img src="shaders/shaders_vertex_displacement.png" alt="shaders_deferred_render" width="80"> | ⭐️☆☆☆ | 1.5 | 1.5 | [Alex ZH](https://github.com/ZzzhHe) |
181182

182183
### category: audio
183184

184185
Examples using raylib audio functionality, including sound/music loading and playing. This functionality is provided by raylib [raudio](../src/raudio.c) module. Note this module can be used standalone independently of raylib, check [raudio_standalone](others/raudio_standalone.c) example.
185186

186187
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
187188
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
188-
| 118 | [audio_module_playing](audio/audio_module_playing.c) | <img src="audio/audio_module_playing.png" alt="audio_module_playing" width="80"> | ⭐️☆☆☆ | 1.5 | 3.5 | [Ray](https://github.com/raysan5) |
189-
| 119 | [audio_music_stream](audio/audio_music_stream.c) | <img src="audio/audio_music_stream.png" alt="audio_music_stream" width="80"> | ⭐️☆☆☆ | 1.3 | **4.2** | [Ray](https://github.com/raysan5) |
190-
| 120 | [audio_raw_stream](audio/audio_raw_stream.c) | <img src="audio/audio_raw_stream.png" alt="audio_raw_stream" width="80"> | ⭐️⭐️⭐️☆ | 1.6 | **4.2** | [Ray](https://github.com/raysan5) |
191-
| 121 | [audio_sound_loading](audio/audio_sound_loading.c) | <img src="audio/audio_sound_loading.png" alt="audio_sound_loading" width="80"> | ⭐️☆☆☆ | 1.1 | 3.5 | [Ray](https://github.com/raysan5) |
189+
| 119 | [audio_module_playing](audio/audio_module_playing.c) | <img src="audio/audio_module_playing.png" alt="audio_module_playing" width="80"> | ⭐️☆☆☆ | 1.5 | 3.5 | [Ray](https://github.com/raysan5) |
190+
| 120 | [audio_music_stream](audio/audio_music_stream.c) | <img src="audio/audio_music_stream.png" alt="audio_music_stream" width="80"> | ⭐️☆☆☆ | 1.3 | **4.2** | [Ray](https://github.com/raysan5) |
191+
| 121 | [audio_raw_stream](audio/audio_raw_stream.c) | <img src="audio/audio_raw_stream.png" alt="audio_raw_stream" width="80"> | ⭐️⭐️⭐️☆ | 1.6 | **4.2** | [Ray](https://github.com/raysan5) |
192+
| 122 | [audio_sound_loading](audio/audio_sound_loading.c) | <img src="audio/audio_sound_loading.png" alt="audio_sound_loading" width="80"> | ⭐️☆☆☆ | 1.1 | 3.5 | [Ray](https://github.com/raysan5) |
192193

193194
### category: others
194195

195196
Examples showing raylib misc functionality that does not fit in other categories, like standalone modules usage or examples integrating external libraries.
196197

197198
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
198199
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
199-
| 122 | [rlgl_standalone](others/rlgl_standalone.c) | <img src="others/rlgl_standalone.png" alt="rlgl_standalone" width="80"> | ⭐️⭐️⭐️⭐️ | 1.6 | **4.0** | [Ray](https://github.com/raysan5) |
200-
| 123 | [rlgl_compute_shader](others/rlgl_compute_shader.c) | <img src="others/rlgl_compute_shader.png" alt="rlgl_compute_shader" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Teddy Astie](https://github.com/tsnake41) |
201-
| 124 | [easings_testbed](others/easings_testbed.c) | <img src="others/easings_testbed.png" alt="easings_testbed" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | 3.0 | [Juan Miguel López](https://github.com/flashback-fx) |
202-
| 125 | [raylib_opengl_interop](others/raylib_opengl_interop.c) | <img src="others/raylib_opengl_interop.png" alt="raylib_opengl_interop" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Stephan Soller](https://github.com/arkanis) |
203-
| 126 | [embedded_files_loading](others/embedded_files_loading.c) | <img src="others/embedded_files_loading.png" alt="embedded_files_loading" width="80"> | ⭐️⭐️☆☆ | 3.5 | 3.5 | [Kristian Holmgren](https://github.com/defutura) |
200+
| 123 | [rlgl_standalone](others/rlgl_standalone.c) | <img src="others/rlgl_standalone.png" alt="rlgl_standalone" width="80"> | ⭐️⭐️⭐️⭐️ | 1.6 | **4.0** | [Ray](https://github.com/raysan5) |
201+
| 124 | [rlgl_compute_shader](others/rlgl_compute_shader.c) | <img src="others/rlgl_compute_shader.png" alt="rlgl_compute_shader" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Teddy Astie](https://github.com/tsnake41) |
202+
| 125 | [easings_testbed](others/easings_testbed.c) | <img src="others/easings_testbed.png" alt="easings_testbed" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | 3.0 | [Juan Miguel López](https://github.com/flashback-fx) |
203+
| 126 | [raylib_opengl_interop](others/raylib_opengl_interop.c) | <img src="others/raylib_opengl_interop.png" alt="raylib_opengl_interop" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Stephan Soller](https://github.com/arkanis) |
204+
| 127 | [embedded_files_loading](others/embedded_files_loading.c) | <img src="others/embedded_files_loading.png" alt="embedded_files_loading" width="80"> | ⭐️⭐️☆☆ | 3.5 | 3.5 | [Kristian Holmgren](https://github.com/defutura) |
204205

205206
As always contributions are welcome, feel free to send new examples! Here is an [examples template](examples_template.c) to start with!
206207

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#version 100
2+
3+
precision mediump float;
4+
5+
// Input vertex attributes (from fragment shader)
6+
varying vec2 fragTexCoord;
7+
varying float height;
8+
9+
10+
void main()
11+
{
12+
vec4 darkblue = vec4(0.0, 0.13, 0.18, 1.0);
13+
vec4 lightblue = vec4(1.0, 1.0, 1.0, 1.0);
14+
// Interpolate between two colors based on height
15+
vec4 finalColor = mix(darkblue, lightblue, height);
16+
17+
gl_FragColor = finalColor;
18+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#version 100
2+
3+
precision mediump float;
4+
5+
attribute vec3 vertexPosition;
6+
attribute vec2 vertexTexCoord;
7+
attribute vec3 vertexNormal;
8+
attribute vec4 vertexColor;
9+
10+
uniform mat4 mvp;
11+
uniform mat4 matModel;
12+
uniform mat4 matNormal;
13+
14+
uniform float time;
15+
16+
uniform sampler2D perlinNoiseMap;
17+
18+
varying vec3 fragPosition;
19+
varying vec2 fragTexCoord;
20+
varying vec3 fragNormal;
21+
varying float height;
22+
23+
void main()
24+
{
25+
// Calculate animated texture coordinates based on time and vertex position
26+
vec2 animatedTexCoord = sin(vertexTexCoord + vec2(sin(time + vertexPosition.x * 0.1), cos(time + vertexPosition.z * 0.1)) * 0.3);
27+
28+
// Normalize animated texture coordinates to range [0, 1]
29+
animatedTexCoord = animatedTexCoord * 0.5 + 0.5;
30+
31+
// Fetch displacement from the perlin noise map
32+
float displacement = texture2D(perlinNoiseMap, animatedTexCoord).r * 7.0; // Amplified displacement
33+
34+
// Displace vertex position
35+
vec3 displacedPosition = vertexPosition + vec3(0.0, displacement, 0.0);
36+
37+
// Send vertex attributes to fragment shader
38+
fragPosition = vec3(matModel * vec4(displacedPosition, 1.0));
39+
fragTexCoord = vertexTexCoord;
40+
fragNormal = normalize(vec3(matNormal * vec4(vertexNormal, 1.0)));
41+
height = displacedPosition.y * 0.2; // send height to fragment shader for coloring
42+
43+
// Calculate final vertex position
44+
gl_Position = mvp * vec4(displacedPosition, 1.0);
45+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#version 330
2+
3+
// Input fragment attributes (from fragment shader)
4+
in vec2 fragTexCoord;
5+
in float height;
6+
7+
// Output fragment color
8+
out vec4 finalColor;
9+
10+
void main()
11+
{
12+
vec4 darkblue = vec4(0.0, 0.13, 0.18, 1.0);
13+
vec4 lightblue = vec4(1.0, 1.0, 1.0, 1.0);
14+
// interplate between two colors based on height
15+
finalColor = mix(darkblue, lightblue, height);
16+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#version 330
2+
3+
// Input vertex attributes
4+
in vec3 vertexPosition;
5+
in vec2 vertexTexCoord;
6+
in vec3 vertexNormal;
7+
in vec4 vertexColor;
8+
9+
// Input uniform values
10+
uniform mat4 mvp;
11+
uniform mat4 matModel;
12+
uniform mat4 matNormal;
13+
14+
uniform float time;
15+
16+
uniform sampler2D perlinNoiseMap;
17+
18+
// Output vertex attributes (to fragment shader)
19+
out vec3 fragPosition;
20+
out vec2 fragTexCoord;
21+
out vec3 fragNormal;
22+
out float height;
23+
24+
void main()
25+
{
26+
// Calculate animated texture coordinates based on time and vertex position
27+
vec2 animatedTexCoord = sin(vertexTexCoord + vec2(sin(time + vertexPosition.x * 0.1), cos(time + vertexPosition.z * 0.1)) * 0.3);
28+
29+
// Normalize animated texture coordinates to range [0, 1]
30+
animatedTexCoord = animatedTexCoord * 0.5 + 0.5;
31+
32+
// Fetch displacement from the perlin noise map
33+
float displacement = texture(perlinNoiseMap, animatedTexCoord).r * 7; // Amplified displacement
34+
35+
// Displace vertex position
36+
vec3 displacedPosition = vertexPosition + vec3(0.0, displacement, 0.0);
37+
38+
// Send vertex attributes to fragment shader
39+
fragPosition = vec3(matModel*vec4(displacedPosition, 1.0));
40+
fragTexCoord = vertexTexCoord;
41+
fragNormal = normalize(vec3(matNormal*vec4(vertexNormal, 1.0)));
42+
height = displacedPosition.y * 0.2; // send height to fragment shader for coloring
43+
44+
// Calculate final vertex position
45+
gl_Position = mvp*vec4(displacedPosition , 1.0);
46+
}
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*******************************************************************************************
2+
*
3+
* raylib [shaders] example - Vertex displacement
4+
*
5+
* Example originally created with raylib 5.0, last time updated with raylib 4.5
6+
*
7+
* Example contributed by <Alex ZH> (@ZzzhHe) and reviewed by Ramon Santamaria (@raysan5)
8+
*
9+
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
10+
* BSD-like license that allows static linking with closed source software
11+
*
12+
* Copyright (c) 2023 <Alex ZH> (@ZzzhHe)
13+
*
14+
********************************************************************************************/
15+
16+
#include "raylib.h"
17+
#include "raymath.h"
18+
#include "rlgl.h"
19+
20+
#include <printf.h>
21+
22+
#define RLIGHTS_IMPLEMENTATION
23+
#include "rlights.h"
24+
25+
#if defined(PLATFORM_DESKTOP)
26+
#define GLSL_VERSION 330
27+
#else // PLATFORM_ANDROID, PLATFORM_WEB
28+
#define GLSL_VERSION 100
29+
#endif
30+
31+
//------------------------------------------------------------------------------------
32+
// Program main entry point
33+
//------------------------------------------------------------------------------------
34+
int main(void)
35+
{
36+
// Initialization
37+
//--------------------------------------------------------------------------------------
38+
const int screenWidth = 800;
39+
const int screenHeight = 450;
40+
41+
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - vertex displacement");
42+
43+
// set up camera
44+
Camera camera = {0};
45+
camera.position = (Vector3) {20.0f, 5.0f, -20.0f};
46+
camera.target = (Vector3) {0.0f, 0.0f, 0.0f};
47+
camera.up = (Vector3) {0.0f, 1.0f, 0.0f};
48+
camera.fovy = 60.0f;
49+
camera.projection = CAMERA_PERSPECTIVE;
50+
51+
// Load vertex and fragment shaders
52+
Shader shader = LoadShader(
53+
TextFormat("resources/shaders/glsl%i/vertex_displacement.vs", GLSL_VERSION),
54+
TextFormat("resources/shaders/glsl%i/vertex_displacement.fs", GLSL_VERSION)
55+
);
56+
57+
// Load perlin noise texture
58+
Image perlinNoiseImage = GenImagePerlinNoise(512, 512, 0, 0, 1.0f);
59+
Texture perlinNoiseMap = LoadTextureFromImage(perlinNoiseImage);
60+
UnloadImage(perlinNoiseImage);
61+
62+
// Set shader uniform location
63+
int perlinNoiseMapLoc = GetShaderLocation(shader, "perlinNoiseMap");
64+
rlEnableShader(shader.id);
65+
rlActiveTextureSlot(1);
66+
rlEnableTexture(perlinNoiseMap.id);
67+
rlSetUniformSampler(perlinNoiseMapLoc, 1);
68+
69+
// Create a plane mesh and model
70+
Mesh planeMesh = GenMeshPlane(50, 50, 50, 50);
71+
Model planeModel = LoadModelFromMesh(planeMesh);
72+
// Set plane model material
73+
planeModel.materials[0].shader = shader;
74+
75+
float time = 0.0f;
76+
77+
SetTargetFPS(60);
78+
//--------------------------------------------------------------------------------------
79+
80+
// Main game loop
81+
while (!WindowShouldClose()) // Detect window close button or ESC key
82+
{
83+
// Update
84+
//----------------------------------------------------------------------------------
85+
UpdateCamera(&camera, CAMERA_FREE); // Update camera
86+
87+
time += GetFrameTime(); // Update time variable
88+
SetShaderValue(shader, GetShaderLocation(shader, "time"), &time, SHADER_UNIFORM_FLOAT); // Send time value to shader
89+
90+
// Draw
91+
//----------------------------------------------------------------------------------
92+
BeginDrawing();
93+
94+
ClearBackground(RAYWHITE);
95+
96+
BeginMode3D(camera);
97+
98+
BeginShaderMode(shader);
99+
// Draw plane model
100+
DrawModel(planeModel, (Vector3){ 0.0f, 0.0f, 0.0f }, 1.0f, (Color) {255, 255, 255, 255});
101+
EndShaderMode();
102+
103+
EndMode3D();
104+
105+
DrawText("Vertex displacement", 10, 10, 20, DARKGRAY);
106+
DrawFPS(10, 40);
107+
108+
EndDrawing();
109+
//----------------------------------------------------------------------------------
110+
}
111+
112+
// De-Initialization
113+
//--------------------------------------------------------------------------------------
114+
115+
UnloadShader(shader);
116+
UnloadModel(planeModel);
117+
118+
CloseWindow(); // Close window and OpenGL context
119+
//--------------------------------------------------------------------------------------
120+
121+
return 0;
122+
}
302 KB
Loading

0 commit comments

Comments
 (0)