GLSL写vertex shader和fragment shader
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的更多相关文章
- Stage3d 由浅到深理解AGAL的管线vertex shader和fragment shader || 简易教程 学习心得 AGAL 非常非常好的入门文章
Everyday Stage3D (一) Everyday Stage3D (二) Triangle Everyday Stage3D (三) AGAL的基本概念 Everyday Stage3D ( ...
- 「游戏引擎 浅入浅出」4.1 Unity Shader和OpenGL Shader
「游戏引擎 浅入浅出」从零编写游戏引擎教程,是一本开源电子书,PDF/随书代码/资源下载: https://github.com/ThisisGame/cpp-game-engine-book 4.1 ...
- Unity Shaders Vertex & Fragment Shader入门
http://blog.csdn.net/candycat1992/article/details/40212735 三个月以前,在一篇讲卡通风格的Shader的最后,我们说到在Surface Sha ...
- 【Unity Shaders】Vertex & Fragment Shader入门
写在前面 三个月以前,在一篇讲卡通风格的Shader的最后,我们说到在Surface Shader中实现描边效果的弊端,也就是只对表面平缓的模型有效.这是因为我们是依赖法线和视角的点乘结果来进行描边判 ...
- 3D Computer Grapihcs Using OpenGL - 07 Passing Data from Vertex to Fragment Shader
上节的最后我们实现了两个绿色的三角形,而绿色是直接在Fragment Shader中指定的. 这节我们将为这两个三角形进行更加自由的着色——五个顶点各自使用不同的颜色. 要实现这个目的,我们分两步进行 ...
- UnityShader之顶点片段着色器Vertex and Fragment Shader【Shader资料】
顶点片段着色器 V&F Shader:英文全称Vertex and Fragment Shader,最强大的Shader类型,也是我们在使用ShaderLab中的重点部分,属于可编程管线,使用 ...
- Vertex And Fragment Shader(顶点和片段着色器)
Vertex And Fragment Shader(顶点和片段着色器) Shader "Unlit/ Vertex_And_Fragment_Shader " { Proper ...
- Learn to Create Everything In a Fragment Shader(译)
学习在片元着色器中创建一切 介绍 这篇博客翻译自Shadertoy: learn to create everything in a fragment shader 大纲 本课程将介绍使用Shader ...
- Unity之fragment shader中如何获得视口空间中的坐标
2种方法: 1. 使用 VPOS 或 WPOS语义,如: Shader "Test/ScreenPos1" { SubShader { Pass { CGPROGRAM #prag ...
随机推荐
- Python3学习之路~3.1 函数基本语法及特性、返回值、参数、局部与全局变量
1 函数基本语法及特性 定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可 特性: 减少重复代码 使程序变的可扩展 使程序变得易维护 语法定义: d ...
- 帝国cms建站-动态获取栏目id
<?php $fcr=explode('|',$class_r[$GLOBALS[navclassid]][featherclass]); $topbclassid=$fcr[1]?$fcr[1 ...
- 敏捷开发— —Scrum 学习笔记
敏捷开发模式是一种从1990年代开始逐渐引起广泛关注的一些新型软件开发方法,是一种应对快速变化的需求的一种软件开发能力.它们的具体名称.理念.过程.术语都不尽相同,相对于"非敏捷" ...
- MySQL大表优化方案 Mysql的row_format(fixed与dynamic)
转自:https://mp.weixin.qq.com/s/VY69wWlrVLjRtKU7ULrYGw 当MySQL单表记录数过大时,增删改查性能都会急剧下降,可以参考以下步骤来优化: 单表优化 除 ...
- php合并数组并保留键值的方法
答案:使用 + 连接两个数组,替换array_merge()函数. php合并数组,一般会使用array_merge方法. array_merge — 合并一个或多个数组 array array_me ...
- Entity Framework Code First(Mysql)
1.添加NuGet包 引用NuGet包:EntityFramework6.1.3.MySql.Data.Entity6.9.8 2.修改配置 SqlServer配置: <add name=&qu ...
- Windows服务器时间不同步问题
一台域内的服务器时间不停地被修改,我先向用户收集了一些信息 只有这一台出现此问题,其他服务器均为正常(补充一下,问题快解决完的时候用户告诉我一个重要的消息,就是时间被修改了一段时间后自动会被修改回去) ...
- 巧用CurrentThread.Name来统一标识日志记录(续)
▄︻┻┳═一Agenda: ▄︻┻┳═一巧用CurrentThread.Name来统一标识日志记录 ▄︻┻┳═一巧用CurrentThread.Name来统一标识日志记录(续) ▄︻┻┳═一巧用Cur ...
- JS怎么控制input框的背景颜色
$("input").css("background-color","red"); 参考:https://zhidao.baidu.com/ ...
- JDK源码调试常见错误。
1.删除不需要的代码,即swing相关的代码 2.执行命令时要将前提环境进入文件夹如下: 起初没有完全执行第一条,因为网上说可以根据需要选择相关的代码,于是就没有删除,以后第一次模仿网上的例子的时候要 ...