opengl光照之漫反射逐顶点渲染与逐像素渲染
来源:互联网 发布:apache beam 实时流 编辑:程序博客网 时间:2024/05/19 23:55
1,逐顶点渲染:模型中有多少个顶点就计算多少次,这种方式比较节约系统资源,但效果比较粗糙
2,逐像素渲染:这种方式计算量特别大,有多少个像素就计算多少次,但是效果会很好
逐顶点渲染漫反射光照效果
顶点shader
attribute vec3 pos;//顶点坐标attribute vec2 texcoord;//纹理坐标attribute vec3 normal;//法线坐标uniform mat4 M;//模型变换矩阵uniform mat4 P;//投影矩阵uniform mat4 V;//摄像机观察矩阵uniform mat4 NM;//normalMatrix 将法线转换到世界坐标系或者视口坐标系的矩阵uniform vec3 U_LightPos;//光源位置 本例只讨论平行光uniform vec4 U_DiffuseLightColor;//漫反射光的颜色uniform vec4 U_DiffuseMaterial;//漫反射光的材质varying vec4 V_DiffuseColor;//最终光照颜色void main(){vec3 L=U_LightPos;//平行光的反射方向 ,方向是由模型上的入射点指向光源,本例所有光线都是平行的//归一化处理L=normalize(L);//将法线转换到世界坐标系或视口坐标系,这步很重要,否则得到的光照是不正确的vec3 n=normalize(mat3(NM)*normal);//得到漫反射光的强度 在 0.0和 L,n的点积之间取最大值 点积就是两向量分量分别相乘然后相加float diffuseIntensity=max(0.0,dot(L,n));//漫反射光的最终计算方式V_DiffuseColor=U_DiffuseLightColor*U_DiffuseMaterial*diffuseIntensity;gl_Position=P*V*M*vec4(pos,1.0);}
这种情况下 fs非常简单
uniform vec4 U_AmbientLightColor;//环境光颜色uniform vec4 U_AmbientMaterial;//环境光材质varying vec4 V_DiffuseColor;void main(){vec4 ambientColor=U_AmbientLightColor*U_AmbientMaterial;gl_FragColor=ambientColor+V_DiffuseColor;//最终渲染像素=环境光+漫反射光}
逐像素渲染漫反射光照效果
将光照计算从顶点shader放到了片段shader
顶点shader
attribute vec3 pos;attribute vec2 texcoord;attribute vec3 normal;uniform mat4 M;uniform mat4 P;uniform mat4 V;uniform mat4 NM;varying vec3 V_Normal; //法线void main(){V_Normal=mat3(NM)*normal;//将法线坐标转换到世界坐标系gl_Position=P*V*M*vec4(pos,1.0);}片元shader
uniform vec3 U_LightPos;//光源位置uniform vec4 U_AmbientLightColor;//环境光颜色uniform vec4 U_AmbientMaterial;//环境光材质uniform vec4 U_DiffuseLightColor;//漫反射光颜色uniform vec4 U_DiffuseMaterial;//漫反射光材质varying vec3 V_Normal;//顶点shader中已转换到世界坐标系或者视口坐标系的法线,不转换就得不到正确的光照void main(){//计算环境光vec4 ambientColor=U_AmbientLightColor*U_AmbientMaterial;//计算漫反射光//入射光向量vec3 L=U_LightPos;//此次只考虑平行光L=normalize(L);//法线坐标归一化vec3 n=normalize(V_Normal);//计算漫反射光照强度float diffuseIntensity=max(0,dot(L,n));//最终漫反射光照颜色vec4 diffuseColor=U_DiffuseLightColor*U_DiffuseMaterial*diffuseIntensity;//最终渲染像素值gl_FragColor=ambientColor+diffuseColor;}
其中很关键的一点
uniform mat4 NM;
的计算 也就是normalMatrix的计算方式=模型矩阵的逆矩阵的转置
glm::mat4 modelMatrix = glm::translate<float>(0.0f,0.0f,-3.0f);glm::mat4 projectionMatrix = glm::perspective(50.0f, 800.0f / 600.0f, 0.1f, 1000.0f);//法线矩阵=模型矩阵的逆矩阵的转置glm::mat4 normalMatrix = glm::inverseTranspose(modelMatrix);
完整的渲染函数
#include <windows.h>#include "glew.h"#include <stdio.h>#include <math.h>#include "utils.h"#include "GPUProgram.h"#include "ObjModel.h"#include "FBO.h"#include "FullScreenQuad.h"#include "Glm/glm.hpp"#include "Glm/ext.hpp"#pragma comment(lib,"opengl32.lib")#pragma comment(lib,"glew32.lib")LRESULT CALLBACK GLWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){switch (msg){case WM_CLOSE:PostQuitMessage(0);break;}return DefWindowProc(hwnd,msg,wParam,lParam);}INT WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd){WNDCLASSEX wndClass;wndClass.cbClsExtra = 0;wndClass.cbSize = sizeof(WNDCLASSEX);wndClass.cbWndExtra = 0;wndClass.hbrBackground = NULL;wndClass.hCursor = LoadCursor(NULL,IDC_ARROW);wndClass.hIcon = NULL;wndClass.hIconSm = NULL;wndClass.hInstance = hInstance;wndClass.lpfnWndProc=GLWindowProc;wndClass.lpszClassName = L"OpenGL";wndClass.lpszMenuName = NULL;wndClass.style = CS_VREDRAW | CS_HREDRAW;ATOM atom = RegisterClassEx(&wndClass);HWND hwnd = CreateWindowEx(NULL, L"OpenGL", L"RenderWindow", WS_OVERLAPPEDWINDOW, 100, 100, 800, 600, NULL, NULL, hInstance, NULL);HDC dc = GetDC(hwnd);PIXELFORMATDESCRIPTOR pfd;memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));pfd.nVersion = 1;pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_TYPE_RGBA | PFD_DOUBLEBUFFER;pfd.iLayerType = PFD_MAIN_PLANE;pfd.iPixelType = PFD_TYPE_RGBA;pfd.cColorBits = 32;pfd.cDepthBits = 24;pfd.cStencilBits = 8;int pixelFormatID = ChoosePixelFormat(dc, &pfd);SetPixelFormat(dc,pixelFormatID,&pfd);HGLRC rc = wglCreateContext(dc);wglMakeCurrent(dc, rc);glewInit();//初始化环境//加载shader并编译GPUProgram gpuProgram;//逐顶点渲染shader//gpuProgram.AttachShader(GL_VERTEX_SHADER, "Debug/res/shader/diffuse_vs.vs");//gpuProgram.AttachShader(GL_FRAGMENT_SHADER, "Debug/res/shader/diffuse_vs.fs");//逐像素渲染shadergpuProgram.AttachShader(GL_VERTEX_SHADER, "Debug/res/shader/diffuse_fs.vs");gpuProgram.AttachShader(GL_FRAGMENT_SHADER, "Debug/res/shader/diffuse_fs.fs");gpuProgram.Link();//获取shader中变量的引用 并将属性名,产生的引用id放入mapgpuProgram.DetectAttribute("pos");gpuProgram.DetectAttribute("texcoord");gpuProgram.DetectAttribute("normal");gpuProgram.DetectUniform("M");gpuProgram.DetectUniform("V");gpuProgram.DetectUniform("P");gpuProgram.DetectUniform("NM");gpuProgram.DetectUniform("U_AmbientLightColor");gpuProgram.DetectUniform("U_AmbientMaterial");gpuProgram.DetectUniform("U_DiffuseLightColor");gpuProgram.DetectUniform("U_DiffuseMaterial");gpuProgram.DetectUniform("U_LightPos");//加载并解析模型ObjModel model;model.Init("Debug/res/model/Sphere.obj");float identity[] = {1.0f,0,0,0,0,1.0f,0,0,0,0,1.0f,0,0,0,0,1.0f};float ambientLightColor[] = {0.4f,0.4f,0.4f,1.0f};//环境光颜色float ambientMaterial[] = { 0.2f,0.2f,0.2f,1.0f };//环境光材质float diffuseLightColor[] = { 1.0f,1.0f,1.0f,1.0f };//漫反射光颜色float diffuseMaterial[] = { 0.8f,0.8f,0.8f,1.0f };//漫反射光材质float lightPos[] = {1.0f,1.0f,0.0f};glm::mat4 modelMatrix = glm::translate<float>(0.0f,0.0f,-3.0f);glm::mat4 projectionMatrix = glm::perspective(50.0f, 800.0f / 600.0f, 0.1f, 1000.0f);//法线矩阵=模型矩阵的逆矩阵的转置glm::mat4 normalMatrix = glm::inverseTranspose(modelMatrix);glClearColor(41.0f/255.0f, 71.0f/255.0f, 121.0f / 255.0f, 1.0f);ShowWindow(hwnd, SW_SHOW);UpdateWindow(hwnd);MSG msg;while (true){if (PeekMessage(&msg,NULL,NULL,NULL,PM_REMOVE)){if (msg.message==WM_QUIT){break;}TranslateMessage(&msg);DispatchMessage(&msg);}glClearColor(0.0f, 0.0f, 0.0f, 1.0f);glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);glEnable(GL_DEPTH_TEST);glUseProgram(gpuProgram.mProgram);glUniformMatrix4fv(gpuProgram.GetLocation("M"), 1,GL_FALSE, glm::value_ptr(modelMatrix));glUniformMatrix4fv(gpuProgram.GetLocation("V"), 1, GL_FALSE, identity);glUniformMatrix4fv(gpuProgram.GetLocation("P"), 1, GL_FALSE, glm::value_ptr(projectionMatrix));glUniformMatrix4fv(gpuProgram.GetLocation("NM"), 1, GL_FALSE, glm::value_ptr(normalMatrix));glUniform4fv(gpuProgram.GetLocation("U_AmbientLightColor"), 1,ambientLightColor);glUniform4fv(gpuProgram.GetLocation("U_AmbientMaterial"), 1, ambientMaterial);glUniform4fv(gpuProgram.GetLocation("U_DiffuseLightColor"), 1, diffuseLightColor);glUniform4fv(gpuProgram.GetLocation("U_DiffuseMaterial"), 1, diffuseMaterial);glUniform3fv(gpuProgram.GetLocation("U_LightPos"), 1, lightPos);model.Bind(gpuProgram.GetLocation("pos"), gpuProgram.GetLocation("texcoord"), gpuProgram.GetLocation("normal"));model.Draw();glUseProgram(0);glFinish();SwapBuffers(dc);}return 0;}
阅读全文
0 0
- opengl光照之漫反射逐顶点渲染与逐像素渲染
- opengl光照之镜面光逐顶点渲染与逐像素渲染
- opengl卡通渲染之逐顶点渲染与逐像素渲染
- 漫反射-逐顶点光照
- 漫反射-逐像素光照(半兰伯特)
- OpenGL 4.0 GLSL 用单光源 实现逐顶点 漫反射光照模型
- OpenGL-渲染光照球体
- unity3d 渲染路径(延迟光照,正向渲染,顶点光照)
- unity Shader 的漫反射逐顶点的光照模型
- 逐像素、逐顶点光照差异对比
- 逐顶点和逐像素光照
- Shader 逐顶点和逐像素光照
- unity shader漫反射中逐像素的光照模型
- Opengl渲染管线 坐标变换 纹理与光照
- 光照与渲染(四)- 渲染路径
- Opengl RC(Render context,渲染上下文)与像素格式(转)
- 顶点渲染
- 顶点渲染
- 框架整合____Spring整合Mybatis(主流,最精简整合方式,)
- httpclient常用方法封装
- 求N!的长度【数学】 51nod 1058 1130
- centos下安装nginx
- PHP 运用 Redis 构建高性能的实时搜索
- opengl光照之漫反射逐顶点渲染与逐像素渲染
- Codeforces Round #406 (Div. 2)
- Hibernate学习笔记(二)
- Codeforces Round #407 (Div. 2)
- python 中 类 子类 属性 方法 对象 self 理解
- n & (n-1) 和 n & (-n)
- Nginx 反向代理 如何在web应用中获取用户ip
- java23种设计模式之装饰器模式
- Codeforces Round #409 (Div. 2)