ytgui / temp

0 stars 0 forks source link

graphic phrases 1 basic shading #78

Closed ytgui closed 5 years ago

ytgui commented 5 years ago

Sprites

A 2D graphic objects. If you are used to working in 3D, Sprites are essentially just standard textures but there are special techniques for combining and managing sprite textures for efficiency and convenience during development.

Perspective vs Orthographic

Cardboard Theater

PBR (physically based rendering)

https://learnopengl.com/PBR/Theory

Realtime lighting

Baked lightmaps

Precomputed realtime global illumination

Normal Mapping 法线贴图

http://www.opengl-tutorial.org/cn/intermediate-tutorials/tutorial-13-normal-mapping/ https://cgcookie.com/articles/normal-vs-displacement-mapping-why-games-use-normals

点乘 dot(a, b): float = norm(a): float * norm(b): float * cos(theta): float 叉乘 norm(cross(a, b): vec): float = norm(a): float * norm(b): float * sin(theta): float

Triangle normals

// PSEUDO
triangle ( v1, v2, v3 )
edge1 = v2-v1
edge2 = v3-v1
triangle.normal = cross(edge1, edge2).normalize()

Vertex normals

The normal of a vertex is the combination of the normals of the surroundings triangles. This is because in vertex shaders, we deal with vertices, not triangles.

// PSEUDO
vertex v1, v2, v3, ....
triangle tr1, tr2, tr3 // all share vertex v1
v1.normal = normalize(tr1.normal + tr2.normal + tr3.normal)
ytgui commented 5 years ago

Basic Shading

http://www.opengl-tutorial.org/beginners-tutorials/tutorial-8-basic-shading/

  • Specular lighting 镜面反射
  • Diffuse lighting 漫反射
  • Ambient lighting 环境光
  • Subsurface scattering (like wax) 次表面反射(蜡)
  • Anisotrophic materials (like brushed metal) 各向异性(拉丝金属)
  • Ambient Occlusion 环境遮挡 (凹处更暗)
  • Color Bleeding 辉映(红色地毯让天花板变红)
  • Regroups all previous ones -> GI
  • Rim lighting 边缘光

Diffuse component 漫反射

Each point of the surface will look darker with gazing light (but remember, more points will be illuminated, so the total quantity of light will remain the same)
光线斜照能照射到的表面范围更大单位面积亮度低,垂直照射表面范围更小但单位面积亮度大(能量守恒符合直观感受)
So the angle between the incoming light and the surface normal really matters.

// n -> surface normal
// l -> light unit vector (from surface to light)

// `dot(a, b) = |a| |b| cos(theta)`
float cosTheta = dot(n, l);
cosTheta = clamp(cosTheta, 0, 1);

color = LightColor * cosTheta;

output color depends on the color of material

// redMaterial(1, 0, 0) * whiteLight(1, 1, 1) -> redColor(1, 0, 0)
color = MaterialDiffuseColor * LightColor * cosTheta;

Introduce luminous flux (光通量)

// LightPower 光照强度
color = MaterialDiffuseColor * LightColor * LightPower * cosTheta / (distance * distance);

Final

// Normal of the computed fragment, in camera space
vec3 n = normalize( Normal_cameraspace );

// Direction of the light (from the fragment to the light)
vec3 l = normalize( LightDirection_cameraspace );

// Output position of the vertex, in clip space : MVP * position
gl_Position =  MVP * vec4(vertexPosition_modelspace,1);

// Position of the vertex, in worldspace : M * position
Position_worldspace = (M * vec4(vertexPosition_modelspace,1)).xyz;

// Vector that goes from the vertex to the camera, in camera space.
// In camera space, the camera is at the origin (0,0,0).
vec3 vertexPosition_cameraspace = ( V * M * vec4(vertexPosition_modelspace,1)).xyz;
EyeDirection_cameraspace = vec3(0,0,0) - vertexPosition_cameraspace;

// Vector that goes from the vertex to the light, in camera space. M is ommited because it's identity.
vec3 LightPosition_cameraspace = ( V * vec4(LightPosition_worldspace,1)).xyz;
LightDirection_cameraspace = LightPosition_cameraspace + EyeDirection_cameraspace;

// Normal of the the vertex, in camera space
Normal_cameraspace = ( V * M * vec4(vertexNormal_modelspace,0)).xyz; // Only correct if ModelMatrix does not scale the model ! Use its inverse transpose if not.

Ambient component 环境光

vec3 MaterialAmbientColor = vec3(0.1,0.1,0.1) * MaterialDiffuseColor;

color =
// Ambient : simulates indirect lighting
MaterialAmbientColor +
// Diffuse : "color" of the object
MaterialDiffuseColor * LightColor * LightPower * cosTheta / (distance*distance) ;

Specular component 镜面反射

R is the direction in which the light reflects. E is the inverse direction of the eye (just like we did for “l”); If the angle between these two is little, it means we are looking straight into the reflection.


// Eye vector (towards the camera)
vec3 E = normalize(EyeDirection_cameraspace);
// Direction in which the triangle reflects the light
vec3 R = reflect(-l,n);
// Cosine of the angle between the Eye vector and the Reflect vector,
// clamped to 0
//  - Looking into the reflection -> 1
//  - Looking elsewhere -> < 1
float cosAlpha = clamp( dot( E,R ), 0,1 );

color = // Ambient : simulates indirect lighting MaterialAmbientColor + // Diffuse : "color" of the object MaterialDiffuseColor LightColor LightPower cosTheta / (distancedistance) ; // Specular : reflective highlight, like a mirror MaterialSpecularColor LightColor LightPower pow(cosAlpha,5) / (distancedistance);

ytgui commented 5 years ago

Attachment

image

image

Refefence

https://www.saschawillems.de/blog/2018/07/19/vulkan-input-attachments-and-sub-passes/