418341 สภาพแวดล้อมการทำงานคอมพิวเตอร์...
DESCRIPTION
418341 สภาพแวดล้อมการทำงานคอมพิวเตอร์ กราฟิกส์ การบรรยายครั้งที่ 14. ประมุข ขันเงิน [email protected]. Environment Map. การใช้ texture เก็บแสงที่พุ่งจาก “สิ่งแวดล้อม” เข้าหาวัตถุในทิศทางต่างๆ สมมติว่าวัตถุเป็น “จุด” - PowerPoint PPT PresentationTRANSCRIPT
418341 สภาพแวดล้อมการทำ�างานคอมพ�วเตอร�กราฟิ�กส�
การบรรยายคร��งทำ�� 14
ประม!ข ข�นเง�น[email protected]
Environment Map
• การใช้ texture “ ” เก%บแสงทำ��พ! &งจาก ส��งแวดล้อมเขาหาว�ตถุ!ในทำ�ศทำางต&างๆ
• “ ”สมมต�ว&าว�ตถุ!เป,น จ!ด
• Texture “ใช้ในการตอบค�าถุามว&า แสงทำ��พ! &งเขาหา ว�ตถุ!ในทำ�ศทำาง (x,y,z) ”ม�ส�อะไร
Environment Map
Cube Map
• เป,นว�ธี�เก%บ environment map แบบหน/�ง• ใช้ภาพหกภาพมาประกอบก�นเป,นล้0กบาศก�
Cube Map ใน OpenGL
• เราสามารถุใช้ cube map ใน OpenGL ไดต��งแต&OpenGL เวอร�ช้�น 1.3
• ตองใช้ extension ช้1�อ EXT_texture_cube_map
• หมายความว&าเวล้าเข�ยนโปรแกรมใน Windows จะ ตองใช้ GLEW
การสราง Cube Map
• ม�ข� �นตอนคล้ายก�บการสราง texture ธีรรมดา
– Enable การใช้ cube map
– สราง handle ของ cube map ดวย glGenTextures
– ทำ�าการ bind cube map ทำ��สรางข/�น
– Download ร0ปทำ��ใช้ทำ�า cube map ล้งส0& GPU
Enable การใช้ Cube Map
• ใหส� �ง
glEnable(GL_TEXTURE_CUBE_MAP_EXT);
• แล้ะอย&าล้1มส��ง
glDisable(GL_TEXTURE_CUBE_MAP_EXT);
ก&อนใช้งาน texture แบบอ1�น
การสราง Handle ของ Cube Map
• เช้&นเด�ยวก�บการสราง texture อ1�นเราตองประกาศ ต�วแปรประเภทำ GLunit เพ1�อใช้เก%บช้1�อของ cube map
GLuint cubeMap;
• หล้�งจากน��นใช้ glGenTextures สราง texture ตามปกต�
glGenTextures(1, &cubeMap);
Bind Cube Map ทำ��สรางข/�น• ส��ง glBindTexture โดยใช้ target เป,น
GL_TEXTURE_CUBE_MAP_EXT
glBindTexture(GL_TEXTURE_CUBE_MAP_EXT, cubeMap)
Download ร0ป• ใช้ค�าส��ง glTexImage2D หร1อ
gluBuild2DMipmaps เพ1�อ download ร0ปเช้&นเด�ม แต&เราตอง download ร0ปจ�านวนทำ��งหมด 6 ร0ป
ส�าหร�บ 6 ดานของล้0กบาศก�
• เราสามารถุระบ!ว&าจะ download ร0ปของดานไหนได ดวยการระบ! target ของค�าส��งทำ��งสองด�งในสไล้ด�
หนาต&อไป
Target ส�าหร�บ Download ร0ป
Target ดานGL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT ขวาGL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT ซ้ายGL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT บนGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT ล้&างGL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT หนาGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT หล้�ง
ต�วอย&างโคด• ผมสรางฟิ5งก�ช้�น loadCubeMapSide ไวส�าหร�บ
download ร0ปเขาไปย�งดานหน/�งของ cube map โดยก�าหนด– Target ทำ��จะ download ร0ปล้งไป– ช้1�อไฟิล้�ของร0ปน��น
• loadCubeMapSide ใช้ DevIL ในการด/งขอม0ล้ร0ปออกมาจากไฟิล้�
loadCubeMapSide
void loadCubeMapSide(GLuint target, const char *imageName)
{ILuint image;ilGenImages(1, &image);ilBindImage(image);ilLoadImage((wchar_t *)imageName);ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE)gluBuild2DMipmaps(target, ilGetInteger(IL_IMAGE_BPP),
ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT),
ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, ilGetData());
ilDeleteImages(1, &image);}
โคดต�วอย&าง• ผมเข�ยนฟิ5งก�ช้�น initCubeMap เพ1�อ load ร0ปทำ��ง
ส�าหร�บทำ��ง 6 ดาน
• ใน initCubeMap ผมเร�ยก loadCubeMapSide เป,นจ�านวนหกคร��งเพ1�อ download ร0ป
initCubeMap
void initCubeMap(){
glEnable(GL_TEXTURE_CUBE_MAP_EXT);glGenTextures(1, &cubeMap);glBindTexture(GL_TEXTURE_CUBE_MAP_EXT, cubeMap);
glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP);glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP);glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
loadCubeMapSide(GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT, "../images/cm_right.jpg");loadCubeMapSide(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT, "../images/cm_left.jpg");loadCubeMapSide(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT, "../images/cm_top.jpg");loadCubeMapSide(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT, "../images/cm_bottom.jpg");loadCubeMapSide(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT, "../images/cm_front.jpg");loadCubeMapSide(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT, "../images/cm_back.jpg");
glDisable(GL_TEXTURE_CUBE_MAP_EXT);}
การน�า Cube Map ไปใช้งาน• กระจก = การสะทำอนแสง
• แกวใส = การห�กเหแสง
หล้�กการสรางกระจก• สราง “skybox” หร1อกล้&องทำ��ม�ร0ปทำองฟิ6า ล้อมรอบ
ว�ตถุ!ไว
• ส�าหร�บ fragment แต&ล้ะ fragment ใหค�านวณ ทำ�ศทำางทำ��แสงทำ��เด�นทำางจากตาไปย�งต�าแหน&งของ
fragment แล้วสะทำอนออกไป
• ใหน�าทำ�ศทำางทำ��ไดไปอ&านขอม0ล้จาก cube map
หล้�กการสรางกระจก
การสรางกระจกใน OpenGL
• โดยปกต�แล้วเวล้าจะอ&านขอม0ล้จาก cube map เรา จะตองใช้ texture coordinate 3 ต�ว เน1�องจาก
ทำ�ศทำางเป,นทำ�ศทำางในสามม�ต�
• เราสามารถุก�าหนดทำ�ศทำางไดเองดวยค�าส��งglTexCoord3d
• แต&ล้ะ component ของทำ�ศทำางจะม�ค&าต��งแต& -1 ถุ/ง 1
– ไม&ใช้ 0 ถุ/ง 1 เหม1อนก�บ texture coordinate อ1�นๆ
การสรางกระจกใน OpenGL
• Texture coordinate ทำ��จะใช้ม�สามต�วค1อ s, t, แล้ะ r
• เราสามารถุส��งให OpenGL สราง texture coordinate ใหโดยอ�ตโนม�ต�ไดดวยค�าส��งglEnable(GL_TEXTURE_GEN_?)– ถุาอยากใหสราง s ใหโดยอ�ตโนม�ต�ก%ส� �ง
glEnable(GL_TEXTURE_GEN_S);– ถุาอยากใหสราง t ใหโดยอ�ตโนม�ต�ก%ส� �ง
glEnable(GL_TEXTURE_GEN_T);
การสรางกระจกใน OpenGL
• นอกจากน1�ย�งตองบอกดวยว&าจะใหสราง texture coordinate ให แบบใด ดวยค�าส��ง glTexGeni
• ในกรณ�การสรางกระจกเราตองส��ง
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT);
ต�วอย&างโคดvoid display(){
glEnable(GL_TEXTURE_CUBE_MAP_EXT);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT);glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT);glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT);
glEnable(GL_TEXTURE_GEN_S);glEnable(GL_TEXTURE_GEN_T);glEnable(GL_TEXTURE_GEN_R);
glutSolidSphere(1.5, 50, 50);
glutSwapBuffers();}
ด0 demo
การใช้ Cube Map ใน GLSL
• GLSL ใหผ0ใช้สามารถุประกาศ uniform parameter ประเภทำsamplerCube ใน shader ได เช้&น
uniform samplerCube env_map;
void main(){
::
}
การใช้ Cube Map ใน GLSL
• เวล้าอ&านขอม0ล้จาก cube map ใหใช้ค�าส��งtexureCube โดย– Parameter ต�วแรกเป,นต�วแปรประเภทำ samplerCube– Parameter ต�วทำ��สองเป,นค&าประเภทำ vec3
• ต�วอย&าง
color = textureCube(env, vec3(1,0,0));
การใช้ Cube Map ใน GLSL
• ต�วแปรประเภทำ vec3 ทำ��เราใหไปตองเป,นเวกเตอร� หน/�งหน&วยทำ��แต&ล้ะม�ต�ม�ค&าอย0&ในช้&วง [-1,1]
• ค&าทำ��อ&านไดจาก cube map ค1อค&าของส�ทำ��จ!ดทำ��เก�ด จากการย�งร�งส�จากจ!ด (0,0,0) ไปในทำ�ศทำางทำ��
ก�าหนดดวยต�วแปร vec3 ทำ��ใหฟิ5งก�ช้�นtextureCube ไปต�ดก�บกล้&องล้0กบาศก�ทำ��ม�ความ
ยาวดานล้ะสองหน&วยทำ��ม�จ!ดศ0นย�กล้างอย0&ทำ��จ!ด(0,0,0)
การใช้ Cube Map ใน GLSL
การทำ�ากระจกใน Cg
• ให vertex program ค�านวณ– ต�าแหน&งใน world space ของแต& fragment– Normal ใน world space แต&ล้ะ fragment
• ให fragment program ร�บต�าแหน&งของตา
• แล้วให fragment program ค�านวณ– เวกเตอร�ทำ�ศทำางการสะทำอนแสงซ้/�งเก�ดจากแสงจากตา เด�น
ทำางไปย�งต�าแหน&งของ fragment– เอาเวกเตอร�ทำ�ศทำางทำ��ไดไปอ&านส�จาก cube map
Vertex Program ส�าหร�บทำ�ากระจกvarying vec3 normal;varying vec3 position;
void main(){ gl_Position = ftransform(); position = (gl_ModelViewMatrix * gl_Vertex).xyz; normal = (gl_NormalMatrix * gl_Normal).xyz;}
Vertex Program ส�าหร�บทำ�ากระจก• ความหมายของต�วแปร– position ใช้เก%บต�าแหน&งใน world space– normal ใช้เก%บเวกเตอร�ต��งฉากใน world space
• เวล้าเข�ยนโปรแกรมภาษา C ตองทำ�าให modelview matrix เป,น model เฉยๆ ซ้/�งทำ�าไดโดยการยกview matrix ไปค0ณเขาก�บ projection matrix (เหม1อนในคาบทำ��แล้ว)
Fragment Program ส�าหร�บทำ�ากระจกuniform vec3 eye_position;uniform samplerCube env;
varying vec3 position;varying vec3 normal;
void main(){ vec3 n = normalize(normal); vec3 eye_to_point = normalize(position - eye_position); vec3 reflected = reflect(eye_to_point, n); gl_FragColor = textureCube(env, reflected);}
Fragment Program ส�าหร�บทำ�ากระจก• เราทำ�าการค�านวณเวกเตอร�ทำ�ศทำางของแสงทำ��เด�นทำางจาก
ตาไปย�งต�าแหน&งของ fragment ดวยค�าส��ง
vec3 eye_to_point = normalize(position - eye_position);
• หล้�งจากน��นค�านวณทำ�ศทำางทำ��แสงสะทำอนออกไปดวยค�าส��ง
vec3 reflected = reflect(eye_to_point, n);
• ฟิ5งก�ช้�น reflect ม�ไวส�าหร�บค�านวณเวกเตอร�แสงสะทำอน
Fragment Program ส�าหร�บทำ�ากระจก• ข��นส!ดทำาย เราน�าเอาทำ�ศทำางของเวกเตอร�แสง
สะทำอนไปอ&านค&าจาก cube map
gl_FragColor = textureCube(env, reflected);
ด0 demo
การทำ�าว�ตถุ!ผ�วม�นวาว• เราอาจมองว&าพ1�นผ�วของว�ตถุ!ม�นวาวม�ส&วน
ประกอบอย0&สองส&วน– ส&วนหน/�งม�พฤต�กรรมเหม1อนกระจก– อ�กส&วนม�พฤต�กรรมตาม lighting model อ1�น เช้&น
phong lighting model
• ส�ของพ1�นผ�วประเภทำน��เก�ดจากการน�าเอาส�ทำ��ไดจากการสะทำอนแสงแบบกระจกมารวมก�บส�ทำ��ไดจากพฤต�กรรมการสะทำอนแสงอ1�นๆ
การทำ�าว�ตถุ!ผ�วม�นวาว• เราสามารถุค�านวณส�ของทำ��งสองส&วน– สมมต�ว&าส&วนแรกไดส� a แล้ะ– ส&วนทำ��สองไดส� b
• เราก�าหนดเล้ข w ( ย&อค�าว&า weight) โดยทำ�� 0 ≤ w ≤ 1 แล้วใหส�ข� �นส!ดทำายม�ค&าเทำ&าก�บ
color = w × a + (1-w) × b
ด0 demo
การหั�กเหัแสง
การจ�าล้องการห�กเหของแสง• การห�กเหของแสงเป,นไปตาม กฎของสเนลล�
(Snell’s Law)2211 sinsin
เม1�อ• ค1อดรรช้น�ห�กเหของต�วกล้างแรก• ค1อดรรช้น�ห�กเหของต�วกล้างทำ��สอง• แล้ะ ค1อม!มระหว&าง
ทำางเด�นของแสงก�บ normal ตามร0ป
1
2
1 2
การจ�าล้องการห�กเหของแสง• ค&าดรรช้น�ห�กเหของแสงเป,นค&าคงต�วของต�วกล้างแบบต&างๆ– ถุาตองการจะร0 ค&าก%ตองไปเป�ดหน�งส1อ
• ภาษา GLSL ม�ฟิ5งก�ช้�นอ�านวยความสะดวกใหเราสามารถุ ค�านวณทำ�ศทำางในการห�กแสงไดอย&างง&ายดาย ค1อ ฟิ5งก�ช้�น
reflectrefract(vec3 I, vec3 N, float etaRatio)– I ค1อเวกเตอร�ทำ��แสงเด�นทำางเขาว�ตถุ! ( เวกเตอร� PO)– N ค1อเวกเตอร�ต��งฉาก– etaRatio ค1อค&า– ฟิ5งก�ช้�นน��จะค1นค&าทำ�ศทำางทำ��แสดงห�กเหออกมา ( เวกเตอร� OQ)
21 /
การสรางแกวใน GLSL
• ใช้หล้�กการเด�ยวก�บการสรางกระจกในคาบทำ��แล้ว– ใช้ fragment program ค�านวณทำ�ศทำางทำ��แสงห�กเห– น�าทำ�ศทำางทำ��แสงห�กเหไปอ&านค&าจาก cube map แล้วน�า
ค&าน��มาเป,นส�• เราทำ�าการค�านวณทำ!กอย&างใน world space– ด�งน��นใช้ vertex program ต�วเด�ยวก�บโปรแกรมทำ��แล้ว
ได
Fragment Program ส�าหร�บจ�าล้องแกว
uniform vec3 eye;uniform samplerCube env;uniform float eta_ratio;
varying vec3 position;varying vec3 normal;
void main(){ vec3 n = normalize(normal); vec3 eye_to_point = normalize(position - eye); vec3 refracted = refract(eye_to_point, n, eta_ratio); vec4 refraction = textureCube(env, refracted); gl_FragColor = refraction;}
ด0 demo
ขอส�งเกต• การห�กเหแสงทำ��เห%นใน demo ไม&ใช้การห�กเหแสง
แบบทำ��เก�ดข/�นจร�งในธีรรมช้าต�• ทำ�าไม? เพราะม�นม�การห�กเหแสงแค&คร��งเด�ยว!
ความจร�งร0ปโดน�ทำเป,นร0ปป�ด เพราะฉะน��นกว&าแสง จะไปหา skybox ไดตองม�การห�กเหมากกว&าหน/�ง
คร��ง
ขอส�งเกต (ต&อ)
ส��งทำ��เราทำ�า ส��งทำ��ควรจะเป,น
ขอส�งเกต (ต&อ)
• ทำ�าไมเราถุ/งไม&ทำ�าใหม�นตรงก�บความเป,นจร�ง?• เพราะม�นทำ�ายากมาก!– เราตองร0 ว&าแสงเขาไปส0&ว�ตถุ!ทำ��จ!ดไหน– เราตองร0 ว&าแสงออกไปส0&ว�ตถุ!ทำ��จ!ดไหน– OpenGL หร1อ GLSL ไม&ไดเก%บขอม0ล้เหล้&าน��ไวใหเรา
• “ ” ด�งน��นเราจ/ง โกง ดวยการค�ดว&าม�การห�กเหแสงแค&คร��งเด�ยว
• ในคอมพ�วเตอร�กราฟิ�กส� การโกงเช้&นน��เป,นเร1�องทำ�� พบเห%นไดบ&อยมาก เพราะม�นช้&วยทำ�าใหภาพสวยได
โดยไม&ตองเปล้1องเวล้าค�านวณมาก
ปรากฏการณ� Fresnel
• จะเห%นว&าต�วอย&างทำ�� demo ไปย�งไม&ค&อยสวยแล้ะเหม1อนจร�งเทำ&าไหร&
• เพราะแกวน��นไม&ไดห�กเหแสงเพ�ยงอย&างเด�ยว ม�นย�งม�การสะทำอนแสงดวย
• ปรากฏการณ�ทำ��แสงส&วนสะทำอนทำ��พ1�นผ�วว�ตถุ!แต& แสงบางส&วนห�กเหทำ��พ1�นผ�วว�ตถุ!เร�ยกว&า
ปรากฏการณ์� Fresnel• การค�านวณปร�มาณแสงทำ��สะทำอนแล้ะห�กเหจร�งๆ
ในธีรรมช้าต�น��นใช้ส0ตรทำ��ซ้�บซ้อน ด�งน��นเราจะโกงโดยฝั5นส0ตรข/�นมาเอง
ปรากฏการณ� Fresnel (ต&อ)
• สมมต�ว&าเราค�านวณส�ทำ��ไดจากการสะทำอนแสงเก%บ ไวในต�วแปร a
• แล้ะค�านวณส�ทำ��ไดจากการห�กเหแสงไวในต�วแปร b• เราตองการเอาส�ทำ��งสองมารวมก�น เพ1�อจ�าล้อง
ปรากฏการณ� Fresnel ดวยส0ตร:color = w × a + (1-w) × b
ปรากฏการณ� Fresnel (ต&อ)
• เราสามารถุค�านวณค&า w ไดด�งต&อไปน�� (ส0ตรน��ฝั5นข/�นมาเอง)
โดยทำ��– bias, scale, แล้ะ power ค1อค&าทำ��ผ0ใช้ก�าหนดข/�นมา– I ค1อเวกเตอร�ทำ�ศทำางทำ��แสงเด�นทำางเขาส0&ว�ตถุ!– N ค1อเวกเตอร�ต��งฉาก
))))(1(,1min(,0max( powerNIscalebiasw
Fragment Program ส�าหร�บจ�าล้องปรากฏการณ� Fresnel
uniform vec3 eye;uniform samplerCube env;uniform float eta_ratio;uniform float fresnel_bias;uniform float fresnel_scale;uniform float fresnel_power;
varying vec3 position;varying vec3 normal;
void main(){ vec3 n = normalize(normal); vec3 eye_to_point = normalize(position - eye); vec3 refracted = refract(eye_to_point, n, eta_ratio); vec3 reflected = reflect(eye_to_point, n); vec4 refraction = textureCube(env, refracted); vec4 reflection = textureCube(env, reflected); float reflected_weight = fresnel_bias + fresnel_scale * pow(1.0 + dot(n, eye_to_point), fresnel_power); reflected_weight = max(0.0, min(reflected_weight, 1.0)); gl_FragColor = reflected_weight * reflection + (1.0-reflected_weight) * refraction;}
ด0 demo
Chromatic Dispersion
• แสงขาวทำ��เราเห%น ความจร�งประกอบดวยแสง ความถุ��ต&างๆ ส�ต&างๆ มากมาย
• แสงส�ต&างๆ เหล้&าน��เม1�อห�กเหจะม�ม!มในการห�กเห ต&างๆ ก�น ทำ�าใหแยกออกจากก�นมาเป,นแถุบๆ
• เราจ/งเห%นปรากฏการณ�เช้&น ร! &งก�นน��า หร1อแถุบส�เม1�อแสงเด�นทำางผ&านปร�ซ้/ม
Chromatic Dispersion (ต&อ)
การจ�าล้อง Chromatic Dispersion ในCg
• ส�ใน OpenGL ม�สามย&านความถุ��ค1อ R, G, แล้ะ B• เราสามารถุแค&ก�าหนดให eta_ratio ของสามย&าน
ความถุ��น��ม�ค&าแตกต&างก�น เพ1�อจ�าล้อง chromatic dispersion ได
Fragment Program ส�าหร�บจ�าล้อง Chromatic Dispersion
uniform vec3 eye;uniform samplerCube env;uniform vec3 eta_ratio;uniform float fresnel_bias;uniform float fresnel_scale;uniform float fresnel_power;
varying vec3 position;varying vec3 normal;
void main(){ vec3 n = normalize(normal); vec3 eye_to_point = normalize(position - eye);
vec3 refracted_r = refract(eye_to_point, n, eta_ratio.r); vec3 refracted_g = refract(eye_to_point, n, eta_ratio.g);
vec3 refracted_b = refract(eye_to_point, n, eta_ratio.b); vec3 refraction_r = textureCube(env, refracted_r).rgb * vec3(1,0,0); vec3 refraction_g = textureCube(env, refracted_g).rgb * vec3(0,1,0); vec3 refraction_b = textureCube(env, refracted_b).rgb * vec3(0,0,1); vec4 refraction = vec4(refraction_r + refraction_g + refraction_b, 1);
Fragment Program ส�าหร�บจ�าล้อง Chromatic Dispersion
vec3 reflected = reflect(eye_to_point, n); vec4 reflection = textureCube(env, reflected); float reflected_weight = fresnel_bias + fresnel_scale * pow(1.0 + dot(n, eye_to_point),
fresnel_power); reflected_weight = max(0.0, min(reflected_weight, 1.0)); gl_FragColor = reflected_weight * reflection + (1.0-reflected_weight) * refraction;}
ด0 demo