Author Topic: Surface Normals  (Read 5366 times)

0 Members and 1 Guest are viewing this topic.

Charles Pegge

  • Guest
Surface Normals
« on: December 11, 2010, 03:36:48 AM »

Code: [Select]
/*
Surface Normals
===============

These are vectors perpendicular to a surface.
They are mostly used to calculate light reflected from 3d surfaces.

http://www.opengl.org/wiki/Calculating_a_Surface_Normal
discussion on use of normals:
http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/


Pseudocode
----------

Begin Function CalculateSurfaceNormal (Input Triangle) Returns Vector

Set Vector U to (Triangle.p2 minus Triangle.p1)
Set Vector V to (Triangle.p3 minus Triangle.p1)

Set Normal.x to (multiply U.y by V.z) minus (multiply U.z by V.y)
Set Normal.y to (multiply U.z by V.x) minus (multiply U.x by V.z)
Set Normal.z to (multiply U.x by V.y) minus (multiply U.y by V.x)

Returning Normal

End Function
*/

  basic

  type vector3f
  single x
  single y
  single z
  end type

  type triangle9f
  vector3f p1
  vector3f p2
  vector3f p3
  end type

  'print structureof triangle9f


  '------------------------------------------
  sub normal(t as triangle9f, n as vector3f)
  '==========================================

  'assumes points are defined anticlockwise

  vector3f u,v

  'set Vector U to (Triangle.p2 minus Triangle.p1)
  'set Vector V to (Triangle.p3 minus Triangle.p1)

  u.x=t.p2.x-t.p1.x
  u.y=t.p2.y-t.p1.y
  u.z=t.p2.z-t.p1.z
  v.x=t.p3.x-t.p1.x
  v.y=t.p3.y-t.p1.y
  v.z=t.p3.z-t.p1.z


  'Set Normal.x to (multiply U.y by V.z) minus (multiply U.z by V.y)

  n.x= (u.y*v.z)-(u.z*v.y)

  'Set Normal.y to (multiply U.z by V.x) minus (multiply U.x by V.z)

  n.y=(u.z*v.x)-(u.x*v.z)

  'Set Normal.z to (multiply U.x by V.y) minus (multiply U.y by V.x)

  n.z=(u.x*v.y)-(u.y*v.x)


  ' scale the normal to unit length
  '--------------------------------
 
  single s=1/sqr (n.x*n.x + n.y*n.y + n.z*n.z)
  n.x *=s
  n.y *=s
  n.z *=s


  end sub


  '=========

  triangle9f t
  vector3f   n
 
 
  t=>(-1,0,0, 1,0,0, 0,1,0)
  normal t,n
  cm=","
  print "Normal=" n.x cm n.y cm n.z




Charles

kryton9

  • Guest
Re: Surface Normals
« Reply #1 on: December 11, 2010, 12:42:45 PM »
Charles it scares me sometimes how we seem to match interests on certain days. Last night I have been reading up on calculating
tangents, binormals and normals for using Normal Maps in textures. I still don't understand it yet, but by researching some more I am sure it will click in.

http://www.3dkingdoms.com/tutorial.htm

Peter

  • Guest
Re: Surface Normals
« Reply #2 on: December 11, 2010, 01:24:20 PM »

 lol!

Charles Pegge

  • Guest
Re: Surface Normals
« Reply #3 on: December 12, 2010, 02:32:36 AM »

Very interesting Kent, I get the general idea - instead of using rgb colours in a texture, use normal vectors and get the hardware to calculate the light values from these using the standard Gouraud shading.

There is also vertex displacement mapping now  to give even more realistic rendering - this is where programming the graphics card directly using GLSL comes into its own.

Presumably desktop graphics cards less than 5 years old should be able to do this:

http://www.ozone3d.net/tutorials/vertex_displacement_mapping.php

Charles

Petr Schreiber

  • Guest
Re: Surface Normals
« Reply #4 on: December 12, 2010, 10:57:56 AM »
Yes,

shader programming is the future of CG, at least for a while :)

Regarding the displacement mapping - it gets even easier with last generation of cards (GeForce 4xx+, Radeon HD 5xxx+), where there is tesselation unit built in. That means - you can have really low poly model, then you send it to tesselator which automagically generates denser (and rounder) mesh and then you throw displacement shader at it.

But as is typical when playing with last gen, the tesselators, although they are parametrizable by design, behave still a bit oddly in current drivers.


Petr

Charles Pegge

  • Guest
Re: Surface Normals
« Reply #5 on: December 15, 2010, 01:32:39 PM »

Okay Petr, I will add some GLSL to the example list.

Charles

kryton9

  • Guest
Re: Surface Normals
« Reply #6 on: December 15, 2010, 05:42:09 PM »
Petr, can a shader be loaded as a texture file?  I think DarkBasic Pro had a way to load shaders this way... will check...
yes, here is how: dbLoadEffect("waves\\Shading.fx",52,0);

the code snippet is from this thread:
http://forum.thegamecreators.com/?m=forum_view&t=175832&b=22

Petr Schreiber

  • Guest
Re: Surface Normals
« Reply #7 on: November 20, 2011, 02:47:08 AM »
Kent,

my apologies, delay of 1 year for reply is slightly extreme. I somehow overlooked this.

The shader and texture are two different beasts.

The shader type most close to texture is fragment (aka pixel) shader. It takes as input fragment from rasterizer, and can retrieve various information about it - such as fragment color, mapped texel color or normal. What the fragment shader does is that it can alter the final color of the pixel.

Here pseudocode for classic rendering:
Code: [Select]
glColor3ub(255, 0, 0)
drawSphere(1)
This will result in red sphere.

Here another pseudocode, now with shaders enabled:
Code: [Select]
setActiveShader(myShaderToTurnEverythingBlack)
  glColor3ub(255, 0, 0)
  drawSphere(1)
setActiveShader(null)

What does this do:
  • first it sets active shader to my custom one, which is program to take fragment and set it to black - by setting it active no action is performed yet!
  • then the color is set to red in OpenGL state machine
  • then the sphere is drawn - here the geometry is rasterized, therefore fragments are. Here the shader wakes up, looks on the fragment (red piece of sphere) and it can paint it black
  • then the shader is disabled

So the point is - due to shader postprocessing and dynamic nature, it cannot pre-generate "texture". Because it can depend on for example normal information, which is (object) fragment dependant.
The FX file DarkBasic uses is probably just the source code of the shader.

I am sure one could create something like Material class in Oxygen, which would allow to hold definition for color, textures and wanted shader, and when some method would be invoked, it would enable the needed states and when another, it would disable them again.

In short - you can have assigned both (multiple) textures and (single) shader as active for rendering. The shader has the final word in what the result will look like in the end.

As a material for study, there is an excellent tutorial on GLSL here:
http://www.lighthouse3d.com/tutorials/glsl-tutorial/


Uff, I hoped I answered your question and my apologies for the delay,
Petr

Peter

  • Guest
Re: Surface Normals
« Reply #8 on: November 20, 2011, 03:54:43 AM »
Hi Petr,

You really needed a long time for these explanations of the simple things with OpenGl.
I hope Santa Claus isn't angry about you!

kryton9

  • Guest
Re: Surface Normals
« Reply #9 on: November 21, 2011, 10:07:39 PM »
Reply, thanks for all info Petr. I will refer to this in the future more when I am ready to add shaders to my engine. I forgot about that site. It is a good place for tutorials, thanks for the reminder and explanation again!

Charles Pegge

  • Guest
Re: Surface Normals
« Reply #10 on: November 22, 2011, 01:01:13 AM »

Thanks Petr,

I have some GLSL on my list but I'm having trouble with time dilation due to spinning head :)

Charles