Difference between revisions of "Implementing a Texture"

From LuxCoreRender Wiki
Jump to navigation Jump to search
(One intermediate revision by the same user not shown)
Line 13: Line 13:
Commit with example: adding the "Divide" texture: https://github.com/LuxCoreRender/LuxCore/commit/ce6e23c244b1bb426c1dcd13099a41982e565b88
Commit with example: adding the "Divide" texture: https://github.com/LuxCoreRender/LuxCore/commit/ce6e23c244b1bb426c1dcd13099a41982e565b88


==== Creating the header file ====
=== Creating the header file ===


==== Creating the source file ====
=== Creating the source file ===


TODO: Description of the methods that need to be implemented:
Each texture has to implement the following methods:


* GetFloatValue
==== Y() ====
* GetSpectrumValue
* Filter
* Y
etc.


What do they do, what should they return?
The average luminance of the whole texture.
You can use the [https://github.com/LuxCoreRender/LuxCore/blob/c520ded3d8c845e30ef1176607109c5fa4eda4c1/include/luxrays/core/color/color.h#L285 Y()] method of the Spectrum class to get this value.


==== Modifying the base texture header ====
In case this information cannot be computed, 1.0 should be returned.
 
==== Filter() ====
 
The average mean of the whole texture.
You can use the [https://github.com/LuxCoreRender/LuxCore/blob/c520ded3d8c845e30ef1176607109c5fa4eda4c1/include/luxrays/core/color/color.h#L288 Filter()] method of the Spectrum class to get this value.
 
In case this information cannot be computed, 1.0 should be returned.
 
==== GetFloatValue(HitPoint) ====
 
This method is called when a texture slot of a material/volume/texture requests a float value from the texture. For example, the roughness slot of a glossy2 material would call this method, because the roughness is a floating point input.
 
It should return the float value at this particular hitpoint.
 
==== GetSpectrumValue(HitPoint) ====
 
This method is called when a Spectrum (RGB color) value is requested from the texture.
 
It should return the color value at this particular hitpoint.
 
If your texture is only usable for floating point math, you can return a Spectrum constructed from the floating point result:
<pre>return Spectrum(GetFloatValue(hitPoint));</pre>
 
=== Modifying the base texture header ===


Open the file include/slg/textures/texture.h<br>
Open the file include/slg/textures/texture.h<br>
Add your new texture type to the <code>TextureType</code> enum.
Add your new texture type to the <code>TextureType</code> enum.


==== Modifying Sceneparse ====
=== Modifying Sceneparse ===


Open src/slg/scene/parsetextures.cpp<br>
Open src/slg/scene/parsetextures.cpp<br>
Line 39: Line 60:
Next, go to the method <code>Scene::CreateTexture</code>, scroll down until the end of the big <code>if/else</code> statement and add a new <code>else if</code> for your texture.
Next, go to the method <code>Scene::CreateTexture</code>, scroll down until the end of the big <code>if/else</code> statement and add a new <code>else if</code> for your texture.


==== Modifying CMakeLists.txt ====
=== Modifying CMakeLists.txt ===


Open src/slg/CMakeLists.txt<br>
Open src/slg/CMakeLists.txt<br>
Search for <code>set(SLG_CORE_SRCS</code> and add your source filepath among the other textures (they are sorted alphabetically).
Search for <code>set(SLG_CORE_SRCS</code> and add your source filepath among the other textures (they are sorted alphabetically).


==== Compile and Test ====
=== Compile and Test ===
To test your plugin, compile LuxCore: [[Compiling_LuxCore]]
To test your plugin, compile LuxCore: [[Compiling_LuxCore]]


Line 76: Line 97:
* src/slg/engines/pathoclbase/pathoclbaseoclthreadkernels.cpp
* src/slg/engines/pathoclbase/pathoclbaseoclthreadkernels.cpp


==== include/slg/textures/texture_funcs.cl ====
=== include/slg/textures/texture_funcs.cl ===


<pre>
<pre>
Line 100: Line 121:
</pre>
</pre>


==== include/slg/textures/texture_types.cl ====
=== include/slg/textures/texture_types.cl ===


Add a new texture type for your texture to the <code>TextureType</code> enum.
Add a new texture type for your texture to the <code>TextureType</code> enum.
Line 112: Line 133:
and add it to the big union in the <code>Texture</code> struct.
and add it to the big union in the <code>Texture</code> struct.


==== src/slg/engines/pathoclbase/compiletextures.cpp ====
=== src/slg/engines/pathoclbase/compiletextures.cpp ===


Include the C++ header of your texture.
Include the C++ header of your texture.
Line 120: Line 141:
Add a new <code>case</code> for your function to the <code>CompiledScene::GetTexturesEvaluationSourceCode()</code> method.
Add a new <code>case</code> for your function to the <code>CompiledScene::GetTexturesEvaluationSourceCode()</code> method.


==== src/slg/engines/pathoclbase/pathoclbaseoclthreadkernels.cpp ====
=== src/slg/engines/pathoclbase/pathoclbaseoclthreadkernels.cpp ===


Add a new <code>if</code> statement for your texture to the <code>PathOCLBaseOCLRenderThread::InitKernels()</code> method.
Add a new <code>if</code> statement for your texture to the <code>PathOCLBaseOCLRenderThread::InitKernels()</code> method.

Revision as of 20:13, 6 June 2019

Note: this guide is not yet finished. All necessary steps for creating are texture are included, with C++ and OpenCL code, but some of the steps are not explained in detail yet.

C++ Code

Files that need to be created:

  • Header: include/slg/textures/yourtexturename.h
  • Source: src/slg/textures/yourtexturename.cpp

Files that need to be edited:

  • Base texture header: include/slg/textures/texture.h
  • Sceneparse: src/slg/scene/parsetextures.cpp
  • CMakeLists.txt: src/slg/CMakeLists.txt

Commit with example: adding the "Divide" texture: https://github.com/LuxCoreRender/LuxCore/commit/ce6e23c244b1bb426c1dcd13099a41982e565b88

Creating the header file

Creating the source file

Each texture has to implement the following methods:

Y()

The average luminance of the whole texture. You can use the Y() method of the Spectrum class to get this value.

In case this information cannot be computed, 1.0 should be returned.

Filter()

The average mean of the whole texture. You can use the Filter() method of the Spectrum class to get this value.

In case this information cannot be computed, 1.0 should be returned.

GetFloatValue(HitPoint)

This method is called when a texture slot of a material/volume/texture requests a float value from the texture. For example, the roughness slot of a glossy2 material would call this method, because the roughness is a floating point input.

It should return the float value at this particular hitpoint.

GetSpectrumValue(HitPoint)

This method is called when a Spectrum (RGB color) value is requested from the texture.

It should return the color value at this particular hitpoint.

If your texture is only usable for floating point math, you can return a Spectrum constructed from the floating point result:

return Spectrum(GetFloatValue(hitPoint));

Modifying the base texture header

Open the file include/slg/textures/texture.h
Add your new texture type to the TextureType enum.

Modifying Sceneparse

Open src/slg/scene/parsetextures.cpp
Include the new header file you created for your texture (the list is alphabetic).

Next, go to the method Scene::CreateTexture, scroll down until the end of the big if/else statement and add a new else if for your texture.

Modifying CMakeLists.txt

Open src/slg/CMakeLists.txt
Search for set(SLG_CORE_SRCS and add your source filepath among the other textures (they are sorted alphabetically).

Compile and Test

To test your plugin, compile LuxCore: Compiling_LuxCore

After the compilation succeeds, you will need a scene to test your plugin. The easiest method is to edit one of the .scn files in the scenes/luxball directory.

TODO Example

Now, run luxcoreui from the root LuxCore directory with

./bin/luxcoreui ./scenes/luxball/luxball-sunset.cfg

TODO result example image

OpenCL Code

Files that need to be edited:

  • include/slg/textures/texture_funcs.cl
  • include/slg/textures/texture_types.cl
  • src/slg/engines/pathoclbase/compiletextures.cpp
  • src/slg/engines/pathoclbase/pathoclbaseoclthreadkernels.cpp

include/slg/textures/texture_funcs.cl

//------------------------------------------------------------------------------
// Your texture
//------------------------------------------------------------------------------

#if defined(PARAM_ENABLE_TEX_YOURS)

OPENCL_FORCE_NOT_INLINE float YourTexture_ConstEvaluateFloat(__global HitPoint *hitPoint,
		const float tex1, const float tex2) {
	// The actual work is done here (this function is executed when a float value of your texture is requested)
	return tex1 * tex2;
}

OPENCL_FORCE_NOT_INLINE float3 YourTexture_ConstEvaluateSpectrum(__global HitPoint *hitPoint,
		const float3 tex1, const float3 tex2) {
	// The actual work is done here (this function is executed when a color value of your texture is requested)
	return tex1 * tex2;
}

#endif

include/slg/textures/texture_types.cl

Add a new texture type for your texture to the TextureType enum.

If your texture has input parameters, create a new struct in the form

typedef struct {
	unsigned int tex1Index, tex2Index;
} YourTexParam;

and add it to the big union in the Texture struct.

src/slg/engines/pathoclbase/compiletextures.cpp

Include the C++ header of your texture.

Add a new case for your function to the CompiledScene::CompileTextures() method.

Add a new case for your function to the CompiledScene::GetTexturesEvaluationSourceCode() method.

src/slg/engines/pathoclbase/pathoclbaseoclthreadkernels.cpp

Add a new if statement for your texture to the PathOCLBaseOCLRenderThread::InitKernels() method.