About Store Forum Documentation Contact



Post Reply 
Shader-related problem
Author Message
3DRaddict Offline
Member

Post: #1
Shader-related problem
I'm currently having a shader-related problem which is preventing me from continuing with my Surfing Simulation Project.
I have two meshes, each with a different custom shader.
The problem is that I cannot seem to update each shader's parameter values seperately. Changing a value in one shader also changes the value in the other shader as well.
To better illustrate the problem I've put together a small example project.

Firstly here is a video:



You can see that adjusting the Ball1 slider (on the left) has no effect on Ball1.
Adjusting the Ball2 slider (on the right) changes the opacity of BOTH Ball1 AND Ball2.

Here is the custom shader code for use with Ball1:
PHP Code:
/******************************************************************************/
#include "Main.h"
/******************************************************************************/
// PARAMETERS
/******************************************************************************/
BUFFER(ShaderWithParameterBuffer// store parameters in custom Constant Buffer
   
Flt Opacity_1// declare a global Opacity_1 parameter
BUFFER_END
/******************************************************************************/
/******************************************************************************/
// VERTEX SHADER
/******************************************************************************/
void VS
(
   
// vertex input
   
VtxInput vtx,

   
// output
   
out Vec2 outTex:TEXCOORD,
   
out Vec4 outVtx:POSITION
)
{
   
outTex=vtx.tex(); // copy output texture coordinates

   
Vec view_space_pos=          TransformPos(vtx.pos4()) ; // transform input mesh vertex position by 'object/camera matrix' to view space
   
Vec view_space_nrm=Normalize(TransformDir(vtx.nrm ())); // transform input mesh vertex normal   by 'object/camera matrix' to view space and normalize it

   
outVtx=Project(view_space_pos); // return output position transformed by projection matrix
}
/******************************************************************************/
// PIXEL SHADER
/******************************************************************************/
Vec4 PS
(
   
Vec2 inTex:TEXCOORD
):COLOR
{
   
Vec  texture_color=Tex(ColinTex).rgb,
       
material_color=MaterialColor().rgb;

   return 
Vec4(texture_color*material_colorOpacity_1);
}
/******************************************************************************/
// TECHNIQUE
/******************************************************************************/
TECHNIQUE(MainVS(), PS()); // create the Shader's Main Technique which will be automatically used for meshes, here you can specify custom Vertex/Pixel Shader functions
/******************************************************************************/ 

And here is the custom shader code for use with Ball2:
PHP Code:
/******************************************************************************/
#include "Main.h"
/******************************************************************************/
// PARAMETERS
/******************************************************************************/
BUFFER(ShaderWithParameterBuffer// store parameters in custom Constant Buffer
   
Flt Opacity_2// declare a global Opacity_2 parameter
BUFFER_END
/******************************************************************************/
/******************************************************************************/
// VERTEX SHADER
/******************************************************************************/
void VS
(
   
// vertex input
   
VtxInput vtx,

   
// output
   
out Vec2 outTex:TEXCOORD,
   
out Vec4 outVtx:POSITION
)
{
   
outTex=vtx.tex(); // copy output texture coordinates

   
Vec view_space_pos=          TransformPos(vtx.pos4()) ; // transform input mesh vertex position by 'object/camera matrix' to view space
   
Vec view_space_nrm=Normalize(TransformDir(vtx.nrm ())); // transform input mesh vertex normal   by 'object/camera matrix' to view space and normalize it

   
outVtx=Project(view_space_pos); // return output position transformed by projection matrix
}
/******************************************************************************/
// PIXEL SHADER
/******************************************************************************/
Vec4 PS
(
   
Vec2 inTex:TEXCOORD
):COLOR
{
   
Vec  texture_color=Tex(ColinTex).rgb,
       
material_color=MaterialColor().rgb;

   return 
Vec4(texture_color*material_colorOpacity_2);
}
/******************************************************************************/
// TECHNIQUE
/******************************************************************************/
TECHNIQUE(MainVS(), PS()); // create the Shader's Main Technique which will be automatically used for meshes, here you can specify custom Vertex/Pixel Shader functions
/******************************************************************************/ 

And here is the project application code for this example:
PHP Code:
/******************************************************************************/
// NOTE: Change the path to suit your location of "material_user_shader.enum.h"
#include "C:/EsenthelEngine_DX10plus/Editor/Projects/material_user_shader.enum.h"
/******************************************************************************/
// --------------------------------------------------
// This is the "material_user_shader.enum.h" file :
// --------------------------------------------------
//enum MATERIAL_USER_SHADER
//{
//   MUS_DEFAULT,
//   MUS_CUSTOM ,
//   MUS_CUSTOM2,
//};
// --------------------------------------------------
/******************************************************************************/

Mesh ball1ball2;
Matrix ball1_matrixball2_matrix;

MaterialPtr mat0;
Material    mat0_with_custom_shader;
MaterialPtr mat1;
Material    mat1_with_custom_shader;

Slider   slider1  // gui slider
Slider   slider2  // gui slider
/******************************************************************************/
void CompileShaders_1()
{
   if(
D.shaderModel()==SM_GL)
   {
      
ShaderCompile("C:/EsenthelEngine_DX10plus/Editor/Projects/Shader HLSL/TwoShader_1.cpp"S+DataPath()+"Shader/GL/User/Custom Shader"SM_GL);
   }else
   if(
D.shaderModel()>=SM_4)
   {
      
ShaderCompile("C:/EsenthelEngine_DX10plus/Editor/Projects/Shader HLSL/TwoShader_1.cpp"S+DataPath()+"Shader/4/User/Custom Shader"SM_4);
   }else
   {
      
ShaderCompile("C:/EsenthelEngine_DX10plus/Editor/Projects/Shader HLSL/TwoShader_1.cpp"S+DataPath()+"Shader/2/User/Custom Shader"SM_2);
      
ShaderCompile("C:/EsenthelEngine_DX10plus/Editor/Projects/Shader HLSL/TwoShader_1.cpp"S+DataPath()+"Shader/3/User/Custom Shader"SM_3);
   }
}
/******************************************************************************/
void CompileShaders_2()
{
   if(
D.shaderModel()==SM_GL)
   {
      
ShaderCompile("C:/EsenthelEngine_DX10plus/Editor/Projects/Shader HLSL/TwoShader_2.cpp"S+DataPath()+"Shader/GL/User/Custom Shader2"SM_GL);
   }else
   if(
D.shaderModel()>=SM_4)
   {
      
ShaderCompile("C:/EsenthelEngine_DX10plus/Editor/Projects/Shader HLSL/TwoShader_2.cpp"S+DataPath()+"Shader/4/User/Custom Shader2"SM_4);
   }else
   {
      
ShaderCompile("C:/EsenthelEngine_DX10plus/Editor/Projects/Shader HLSL/TwoShader_2cpp"S+DataPath()+"Shader/2/User/Custom Shader2"SM_2);
      
ShaderCompile("C:/EsenthelEngine_DX10plus/Editor/Projects/Shader HLSL/TwoShader_2.cpp"S+DataPath()+"Shader/3/User/Custom Shader2"SM_3);
   }
}
/******************************************************************************/
ShaderTechGetShader(RENDER_MODE modeMaterial *material[4], UInt mesh_base_flagInt lod_indexBool allow_tesselation)
{
   if(
material[0])switch(material[0]->user_shader)
   {
      case 
MUS_CUSTOM:
      {
         if(
mode==RM_BLEND)return Shaders("User/Custom Shader")->firstTech();
         return 
NULL;
      }break;
      case 
MUS_CUSTOM2:
      {
         if(
mode==RM_BLEND)return Shaders("User/Custom Shader2")->firstTech();
         return 
NULL;
      }break;
   }
   return 
GetDefaultShader(modematerialmesh_base_flaglod_indexallow_tesselation);
}
/******************************************************************************/
void InitPre()
{
   
EE_INIT();
   
D.ambientPower(0.3f);
   
D.setGetShaderFunc(GetShader);
}
/******************************************************************************/
Bool Init()
{
   
// set initial camera position
   
Vec InitialCameraLocation Vec(0.0f0.0f,-4.0f);
   
Cam.setPosDir(InitialCameraLocation);
   

   
// compile shaders
   
CompileShaders_1(); // compile "TwoShader_1" as "Custom Shader"
   
CompileShaders_2(); // compile "TwoShader_2" as "Custom shader2"
   
   // create sliders to control opacity of each ball
   
Gui+=slider1.create(Rect( -1.0, -0.6, -0.2, -0.5), 0.5); // create slider1 with initial value 0.5
   
Gui+=slider2.create(Rect0.4, -0.61.2, -0.5), 0.5);   // create slider2 with initial value 0.5
   
   // set materials and meshes
   
mat0.require(UID(674972757134201076721064615921897094128));
   
mat0_with_custom_shader=*mat0;
   
mat0_with_custom_shader.user_shader=MUS_CUSTOM// custom shader for ball1 material
   
mat0_with_custom_shader.validate();
   
mat1.require(UID(674972757134201076721064615921897094128));
   
mat1_with_custom_shader=*mat1;
   
mat1_with_custom_shader.user_shader=MUS_CUSTOM2// custom shader for ball2 material
   
mat1_with_custom_shader.validate();

   
ball1.parts.New().base.create(Ball(1), VTX_TEX0|VTX_NRM|VTX_TAN);
   
ball2.parts.New().base.create(Ball(1), VTX_TEX0|VTX_NRM|VTX_TAN);

   
ball1.setMaterial(&mat0_with_custom_shader ).setRender().setBox(); // ball1 to use MUS_CUSTOM
   
ball2.setMaterial(&mat1_with_custom_shader ).setRender().setBox(); // ball2 to use MUS_CUSTOM2
   
   
ball1_matrix.setPos(Vec(-200));
   
ball2_matrix.setPos(Vec(200));

   return 
true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Update()
{
   if(
Kb.bp(KB_ESC))return false;
   
//Cam.transformByMouse(0.1f, 1000, CAMH_ZOOM|(Ms.b(1)?CAMH_MOVE:CAMH_ROT));
   
Cam.set();
   
   
Gui.update();

   
// set shader's custom parameter value
   
SPSet(8"Opacity_1"slider1());
   
SPSet(8"Opacity_2"slider2());

   return 
true;
}
/******************************************************************************/
void Render()
{
   switch(
Renderer())
   {
      case 
RM_PREPARE:
      {
         
         
LightDir(!Vec(00, -1)).add();
      }break;
      case 
RM_BLEND:
      {
         
         
ball1.drawBlend(ball1_matrix);
         
ball2.drawBlend(ball2_matrix);
         
      }break;
      
   }
}
void Draw()
{
   
Renderer(Render);
   
Gui.draw();
   
}
/******************************************************************************/ 

There must be something wrong in my logic which I'm failing to see, so any pointers in the right direction will be gratefully received.
You could even copy/paste into your own project if that would help in gaining a solution for me.wink
11-02-2014 12:22 PM
Visit this user's website Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #2
RE: Shader-related problem
Hello!

I was able to reproduce the issue on DX10+, on DX9 it works fine.

I'll investigate this.

BTW you can check this out:
Renderer.h
Code:
/******************************************************************************
   Use following functions for specifying Shader Parameter Changes for specific instances of meshes
   Call in following order: 1. link, 2. draw, 3. unlink, like this:

        LinkShaderParamChanges(changes); mesh.draw(..);
      UnlinkShaderParamChanges(changes);

/******************************************************************************/
void   LinkShaderParamChanges(const_mem_addr C Memc<ShaderParamChange> &changes); // this can  be called before drawing mesh, 'changes' must point to object in constant memory address (only pointer is stored through which the object is later accessed), 'changes' must exist until the rendering is finished
void UnlinkShaderParamChanges(const_mem_addr C Memc<ShaderParamChange> &changes); // this must be called after  drawing mesh
11-03-2014 05:49 AM
Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #3
RE: Shader-related problem
Ok I've found out the reason:
you're using Shader Buffers with the same name:
BUFFER(ShaderWithParameterBuffer)
in both shaders, which makes them shared (only one buffer in total).

You need to use different names for that case.
11-03-2014 05:54 AM
Find all posts by this user Quote this message in a reply
3DRaddict Offline
Member

Post: #4
RE: Shader-related problem
Thank you, Esenthel, for picking this up and finding the solution!
Yes, its the small overlooked things that often cause the most problems in coding.
A lesson to all... be aware when copying/pasting code!grin
11-03-2014 06:24 AM
Visit this user's website Find all posts by this user Quote this message in a reply
Post Reply