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. 浅谈JS的变量提升

    JS的解析机制,是JS的又一大重点知识点,在面试题中更经常出现,今天就来唠唠他们的原理.首先呢,我们在我们伟大的浏览器中,有个叫做JS解析器的东西,它专门用来读取JS,执行JS.一般情况是存在作用域就 ...

  2. 多线程——newCachedThreadPool线程池

    newCachedThreadPool线程池: 理解: 1).newCachedThreadPool可以创建一个无限大小的线程池(实际上是一个可缓存线程池).      可以通过Executors的静 ...

  3. PHP策略模式2

    <?php /** PHP 策略模式 * 策略模式是对象的行为模式,用意是对一组算法的封装.动态的选择需要的算法并使用. * 策略模式指的是程序中涉及决策控制的一种模式.策略模式功能非常强大,因 ...

  4. Laravel中路由怎么写(二)

    1.路由命名——给路由起个名字 1.1 基本使用 我们使用as关键字来为路由命名: Route::get('/hello/Laravel',['as'=>'academy',function() ...

  5. Centos的升级与更新

    系统升级(6.5->7.2): 这里拿Centos6升级到Centos7为例: 1.查看当前CentOS版本cat /etc/redhat-release 2.更新源vim /etc/yum.r ...

  6. vue弹窗组件

    文件结构 component.vue <template> <div class="_vuedals" v-show="show"> & ...

  7. zip()

    zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表. 如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以 ...

  8. InterProScan 5.25-64.0 安装和使用

    InterProScan 5.25-64.0 安装和使用,目前最新版的interproscan 引用自 每日一生信--interproscan安装及使用(终结版)原文官网:http://code.go ...

  9. HTML布局规范

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  10. 同一个电脑安装两个jdk版本

    同一个电脑安装两个jdk版本 场景:公司项目使用的jdk为1.,最近不是很忙,学习scala.该系统使用到了jdk1.8的特性,所以I need 俩版本,开整!!! . 准备两个版本的jdk我的两个j ...