Open LeeMcQueen opened 3 years ago
应该还是不对,不然还原就可以表示出来了,不会是只有底色
lastFrame = std::chrono::steady_clock::now()
下面的内容不应该在while循环里面 unsigned int cameraUniformBuffer = 0; glGenBuffer(1, &cameraUniformBuffer); glBindBuffer(GL_UNIFORM_BUFFER, cameraUniformBuffer); glBufferData(GL_UNIFORM_BUFFER, 128, nullptr, GL_STATIC_DRAW); glBindBufferBase(GL_UNIFORM_BUFFER, 0, cameraUniformBuffer);
glGenBuffer(1, &grass_input_buffer) 看看教程里面的(广告牌)computerShader是如何给vertexShader传值的
fragment shader layout(location = 0) out vec4 outColor; out vec4 out_Colour;
使用和给computershader传相机投影矩阵和观察矩阵一样的方法 进行变换矩阵的传值 设置一个 mat4 transformationMatrix
就是一个computershader的工作组大小(gl_WorkGroupSize)xyz之积
layout(local_size_x = WORKGROUP_SIZE, local_size_y = 1, local_size_z = 1) in;
相机buffer输入参数 程序面对应的是glbindBufferBase(0) layout(binding = 0) uniform CameraBufferObject { mat4 view; mat4 proj; } camera;
uniform传值 uniform float current_time; uniform float delta_time; uniform传值 uniform float wind_magnitude; uniform float wind_wave_length; uniform float wind_wave_period;
新宣言的变数 struct Blade { vec4 v0; vec4 v1; vec4 v2; vec4 up; };
程序面输入 程序面对应的是glbindBufferBase(1) layout(binding = 1, std140) buffer inputBuffer { Blade inputBlades[]; };
对vertexShader输出值 晨旭面对应的是glbindBufferBase(2) layout(binding = 2, std140) buffer outputBuffer { Blade outputBlades[]; };
程序面输入 程序面对应的是glbindBufferBase(3) // Indirect drawing count layout(binding = 3) buffer NumBlades { 输出buffer的值 uint vertexCount;
uint instanceCount;// = 1
uint firstVertex;// = 0
uint firstInstance;// = 0
} numBlades;
bool inBounds(float value, float bounds) { return (value >= -bounds) && (value <= bounds); }
返回 (sin(seed)100000.0)的小数部分 float rand(float seed) { return fract(sin(seed)100000.0); }
void main() { // Reset the number of blades to 0 if (gl_GlobalInvocationID.x == 0) { numBlades.vertexCount = 0; } barrier();// Wait till all threads reach this point
全部工作组乘上工作组大小 (400*400) *32
uint index = gl_GlobalInvocationID.x;
草的position
vec3 v0 = inputBlades[index].v0.xyz;
草的弯曲值 贝塞尔曲线值
vec3 v1 = inputBlades[index].v1.xyz;
草的物理模型 传入的时候和贝塞尔曲线完全一直 可能是通过computershader的计算以后得到差值实现摇摆的效果
vec3 v2 = inputBlades[index].v2.xyz;
正规化之后向上向量
vec3 up = normalize(inputBlades[index].up.xyz);
草尖半径上的方向
float orientation = inputBlades[index].v0.w;
草的高度 程序端进行了设置 (0.6 1.2) 之间
float height = inputBlades[index].v1.w;
固定0.1的风 在computershader里面没有使用到 估计是在后面的vertexshader或者fragmentshader里面使用
float width = inputBlades[index].v2.w;
草的硬度 在comptershader里用于被压弯的草的回复计算
float stiffness = inputBlades[index].up.w;
//计算了相机的剪切范围 具体的算法还没有看明白
// Frustum culling 锥体截面
vec4 v0ClipSpace = camera.proj * camera.view * vec4(v0, 1);
vec4 v1ClipSpace = camera.proj * camera.view * vec4(v1, 1);
v0ClipSpace /= v0ClipSpace.w;
v1ClipSpace /= v1ClipSpace.w;
bool v0OutFrustum =
v0ClipSpace.x < -1 || v0ClipSpace.x > 1
|| v0ClipSpace.y < -1 || v0ClipSpace.y > 1;
bool v1OutFrustum =
v1ClipSpace.x < -1 || v1ClipSpace.x > 1
|| v1ClipSpace.y < -1 || v1ClipSpace.y > 1;
if (v0OutFrustum && v1OutFrustum) return;
//
距离的剪切范围 具体算法没有看明白
// Distance culling
const float far1 = 0.95;
if (v0ClipSpace.z > far1 && v1ClipSpace.z > far1 && rand(index) > 0.5) {
return;
}
const float far2 = 0.98;
if (v0ClipSpace.z > far2 && v1ClipSpace.z > far2 && rand(index) > 0.2) {
return;
}
const float far3 = 0.99;
if (v0ClipSpace.z > far3 && v1ClipSpace.z > far3 && rand(index) > 0.1) {
return;
}
// Apply forces {
// Gravities
vec3 gE = vec3(0, -0.98, 0);
vec3 widthDir = vec3(cos(orientation), 0, sin(orientation));
vec3 bladeFace = normalize(cross(up, widthDir));
vec3 gF = 0.25*length(gE)*bladeFace;
vec3 g = gE + gF;
// Recovery 回复量
vec3 r = (v0 + up * height - v2) * stiffness;
// Wind
vec3 windForce = 0.25 * wind_magnitude *
vec3(
sin(current_time * 3. / wind_wave_period + v0.x * 0.1 * 11 / wind_wave_length),
0,
sin(current_time * 3. / wind_wave_period + v0.z * 0.2 * 11 / wind_wave_length) * 0.1
);
float fd = 1 - abs(dot(normalize(windForce), normalize(v2 - v0)));
float fr = dot((v2 - v0), up) / height;
vec3 w = windForce * fd * fr;
v2 += (0.1 * g + r + w) * delta_time;
float lproj = length(v2 - v0 - up * dot((v2-v0), up));
v1 = v0 + height*up*max(1-lproj/height, 0.05*max(lproj/height, 1));
inputBlades[index].v1.xyz = v1;
inputBlades[index].v2.xyz = v2;
// }
只是对 v1草弯曲的贝塞尔曲线 v2物理表现进行了计算然后给vertexShader进行传值
outputBlades[atomicAdd(numBlades.vertexCount, 1)] = inputBlades[index];
}
grasses.cpp 的双循环里面用判断抠除一部分的草地,然后上面加上火焰的效果和点光源的效果 再根据多光源里面的 1.平行光(漫反射 镜面反射 环境光)2.点光源 3.其他光源(聚光灯) 在一个物体上实现这三个效果来体现一下光方面的技术
tesseShader 里面把相机的远近的细分值加大不就可以让草更加密集了嘛
2021/10/04 Grasses 无法渲染对策
GLFW的opengl版本不对 需要4.5
glEnable(GL_DEPTH_TEST) 草地渲染开始深度测试的时机
GrassesShader.h 的Shader种类枚举结构 为什么enum class type : GLenum 不能使用
把GrassesShader 的ShaderPrograms命名改一下 这个太容易混淆
checkCompilingError() 的glGetShaderiv 没有执行 把shader的检测函数加上
检测shader代码是否读取
对computer,tessellation,vertexShader,FragmentShader的逻辑进行梳理