How to use lighting values from 3ds max in OpenGL - opengl

I'm struggling to see how I should use material and lighting values obtained from 3DS Max to recreate similar lighting. I am taking the material and lighting from a Collada file exported from 3DS Max and using them to render a scene in OpenGL. The scene is rendered using a Blinn-Phong shader. However the scene always ends up way to bright.
The light data from 3DS max seems quite odd to me. It consists of two lights, an ambient light and a directional light which only has a single colour. As I was not quite sure what this single colour relates to I've applied it to both the diffuse and specular components of the light.
Anyways, does anyone know if there is something odd with the 3DS Max/Collada material and lighting data? Or have you used it successfully with no problems meaning that I'm simply doing something wrong?
Edit #1
As requested, heres the material/lighting info from collada. I'm afraid I cannot post any screenshots, however the scene is coming out painfully bright, e.g Oranges becoming bright yellow. The specular values in particular seem very high, yet they seem to work fine in Max...
Collada Material:
<library_effects>
<effect id="WorldTexture">
<profile_COMMON>
<newparam sid="world_texture_png-surface">
<surface type="2D">
<init_from>world_texture_png</init_from>
</surface>
</newparam>
<newparam sid="world_texture_png-sampler">
<sampler2D>
<source>world_texture_png-surface</source>
</sampler2D>
</newparam>
<technique sid="common">
<blinn>
<emission>
<color>0 0 0 1</color>
</emission>
<ambient>
<color>0.588 0.588 0.588 1</color>
</ambient>
<diffuse>
<texture texture="world_texture_png-sampler" texcoord="CHANNEL1"/>
</diffuse>
<specular>
<color>0.9 0.9 0.9 1</color>
</specular>
<shininess>
<float>10</float>
</shininess>
<reflective>
<color>0 0 0 1</color>
</reflective>
<transparent opaque="A_ONE">
<color>1 1 1 1</color>
</transparent>
<transparency>
<float>1</float>
</transparency>
</blinn>
</technique>
</profile_COMMON>
<extra>
<technique profile="OpenCOLLADA3dsMax">
<extended_shader>
<apply_reflection_dimming>0</apply_reflection_dimming>
<dim_level>0</dim_level>
<falloff_type>0</falloff_type>
<index_of_refraction>1.5</index_of_refraction>
<opacity_type>0</opacity_type>
<reflection_level>3</reflection_level>
<wire_size>1</wire_size>
<wire_units>0</wire_units>
</extended_shader>
<shader>
<ambient_diffuse_lock>1</ambient_diffuse_lock>
<ambient_diffuse_texture_lock>1</ambient_diffuse_texture_lock>
<diffuse_specular_lock>0</diffuse_specular_lock>
<soften>0.1</soften>
<use_self_illum_color>0</use_self_illum_color>
</shader>
</technique>
</extra>
</effect>
Collada Lights:
<library_lights>
<light id="EnvironmentAmbientLight" name="EnvironmentAmbientLight">
<technique_common>
<ambient>
<color>0.6235294 0.6235294 0.6235294</color>
</ambient>
</technique_common>
</light>
<light id="FDirect001-light" name="FDirect001">
<technique_common>
<directional>
<color>0.937255 0.7921569 0.5411765</color>
</directional>
</technique_common>
<extra>
<technique profile="OpenCOLLADA3dsMax">
<max_light>
<aspect_ratio>1</aspect_ratio>
<atmosphere_color_amount>1</atmosphere_color_amount>
<atmosphere_on>0</atmosphere_on>
<atmosphere_opacity>1</atmosphere_opacity>
<attenuation_far_end>100</attenuation_far_end>
<attenuation_far_start>80</attenuation_far_start>
<attenuation_near_end>26.8</attenuation_near_end>
<attenuation_near_start>0</attenuation_near_start>
<contrast>0</contrast>
<decay_falloff>40</decay_falloff>
<decay_type>0</decay_type>
<diffuse_soften>0</diffuse_soften>
<falloff>902</falloff>
<hotspot_beam>900</hotspot_beam>
<multiplier>0.5</multiplier>
<overshoot>0</overshoot>
<shadow_density>1</shadow_density>
<shadow_map>0</shadow_map>
<target_distance>440</target_distance>
<use_far_attenuation>0</use_far_attenuation>
<use_near_attenuation>0</use_near_attenuation>
</max_light>
</technique>
</extra>
</light>
</library_lights>

Related

Which GL blend mode for blending the same color in source and destination, and getting the same color back?

I have an texture that is with a solid background (let's say navy blue, #000080) and white text on it. Even though the texture is a single file with both background and text, I'd like to cause just the text to fade out.
I've prepared a second texture, just solid navy blue without any text. I'd like to "fade" the text out by modifying the texture's alpha layer, until just the second texture (blue with no text) remains.
My problem is that when I start making the front layer (color + text) transparent, the text fades out as I expect, but the resulting blue is darker. The blue I see is the background color blue (#000080), tinted dark by the semitransparent layer in front of it. After some reading, it looks like I want to modify OpenGL's blend mode for this part.
I'm looking for a blend mode that generates:
#000080 + #000080*tranparency = #000080
#000080 + #FFFFFF*transparency = #FFFFFF*transparency
I've tried GL_MIN and GL_MAX, but those don't seem to be the ones I'm looking for here...
You shouldn't need anything more than just:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBlendEquation(GL_ADD);
glEnable(GL_BLEND);
Which corresponds to the following:
original_pixel = [0, 0, 0.5, 1]
incoming_pixel = [0, 0, 0.5, 0.5]
final_pixel = incoming_pixel * 0.5 + original_pixel * (1 - 0.5);
Which should leave the colour intact.
You shouldn't need the second texture - just draw an untextured quad with the correct colour.

Matplotlib: how to change alpha of edges only

I have a scatterplot:
x=[0.1,0.2,0.3,0.4]
y=[0.1,0.3,0.4,0.6]
I would like to plot it adding transparency in each point, so I used
plt.scatter(x,y,alpha =0.5, marker='o',color='g', markersize=12)
However, what happens is that I get circles filled with green colours and with a transpacency all over. What I would like to get is transparency only in the inner region, and edges really visible, so that if I have may points close to each other, I can always see the borders.
Is there a way?
You can specify the edge- and facecolor independently. For the facecolor you can choose a color with an alpha of less then 1. To specify such color use an RGBA (red,green,blue,alpha) tuple.
import matplotlib.pyplot as plt
x=[0.1, 0.105, 0.2, 0.3, 0.4]
y=[0.1, 0.095, 0.3, 0.4, 0.6]
plt.scatter(x,y, s=144, marker='o', edgecolor='g', facecolor=(0,1,0,0.5), )
plt.show()

finding spots and lines in image

I was working on following images to find lines and spots in these images. I am working with OpenCV, C++. I have tried HoughLineP, HoughLine, Contour and Canny methods but couldn't get the results. If someone can help or write a pseudo-code, I shall be grateful.
Thanks.
Image to detect line:
Image to detect spot:
Mmmmm - where did you get those awful images? Well, they were worth 2 minutes of effort... the spot is lighter than the rest, so if you divide the image into 100 rectangles and find the brightest ones, you will probably get it... I use ImageMagick here just at the command line - it is installed on most Linux distros and available for OSX and Windows:
convert noise.jpg -crop 10x10# -format "%[mean] %g\n" info: | sort -n
32123.3 640x416+384+291
32394.6 640x416+256+42
32442.2 640x416+320+125
32449.1 640x416+384+250
32459.6 640x416+192+374
32464.4 640x416+0+374
32486.5 640x416+448+125
32491.4 640x416+576+374
32493.7 640x416+576+333
32504.3 640x416+576+83
32520.9 640x416+576+0
32527 640x416+448+0
32621.8 640x416+384+333
32624.1 640x416+320+42
32631.3 640x416+192+333
32637.8 640x416+384+42
32643.4 640x416+512+0
32644.2 640x416+0+0
32652.6 640x416+384+83
32659.1 640x416+128+374
32660.4 640x416+320+208
32662.2 640x416+384+0
32668.5 640x416+256+208
32669.4 640x416+0+333
32676.7 640x416+256+250
32683.5 640x416+256+83
32699.7 640x416+0+208
32701.3 640x416+64+166
32704 640x416+576+208
32704 640x416+64+333
32707.5 640x416+512+208
32710.8 640x416+192+83
32729.8 640x416+320+83
32733.4 640x416+256+166
32735 640x416+576+250
32741 640x416+256+125
32745.4 640x416+0+166
32748.4 640x416+320+166
32751.4 640x416+512+166
32752.4 640x416+512+42
32755.1 640x416+384+208
32770.9 640x416+448+291
32776.8 640x416+128+166
32777.1 640x416+256+0
32795.8 640x416+512+125
32801.5 640x416+128+333
32803.3 640x416+192+125
32805.5 640x416+256+374
32809.6 640x416+448+166
32810 640x416+576+166
32822.2 640x416+0+291
32822.8 640x416+576+42
32826.8 640x416+320+333
32831.7 640x416+320+0
32834.8 640x416+192+42
32837.6 640x416+192+166
32843 640x416+384+125
32862 640x416+64+374
32865.8 640x416+0+42
32871.5 640x416+576+291
32872.5 640x416+0+83
32872.8 640x416+448+333
32873.6 640x416+320+291
32877.5 640x416+448+42
32880.5 640x416+64+208
32883.5 640x416+128+42
32883.9 640x416+192+208
32885.5 640x416+128+208
32889.2 640x416+256+333
32921 640x416+192+291
32923.3 640x416+64+291
32929.2 640x416+512+374
32935.4 640x416+192+250
32938.4 640x416+64+250
32943.5 640x416+448+374
32953.3 640x416+384+374
32954.7 640x416+320+374
32962 640x416+320+250
32966.9 640x416+448+83
32967.3 640x416+128+291
32968.3 640x416+0+250
32970.8 640x416+512+333
32974.5 640x416+64+0
32979.6 640x416+512+291
32983.6 640x416+256+291
32988.9 640x416+448+250
32993.3 640x416+576+125
33012.7 640x416+0+125
33057.3 640x416+512+250
33068.6 640x416+128+250
33102.9 640x416+64+42
33126.1 640x416+512+83
33127.9 640x416+384+166
33139.2 640x416+192+0
33141.4 640x416+64+83
33142.3 640x416+64+125
33181.5 640x416+448+208
33190.8 640x416+128+0
34693 640x416+128+125
36178.3 640x416+128+83
The last 2 rectangles are the brightest, so if I box them in in red and blue you can see what it has found:
convert noise.jpg -fill none -stroke red -draw "rectangle 128,83 192,123" -stroke blue -draw "rectangle 128,125 192,168" result.png
Alternatively, you could create a new image in which each pixel is the mean of the 50x50 square of surrounding pixels in the original image, like this:
convert noise.jpg -virtual-pixel edge -statistic mean 50x50 -auto-level result.png
Of course, you can also threshold that:
convert noise.jpg -virtual-pixel edge -statistic mean 50x50 -auto-level -threshold 80% result.png
As regards the lines, I want to use some type of mode to detect the frequently occurring values within small areas but as the colours vary, I need to reduce the palette of colours to find things that are just similarly coloured so I would go with an approach something like this which reduces the colours then calculates the mode:
convert noise2.jpg -colors 8 -statistic mode 8x8 result.jpg
It needs refinement, but you get the idea hopefully.
Alternatively, you could calculate a new image wherein each pixel is the standard deviation of the surrounding 3x3 pixels in the original image and then look for the ones where this value is lowest - i.e. where the image is darkest which corresponds to areas in the input image where there is least variation in the pixel colours:
convert noise2.png -statistic standarddeviation 3x3 -auto-level result.png

Loading Collada animation joints?

I'm having trouble loading joint data information from 'animation' node of collada file.
First, I try to load joints from 'library_visual_scenes' :
The first 2 joints look like that :
<visual_scene id="" name="">
<node name="joint1" id="joint1" sid="joint1" type="JOINT">
<translate sid="translate">0.000000 -2.000000 0.000000</translate>
<rotate sid="jointOrientZ">0 0 1 90.000000</rotate>
<rotate sid="rotateZ">0 0 1 0.000000</rotate>
<rotate sid="rotateY">0 1 0 0.000000</rotate>
<rotate sid="rotateX">1 0 0 0.000000</rotate>
<scale sid="scale">1.000000 1.000000 1.000000</scale>
<extra>
<node name="joint2" id="joint2" sid="joint2" type="JOINT">
<translate sid="translate">2.000000 0.000000 0.000000</translate>
<rotate sid="rotateZ">0 0 1 0.000000</rotate>
<rotate sid="rotateY">0 1 0 0.000000</rotate>
<rotate sid="rotateX">1 0 0 0.000000</rotate>
<scale sid="scale">1.000000 1.000000 1.000000</scale>
<extra>
which went well !
Maya joints :
My joints :
I would like to put a picture but as a new member, i'm not allowed. You'll have to trust me on this case, in my engine, joints are in the same place as in maya.
Then, I try to load joints from 'animation' node. Here is the problem, I can't find any jointOrient.
<animation id="joint1-anim" name="joint1">
<animation>
<source id="joint1-translate.Y-output">
<float_array id="joint1-translate.Y-output-array" count="2">-2.000000 -2.000000</float_array>
<animation>
<source id="joint1-rotateZ.ANGLE-output">
<float_array id="joint1-rotateZ.ANGLE-output-array" count="2">0.000000 0.000000</float_array>
<animation id="joint2-anim" name="joint2">
<animation>
<source id="joint2-translate.X-output">
<float_array id="joint2-translate.X-output-array" count="2">2.000000 2.000000</float_array>
So after loading joints, they look like that :
Anybody here could help ?
Thanks.
(Sorry as I don't have more than 10 reputations, i'm not allowed to put pictures.)
I finally figured out the answer, for those who might be interested.
The visual_scene node from collada will give you the bind pose for your joints.
So, I'm going to load visual_scene joint coordinates in a structure :
Something like that :
struct Pose
{
vec3 translation,
orientation,
rotation,
scale;
};
Pose bind_pose;
Then I'm going to create another instanciation of "Pose" struct, with a constructor which take a Pose as parameter :
Pose anim_pose(bind_pose);
So after construction, bind_pose from visual_scene and anim_pose are the same.
Then I'm going to iterate through all the animation node in library_animations, find the channel and get interested with :
the source data, which tell where to find joint animations info ("n" float(s) for "n" animation(s) :))
and the target joint.
<channel source="#joint1-translate.X" target="joint1/translate.X"></channel>
This tell us (and that's where I was a little lost) that we are going to REPLACE the targeted value with the source value.
If the source data find in channel node is the same as the target data, ie. :
bind_pose.translation.x has -3.0 as a value after loading visual_scene data, and
<source id="joint1-translate.X-output">
<float_array id="joint1-translate.X-output-array" count="1">-3.000000</float_array>
I do nothing.
If the source data is different from the target data, I simply replace in anim_pose with the good value.
And that's pretty much all you have to do to properly load animated joints from collada.
If you see anything wrong here, please tell me.
Hope this will help.

How to change textures in OpenGL using Haskell

I'm stuck trying to get multiple textures working in OpenGL using Haskell. I've been following the NeHe tuts and some various other OpenGL resources online, but the combination of slightly different calls and my newbness has caused a roadblock.
To be specific I want to render two cubes, each with a different texture (same texture for all 6 faces for the time being). Rendering one cube, with a texture is fine. Rendering multiple cubes of the same texture works fine as well. But I've not been able to figure out how to change textures for the two cubes
If I'm not mistaken the call to change textures is:
textureBinding $ Texture2D $= Just *mytexture*
where mytexture is supposed to be some form of textureID (a TextureObject). What the heck goes into the mytexture spot? This should be really easy but I've spent the better part of 2 days trying to figure this out to no avail. Any help is appreciated.
Main:
-- imports --
import Graphics.Rendering.OpenGL
import Graphics.UI.GLUT
import Data.IORef
import Display
import Bindings
import Control.Monad
import Textures
-- main --
main = do
(program, _) <- getArgsAndInitialize -- convenience, return program name and non-GLUT commands
initialDisplayMode $= [DoubleBuffered, WithDepthBuffer] -- inital display mode
initialWindowSize $= Size 600 600
createWindow "OpenGL Basics"
reshapeCallback $= Just reshape
angle <- newIORef (0.1::GLfloat) -- linked to angle of rotation (speed?)
delta <- newIORef (0.1::GLfloat)
position <- newIORef (0.0::GLfloat, 0.0) -- position, pass to display
texture Texture2D $= Enabled
tex <- getAndCreateTextures ["goldblock","pumpkintop"]
keyboardMouseCallback $= Just (keyboardMouse delta position) --require keys, delta, and position
idleCallback $= Just (idle angle delta) --ref idle angle and delta
displayCallback $= (display angle position tex) --ref display angle and delta
cullFace $= Just Front
mainLoop -- runs forever until a hard exit is called
In Main I call getAndCreateTextures (borrowed from the net), which returns a list of texture objects.
Display (for rendering):
-- display (main) --
display angle position tex = do
clear [ColorBuffer, DepthBuffer]
loadIdentity --modelview
shadeModel $= Smooth
(x,z) <- get position --get current position from init or keys
translate $ Vector3 x 0 z -- move to the position before drawing stuff
-- DO STUFF HERE
-- texture $ Texture2D $= Just wtfgoeshere
preservingMatrix $ do
a <- get angle
rotate a $ Vector3 (1::GLfloat) 0 0
-- rotate a $ Vector3 0 0 (1::GLfloat)
rotate a $ Vector3 0 (1::GLfloat) 0
-- scale 0.7 0.7 (0.7::GLfloat)
-- color $ Color3 (0.5::GLfloat) (0.1::GLfloat) (0.1::GLfloat)
cubeTexture (0.1::GLfloat)
swapBuffers
--idle (main)
idle angle delta = do
a <- get angle -- get existing angle
d <- get delta -- get delta
angle $= a + d -- new angle is old angle plus plus delta
postRedisplay Nothing
getAndCreateTextures is almost certainly doing what you need. The function of that name I found on the web has type IO [Maybe TextureObject], those are the TextureObject values you need. So you could do,
[gtex, ptex] <- getAndCreateTextures ["goldblock","pumpkintop"]
textureBinding Texture2D $= gtex
for example.
You pass the texture object. getAndCreateTextures seemingly gives you a list of texture objects. You pass one of those to the binding, like
textureBinding $ Texture2D $= Just tex[0]