当前位置:网站首页>Normal visualization
Normal visualization
2022-07-29 08:25:00 【longlongway2012】
Normal Visualization
author: longlongwaytogo
date: 2022/07/20
email: [email protected]
repo: https://github.com/longlongwaytogo/LearnOsgGL3
brief introduction
Normals are of great significance for lighting calculation , But sometimes , It is difficult to visually check whether the calculated lighting effect is correct . Sometimes it feels strange , But I don't know if it's wrong , We can display the discovery graph to the output , But more intuitively , Draw the normal directly .
There are many ways to display normals
- Show color normals
- Show vertex normals
- Show face normals
Show color normals
Display of color normals , Just transfer the normals in the vertex shader to the clip for display , But we must pay attention to , The normal value range is [-1,1], The color buffer range is [0,1], Range conversion mapping is required , Usually use P*.5+0.5 take [-1,1] Mapping to [0,1], The specific code is as follows :
const std::string vs =
"#version 330 \n"
"uniform mat4 osg_ModelViewProjectionMatrix; \n"
"uniform mat3 osg_NormalMatrix; \n"
"uniform mat4 osg_ViewMatrixInverse;\n"
"uniform mat4 osg_ModelViewMatrix;\n"
"in vec4 osg_Vertex; \n"
"in vec3 osg_Normal; \n"
"out vec4 color;\n"
"void main() \n"
"{ \n"
" vec3 ecNormal;// = normalize( osg_NormalMatrix * osg_Normal ); \n"
" gl_Position = osg_ModelViewProjectionMatrix * osg_Vertex; \n"
//" vec4 pos = gl_Position/gl_Position.w;\n"
// " color = vec4(pos.xyz,1.0);\n"
" mat4 modelMatrix = osg_ViewMatrixInverse * osg_ModelViewMatrix;\n"
" ecNormal = mat3(modelMatrix) * osg_Normal;\n"
" ecNormal = ecNormal*0.5 + 0.5;\n"
" color = vec4(ecNormal,1.0);\n"
"} \n";
const std::string fs =
"#version 330 \n"
"in vec4 color;\n"
"out vec4 fragData; \n"
"void main() \n"
"{ \n"
" fragData = color; \n"
"} \n";
The effect is as follows :
Show vertex normals
Vertex by vertex normal , yes opengl Common normal input methods , Application direction GPU When transferring vertex attributes , Most of them are bound with an independent normal for each vertex , however OpenGL It also supports the transfer of face by face normals , But for shader programs , The latter is also related to each vertex , Visualization of normals per vertex , For each vertex , A certain distance along their normal direction , Draw a line segment . But to generate the normal of each vertex , We need to use geometry shaders , Geometric coloring can be easily generated 、 Delete vertices or change the entity type , In this way, you can convert the elements of drawing faces to those of drawing lines , The specific code is as follows :
#version 330
uniform mat4 osg_ModelViewProjectionMatrix;
uniform mat3 osg_NormalMatrix;
uniform float normal_length;
uniform int show_normal_mode;
in vec3 local_normal[];
out vec4 color;
layout(triangles) in;
layout(line_strip,max_vertices = 8) out;
void main()
{
for(int i = 0; i < gl_in.length(); i++)
{
vec4 P0 = gl_in[i].gl_Position;
gl_Position = osg_ModelViewProjectionMatrix * P0;
color = vec4(0,1,0,1);
EmitVertex();
vec4 N = vec4(local_normal[i],0.0);
vec4 P1 = gl_in[i].gl_Position + N * normal_length;//normal_length ;
color = vec4(1,0,0,1);
gl_Position = osg_ModelViewProjectionMatrix * P1;
EmitVertex();
EndPrimitive();
}
}
The effect is as follows :
Show face normals
There are two ways to display the normals of faces :
- Display the average normal of each entity
- Displays the normal calculated by cross multiplying two edges based on the right-hand rule
Display the average normal of each entity
Display the average normal of each entity , We only need to add several vertices to get the central coordinates of the face , Then add the normals of each vertex to get the average normal , Starting from the central point , A straight line can be generated along the direction of the normal , The code is as follows :
int n = gl_in.length();
if(n >2)
{
vec4 P0 = gl_in[0].gl_Position;
vec4 P1 = gl_in[1].gl_Position;
vec4 P2 = gl_in[2].gl_Position;
vec4 N0 = (P0 + P1 + P2) / 3.0;
color = vec4(0,1,0,1);
gl_Position = osg_ModelViewProjectionMatrix * N0;
EmitVertex();
vec3 n = (local_normal[0] + local_normal[1] + local_normal[2])/3.0;
vec4 delta = vec4(n * normal_length,0);
vec4 NP0 = N0 + delta;
color = vec4(1,0,0,1);
gl_Position = osg_ModelViewProjectionMatrix * NP0;
EmitVertex();
EndPrimitive();
}
The effect is as follows :
Displays the normal calculated by cross multiplying two edges based on the right-hand rule
Use the cross multiplication line , Need to follow the right-hand rule , Find the two edges of the element , Counter clockwise (WCC) Sequential cross multiplication yields a normal ( but geometry It is impossible to know whether the current face order is CCW, Here is just a demonstration of the way of cross multiplication ), The code is as follows :
// face normal
vec3 P0 = gl_in[0].gl_Position.xyz;
vec3 P1 = gl_in[1].gl_Position.xyz;
vec3 P2 = gl_in[2].gl_Position.xyz;
// Center of the triangle
vec3 P = (P0+P1+P2) / 3.0;
vec3 V0 = P0 - P1;
vec3 V1 = P2 - P1;
vec3 N = cross(V1, V0);
N = normalize(N);
gl_Position = osg_ModelViewProjectionMatrix * vec4(P, 1.0);
color = vec4(0, 0, 0, 1);
EmitVertex();
gl_Position = osg_ModelViewProjectionMatrix * vec4(P + N * normal_length, 1.0);
color = vec4(1, 0, 0, 1);
EmitVertex();
EndPrimitive();
The effect is as follows :
summary
The above explains several normal generation algorithms , The specific knowledge of geometric shaders is not discussed in detail , You need to supplement your knowledge . In addition to this , Calculate face normals , Nor is it clear that the current face direction is GL_CCW still GL_CW,gl_FrontFacing Built in variables can only be used in clip shaders , This needs to be supplemented by consulting materials in the future .
Welcome to the official account

边栏推荐
- Leetcode Hot 100 (brush question 9) (301/45/517/407/offer62/mst08.14/)
- 110 MySQL interview questions and answers (continuously updated)
- Simple calculator wechat applet project source code
- Cluster usage specification
- 2.4G band wireless transceiver chip si24r1 summary answer
- Solve the problem of MSVC2017 compiler with yellow exclamation mark in kits component of QT
- Cv520 domestic replacement of ci521 13.56MHz contactless reader chip
- Unity Shader学习(六)实现雷达扫描效果
- ML.NET相关资源整理
- Charging pile charging technology new energy charging pile development
猜你喜欢

Virtual augmentation and reality Part 2 (I'm a Firebird)

Deep learning (1): prediction of bank customer loss

Simulation of four way responder based on 51 single chip microcomputer

Tensorboard use

Selenium actual combat case crawling JS encrypted data

Temperature acquisition and control system based on WiFi

Clickhouse learning (II) Clickhouse stand-alone installation

Hal library learning notes - 8 concept of serial communication

Gan: generate adversarial networks

Unity Shader学习(六)实现雷达扫描效果
随机推荐
STM32 MDK (keil5) contents mismatch error summary
AES bidirectional encryption and decryption tool
Hal learning notes - Advanced timer of 7 timer
Domestic application of ft232 replacing gp232rl usb-rs232 converter chip
华为无线设备配置利用WDS技术部署WLAN业务
User identity identification and account system practice
What is Amazon self support number and what should sellers do?
Proteus simulation based on msp430f2491 (realize water lamp)
Inclination sensor is used for long-term monitoring of communication tower and high-voltage tower
leetcode hot 100(刷题篇9)(301/45/517/407/offer62/MST08.14/)
Intelligent temperature control system
torch.nn.functional.one_hot()
Simple operation of SQL server data table
What is the working principle of the noise sensor?
SQL 面试碰到的一个问题
Chrony time synchronization
Day6: using PHP to write landing pages
Play Parkour with threejs Technology
Day13: file upload vulnerability
Day6: use PHP to write file upload page