0.一般来说vertex shader处理顶点坐标,然后向后传输,经过光栅化之后,传给fragment shader,其负责颜色、纹理、光照等等。

前者处理之后变成裁剪坐标系(三维),光栅化之后一般认为变成二维的设备坐标系

1.每个顶点有多个属性时的顶点着色器:

 #version  core
layout (location = ) in vec3 aPos;
layout (location = ) in vec3 aColor;
layout (location = ) in vec2 aTexCoord; out vec3 ourColor;
out vec2 TexCoord; void main()
{
gl_Position = vec4(aPos, 1.0);
ourColor = aColor;
TexCoord = aTexCoord;
}

2.只处理纹理的片元着色器:

 #version  core
out vec4 FragColor; in vec3 ourColor;
in vec2 TexCoord; uniform sampler2D ourTexture; void main()
{
FragColor = texture(ourTexture, TexCoord);
}

3.将2中的纹理添加之后再加入顶点的颜色,片元着色器咋写呢:

 #version  core
out vec4 FragColor; in vec3 ourColor;
in vec2 TexCoord; uniform sampler2D ourTexture; void main()
{
FragColor = texture(ourTexture, TexCoord);
FragColor = texture(ourTexture, TexCoord) * vec4(ourColor, 1.0);
}

4.渲染多个纹理咋办呢?

 #version  core
... uniform sampler2D texture1;
uniform sampler2D texture2; void main()
{
FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2);
}

5.带有坐标变换的顶点着色器

 #version  core
layout (location = ) in vec3 aPos;
layout (location = ) in vec2 aTexCoord; out vec2 TexCoord; uniform mat4 transform; void main()
{
gl_Position = transform * vec4(aPos, 1.0f);
TexCoord = vec2(aTexCoord.x, 1.0 - aTexCoord.y);
}

注意照片像素y轴和opengl中纹理坐标的y轴是反向的,所以用个1.0-y,或者加载纹理图片时候可以设置一下std_image库的api,也能解决问题

6.坐标系转换,加入相机后,标准的模型矩阵,观察矩阵,投影矩阵作用下的顶点着色器

 #version  core
layout (location = ) in vec3 aPos;
layout (location = ) in vec2 aTexCoord; out vec2 TexCoord; uniform mat4 model;
uniform mat4 view;
uniform mat4 projection; void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0f);
TexCoord = vec2(aTexCoord.x, aTexCoord.y); }

7.加入光照和材质的顶点着色器

 #version  core
layout (location = ) in vec3 aPos;
layout (location = ) in vec3 aNormal; out vec3 FragPos;
out vec3 Normal; uniform mat4 model;
uniform mat4 view;
uniform mat4 projection; void main()
{
FragPos = vec3(model * vec4(aPos, 1.0));
Normal = mat3(transpose(inverse(model))) * aNormal; gl_Position = projection * view * vec4(FragPos, 1.0);
}

8.加入光照和材质的片元着色器

 #version  core
out vec4 FragColor; struct Material {
vec3 ambient;
vec3 diffuse;
vec3 specular;
float shininess;
}; struct Light {
vec3 position; vec3 ambient;
vec3 diffuse;
vec3 specular;
}; in vec3 FragPos;
in vec3 Normal; uniform vec3 viewPos;
uniform Material material;
uniform Light light; void main()
{
// ambient
vec3 ambient = light.ambient * material.ambient; // diffuse
vec3 norm = normalize(Normal);
vec3 lightDir = normalize(light.position - FragPos);
float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = light.diffuse * (diff * material.diffuse); // specular
vec3 viewDir = normalize(viewPos - FragPos);
vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
vec3 specular = light.specular * (spec * material.specular); vec3 result = ambient + diffuse + specular;
FragColor = vec4(result, 1.0);
}

9.带光照纹理贴图的顶点着色器(光照射在纹理贴图上,贴图颜色代表物体颜色)

 #version  core
layout (location = ) in vec3 aPos;
layout (location = ) in vec3 aNormal;
layout (location = ) in vec2 aTexCoords; out vec3 FragPos;
out vec3 Normal;
out vec2 TexCoords; uniform mat4 model;
uniform mat4 view;
uniform mat4 projection; void main()
{
FragPos = vec3(model * vec4(aPos, 1.0));
Normal = mat3(transpose(inverse(model))) * aNormal;
TexCoords = aTexCoords; gl_Position = projection * view * vec4(FragPos, 1.0);
}

10.带光照纹理贴图的片元着色器(光照射在纹理贴图上,贴图颜色代表物体颜色)

 #version  core
out vec4 FragColor; struct Material {
sampler2D diffuse;
sampler2D specular;
float shininess;
}; struct Light {
vec3 position; vec3 ambient;
vec3 diffuse;
vec3 specular;
}; in vec3 FragPos;
in vec3 Normal;
in vec2 TexCoords; uniform vec3 viewPos;
uniform Material material;
uniform Light light; void main()
{
// ambient
vec3 ambient = light.ambient * texture(material.diffuse, TexCoords).rgb; // diffuse
vec3 norm = normalize(Normal);
vec3 lightDir = normalize(light.position - FragPos);
float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = light.diffuse * diff * texture(material.diffuse, TexCoords).rgb; // specular
vec3 viewDir = normalize(viewPos - FragPos);
vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
vec3 specular = light.specular * spec * texture(material.specular, TexCoords).rgb; vec3 result = ambient + diffuse + specular;
FragColor = vec4(result, 1.0);
}

11.关于9、10的补充说明:

光照模型其实也分为好多种:平行光(也叫定向光direction light)、点光源(point light)、聚光(spotlight),每种具体的光源渲染细节不同,但是大概结构相似,都满足1中的基本模型解释,只不过在细节和逼真度方面做了调整。具体参看https://learnopengl-cn.github.io/02%20Lighting/05%20Light%20casters/和12

12.带有三种不同光照模型的带纹理的顶点着色器跟片元着色器(终极版)

 #version  core
layout (location = ) in vec3 aPos;
layout (location = ) in vec3 aNormal;
layout (location = ) in vec2 aTexCoords; out vec3 FragPos;
out vec3 Normal;
out vec2 TexCoords; uniform mat4 model;
uniform mat4 view;
uniform mat4 projection; void main()
{
FragPos = vec3(model * vec4(aPos, 1.0));
Normal = mat3(transpose(inverse(model))) * aNormal;
TexCoords = aTexCoords; gl_Position = projection * view * vec4(FragPos, 1.0);
}

vertex shader

 #version  core
out vec4 FragColor; struct Material {
sampler2D diffuse;
sampler2D specular;
float shininess;
}; struct DirLight {
vec3 direction; vec3 ambient;
vec3 diffuse;
vec3 specular;
}; struct PointLight {
vec3 position; float constant;
float linear;
float quadratic; vec3 ambient;
vec3 diffuse;
vec3 specular;
}; struct SpotLight {
vec3 position;
vec3 direction;
float cutOff;
float outerCutOff; float constant;
float linear;
float quadratic; vec3 ambient;
vec3 diffuse;
vec3 specular;
}; #define NR_POINT_LIGHTS 4 in vec3 FragPos;
in vec3 Normal;
in vec2 TexCoords; uniform vec3 viewPos;
uniform DirLight dirLight;
uniform PointLight pointLights[NR_POINT_LIGHTS];
uniform SpotLight spotLight;
uniform Material material; // function prototypes
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir);
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir);
vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir); void main()
{
// properties
vec3 norm = normalize(Normal);
vec3 viewDir = normalize(viewPos - FragPos); // == =====================================================
// Our lighting is set up in 3 phases: directional, point lights and an optional flashlight
// For each phase, a calculate function is defined that calculates the corresponding color
// per lamp. In the main() function we take all the calculated colors and sum them up for
// this fragment's final color.
// == =====================================================
// phase 1: directional lighting
vec3 result = CalcDirLight(dirLight, norm, viewDir);
// phase 2: point lights
for(int i = ; i < NR_POINT_LIGHTS; i++)
result += CalcPointLight(pointLights[i], norm, FragPos, viewDir);
// phase 3: spot light
result += CalcSpotLight(spotLight, norm, FragPos, viewDir); FragColor = vec4(result, 1.0);
} // calculates the color when using a directional light.
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir)
{
vec3 lightDir = normalize(-light.direction);
// diffuse shading
float diff = max(dot(normal, lightDir), 0.0);
// specular shading
vec3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
// combine results
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
return (ambient + diffuse + specular);
} // calculates the color when using a point light.
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
{
vec3 lightDir = normalize(light.position - fragPos);
// diffuse shading
float diff = max(dot(normal, lightDir), 0.0);
// specular shading
vec3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
// attenuation
float distance = length(light.position - fragPos);
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
// combine results
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
ambient *= attenuation;
diffuse *= attenuation;
specular *= attenuation;
return (ambient + diffuse + specular);
} // calculates the color when using a spot light.
vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
{
vec3 lightDir = normalize(light.position - fragPos);
// diffuse shading
float diff = max(dot(normal, lightDir), 0.0);
// specular shading
vec3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
// attenuation
float distance = length(light.position - fragPos);
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
// spotlight intensity
float theta = dot(lightDir, normalize(-light.direction));
float epsilon = light.cutOff - light.outerCutOff;
float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0);
// combine results
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
ambient *= attenuation * intensity;
diffuse *= attenuation * intensity;
specular *= attenuation * intensity;
return (ambient + diffuse + specular);
}

fragment shader

GLSL写vertex shader和fragment shader的更多相关文章

  1. Stage3d 由浅到深理解AGAL的管线vertex shader和fragment shader || 简易教程 学习心得 AGAL 非常非常好的入门文章

    Everyday Stage3D (一) Everyday Stage3D (二) Triangle Everyday Stage3D (三) AGAL的基本概念 Everyday Stage3D ( ...

  2. 「游戏引擎 浅入浅出」4.1 Unity Shader和OpenGL Shader

    「游戏引擎 浅入浅出」从零编写游戏引擎教程,是一本开源电子书,PDF/随书代码/资源下载: https://github.com/ThisisGame/cpp-game-engine-book 4.1 ...

  3. Unity Shaders Vertex & Fragment Shader入门

    http://blog.csdn.net/candycat1992/article/details/40212735 三个月以前,在一篇讲卡通风格的Shader的最后,我们说到在Surface Sha ...

  4. 【Unity Shaders】Vertex & Fragment Shader入门

    写在前面 三个月以前,在一篇讲卡通风格的Shader的最后,我们说到在Surface Shader中实现描边效果的弊端,也就是只对表面平缓的模型有效.这是因为我们是依赖法线和视角的点乘结果来进行描边判 ...

  5. 3D Computer Grapihcs Using OpenGL - 07 Passing Data from Vertex to Fragment Shader

    上节的最后我们实现了两个绿色的三角形,而绿色是直接在Fragment Shader中指定的. 这节我们将为这两个三角形进行更加自由的着色——五个顶点各自使用不同的颜色. 要实现这个目的,我们分两步进行 ...

  6. UnityShader之顶点片段着色器Vertex and Fragment Shader【Shader资料】

    顶点片段着色器 V&F Shader:英文全称Vertex and Fragment Shader,最强大的Shader类型,也是我们在使用ShaderLab中的重点部分,属于可编程管线,使用 ...

  7. Vertex And Fragment Shader(顶点和片段着色器)

    Vertex And Fragment Shader(顶点和片段着色器) Shader "Unlit/ Vertex­_And_Fragment_Shader " { Proper ...

  8. Learn to Create Everything In a Fragment Shader(译)

    学习在片元着色器中创建一切 介绍 这篇博客翻译自Shadertoy: learn to create everything in a fragment shader 大纲 本课程将介绍使用Shader ...

  9. Unity之fragment shader中如何获得视口空间中的坐标

    2种方法: 1. 使用 VPOS 或 WPOS语义,如: Shader "Test/ScreenPos1" { SubShader { Pass { CGPROGRAM #prag ...

随机推荐

  1. jmeter报错:内存溢出

    使用jmeter进行压力测试时,经常会遇到内存溢出错误: 2018-08-28 09:01:26,686 ERROR o.a.j.JMeter: Uncaught exception: java.la ...

  2. HTML5(Canvas Vedio Audio 拖动)

    1.Canvas    (在画布上(Canvas)画一个红色矩形,渐变矩形,彩色矩形,和一些彩色的文字) HTML5 元素用于图形的绘制,通过脚本 (通常是JavaScript)来完成. 标签只是图形 ...

  3. System.getProperty("user.dir")

    /**获得当前类的完整路径.最后一句*/package test;import java.net.MalformedURLException;import java.net.URI;import ja ...

  4. 万恶之源 - Python迭代器

    函数名的使用以及第一类对象 函数名的运用 函数名是一个变量, 但它是一个特殊的变量, 与括号配合可以执行函数的变量 1.函数名的内存地址 def func(): print("呵呵" ...

  5. iot-hub运行在虚拟上

    ng  build gradlew build java -jar iot-hub-0.0.1-SNAPSHOT.jar 后台运行  nohup java -jar iot-dm-0.0.1-SNAP ...

  6. jenkins配置详解之——执行者数量

    jenkins上的执行者数量的设置并不是随意设置的,位置如下: 他是跟cpu核数密切相关的,原则上是不能超过cpu的核数的, 如何查看cpu的核数呢,命令如下: # 查看物理CPU个数cat /pro ...

  7. Linux性能优化gprof使用

    gprof用于分析函数调用耗时,可用之抓出最耗时的函数,以便优化程序. gcc链接时也一定要加-pg参数,以使程序运行结束后生成gmon.out文件,供gprof分析. gprof默认不支持多线程程序 ...

  8. 01JAVA语言基础课后作业

    1.问题 一个Java类文件中真的只能有一个公有类吗? 请使用Eclipse或javac检测一下以下代码,有错吗? 回答  真的只能有一个公有类 一个Java源文件中最多只能有一个public类,当有 ...

  9. redis_bj_01

    windows下安装redis 下载地址https://github.com/dmajkic/redis/downloads.下载到的Redis支持32bit和64bit.根据自己实际情况选择,我选择 ...

  10. 关于js语句的分号

    我在使用js的时候可能发现一个现象:js语句结尾有时候有分号,有时候没有,没有的时候js代码也是能正确执行的. 到底要不要写分号?QAQ 转自博客园@winter-cn JavaScript自动加分号 ...