Results 1 to 10 of 10

Thread: GeoShader as light

  1. #1
    Join Date
    Dec 2006
    Location
    Zurich
    Posts
    13

    Default GeoShader as light

    Hello all,

    I'm beginning to write shaders and i'm stuck with some basic problems. I don't even know if this is possible or not but I assume it is. So here it goes: I figured out how to create objects (polygons) in a geoshder. That wasn't that hard because of the manual examples. BUT I just can not manage to create a light in a geoshder. All I want to do, is to make a geoshader that is a point light that has the intensity of 1 and a color, lets say 0.8,0.2,0.8.

    If someone just could explain me some basic approaches to the solution.
    I have tried the mi_api_light_begin. That did the job and everything was compiled without error but the light didn't had any shader on it so it could not enlighten the scene.
    shader (default miNULLTAG) is the tag of a database element of type miSCENE_FUNCTION containing the light shader, which computes illumination by this light at render time.
    Then I tried some things with the help of this thread http://forum.lamrug.org/viewtopic.php?t=729 but it didn't work.
    I don't even know if this is the right way...

    I hope someone can help me...

    Thank you

    ps.
    I'm on a win xp 32 bit system
    programing shaders for xsi 5.11 mr 3.4
    and compiling with VS2005

  2. #2
    Join Date
    Dec 2004
    Location
    Marina Del Rey, California
    Posts
    2,916

    Default

    I'm not sure what that other topic reference has to do with lights.

    You do need to create a point light shader, maybe try mib_light_point, and set the light shader color parameter to your light color values.

    Look at mi_api_function_call to make the shader definition/use.

    Attach it to the light with mi_api_function_append
    Barton Gawboy
    Training and Special Projects, NVIDIA ARC
    LAmrUG Forum Originator

  3. #3
    Join Date
    Dec 2006
    Location
    Zurich
    Posts
    13

    Default

    ok, now we're a step closer...
    I didn't realize that I need to create the light shader within the c++ source. That's clear now.

    The thread I've posted in my last post was just a help to understand the declaration and definition of parameters and functions. it has nothing to do with the light itself.

    NOW, i have managed to create everything and to attach the shader to the light and the light (for this test an area sphere) is visible in the scene but doesn't illuminate anything. Pretty weird. Here is the code:


    Code:
    /////////////////////////////////////////////////////////////////////////////////////////////////////
    // Parameters
    
    	miColor l_color_eva = *mi_eval_color(&params->color);
    
    
    /////////////////////////////////////////////////////////////////////////////////////////////////////
    // Declaration
    
    miTag cache_decl = mi_api_name_lookup( mi_mem_strdup("light_shader") );
       if(!cache_decl)  //maybe already cached
       { 
    	miParameter *out_color = mi_api_parameter_decl(miTYPE_COLOR,mi_mem_strdup("out_color"),NULL);
    	miParameter *l_color = mi_api_parameter_decl(miTYPE_COLOR,mi_mem_strdup("l_color"),NULL);
    
    	miFunction_decl *func_decl = mi_api_funcdecl_begin(out_color,mi_mem_strdup("light_shader"),l_color);
    	func_decl->version = 1;
    	miTag func_decl_tag = mi_api_funcdecl_end();
       }
    
    /////////////////////////////////////////////////////////////////////////////////////////////////////
    // Definition
    
       miTag func_def;
       if(mi_api_function_call(mi_mem_strdup("light_shader")))
       { 
    	
    	
    	mi_api_parameter_name(mi_mem_strdup("l_color"));
    	mi_api_parameter_value(miTYPE_COLOR,&l_color_eva,NULL,NULL);
    
    
    
    	func_def = mi_api_function_call_end(miNULLTAG);
    	if(func_def){
    		
    	//mi_api_shader_add(mi_mem_strdup("lshader"), func_def);
    	mi_warning("defining output shader");
    	}
          else
          {
             mi_warning("problems defining output shader");
             return miFALSE;
          }
       } 
    
    /////////////////////////////////////////////////////////////////////////////////////////////////////
    // LIGHT
    
    	
    miVector org;
    org.x = 0;
    org.y = 0;
    org.z = 0;
    
        miLight *oLight = mi_api_light_begin(mi_mem_strdup("test"));
    	oLight->type = miLIGHT_ORIGIN;
    	oLight->origin = org;
    	oLight->visible = miTRUE;
    	oLight->area = miLIGHT_SPHERE;
    	oLight->primitive.sphere.radius = 1;
    	//mi_api_function_append(oLight->shader,func_def);
    	miTag lshader = oLight->shader;
    	oLight->shader = func_def;
    	oLight->shader = mi_api_function_append(oLight->shader, lshader); 
    
    
    	
    	return(mi_geoshader_add_result(result,mi_api_light_end()));
    	return( miTRUE );
    }
    The shader itself is just a color output! But I think this should be enough information to the light so it can shine.

    One other thing is the output that mr gives at render time:
    Code:
    ' INFO : API  0.3  debug: entering scope "_0@35:464::"
    ' INFO : LIB  0.3  debug: registry lookup: "light_shader" -> "light_shader"
    ' INFO : PHEN 0.3  debug: add shader 0x477 with decl 0x465
    ' WARNING : PHEN 0.3  warn : defining output shader
    ' INFO : API  0.3  debug: begin light test
    ' INFO : API  0.3  debug: leaving scope "_0@35:464::"
    ' INFO : SCEN 0.3  debug: calling traversal function 07A20F00 for instance 0x47b, DAG level 6
    ' INFO : SCEN 0.3  vdebg: TCB: No instances for a given path to '_0@35:464::test' 
    ' INFO : SCEN 0.3  debug: calling traversal function 07A20F00 for instance 0x46a, DAG level 2
    ' INFO : SCEN 0.3  debug: calling traversal function 07A20F00 for instance 0x473, DAG level 4
    ' INFO : SCEN 0.3  debug: calling traversal function 07A20F00 for instance 0x472, DAG level 6
    ' INFO : SCEN 0.3  vdebg: TCB: No instances for a given path to 'grid/Polygon Mesh(0)' 
    ' INFO : SCEN 0.3  debug: calling traversal function 07A20F00 for instance 0x41b, DAG level 2
    ' INFO : SCEN 0.3  debug: calling traversal function 07A20F00 for instance 0x41f, DAG level 4
    ' INFO : SCEN 0.3  vdebg: TCB: No instances for a given path to 'Point/Light' 
    ' INFO : PHEN 0.3  debug: calling exit shaders
    ' INFO : API  0.3  vdebg: "_0@2c:44f::1" has wrong scope, current scope is ""
    ' INFO : API  0.3  vdebg: "_0@2c:44f::0" has wrong scope, current scope is ""
    ' INFO : API  0.3  vdebg: "_0@2c:44f::test" has wrong scope, current scope is ""
    ' INFO : PHEN 0.3  debug: delete shader 0x4c6
    ' INFO : PHEN 0.3  debug: add shader 0x4c6 with decl 0x465
    ' INFO : PHEN 0.3  debug: delete shader 0x4c6
    ' INFO : SCEN 0.3  info : 1 geometry leaf instance (1 scheduled, 0 cached, 0 shared)
    ' INFO : SCEN 0.3  info : 2 light leaf instances
    What does this mean? Can someone explain to me what exactly is meant by this output.

    Thanks in advance...

  4. #4
    Join Date
    Dec 2004
    Location
    Marina Del Rey, California
    Posts
    2,916

    Default

    I'm not understanding why the warnings you have talk about an output shader. Are you using a template from someone else's code?

    For clarity, I'd get rid of confusing things.

    For one, there is no need to make the shader declaration if you already have an mi file that gets included to declare your "light_shader" shader.

    If you are simply passing a color out, why are there two parameters for your light shader, l_color and out_color? Can you simply state what the light_color shader is doing?

    So in your shader definition, you do the equivalent of

    "light_shader" ("l_color" <your evaluated color>)

    Now, if you had left the mi_api_shader_add, that would have made it a named shader, ie,

    shader "lshader" "light_shader" ("l_color" <your evaluated color>)

    The "lshader" name would be associated with the func_def tag.

    Then you would need mi_api_function_assign to refer to it by name. It returns the tag you are already keeping around in the func_def tag.

    Instead, it appears you make an anonymous use, without a named shader. However, you are writing to oLight->shader several times, which is extremely confusing to me. First you put your anonymous function call in the list by using func_def. Then you are appending the function that was there before that, which is probably null. What happens if you leave in only the oLight->shader = func_def statement, getting rid of the statement before and after.

    To be clear, I think you are trying to do in code what might look like this in an mi scene description.

    light "test"
    "light_shader" ("l_color" <your evaluated color>)
    origin 0 0 0
    visible on
    sphere 1
    end light

    By the way, I would tend to simplify at first taking smaller steps, so I would try it at first without using an area light.

    Now, how are you using the light? Is a material shader needing an instance to it? You might want to construct a named light instance to the light, before adding in with mi_geoshader_add_result(result, light_inst_tag). That function takes in either instances or objects/lights. Then, in your material shader, you can refer to that light instance by name.

    Either that or the material shader needs to use all the global lights.
    Barton Gawboy
    Training and Special Projects, NVIDIA ARC
    LAmrUG Forum Originator

  5. #5
    Join Date
    Dec 2006
    Location
    Zurich
    Posts
    13

    Default

    no no, that is the debug output of mental ray, there is no output shader.

    For the shader declaration I don't want to use a .mi this has other reasons, but that is no problem.

    OK, cleaned up all that what you said.

    There is no problem with area or not. I just enabled the area light so I could see if the shader is working, because if it is, there would be a colorized sphere in the scene render.

    Yes that's the thing. I need an instance of the light. How do I do this? I saw that I can make an instance with the mi_api_instance_begin() and this works with the mi_api_instance_end(), but how do I do the thing with the transformation function? And I want to add the light to the global lights


    Thank you very much for your help bart.

  6. #6
    Join Date
    Dec 2004
    Location
    Marina Del Rey, California
    Posts
    2,916

    Default

    First, regarding the messages, the warning is in the render output because of these lines in your code:

    Code:
       if&#40;func_def&#41;&#123;
          
       //mi_api_shader_add&#40;mi_mem_strdup&#40;"lshader"&#41;, func_def&#41;;
       mi_warning&#40;"defining output shader"&#41;;
       &#125;
          else
          &#123;
             mi_warning&#40;"problems defining output shader"&#41;;
             return miFALSE;
          &#125;
    I'm just asking to remove these statements because this is not an output shader, and the output could be misleading.
    Barton Gawboy
    Training and Special Projects, NVIDIA ARC
    LAmrUG Forum Originator

  7. #7
    Join Date
    Dec 2004
    Location
    Marina Del Rey, California
    Posts
    2,916

    Default

    Next, the declaration looks ok if you are not going to use an mi file. I'm still curious as to how you are using the two different input arguments. Once explained, it may help to describe what you are seeing.

    The mi_api_instance_end should return a tag you can use in the geoshader add function. The mi_api_instance_begin should take the light as an arg.
    If you locate the light with the origin, you can make the transform, the identity transform.
    Barton Gawboy
    Training and Special Projects, NVIDIA ARC
    LAmrUG Forum Originator

  8. #8
    Join Date
    Dec 2006
    Location
    Zurich
    Posts
    13

    Default

    thanks for the reply bart.

    I was not referring to the warning messages that I've wrote in the code but to the one I've posted.
    Code:
    ' INFO &#58; API  0&#46;3  vdebg&#58; "_0@2c&#58;44f&#58;&#58;1" has wrong scope, current scope is ""
    ' INFO &#58; API  0&#46;3  vdebg&#58; "_0@2c&#58;44f&#58;&#58;0" has wrong scope, current scope is ""
    ' INFO &#58; API  0&#46;3  vdebg&#58; "_0@2c&#58;44f&#58;&#58;test" has wrong scope, current scope is ""
    but that's ok now. they aren't coming up now anymore. I think it was because I didn't output the instance tag but the light tag. Now everything is working in my code (no errors or such) but the light is still not illuminating the scene. It seems as the light isn't added to the global light list and thus the objects material shader doesn't take the light into account on it's computation.

    [img]http&#58;//xsi&#46;jankin&#46;com/dump/geo_light&#46;jpg[/img]

    I have no clue what is going on.

    here is the code:
    Code:
    /////////////////////////////////////////////////////////////////////////////////////////////////////
    // Parameters
    
    	miColor l_color_eva = *mi_eval_color&#40;&params->color&#41;;
    
    /////////////////////////////////////////////////////////////////////////////////////////////////////
    // Declaration
    
    miTag cache_decl = mi_api_name_lookup&#40; mi_mem_strdup&#40;"light_shader"&#41; &#41;;
       if&#40;!cache_decl&#41;  //maybe already cached
       &#123; 
    	miParameter *l_color = mi_api_parameter_decl&#40;miTYPE_COLOR,mi_mem_strdup&#40;"l_color"&#41;,NULL&#41;;
    
    	miFunction_decl *func_decl = mi_api_funcdecl_begin&#40;NULL,mi_mem_strdup&#40;"light_shader"&#41;,l_color&#41;;
    	func_decl->version = 1;
    	miTag func_decl_tag = mi_api_funcdecl_end&#40;&#41;;
       &#125;
    
    /////////////////////////////////////////////////////////////////////////////////////////////////////
    // Definition
    
       miTag func_def;
       if&#40;mi_api_function_call&#40;mi_mem_strdup&#40;"light_shader"&#41;&#41;&#41;
       &#123; 
    
    	mi_api_parameter_name&#40;mi_mem_strdup&#40;"l_color"&#41;&#41;;
    	mi_api_parameter_value&#40;miTYPE_COLOR,&l_color_eva,NULL,NULL&#41;;
    
    	func_def = mi_api_function_call_end&#40;miNULLTAG&#41;;
    
    	if&#40;func_def&#41;mi_api_shader_add&#40;mi_mem_strdup&#40;"lshader"&#41;, func_def&#41;;
    
          else
          &#123;
             mi_warning&#40;"problems with the lshader"&#41;;
             return miFALSE;
          &#125;
       &#125; 
    
    /////////////////////////////////////////////////////////////////////////////////////////////////////
    // LIGHT
    
    	miVector org;
    	org&#46;x = 0;
    	org&#46;y = 0;
    	org&#46;z = 0;
    
        miLight *oLight = mi_api_light_begin&#40;mi_mem_strdup&#40;"test_light"&#41;&#41;;
    	oLight->type = miLIGHT_ORIGIN;
    	//oLight->origin = org;
    	//oLight->visible = miTRUE;
    	//oLight->area = miLIGHT_SPHERE;
    	//oLight->primitive&#46;sphere&#46;radius = 2;
    	oLight->shader = mi_api_function_assign&#40;mi_mem_strdup&#40;"lshader"&#41;&#41;;
    	mi_api_light_end&#40;&#41;;
    	
    	mi_api_instance_begin&#40;mi_mem_strdup&#40;"test_light_inst"&#41;&#41;;
    	return&#40;mi_geoshader_add_result&#40;result,mi_api_instance_end&#40;mi_mem_strdup&#40;"test_light"&#41;,miNULLTAG,miNULLTAG&#41;&#41;&#41;;
    
    	return&#40; miTRUE &#41;;
    &#125;

  9. #9
    Join Date
    Dec 2004
    Location
    Marina Del Rey, California
    Posts
    2,916

    Default

    Ahh, the code is getting clearer.

    Try moving the origin up above the plane a bit.
    And again, what is your material, and how is it knowing about lights?

    Some materials know how to grab the global list of lights, but it has to be incorporated into the material shader.

    Regarding the "light_shader" light shader, could you show that code? Before you had two input arguments, so I wasn't sure how that was working on the inside. Now, you are back to one, l_color. I know it might be extremely simple, but there may be a simple typo. Also, you could put an mi_info statement in your light shader to make sure it is getting called with the correct l_color.

    Finally, have you tested just putting in a color, say white, directly instead of using &l_color_eva, just to eliminate potential pointer dereferencing typos?
    You could also print it out with mi_info, I suppose.
    Barton Gawboy
    Training and Special Projects, NVIDIA ARC
    LAmrUG Forum Originator

  10. #10
    Join Date
    Dec 2004
    Location
    Marina Del Rey, California
    Posts
    2,916

    Default

    BTW, you could make a material shader which just listed the global lights, to check to see if yours was added. There is an mi_query for that.
    Barton Gawboy
    Training and Special Projects, NVIDIA ARC
    LAmrUG Forum Originator

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •