better shader with sky/ground light, along with half lambert (#96)

* better shader with sky/ground light, along with half lambert

* force recalculate normal

* more wireframe/shade/normal mode!
This commit is contained in:
Kanglai Qian 2017-09-28 16:08:59 -05:00 committed by Perfare
parent 01f1d7c14e
commit bd7a43f0dc
3 changed files with 180 additions and 78 deletions

View File

@ -1,10 +1,10 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// 此代码由工具生成。 // This code was generated by a tool.
// 运行时版本:4.0.30319.42000 // Runtime Version:4.0.30319.42000
// //
// 对此文件的更改可能会导致不正确的行为,并且如果 // Changes to this file may cause incorrect behavior and will be lost if
// 重新生成代码,这些更改将会丢失。 // the code is regenerated.
// </auto-generated> // </auto-generated>
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -13,13 +13,13 @@ namespace Unity_Studio {
/// <summary> /// <summary>
/// 一个强类型的资源类,用于查找本地化的字符串等。 /// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary> /// </summary>
// 此类是由 StronglyTypedResourceBuilder // This class was auto-generated by the StronglyTypedResourceBuilder
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 // class via a tool like ResGen or Visual Studio.
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen // To add or remove a member, edit your .ResX file then rerun ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。 // with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resource1 { internal class Resource1 {
@ -33,7 +33,7 @@ namespace Unity_Studio {
} }
/// <summary> /// <summary>
/// 返回此类使用的缓存的 ResourceManager 实例。 /// Returns the cached ResourceManager instance used by this class.
/// </summary> /// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager { internal static global::System.Resources.ResourceManager ResourceManager {
@ -47,8 +47,8 @@ namespace Unity_Studio {
} }
/// <summary> /// <summary>
/// 使用此强类型资源类,为所有资源查找 /// Overrides the current thread's CurrentUICulture property for all
/// 重写当前线程的 CurrentUICulture 属性。 /// resource lookups using this strongly typed resource class.
/// </summary> /// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture { internal static global::System.Globalization.CultureInfo Culture {
@ -61,28 +61,22 @@ namespace Unity_Studio {
} }
/// <summary> /// <summary>
/// 查找类似 #version 140 /// Looks up a localized string similar to #version 140
/// ///
///in vec3 surfaceNormal; ///in vec3 normal;
///in vec3 toLightVector;
///in vec4 color;
/// ///
///out vec4 outputColor; ///out vec4 outputColor;
/// ///
///void main() ///void main()
///{ ///{
/// vec3 lightColor = vec3(0.5, 0.5, 0.5); /// vec3 unitNormal = normalize(normal);
/// float nDotProduct = clamp(dot(unitNormal, vec3(0.707, 0, 0.707)), 0, 1);
/// vec2 ContributionWeightsSqrt = vec2(0.5, 0.5f) + vec2(0.5f, -0.5f) * unitNormal.y;
/// vec2 ContributionWeights = ContributionWeightsSqrt * ContributionWeightsSqrt;
/// ///
/// // Ambient /// vec3 color = nDotProduct * vec3(1, 0.957, 0.839) / 3.14159;
/// float ambientStrength = 0.9; /// color += vec3(0.779, 0.716, 0.453) * ContributionWeights.y;
/// vec3 ambient = ambientStrength * lightColor; /// color += vec3(0.368, 0.477, 0. [rest of string was truncated]&quot;;.
///
/// // Diffuse
/// vec3 unitNormal = normalize(surfaceNormal);
/// vec3 unitLightVector = normalize(toLightVector);
/// float nDotProduct = dot(unitNormal, unitLightVector);
/// float brightness = clamp(nDotProduct, 0, 1); // max(nDotProduct, 0.0);
/// vec3 diffuse [字符串的其余部分被截断]&quot;; 的本地化字符串。
/// </summary> /// </summary>
internal static string fs { internal static string fs {
get { get {
@ -91,25 +85,55 @@ namespace Unity_Studio {
} }
/// <summary> /// <summary>
/// 查找类似 #version 140 /// Looks up a localized string similar to #version 140
///
///out vec4 outputColor;
///
///void main()
///{
/// outputColor = vec4(0, 0, 0, 1);
///}.
/// </summary>
internal static string fsBlack {
get {
return ResourceManager.GetString("fsBlack", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to #version 140
///
///out vec4 outputColor;
///in vec4 color;
///
///void main()
///{
/// outputColor = color;
///}.
/// </summary>
internal static string fsColor {
get {
return ResourceManager.GetString("fsColor", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to #version 140
/// ///
///in vec3 vertexPosition; ///in vec3 vertexPosition;
///in vec3 normalDirection; ///in vec3 normalDirection;
///in vec4 vertexColor; ///in vec4 vertexColor;
///uniform mat4 viewMatrix; ///uniform mat4 viewMatrix;
/// ///
///out vec3 surfaceNormal; ///out vec3 normal;
///out vec3 toLightVector;
///out vec4 color; ///out vec4 color;
/// ///
///void main() ///void main()
///{ ///{
/// vec3 lightPosition = vec3(200.0, 200.0, 200.0);
/// gl_Position = viewMatrix * vec4(vertexPosition, 1.0); /// gl_Position = viewMatrix * vec4(vertexPosition, 1.0);
/// surfaceNormal = normalDirection; /// normal = normalDirection;
/// toLightVector = lightPosition - vertexPosition;
/// color = vertexColor; /// color = vertexColor;
///} 的本地化字符串。 ///}.
/// </summary> /// </summary>
internal static string vs { internal static string vs {
get { get {

View File

@ -120,30 +120,42 @@
<data name="fs" xml:space="preserve"> <data name="fs" xml:space="preserve">
<value>#version 140 <value>#version 140
in vec3 surfaceNormal; in vec3 normal;
in vec3 toLightVector;
in vec4 color;
out vec4 outputColor; out vec4 outputColor;
void main() void main()
{ {
vec3 lightColor = vec3(0.5, 0.5, 0.5); vec3 unitNormal = normalize(normal);
float nDotProduct = clamp(dot(unitNormal, vec3(0.707, 0, 0.707)), 0, 1);
vec2 ContributionWeightsSqrt = vec2(0.5, 0.5f) + vec2(0.5f, -0.5f) * unitNormal.y;
vec2 ContributionWeights = ContributionWeightsSqrt * ContributionWeightsSqrt;
// Ambient vec3 color = nDotProduct * vec3(1, 0.957, 0.839) / 3.14159;
float ambientStrength = 0.9; color += vec3(0.779, 0.716, 0.453) * ContributionWeights.y;
vec3 ambient = ambientStrength * lightColor; color += vec3(0.368, 0.477, 0.735) * ContributionWeights.x;
outputColor = vec4(sqrt(color), 1);
}</value>
</data>
<data name="fsBlack" xml:space="preserve">
<value>#version 140
// Diffuse out vec4 outputColor;
vec3 unitNormal = normalize(surfaceNormal);
vec3 unitLightVector = normalize(toLightVector);
float nDotProduct = dot(unitNormal, unitLightVector);
float brightness = clamp(nDotProduct, 0, 1); // max(nDotProduct, 0.0);
vec3 diffuse = brightness * lightColor;
// Output Color void main()
vec4 result = color * vec4((ambient + diffuse/2), 0.0); {
outputColor = result; outputColor = vec4(0, 0, 0, 1);
}</value>
</data>
<data name="fsColor" xml:space="preserve">
<value>#version 140
out vec4 outputColor;
in vec4 color;
void main()
{
outputColor = color;
}</value> }</value>
</data> </data>
<data name="vs" xml:space="preserve"> <data name="vs" xml:space="preserve">
@ -154,16 +166,13 @@ in vec3 normalDirection;
in vec4 vertexColor; in vec4 vertexColor;
uniform mat4 viewMatrix; uniform mat4 viewMatrix;
out vec3 surfaceNormal; out vec3 normal;
out vec3 toLightVector;
out vec4 color; out vec4 color;
void main() void main()
{ {
vec3 lightPosition = vec3(200.0, 200.0, 200.0);
gl_Position = viewMatrix * vec4(vertexPosition, 1.0); gl_Position = viewMatrix * vec4(vertexPosition, 1.0);
surfaceNormal = normalDirection; normal = normalDirection;
toLightVector = lightPosition - vertexPosition;
color = vertexColor; color = vertexColor;
}</value> }</value>
</data> </data>

View File

@ -36,9 +36,7 @@ namespace Unity_Studio
private Bitmap imageTexture; private Bitmap imageTexture;
#region OpenTK variables #region OpenTK variables
int pgmID; int pgmID, pgmColorID, pgmBlackID;
int vsID;
int fsID;
int attributeVertexPosition; int attributeVertexPosition;
int attributeNormalDirection; int attributeNormalDirection;
int attributeVertexColor; int attributeVertexColor;
@ -51,10 +49,13 @@ namespace Unity_Studio
int eboElements; int eboElements;
Vector3[] vertexData; Vector3[] vertexData;
Vector3[] normalData; Vector3[] normalData;
Vector3[] normal2Data;
Vector4[] colorData; Vector4[] colorData;
Matrix4[] viewMatrixData; Matrix4[] viewMatrixData;
int[] indiceData; int[] indiceData;
bool wireFrameView; int wireFrameMode;
int shadeMode;
int normalMode;
#endregion #endregion
//asset list sorting helpers //asset list sorting helpers
@ -366,7 +367,7 @@ namespace Unity_Studio
{ {
if (e.Control && e.KeyCode == Keys.W) //Toggle WireFrame if (e.Control && e.KeyCode == Keys.W) //Toggle WireFrame
{ {
wireFrameView = !wireFrameView; wireFrameMode = (wireFrameMode + 1) % 3;
glControl1.Invalidate(); glControl1.Invalidate();
} }
else if (e.Shift && e.KeyCode == Keys.W) //Move else if (e.Shift && e.KeyCode == Keys.W) //Move
@ -384,7 +385,12 @@ namespace Unity_Studio
// Down // Down
if (e.KeyCode == Keys.S) if (e.KeyCode == Keys.S)
{ {
if (e.Shift && e.KeyCode == Keys.S) //Move if (e.Control && e.KeyCode == Keys.S) //Toggle Shade
{
shadeMode = (shadeMode + 1) % 2;
glControl1.Invalidate();
}
else if (e.Shift && e.KeyCode == Keys.S) //Move
{ {
viewMatrixData[0] *= Matrix4.CreateTranslation(0, -0.1f, 0); viewMatrixData[0] *= Matrix4.CreateTranslation(0, -0.1f, 0);
} }
@ -412,6 +418,14 @@ namespace Unity_Studio
glControl1.Invalidate(); glControl1.Invalidate();
} }
// Normal mode
if (e.Control && e.KeyCode == Keys.N)
{
normalMode = (normalMode + 1) % 2;
createVAO();
glControl1.Invalidate();
}
// Toggle Timer // Toggle Timer
if (e.KeyCode == Keys.T) if (e.KeyCode == Keys.T)
{ {
@ -1045,6 +1059,33 @@ namespace Unity_Studio
} }
else else
normalData = null; normalData = null;
// calculate normal by ourself
normal2Data = new Vector3[m_Mesh.m_VertexCount];
int[] normalCalculatedCount = new int[m_Mesh.m_VertexCount];
for (int i = 0; i < m_Mesh.m_VertexCount; i++)
{
normal2Data[i] = Vector3.Zero;
normalCalculatedCount[i] = 0;
}
for (int i = 0; i < m_Mesh.m_Indices.Count; i = i + 3)
{
Vector3 dir1 = vertexData[indiceData[i + 1]] - vertexData[indiceData[i]];
Vector3 dir2 = vertexData[indiceData[i + 2]] - vertexData[indiceData[i]];
Vector3 normal = Vector3.Cross(dir1, dir2);
normal.Normalize();
for (int j = 0; j < 3; j++)
{
normal2Data[indiceData[i + j]] += normal;
normalCalculatedCount[indiceData[i + j]] ++;
}
}
for (int i = 0; i < m_Mesh.m_VertexCount; i++)
{
if(normalCalculatedCount[i] == 0)
normal2Data[i] = new Vector3(0, 1, 0);
else
normal2Data[i] /= normalCalculatedCount[i];
}
#endregion #endregion
#region Colors #region Colors
if (m_Mesh.m_Colors == null) if (m_Mesh.m_Colors == null)
@ -1052,8 +1093,7 @@ namespace Unity_Studio
colorData = new Vector4[m_Mesh.m_VertexCount]; colorData = new Vector4[m_Mesh.m_VertexCount];
for (int c = 0; c < m_Mesh.m_VertexCount; c++) for (int c = 0; c < m_Mesh.m_VertexCount; c++)
{ {
colorData[c] = new Vector4( colorData[c] = new Vector4(0.5f, 0.5f, 0.5f, 1.0f);
0.5f, 0.5f, 0.5f, 1.0f);
} }
} }
else if (m_Mesh.m_Colors.Length == m_Mesh.m_VertexCount * 3) else if (m_Mesh.m_Colors.Length == m_Mesh.m_VertexCount * 3)
@ -1083,9 +1123,9 @@ namespace Unity_Studio
#endregion #endregion
} }
createVAO(); createVAO();
StatusStripUpdate("Using OpenGL Version: " + GL.GetString(StringName.Version) StatusStripUpdate("Using OpenGL Version: " + GL.GetString(StringName.Version) + "\n"
+ " | 'T'=Start/Stop Rotation | 'WASD'=Manual Rotate | " + "'T'=Start/Stop Rotation | 'WASD'=Manual Rotate | 'Shift WASD'=Move | 'Q/E'=Zoom \n"
+ "'Shift WASD'=Move | 'Q/E'=Zoom | 'Ctl W' =Wireframe"); + "'Ctrl W'=Wireframe | 'Ctrl S'=Shade | 'Ctrl N'=ReNormal ");
} }
break; break;
#endregion #endregion
@ -1743,14 +1783,27 @@ namespace Unity_Studio
{ {
GL.Viewport(0, 0, glControl1.ClientSize.Width, glControl1.ClientSize.Height); GL.Viewport(0, 0, glControl1.ClientSize.Width, glControl1.ClientSize.Height);
GL.ClearColor(Color.CadetBlue); GL.ClearColor(Color.CadetBlue);
int vsID, fsID;
pgmID = GL.CreateProgram(); pgmID = GL.CreateProgram();
loadShader("vs", ShaderType.VertexShader, pgmID, out vsID); loadShader("vs", ShaderType.VertexShader, pgmID, out vsID);
loadShader("fs", ShaderType.FragmentShader, pgmID, out fsID); loadShader("fs", ShaderType.FragmentShader, pgmID, out fsID);
GL.LinkProgram(pgmID); GL.LinkProgram(pgmID);
GL.UseProgram(pgmID);
pgmColorID = GL.CreateProgram();
loadShader("vs", ShaderType.VertexShader, pgmColorID, out vsID);
loadShader("fsColor", ShaderType.FragmentShader, pgmColorID, out fsID);
GL.LinkProgram(pgmColorID);
pgmBlackID = GL.CreateProgram();
loadShader("vs", ShaderType.VertexShader, pgmBlackID, out vsID);
loadShader("fsBlack", ShaderType.FragmentShader, pgmBlackID, out fsID);
GL.LinkProgram(pgmBlackID);
attributeVertexPosition = GL.GetAttribLocation(pgmID, "vertexPosition"); attributeVertexPosition = GL.GetAttribLocation(pgmID, "vertexPosition");
attributeNormalDirection = GL.GetAttribLocation(pgmID, "normalDirection"); attributeNormalDirection = GL.GetAttribLocation(pgmID, "normalDirection");
attributeVertexColor = GL.GetAttribLocation(pgmID, "vertexColor"); attributeVertexColor = GL.GetAttribLocation(pgmColorID, "vertexColor");
var str = GL.GetError();
uniformViewMatrix = GL.GetUniformLocation(pgmID, "viewMatrix"); uniformViewMatrix = GL.GetUniformLocation(pgmID, "viewMatrix");
glControl1.Visible = false; glControl1.Visible = false;
} }
@ -1812,8 +1865,15 @@ namespace Unity_Studio
GL.GenVertexArrays(1, out vao); GL.GenVertexArrays(1, out vao);
GL.BindVertexArray(vao); GL.BindVertexArray(vao);
createVBO(out vboPositions, vertexData, attributeVertexPosition); createVBO(out vboPositions, vertexData, attributeVertexPosition);
if (normalMode == 0)
{
createVBO(out vboNormals, normal2Data, attributeNormalDirection);
}
else
{
if (normalData != null) if (normalData != null)
createVBO(out vboNormals, normalData, attributeNormalDirection); createVBO(out vboNormals, normalData, attributeNormalDirection);
}
createVBO(out vboColors, colorData, attributeVertexColor); createVBO(out vboColors, colorData, attributeVertexColor);
createVBO(out vboViewMatrix, viewMatrixData, uniformViewMatrix); createVBO(out vboViewMatrix, viewMatrixData, uniformViewMatrix);
createEBO(out eboElements, indiceData); createEBO(out eboElements, indiceData);
@ -1832,17 +1892,26 @@ namespace Unity_Studio
glControl1.MakeCurrent(); glControl1.MakeCurrent();
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.Enable(EnableCap.DepthTest); GL.Enable(EnableCap.DepthTest);
GL.DepthFunc(DepthFunction.Less); GL.DepthFunc(DepthFunction.Lequal);
GL.BindVertexArray(vao); GL.BindVertexArray(vao);
if (wireFrameView == true) if (wireFrameMode == 0 || wireFrameMode == 2)
{
GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line); //Wireframe
}
else
{ {
GL.UseProgram(shadeMode == 0 ? pgmID : pgmColorID);
GL.UniformMatrix4(uniformViewMatrix, false, ref viewMatrixData[0]);
GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
}
GL.DrawElements(BeginMode.Triangles, indiceData.Length, DrawElementsType.UnsignedInt, 0); GL.DrawElements(BeginMode.Triangles, indiceData.Length, DrawElementsType.UnsignedInt, 0);
}
//Wireframe
if (wireFrameMode == 1 || wireFrameMode == 2)
{
GL.Enable(EnableCap.PolygonOffsetLine);
GL.PolygonOffset(-1, -1);
GL.UseProgram(pgmBlackID);
GL.UniformMatrix4(uniformViewMatrix, false, ref viewMatrixData[0]);
GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
GL.DrawElements(BeginMode.Triangles, indiceData.Length, DrawElementsType.UnsignedInt, 0);
GL.Disable(EnableCap.PolygonOffsetLine);
}
GL.BindVertexArray(0); GL.BindVertexArray(0);
GL.Flush(); GL.Flush();
glControl1.SwapBuffers(); glControl1.SwapBuffers();