From 152db1a5db951f77a55815b0ca7d9c5172fd8dea Mon Sep 17 00:00:00 2001 From: Luke Lau Date: Sun, 12 Apr 2020 00:59:14 +0100 Subject: [PATCH] Hack around brightness and shader viewport size --- Makefile | 2 +- billboardfrag.glsl | 4 +-- clouds.cpp | 63 ++++++++++++++++++++++++++++++++-------------- debug.hpp | 6 +++-- 4 files changed, 51 insertions(+), 24 deletions(-) diff --git a/Makefile b/Makefile index 6465814..cf0c407 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ clouds: clouds.cpp program.cpp simulation.cpp - clang++ -std=c++17 $^ -march=native -o $@ \ + clang++ -std=c++17 $^ -O3 -march=native -o $@ \ -Wall -g \ -I/usr/local/include -L/usr/local/lib \ -framework OpenGL -framework glut -lglew diff --git a/billboardfrag.glsl b/billboardfrag.glsl index c2e480b..39fd71d 100644 --- a/billboardfrag.glsl +++ b/billboardfrag.glsl @@ -13,7 +13,7 @@ void main() { return; } if (debug) { - FragColor = mix(vec4(1, 1, 1, 1), vec4(1, 0, 0, 1), debugVal); + FragColor = mix(vec4(1, 1, 1, 0), vec4(1, 0, 0, 1), debugVal); return; } // Cf = color from fragment, Ct = color from texture @@ -25,7 +25,7 @@ void main() { // GL_MODULATE: C // C = Cf * Ct // A = Af * At - FragColor = color * f; + FragColor = color * (f + 0.03); // the +0.03 is a hack to get lighter clouds! } else { // "That is, the colors in the frame buffer are multiplied by the // attenuation ratio of the billboard texture and then the colors in diff --git a/clouds.cpp b/clouds.cpp index 5d18823..3ed3b10 100644 --- a/clouds.cpp +++ b/clouds.cpp @@ -26,16 +26,16 @@ Mode curMode = render; using namespace std; using namespace glm; -const float metaballR = 2.f * 1.f / 16.f; +const float metaballR = 1.f / 16.f; inline float metaballField(float r) { - if (r > metaballR) + if (r > 1) return 0; - const float a = r / metaballR; + const float a = r / (1); return (-4.f / 9.f * powf(a, 6)) + (17.f / 9.f * powf(a, 4)) - (22.f / 9.f * powf(a, 2)) + 1; } -const float normalizationFactor = 748.f / 405.f * M_PI * metaballR; +const float normalizationFactor = (748.f / 405.f) * M_PI; void checkError() { if (GLenum e = glGetError()) { @@ -65,10 +65,10 @@ void precalculateBillboardTextures() { for (int j = 0; j < 32; j++) { for (int i = 0; i < 32; i++) { // TODO: properly calculate this instead of whatever this is - float r = distance(vec2(i, j), vec2(16, 16)) / 32; + float r = distance(vec2(i, j), vec2(16, 16)) / 16; float density = (float)d / NQ; data[i + j * 32] = - 1 - (density * 0.01 * metaballField(r * metaballR) / normalizationFactor); + 1 - (density * 0.7 * (metaballField(r) / normalizationFactor)); } } @@ -78,12 +78,10 @@ void precalculateBillboardTextures() { saveGrayscale(data, 32, 32, path); glBindTexture(GL_TEXTURE_2D, bbTexIds[d]); - checkError(); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 32, 32, 0, GL_RED, GL_FLOAT, data); glGenerateMipmap(GL_TEXTURE_2D); // required, otherwise texture is blank - checkError(); fprintf(stderr, "\r%i out of %i densities calculated%s", d + 1, NQ, d == NQ - 1 ? "\n" : ""); @@ -100,6 +98,8 @@ struct Metaball { array metaballs; +const float cloudScale = metaballR; +const float metaballScale = metaballR * 3.f; Clouds cs; void calculateMetaballs() { @@ -115,22 +115,27 @@ void calculateMetaballs() { for (int i = 0; i < CLOUD_DIM_X; i++) { for (int j = 0; j < CLOUD_DIM_Y; j++) { for (int k = 0; k < CLOUD_DIM_Z; k++) { - const float cloudScale = 1.f / 16; Metaball m = { vec3(i, j, k) * vec3(cloudScale), {i, j, k} }; /* m.pos = (m.pos * vec3(2)) - (cloudScale / 2); */ m.pos -= vec3(CLOUD_DIM_X, CLOUD_DIM_Y, CLOUD_DIM_Z) * cloudScale / 2.f; m.d = cs.q[i][j][k]; + /* m.d = 0; */ metaballs[i * CLOUD_DIM_Y * CLOUD_DIM_Z + j * CLOUD_DIM_Z + k] = m; } } } + /* for (int z = 0; z < CLOUD_DIM_Z; z++) */ + /* metaballs[32 * CLOUD_DIM_Y * CLOUD_DIM_Z + 32 * CLOUD_DIM_Z + z].d = 1; */ } -vec3 sunPos = {0, 5, 5}, sunDir = {0, -1, -1}; -/* vec4 sunColor = {1,0,0.429,1}; */ -vec4 sunColor = {1,1,1,1}; +vec3 sunPos = {0, 10, 0}, sunDir = {0, -1, 0}; +size_t sunColorIdx = 0; +std::array sunColors = { + vec4(1,1,1,1), + vec4(0.988,0.309,0.677,1) +}; vec3 camPos = {0, 0, -5}, viewPos = {0, 0, 0}; mat4 proj; // projection matrix mat4 view; // view matrix @@ -163,8 +168,6 @@ mat4 faceView(mat4 m) { GLuint attenuationTex; -const float metaballScale = metaballR * 1.4f; - void shadeClouds() { glDisable(GL_DEPTH_TEST); // shaderOutput * 0 + buffer * shader alpha @@ -182,7 +185,16 @@ void shadeClouds() { GLuint modelLoc = glGetUniformLocation(bbProg, "model"); glUniform1i(glGetUniformLocation(bbProg, "debug"), 0); + /* GLuint pboBuf; */ + /* glGenBuffers(1, &pboBuf); */ + /* glBindBuffer(GL_PIXEL_PACK_BUFFER, pboBuf); */ + + /* glViewport(0, 0, shadeWidth, shadeHeight); */ + + + size_t i = 0; for (auto &k : metaballs) { + fprintf(stderr, "\rShading cloud %lu/%lu...", i++, metaballs.size()); // place the billboard at the center of k mat4 model = translate(mat4(1), k.pos); @@ -222,14 +234,16 @@ void shadeClouds() { value_ptr(pixel)); // Multiply the pixel value by the sunlight color. - pixel *= sunColor; + pixel *= sunColors[sunColorIdx % sunColors.size()]; // Store the color into an array C[k] as the color of the billboard. k.col = pixel; } + fprintf(stderr, "\n"); saveFBO(); checkError(); + /* glViewport(0, 0, width, height); */ } void renderObject() { @@ -258,6 +272,9 @@ void renderClouds() { // shaderOutput * 1 + buffer * shader alpha glBlendFunc(GL_ONE, GL_SRC_ALPHA); + /* glBlendColor(1.f,1.f,1.f,1.f); */ + /* glBlendFuncSeparate(GL_ONE, GL_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_SRC_ALPHA); */ + glActiveTexture(GL_TEXTURE0); glUniform1i(glGetUniformLocation(bbProg, "tex"), 0); @@ -281,7 +298,7 @@ void renderClouds() { glm::value_ptr(k.col)); // Map the billboard texture. - int dIdx = k.d * NQ; + int dIdx = k.d * (NQ - 1); glBindTexture(GL_TEXTURE_2D, bbTexIds[dIdx]); // Don't modulate it -- blend it @@ -294,7 +311,7 @@ void renderClouds() { else if (curMode == debugProbAct) debugVal = cs.p_act[k.coords.x][k.coords.y][k.coords.z]; else if (curMode == debugProbExt) debugVal = cs.p_ext[k.coords.x][k.coords.y][k.coords.z]; glUniform1f(glGetUniformLocation(bbProg, "debugVal"), debugVal); - glDisable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); model = scale(model, vec3(0.2)); glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); } @@ -308,8 +325,10 @@ bool needsReshading = true; void display() { if (needsReshading) { // TODO: find a way to make sure there's no clipping - view = glm::lookAt(sunPos + sunDir * vec3(20), sunPos, {0, 1, 0}); - proj = glm::ortho(1.f * aspect, -1.f * aspect, -1.f, 1.f, znear, zfar); + view = glm::lookAt(sunPos + sunDir * vec3(100.f), sunPos, {0, 0, 1}); + // TODO: calculate bounds so everything is covered + proj = glm::ortho(2.5f, -2.5f, -2.5f, 2.5f, znear, 10000.f); + glUseProgram(bbProg); setProjectionAndViewUniforms(bbProg); glClearColor(1, 1, 1, 1); @@ -350,6 +369,7 @@ void keyboard(unsigned char key, int x, int y) { needsReshading = curMode == render; } if (key == '0') { + needsReshading = curMode != render; curMode = render; needsRedisplay = true; } @@ -369,6 +389,11 @@ void keyboard(unsigned char key, int x, int y) { curMode = debugProbExt; needsRedisplay = true; } + if (key == 's') { + sunColorIdx++; + needsRedisplay = true; + needsReshading = true; + } } int prevMouseX, prevMouseY; diff --git a/debug.hpp b/debug.hpp index 6774a1a..87281f9 100644 --- a/debug.hpp +++ b/debug.hpp @@ -20,13 +20,15 @@ inline void dump(glm::vec2 v) { fprintf(stderr, "{%f,%f}\n", v.x, v.y); } typedef struct { char head[12]; short dx /* Width */, dy /* Height */, head2; - char pic[600 * 400 * 3]; + char pic[1000 * 1000 * 3]; } TGA; char tgahead[12] = {0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; void saveFBO() { - float width = 600, height = 400; + GLint ps[4]; + glGetIntegerv(GL_VIEWPORT, ps); + GLint width = ps[2], height = ps[3]; TGA *tga = (TGA *)malloc(sizeof(TGA)); memcpy(tga->head, tgahead, 12); tga->dx = width; -- 2.30.2