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()
這種情況下 fs非常簡單
uniform vec4 u_ambientlightcolor;//環境光顏色
uniform vec4 u_ambientmaterial;//環境光材質
varying vec4 v_diffusecolor;
void main()
逐畫素渲染漫反射光照效果
將光照計算從頂點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()
片元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()
其中很關鍵的一點
uniform mat4 nm;
的計算 也就是normalmatrix的計算方式=模型矩陣的逆矩陣的轉置
glm::mat4 modelmatrix = glm::translate(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 #include "glew.h"
#include #include #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)
return defwindowproc(hwnd,msg,wparam,lparam);
}int winapi winmain(_in_ hinstance hinstance, _in_opt_ hinstance hprevinstance, _in_ lpstr lpcmdline, _in_ int nshowcmd)
; float ambientlightcolor = ;//環境光顏色
float ambientmaterial = ;//環境光材質
float diffuselightcolor = ;//漫反射光顏色
float diffusematerial = ;//漫反射光材質
float lightpos = ;
glm::mat4 modelmatrix = glm::translate(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)
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;
}
Unity shader學習之逐頂點漫反射光照模型
公式如下 cdiffuse clight mdiffuse max 0,dot n,l 其中,n為表面法線,l為指向光源的單位向量,mdiffuse為材質溫反射顏色,cdiffuse為光源顏色。需要注意的是,需要防止法線與光源方向點積為負,因些使用max函式。shader如下 shader cust...
漫反射 逐畫素光照(半蘭伯特)
shader custom testshader subshader pass struct v2f v2f vert a2v v fixed4 frag v2f i sv target 計算漫反射光照模型 說明 1.頂點著色器不需要計算光照模型,只需要把世界空間下的法線傳遞給片元著色器即可。2.在...
Unity Shader 光照模型之漫反射
舊部落格轉移 2016年4月3日 23 27 在現實生活中,我們看見能看見的東西都是光反射出來的顏色,如果反射光太弱,或者沒有進入你的視角範圍,你看到的就是黑色的。在遊戲中光分為幾種,平行光源 太陽光 點光源 燈泡 等等,最常用的是directional light 平行光源 當然在計算機中光不過是...